Introduce basic functionality for invalidation of distributionsets (#1179)

* Basic DS invalidation functionality

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add checks for valid/complete DS

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Stop rollouts + auto assignments when invalidating a DS

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add methods to count AAs + rollouts for invalidation

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Small refactoring for DS management

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add invalidation functionality to REST API

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix update stopped rollouts status

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add various tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Introduce countActionsForInvalidation

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix event tests with incomplete DS

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add H2 migration script

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix action count method

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix REST documentation tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Change flyway version number

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add lock for DS invalidation + adapt tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Move concurrency test to own class

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Handle possible InterruptedException

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix concurrency test

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Use one transaction for all invalidations

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add invalidate endpoint to REST docu

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Execute invalidation in transaction when actions are cancelled

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Check that distribution set is valid when editing/creating metadata

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Remove all changes in UI

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add DB migration files for all databases

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Implement review findings

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Move DS invalidation to own class to check permissions for single steps

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Move invalidation count methods to management classes

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix failing tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>
This commit is contained in:
Sebastian Firsching
2021-09-30 15:26:36 +02:00
committed by GitHub
parent b25e118e6c
commit 825cb64448
66 changed files with 2413 additions and 511 deletions

View File

@@ -20,11 +20,11 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Action;
@@ -34,6 +34,7 @@ import org.eclipse.hawkbit.repository.model.DeploymentRequest;
import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation.CancelationType;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
@@ -56,7 +57,7 @@ public interface DeploymentManagement {
*
* @param deploymentRequests
* information about all target-ds-assignments that shall be made
*
*
* @return the list of assignment results
*
* @throws IncompleteDistributionSetException
@@ -66,17 +67,18 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
*
* @throws AssignmentQuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
* @throws MultiAssignmentIsNotEnabledException
* if the request results in multiple assignments to the same
* target and multiassignment is disabled
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> assignDistributionSets(@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
List<DistributionSetAssignmentResult> assignDistributionSets(
@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
/**
* Assigns {@link DistributionSet}s to {@link Target}s according to the
@@ -88,7 +90,7 @@ public interface DeploymentManagement {
* information about all target-ds-assignments that shall be made
* @param actionMessage
* an optional message for the action status
*
*
* @return the list of assignment results
*
* @throws IncompleteDistributionSetException
@@ -98,23 +100,23 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
*
* @throws AssignmentQuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
* @throws MultiAssignmentIsNotEnabledException
* if the request results in multiple assignments to the same
* target and multiassignment is disabled
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> assignDistributionSets(String initiatedBy,
@Valid @NotEmpty List<DeploymentRequest> deploymentRequests, String actionMessage);
/**
/**
* build a {@link DeploymentRequest} for a target distribution set
* assignment
*
*
* @param controllerId
* ID of target
* @param distributionSetId
@@ -128,9 +130,9 @@ public interface DeploymentManagement {
/**
* Registers "offline" assignments. "offline" assignment means adding a
* completed action for a {@link DistributionSet} to a {@link Target}.
*
*
* The handling differs to hawkBit-managed updates by means that:<br/>
*
*
* <ol type="A">
* <li>it ignores targets completely that are in
* {@link TargetUpdateStatus#PENDING}.</li>
@@ -139,12 +141,12 @@ public interface DeploymentManagement {
* status to {@link TargetUpdateStatus#IN_SYNC}.</li>
* <li>does not send a {@link TargetAssignDistributionSetEvent}.</li>
* </ol>
*
*
* @param assignments
* target IDs with the respective distribution set ID which they
* are supposed to be assigned to
* @return the assignment results
*
*
* @throws IncompleteDistributionSetException
* if mandatory {@link SoftwareModuleType} are not assigned as
* defined by the {@link DistributionSetType}.
@@ -152,11 +154,11 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
*
* @throws AssignmentQuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
*
*
* @throws MultiAssignmentIsNotEnabledException
* if the request results in multiple assignments to the same
* target and multiassignment is disabled
@@ -173,7 +175,7 @@ public interface DeploymentManagement {
* to be canceled
*
* @return canceled {@link Action}
*
*
* @throws CancelActionNotAllowedException
* in case the given action is not active or is already a cancel
* action
@@ -221,20 +223,43 @@ public interface DeploymentManagement {
* @param controllerId
* the target associated to the actions to count
* @return the count value of found actions associated to the target
*
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countActionsByTarget(@NotEmpty String controllerId);
/**
* Counts all active {@link Action}s referring to the given DistributionSet.
*
* @param distributionSet
* DistributionSet to count the {@link Action}s from
* @return the count of actions referring to the given distributionSet
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countActionsByDistributionSetIdAndActiveIsTrue(Long distributionSet);
/**
* Counts all active {@link Action}s referring to the given DistributionSet
* that are not in a given state.
*
* @param distributionSet
* DistributionSet to count the {@link Action}s from
* @param status
* the state the actions should not have
* @return the count of actions referring to the given distributionSet
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countActionsByDistributionSetIdAndActiveIsTrueAndStatusIsNot(Long distributionSet, Status status);
/**
* Get the {@link Action} entity for given actionId.
*
* @param actionId
* to be id of the action
* @return the corresponding {@link Action}
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Optional<Action> findAction(long actionId);
@@ -252,7 +277,7 @@ public interface DeploymentManagement {
/**
* Retrieves all {@link Action} which assigned to a specific
* {@link DistributionSet}.
*
*
* @param pageable
* the page request parameter for paging and sorting the result
* @param distributionSetId
@@ -260,7 +285,7 @@ public interface DeploymentManagement {
* in the result
* @return a list of {@link Action} which are assigned to a specific
* {@link DistributionSet}
*
*
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*/
@@ -279,7 +304,7 @@ public interface DeploymentManagement {
* the page request
* @return a slice of actions assigned to the specific target and the
* specification
*
*
* @throws RSQLParameterUnsupportedFieldException
* if a field in the RSQL string is used but not provided by the
* given {@code fieldNameProvider}
@@ -299,7 +324,7 @@ public interface DeploymentManagement {
* @param pageable
* the pageable request to limit, sort the actions
* @return a slice of actions found for a specific target
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Slice<Action> findActionsByTarget(@NotEmpty String controllerId, @NotNull Pageable pageable);
@@ -313,7 +338,7 @@ public interface DeploymentManagement {
* @param actionId
* to be filtered on
* @return the corresponding {@link Page} of {@link ActionStatus}
*
*
* @throws EntityNotFoundException
* if action with given ID does not exist
*/
@@ -346,13 +371,13 @@ public interface DeploymentManagement {
/**
* Retrieves all active {@link Action}s of a specific target.
*
*
* @param pageable
* the page request parameter for paging and sorting the result
* @param controllerId
* the target associated with the actions
* @return a list of actions associated with the given target
*
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
@@ -367,7 +392,7 @@ public interface DeploymentManagement {
* @param controllerId
* the target associated with the actions
* @return a list of actions associated with the given target
*
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
@@ -377,13 +402,13 @@ public interface DeploymentManagement {
/**
* Retrieves active {@link Action}s with highest weight that are assigned to
* a {@link Target}.
*
*
* @param controllerId
* identifies the target to retrieve the action from
* @param maxActionCount
* max size of returned list
* @return the action
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
List<Action> findActiveActionsWithHighestWeight(@NotEmpty String controllerId, int maxActionCount);
@@ -391,7 +416,7 @@ public interface DeploymentManagement {
/**
* Get weight of an Action. Returns the default value if the weight is null
* according to the properties.
*
*
* @param action
* to extract the weight from
* @return weight of the action
@@ -408,10 +433,10 @@ public interface DeploymentManagement {
* to be canceled
*
* @return quite {@link Action}
*
*
* @throws CancelActionNotAllowedException
* in case the given action is not active
*
*
* @throws EntityNotFoundException
* if action with given ID does not exist
*/
@@ -425,7 +450,7 @@ public interface DeploymentManagement {
* @param actionId
* the ID of the action
* @return the updated or the found {@link Action}
*
*
* @throws EntityNotFoundException
* if action with given ID does not exist
*/
@@ -438,7 +463,7 @@ public interface DeploymentManagement {
*
* @param targetIds
* ids of the {@link Target}s the actions belong to
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
void cancelInactiveScheduledActionsForTargets(List<Long> targetIds);
@@ -468,11 +493,11 @@ public interface DeploymentManagement {
/**
* Returns {@link DistributionSet} that is assigned to given {@link Target}.
*
*
* @param controllerId
* of target
* @return assigned {@link DistributionSet}
*
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
@@ -481,11 +506,11 @@ public interface DeploymentManagement {
/**
* Returns {@link DistributionSet} that is installed on given
* {@link Target}.
*
*
* @param controllerId
* of target
* @return installed {@link DistributionSet}
*
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
@@ -494,20 +519,20 @@ public interface DeploymentManagement {
/**
* Deletes actions which match one of the given action status and which have
* not been modified since the given (absolute) time-stamp.
*
*
* @param status
* Set of action status.
* @param lastModified
* A time-stamp in milliseconds.
*
*
* @return The number of action entries that were deleted.
*/
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
int deleteActionsByStatusAndLastModifiedBefore(@NotNull Set<Action.Status> status, long lastModified);
/**
* Checks if there is an action for the device with the given controller ID that
* is in the {@link Action.Status#CANCELING} state.
* Checks if there is an action for the device with the given controller ID
* that is in the {@link Action.Status#CANCELING} state.
*
* @param controllerId
* of target
@@ -516,4 +541,16 @@ public interface DeploymentManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
boolean hasPendingCancellations(@NotEmpty String controllerId);
/**
* Cancels all actions that refer to a given distribution set. This method
* is called when a distribution set is invalidated.
*
* @param cancelationType
* defines if a force or soft cancel is executed
* @param set
* the distribution set for that the actions should be canceled
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
void cancelActionsForDistributionSet(final CancelationType cancelationType, final DistributionSet set);
}

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2021 Bosch.IO 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;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidationCount;
/**
* A DistributionSetInvalidationManagement service provides operations to
* invalidate {@link DistributionSet}s.
*
*/
public interface DistributionSetInvalidationManagement {
/**
* Invalidates a given {@link DistributionSet}. The invalidation always
* cancels all auto assignments referring this {@link DistributionSet} and
* can not be undone. Optionally, all rollouts and actions referring this
* {@link DistributionSet} can be canceled.
*
* @param distributionSetInvalidation
* defines the {@link DistributionSet} and options what should be
* canceled
*/
void invalidateDistributionSet(final DistributionSetInvalidation distributionSetInvalidation);
/**
* Counts all entities for a list of {@link DistributionSet}s that will be
* canceled when invalidation is called for those {@link DistributionSet}s.
*
*
* @param distributionSetInvalidation
* defines the {@link DistributionSet} and options what should be
* canceled
* @return The {@link DistributionSetInvalidationCount} object that holds
* information about the count of affected rollouts,
* auto-assignments and actions
*/
DistributionSetInvalidationCount countEntitiesForInvalidation(
final DistributionSetInvalidation distributionSetInvalidation);
}

View File

@@ -18,10 +18,12 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetUpdate;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
@@ -53,20 +55,20 @@ public interface DistributionSetManagement
* to assign and update
* @param moduleIds
* to get assigned
*
*
* @return the updated {@link DistributionSet}.
*
*
* @throws EntityNotFoundException
* if (at least one) given module does not exist
*
*
* @throws EntityReadOnlyException
* if use tries to change the {@link DistributionSet} s while
* the DS is already in use.
*
*
* @throws UnsupportedSoftwareModuleForThisDistributionSetException
* if {@link SoftwareModule#getType()} is not supported by this
* {@link DistributionSet#getType()}.
*
*
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link SoftwareModule}s is exceeded
* for the addressed {@link DistributionSet}.
@@ -82,9 +84,9 @@ public interface DistributionSetManagement
* to assign for
* @param tagId
* to assign
*
*
* @return list of assigned ds
*
*
* @throws EntityNotFoundException
* if tag with given ID does not exist or (at least one) of the
* distribution sets.
@@ -101,14 +103,14 @@ public interface DistributionSetManagement
* @param metadata
* the meta data entries to create or update
* @return the updated or created distribution set meta data entries
*
*
* @throws EntityNotFoundException
* if given set does not exist
*
*
* @throws EntityAlreadyExistsException
* in case one of the meta data entry already exists for the
* specific key
*
*
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link MetaData} entries is exceeded
* for the addressed {@link DistributionSet}
@@ -123,7 +125,7 @@ public interface DistributionSetManagement
* where meta data has to be deleted
* @param key
* of the meta data element
*
*
* @throws EntityNotFoundException
* if given set does not exist
*/
@@ -136,7 +138,7 @@ public interface DistributionSetManagement
* @param actionId
* the action associated with the distribution set
* @return the distribution set which is associated with the action
*
*
* @throws EntityNotFoundException
* if action with given ID does not exist
*/
@@ -152,7 +154,7 @@ public interface DistributionSetManagement
*
* @param setId
* to look for.
*
*
* @return {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@@ -165,15 +167,69 @@ public interface DistributionSetManagement
* name of {@link DistributionSet}; case insensitive
* @param version
* version of {@link DistributionSet}
*
*
* @return the page with the found {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSet> getByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version);
/**
* Find distribution set by id and throw an exception if it is deleted,
* incomplete or invalidated.
*
* @param id
* id of {@link DistributionSet}
*
* @return the found valid {@link DistributionSet}
*
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*
* @throws InvalidDistributionSetException
* if distribution set with given ID is invalidated
*
* @throws IncompleteDistributionSetException
* if distribution set with given ID is incomplete
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
DistributionSet getValidAndComplete(long id);
/**
* Find distribution set by id and throw an exception if it is deleted or
* invalidated.
*
* @param id
* id of {@link DistributionSet}
*
* @return the found valid {@link DistributionSet}
*
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*
* @throws InvalidDistributionSetException
* if distribution set with given ID is invalidated
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
DistributionSet getValid(long id);
/**
* Find distribution set by id and throw an exception if it is (soft)
* deleted.
*
* @param id
* id of {@link DistributionSet}
*
* @return the found valid {@link DistributionSet}
*
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
DistributionSet getOrElseThrowException(long id);
/**
* Finds all meta data by the given distribution set id.
*
*
* @param pageable
* the page request to page the result
* @param setId
@@ -181,7 +237,7 @@ public interface DistributionSetManagement
*
* @return a paged result of all meta data entries for a given distribution
* set id
*
*
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*/
@@ -190,7 +246,7 @@ public interface DistributionSetManagement
/**
* Finds all meta data by the given distribution set id.
*
*
* @param pageable
* the page request to page the result
* @param setId
@@ -200,14 +256,14 @@ public interface DistributionSetManagement
*
* @return a paged result of all meta data entries for a given distribution
* set id
*
*
* @throws RSQLParameterUnsupportedFieldException
* if a field in the RSQL string is used but not provided by the
* given {@code fieldNameProvider}
*
*
* @throws RSQLParameterSyntaxException
* if the RSQL syntax is wrong
*
*
* @throws EntityNotFoundException
* of distribution set with given ID does not exist
*/
@@ -249,7 +305,7 @@ public interface DistributionSetManagement
* has details of filters to be applied
* @param assignedOrInstalled
* the id of the Target to be ordered by
*
*
* @return {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@@ -277,14 +333,14 @@ public interface DistributionSetManagement
* @param tagId
* of the tag the DS are assigned to
* @return the page of found {@link DistributionSet}
*
*
* @throws RSQLParameterUnsupportedFieldException
* if a field in the RSQL string is used but not provided by the
* given {@code fieldNameProvider}
*
*
* @throws RSQLParameterSyntaxException
* if the RSQL syntax is wrong
*
*
* @throws EntityNotFoundException
* of distribution set tag with given ID does not exist
*/
@@ -301,7 +357,7 @@ public interface DistributionSetManagement
* @param tagId
* of the tag the DS are assigned to
* @return the page of found {@link DistributionSet}
*
*
* @throws EntityNotFoundException
* of distribution set tag with given ID does not exist
*/
@@ -316,7 +372,7 @@ public interface DistributionSetManagement
* @param key
* of the meta data element
* @return the found DistributionSetMetadata
*
*
* @throws EntityNotFoundException
* is set with given ID does not exist
*/
@@ -329,7 +385,7 @@ public interface DistributionSetManagement
*
* @param setId
* to check
*
*
* @return <code>true</code> if in use
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@@ -338,8 +394,8 @@ public interface DistributionSetManagement
/**
* Toggles {@link DistributionSetTag} assignment to given
* {@link DistributionSet}s by means that if some (or all) of the targets in
* the list have the {@link Tag} not yet assigned, they will be. Only if all of
* theme have the tag already assigned they will be removed instead.
* the list have the {@link Tag} not yet assigned, they will be. Only if all
* of theme have the tag already assigned they will be removed instead.
*
* @param setIds
* to toggle for
@@ -347,7 +403,7 @@ public interface DistributionSetManagement
* to toggle
* @return {@link DistributionSetTagAssignmentResult} with all meta data of
* the assignment outcome.
*
*
* @throws EntityNotFoundException
* if given tag does not exist or (at least one) module
*/
@@ -363,10 +419,10 @@ public interface DistributionSetManagement
* @param moduleId
* to be unassigned
* @return the updated {@link DistributionSet}.
*
*
* @throws EntityNotFoundException
* if given module or DS does not exist
*
*
* @throws EntityReadOnlyException
* if use tries to change the {@link DistributionSet} s while
* the DS is already in use.
@@ -383,7 +439,7 @@ public interface DistributionSetManagement
* @param tagId
* to unassign
* @return the unassigned ds or <null> if no ds is unassigned
*
*
* @throws EntityNotFoundException
* if set or tag with given ID does not exist
*/
@@ -398,7 +454,7 @@ public interface DistributionSetManagement
* @param metadata
* meta data entry to be updated
* @return the updated meta data entry
*
*
* @throws EntityNotFoundException
* in case the meta data entry does not exists and cannot be
* updated
@@ -409,16 +465,25 @@ public interface DistributionSetManagement
/**
* Count all {@link DistributionSet}s in the repository that are not marked
* as deleted.
*
*
* @param typeId
* to look for
*
* @return number of {@link DistributionSet}s
*
*
* @throws EntityNotFoundException
* if type with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
long countByTypeId(long typeId);
/**
* Sets the specified {@link DistributionSet} as invalidated.
*
* @param set
* the ID of the {@link DistributionSet} to be set to invalid
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
void invalidate(DistributionSet set);
}

View File

@@ -59,6 +59,12 @@ public class RepositoryProperties {
*/
private int actionWeightIfAbsent = 1000;
/**
* Defines a timeout for the lock during invalidation of distribution sets
* (in seconds).
*/
private long dsInvalidationLockTimeout = 5;
public boolean isEagerPollPersistence() {
return eagerPollPersistence;
}
@@ -107,4 +113,12 @@ public class RepositoryProperties {
this.actionWeightIfAbsent = actionWeightIfAbsent;
}
public long getDsInvalidationLockTimeout() {
return dsInvalidationLockTimeout;
}
public void setDsInvalidationLockTimeout(final long dsInvalidationLockTimeout) {
this.dsInvalidationLockTimeout = dsInvalidationLockTimeout;
}
}

View File

@@ -20,9 +20,9 @@ import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.builder.RolloutUpdate;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
@@ -49,29 +49,29 @@ public interface RolloutManagement {
/**
* Process rollout based on its current {@link Rollout#getStatus()}.
*
*
* For {@link RolloutStatus#CREATING} that means creating the
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
* {@link RolloutStatus#READY}.
*
*
* For {@link RolloutStatus#READY} that means switching to
* {@link RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is set
* and time of calling this method is beyond this point in time. This auto
* start mechanism is optional. Call {@link #start(Long)} otherwise.
*
*
* For {@link RolloutStatus#STARTING} that means starting the first
* {@link RolloutGroup}s in line and when finished switch to
* {@link RolloutStatus#RUNNING}.
*
*
* For {@link RolloutStatus#RUNNING} that means checking to activate further
* groups based on the defined thresholds. Switched to
* {@link RolloutStatus#FINISHED} is all groups are finished.
*
*
* For {@link RolloutStatus#DELETING} that means either soft delete in case
* rollout was already {@link RolloutStatus#RUNNING} which results in status
* change {@link RolloutStatus#DELETED} or hard delete from the persistence
* otherwise.
*
*
*/
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void handleRollouts();
@@ -95,6 +95,17 @@ public interface RolloutManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
long countByFilters(@NotEmpty String searchText);
/**
* Counts all {@link Rollout}s for a specific {@link DistributionSet} that
* are stoppable
*
* @param setId
* the distribution set
* @return the count
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
long countByDistributionSetIdAndRolloutIsStoppable(long setId);
/**
* Persists a new rollout entity. The filter within the
* {@link Rollout#getTargetFilterQuery()} is used to retrieve the targets
@@ -217,7 +228,7 @@ public interface RolloutManagement {
/**
* Retrieves all rollouts found by the given specification.
*
*
* @param pageable
* the page request to sort and limit the result
* @param rsqlParam
@@ -226,7 +237,7 @@ public interface RolloutManagement {
* flag if deleted rollouts should be included
*
* @return a page of found rollouts
*
*
* @throws RSQLParameterUnsupportedFieldException
* if a field in the RSQL string is used but not provided by the
* given {@code fieldNameProvider}
@@ -282,7 +293,7 @@ public interface RolloutManagement {
* @param deleted
* flag if deleted rollouts should be included
* @return rollout details of targets count for different statuses
*
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
@@ -293,7 +304,7 @@ public interface RolloutManagement {
*
* @param rolloutId
* rollout id
*
*
* @return <code>true</code> if rollout exists
*/
boolean exists(long rolloutId);
@@ -318,7 +329,7 @@ public interface RolloutManagement {
* @throws RolloutIllegalStateException
* if given rollout is not in {@link RolloutStatus#RUNNING}.
* Only running rollouts can be paused.
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE)
void pauseRollout(long rolloutId);
@@ -330,7 +341,7 @@ public interface RolloutManagement {
*
* @param rolloutId
* the rollout to be resumed
*
*
* @throws EntityNotFoundException
* if rollout with given ID does not exist
* @throws RolloutIllegalStateException
@@ -368,14 +379,14 @@ public interface RolloutManagement {
* {@link RolloutStatus#WAITING_FOR_APPROVAL}. If the rollout is approved,
* it switches state to {@link RolloutStatus#READY}, otherwise it switches
* to state {@link RolloutStatus#APPROVAL_DENIED}
*
*
* @param rolloutId
* the rollout to be approved or denied.
* @param decision
* decision whether a rollout is approved or denied.
* @param remark
* user remark on approve / deny decision
*
*
* @return approved or denied rollout
*
* @throws EntityNotFoundException
@@ -399,7 +410,7 @@ public interface RolloutManagement {
* the rollout to be started
*
* @return started rollout
*
*
* @throws EntityNotFoundException
* if rollout with given ID does not exist
* @throws RolloutIllegalStateException
@@ -416,13 +427,13 @@ public interface RolloutManagement {
* rollout to be updated
*
* @return Rollout updated rollout
*
*
* @throws EntityNotFoundException
* if rollout or DS with given IDs do not exist
* @throws EntityReadOnlyException
* if rollout is in soft deleted state, i.e. only kept as
* reference
*
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE)
Rollout update(@NotNull @Valid RolloutUpdate update);
@@ -430,12 +441,24 @@ public interface RolloutManagement {
/**
* Deletes a rollout. A rollout might be deleted asynchronously by
* indicating the rollout by {@link RolloutStatus#DELETING}
*
*
*
*
* @param rolloutId
* the ID of the rollout to be deleted
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE)
void delete(long rolloutId);
/**
* Cancels all rollouts that refer to the given {@link DistributionSet}.
* This is called when a distribution set is invalidated and the cancel
* rollouts option is activated.
*
* @param set
* the {@link DistributionSet} for that the rollouts should be
* canceled
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE)
void cancelRolloutsForDistributionSet(DistributionSet set);
}

View File

@@ -18,10 +18,11 @@ import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.AutoAssignDistributionSetUpdate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryUpdate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
@@ -42,13 +43,13 @@ public interface TargetFilterQueryManagement {
*
* @param create
* to create
*
*
* @return the new {@link TargetFilterQuery}
*
*
* @throws ConstraintViolationException
* if fields are not filled as specified. Check
* {@link TargetFilterQueryCreate} for field constraints.
*
*
* @throws AssignmentQuotaExceededException
* if the maximum number of targets that is addressed by the
* given query is exceeded (auto-assignments only)
@@ -61,7 +62,7 @@ public interface TargetFilterQueryManagement {
*
* @param targetFilterQueryId
* IDs of target filter query to be deleted
*
*
* @throws EntityNotFoundException
* if filter with given ID does not exist
*/
@@ -70,16 +71,16 @@ public interface TargetFilterQueryManagement {
/**
* Verifies the provided filter syntax.
*
*
* @param query
* to verify
*
*
* @return <code>true</code> if syntax is valid
*
*
* @throws RSQLParameterUnsupportedFieldException
* if a field in the RSQL string is used but not provided by the
* given {@code fieldNameProvider}
*
*
* @throws RSQLParameterSyntaxException
* if the RSQL syntax is wrong
*/
@@ -99,12 +100,23 @@ public interface TargetFilterQueryManagement {
/**
* Counts all {@link TargetFilterQuery}s.
*
*
* @return the number of all target filter queries
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long count();
/**
* Counts all target filters that have a given auto assign distribution set
* assigned.
*
* @param autoAssignDistributionSetId
* the id of the distribution set
* @return the count
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countByAutoAssignDistributionSetId(long autoAssignDistributionSetId);
/**
* Retrieves all {@link TargetFilterQuery}s which match the given name
* filter.
@@ -154,7 +166,7 @@ public interface TargetFilterQueryManagement {
* @param rsqlParam
* RSQL filter
* @return the page with the found {@link TargetFilterQuery}s
*
*
* @throws EntityNotFoundException
* if DS with given ID does not exist
*/
@@ -198,17 +210,17 @@ public interface TargetFilterQueryManagement {
*
* @param update
* to be updated
*
*
* @return the updated {@link TargetFilterQuery}
*
*
* @throws EntityNotFoundException
* if either {@link TargetFilterQuery} and/or autoAssignDs are
* provided but not found
*
*
* @throws ConstraintViolationException
* if fields are not filled as specified. Check
* {@link TargetFilterQueryUpdate} for field constraints.
*
*
* @throws QuotaExceededException
* if the update contains a new query which addresses too many
* targets (auto-assignments only)
@@ -218,29 +230,43 @@ public interface TargetFilterQueryManagement {
/**
* Updates the auto assign settings of an {@link TargetFilterQuery}.
*
*
* @param autoAssignDistributionSetUpdate
* the new auto assignment
*
*
* @return the updated {@link TargetFilterQuery}
*
*
* @throws EntityNotFoundException
* if either {@link TargetFilterQuery} and/or autoAssignDs are
* provided but not found
*
*
* @throws AssignmentQuotaExceededException
* if the query that is already associated with this filter
* query addresses too many targets (auto-assignments only)
*
*
* @throws InvalidAutoAssignActionTypeException
* if the provided auto-assign {@link ActionType} is not valid
* (neither FORCED, nor SOFT)
*
* @throws InvalidAutoAssignDistributionSetException
* if the provided auto-assign {@link DistributionSet} is not
* valid (incomplete or soft deleted)
*
* @throws IncompleteDistributionSetException
* if the provided auto-assign {@link DistributionSet} is
* incomplete
*
* @throws InvalidDistributionSetException
* if the provided auto-assign {@link DistributionSet} is
* invalidated
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
TargetFilterQuery updateAutoAssignDS(
@NotNull @Valid AutoAssignDistributionSetUpdate autoAssignDistributionSetUpdate);
/**
* Removes the given {@link DistributionSet} from all auto assignments.
*
* @param setId
* the {@link DistributionSet} to be removed from auto
* assignments.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
void cancelAutoAssignmentForDistributionSet(long setId);
}

View File

@@ -0,0 +1,69 @@
/**
* Copyright (c) 2021 Bosch.IO 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.event.remote;
import java.util.Collection;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
*
* Event that is published when a rollout is stopped due to invalidation of a
* {@link DistributionSet}.
*/
public class RolloutStoppedEvent extends RemoteTenantAwareEvent {
private static final long serialVersionUID = 1L;
private Collection<Long> rolloutGroupIds;
private long rolloutId;
/**
* Default constructor.
*/
public RolloutStoppedEvent() {
// for serialization libs like jackson
}
/**
* Constructor for json serialization.
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param entityClass
* the entity class
* @param applicationId
* the origin application id
*/
public RolloutStoppedEvent(final String tenant, final String applicationId, final long rolloutId,
final Collection<Long> rolloutGroupIds) {
super(rolloutId, tenant, applicationId);
this.rolloutId = rolloutId;
this.rolloutGroupIds = rolloutGroupIds;
}
public Collection<Long> getRolloutGroupIds() {
return rolloutGroupIds;
}
public void setRolloutGroupIds(final Collection<Long> rolloutGroupIds) {
this.rolloutGroupIds = rolloutGroupIds;
}
public long getRolloutId() {
return rolloutId;
}
public void setRolloutId(final long rolloutId) {
this.rolloutId = rolloutId;
}
}

View File

@@ -1,30 +0,0 @@
/**
* Copyright (c) 2019 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.exception;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if a distribution set for auto-assignment is incomplete (i.e.
* mandatory modules are missing) or soft deleted.
*/
public class InvalidAutoAssignDistributionSetException extends AbstractServerRtException {
private static final long serialVersionUID = 1L;
private static final SpServerError THIS_ERROR = SpServerError.SP_AUTO_ASSIGN_DISTRIBUTION_SET_INVALID;
/**
* Default constructor.
*/
public InvalidAutoAssignDistributionSetException() {
super(THIS_ERROR);
}
}

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) 2021 Bosch.IO 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.exception;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
public class InvalidDistributionSetException extends AbstractServerRtException {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new InvalidDistributionSetException with
* {@link SpServerError#SP_DS_INVALID} error.
*/
public InvalidDistributionSetException() {
super(SpServerError.SP_DS_INVALID);
}
/**
* @param cause
* for the exception
*/
public InvalidDistributionSetException(final Throwable cause) {
super(SpServerError.SP_DS_INVALID, cause);
}
/**
* @param message
* of the error
*/
public InvalidDistributionSetException(final String message) {
super(message, SpServerError.SP_DS_INVALID);
}
}

View File

@@ -0,0 +1,51 @@
/**
* Copyright (c) 2021 Bosch.IO 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.exception;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* {@link StopRolloutException} is thrown when an error occurs while stopping
* the rollout (due to an invalidation of distribution set). This could be
* caused by a long ongoing creation of a rollout.
*/
public class StopRolloutException extends AbstractServerRtException {
private static final long serialVersionUID = 1L;
/**
* Creates a new StopRolloutException with
* {@link SpServerError#SP_STOP_ROLLOUT_FAILED} error.
*/
public StopRolloutException() {
super(SpServerError.SP_STOP_ROLLOUT_FAILED);
}
/**
* Creates a new StopRolloutException with
* {@link SpServerError#SP_STOP_ROLLOUT_FAILED} error.
*
* @param cause
* for the exception
*/
public StopRolloutException(final Throwable cause) {
super(SpServerError.SP_STOP_ROLLOUT_FAILED, cause);
}
/**
* Creates a new StopRolloutException with
* {@link SpServerError#SP_STOP_ROLLOUT_FAILED} error.
*
* @param message
* of the error
*/
public StopRolloutException(final String message) {
super(message, SpServerError.SP_STOP_ROLLOUT_FAILED);
}
}

View File

@@ -16,7 +16,7 @@ import java.util.Set;
* A {@link DistributionSet} defines a meta package that combines a set of
* {@link SoftwareModule}s which have to be or are provisioned to a
* {@link Target}.
*
*
* <p>
* A {@link Target} has exactly one target {@link DistributionSet} assigned.
* </p>
@@ -71,4 +71,10 @@ public interface DistributionSet extends NamedVersionedEntity {
*/
boolean isComplete();
/**
* @return <code>false</code> if this {@link DistributionSet} is
* invalidated.
*/
boolean isValid();
}

View File

@@ -20,6 +20,7 @@ public final class DistributionSetFilter {
public static class DistributionSetFilterBuilder {
private Boolean isDeleted;
private Boolean isComplete;
private Boolean isValid;
private DistributionSetType type;
private String searchText;
private String filterString;
@@ -57,6 +58,11 @@ public final class DistributionSetFilter {
return this;
}
public DistributionSetFilterBuilder setIsValid(final Boolean isValid) {
this.isValid = isValid;
return this;
}
public DistributionSetFilterBuilder setSearchText(final String searchText) {
this.searchText = searchText;
return this;
@@ -86,6 +92,7 @@ public final class DistributionSetFilter {
private final Boolean isDeleted;
private final Boolean isComplete;
private final Boolean isValid;
private final DistributionSetType type;
private final String searchText;
private final String filterString;
@@ -104,6 +111,7 @@ public final class DistributionSetFilter {
public DistributionSetFilter(final DistributionSetFilterBuilder builder) {
this.isDeleted = builder.isDeleted;
this.isComplete = builder.isComplete;
this.isValid = builder.isValid;
this.type = builder.type;
this.searchText = builder.searchText;
this.filterString = builder.filterString;
@@ -129,6 +137,10 @@ public final class DistributionSetFilter {
return isDeleted;
}
public Boolean getIsValid() {
return isValid;
}
public String getSearchText() {
return searchText;
}

View File

@@ -0,0 +1,71 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
import java.util.Collection;
/**
* Holds the information about the invalidation of a distribution set
*/
public class DistributionSetInvalidation {
private Collection<Long> distributionSetIds;
private CancelationType cancelationType;
private boolean cancelRollouts;
/**
* Parametric constructor
*
* @param distributionSetIds
* defines which distribution sets should be canceled
* @param cancelationType
* defines if actions should be canceled
* @param cancelRollouts
* defines if rollouts should be canceled
*/
public DistributionSetInvalidation(final Collection<Long> distributionSetIds, final CancelationType cancelationType,
final boolean cancelRollouts) {
this.distributionSetIds = distributionSetIds;
this.cancelationType = cancelationType;
this.cancelRollouts = cancelRollouts;
}
public Collection<Long> getDistributionSetIds() {
return distributionSetIds;
}
public void setDistributionSetIds(final Collection<Long> distributionSetIds) {
this.distributionSetIds = distributionSetIds;
}
public CancelationType getCancelationType() {
return cancelationType;
}
public void setCancelationType(final CancelationType cancelationType) {
this.cancelationType = cancelationType;
}
public boolean isCancelRollouts() {
return cancelRollouts;
}
public void setCancelRollouts(final boolean cancelRollouts) {
this.cancelRollouts = cancelRollouts;
}
/**
* Defines if and how actions should be canceled when invalidating a
* distribution set
*/
public enum CancelationType {
FORCE, SOFT, NONE;
}
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2021 Bosch.IO 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;
/**
* object that holds information about the count of affected rollouts,
* auto-assignments and actions, when a list of distribution sets gets
* invalidated
*/
public class DistributionSetInvalidationCount {
private final long rolloutsCount;
private final long autoAssignmentCount;
private final long actionCount;
public DistributionSetInvalidationCount(final long rolloutsCount, final long autoAssignmentCount,
final long actionCount) {
this.rolloutsCount = rolloutsCount;
this.autoAssignmentCount = autoAssignmentCount;
this.actionCount = actionCount;
}
public long getRolloutsCount() {
return rolloutsCount;
}
public long getAutoAssignmentCount() {
return autoAssignmentCount;
}
public long getActionCount() {
return actionCount;
}
}

View File

@@ -17,7 +17,7 @@ import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status;
/**
* Software update operations in large scale IoT scenarios with hundred of
* thousands of devices require special handling.
*
*
* That includes 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 and reporting capabilities for a complete
@@ -149,6 +149,11 @@ public interface Rollout extends NamedEntity {
*/
STOPPED,
/**
* Rollout is going to be stopped.
*/
STOPPING,
/**
* Rollout is running.
*/
@@ -174,7 +179,7 @@ public interface Rollout extends NamedEntity {
/**
* Rollout could not be created due to errors, might be a database
* problem during asynchronous creating.
*
*
* @deprecated legacy status is not used anymore
*/
@Deprecated
@@ -183,7 +188,7 @@ public interface Rollout extends NamedEntity {
/**
* Rollout could not be started due to errors, might be database problem
* during asynchronous starting.
*
*
* @deprecated legacy status is not used anymore
*/
@Deprecated