Protection against misuse with system-wide quota definitions (#670)

* Added quota for meta data per software module

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Added unit test for "meta data per module" quota

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* quota test enhancements

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Verify enforcement of meta data quota via REST

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota for distribution set meta data

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Verify enforcement of distribution set meta data quota via REST

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* software modules per distribution set quota

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Integration test enhancements for Modules per DistSet quota

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota for software module types per distribution set type

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota for max artifacts per software module

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quotas for ActionStatus per Action and Messages per ActionStatus

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota attributes per target

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota targets per rollout group

Signed-off-by: stefbehl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per rollout group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per manual assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assign

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per auto assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max actions per target

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per manual assignment

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix issues caused by merge

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Improve JavaDoc

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar issues

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max artifact size

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Optimize quota configuration

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix test failures

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Improve test coverage

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max rollout groups per rollout

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Configure Rollout UI enhancements

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* UI enhancements

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Minor changes

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Quota max targets per group

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar finding

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix code review findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix review findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* New approach for 'max artifact size' enforcement

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Sonar findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix failing tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Reduce max artifact size for tests

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>

* Fix Kai's review findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>
This commit is contained in:
Stefan Behl
2018-05-02 12:09:29 +02:00
committed by Kai Zimmermann
parent fcc15a0484
commit 6dd98d2134
63 changed files with 2383 additions and 523 deletions

View File

@@ -54,6 +54,8 @@ public interface ArtifactManagement {
* @param overrideExisting
* to <code>true</code> if the artifact binary can be overridden
* if it already exists
* @param filesize
* the size of the file in bytes.
*
* @return uploaded {@link Artifact}
*
@@ -64,7 +66,7 @@ public interface ArtifactManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
Artifact create(@NotNull InputStream inputStream, long moduleId, final String filename,
final boolean overrideExisting);
final boolean overrideExisting, final long filesize);
/**
* Persists artifact binary as provided by given InputStream. assign the
@@ -85,6 +87,9 @@ public interface ArtifactManagement {
* if it already exists
* @param contentType
* the contentType of the file
* @param filesize
* the size of the file in bytes.
*
* @return uploaded {@link Artifact}
*
* @throws EntityNotFoundException
@@ -100,7 +105,7 @@ public interface ArtifactManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
Artifact create(@NotNull InputStream stream, long moduleId, @NotEmpty String filename, String providedMd5Sum,
String providedSha1Sum, boolean overrideExisting, String contentType);
String providedSha1Sum, boolean overrideExisting, String contentType, long filesize);
/**
* Garbage collects artifact binaries if only referenced by given

View File

@@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEv
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.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Action;
@@ -45,7 +46,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface DeploymentManagement {
/**
* method assigns the {@link DistributionSet} to all {@link Target}s by
* Assigns the addressed {@link DistributionSet} to all {@link Target}s by
* their IDs with a specific {@link ActionType} and {@code forcetime}.
*
* @param dsID
@@ -66,13 +67,17 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
DistributionSetAssignmentResult assignDistributionSet(long dsID, @NotNull ActionType actionType,
long forcedTimestamp, @NotEmpty Collection<String> controllerIDs);
/**
* method assigns the {@link DistributionSet} to all {@link Target}s by
* Assigns the addressed {@link DistributionSet} to all {@link Target}s by
* their IDs with a specific {@link ActionType} and {@code forcetime}.
*
* @param dsID
@@ -88,13 +93,17 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
DistributionSetAssignmentResult assignDistributionSet(long dsID,
@NotEmpty Collection<TargetWithActionType> targets);
/**
* method assigns the {@link DistributionSet} to all {@link Target}s by
* Assigns the addressed {@link DistributionSet} to all {@link Target}s by
* their IDs with a specific {@link ActionType} and an action message.
*
* @param dsID
@@ -112,16 +121,20 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
DistributionSetAssignmentResult assignDistributionSet(long dsID, @NotEmpty Collection<TargetWithActionType> targets,
String actionMessage);
/**
* Method registers an "offline" assignment, i.e. adds a completed action
* for the given {@link DistributionSet} to the given {@link Target}s.
* Registers an "offline" assignment, i.e. adds a completed action for the
* given {@link DistributionSet} to the given {@link Target}s.
*
* The handling differs to hawkBit managed updates my means that:<br/>
* The handling differs to hawkBit-managed updates by means that:<br/>
*
* <ol type="A">
* <li>it ignores targets completely that are in
@@ -145,15 +158,18 @@ public interface DeploymentManagement {
* @throws EntityNotFoundException
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
DistributionSetAssignmentResult offlineAssignedDistributionSet(Long dsID, Collection<String> controllerIDs);
/**
* Cancels given {@link Action} for given {@link Target}. The method will
* immediately add a {@link Status#CANCELED} status to the action. However,
* it might be possible that the controller will continue to work on the
* cancellation.
* Cancels the {@link Action} with the given ID. The method will immediately
* add a {@link Status#CANCELED} status to the action. However, it might be
* possible that the controller will continue to work on the cancellation.
*
* @param actionId
* to be canceled
@@ -170,7 +186,7 @@ public interface DeploymentManagement {
Action cancelAction(long actionId);
/**
* counts all actions associated to a specific target.
* Counts all actions associated to a specific target.
*
* @param rsqlParam
* rsql query string
@@ -202,7 +218,7 @@ public interface DeploymentManagement {
long countActionsAll();
/**
* counts all actions associated to a specific target.
* Counts all actions associated to a specific target.
*
* @param controllerId
* the target associated to the actions to count

View File

@@ -21,6 +21,7 @@ import org.eclipse.hawkbit.repository.builder.DistributionSetUpdate;
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.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
@@ -52,6 +53,7 @@ public interface DistributionSetManagement
* to assign and update
* @param moduleIds
* to get assigned
*
* @return the updated {@link DistributionSet}.
*
* @throws EntityNotFoundException
@@ -62,8 +64,12 @@ public interface DistributionSetManagement
* the DS is already in use.
*
* @throws UnsupportedSoftwareModuleForThisDistributionSetException
* is {@link SoftwareModule#getType()} is not supported by this
* if {@link SoftwareModule#getType()} is not supported by this
* {@link DistributionSet#getType()}.
*
* @throws QuotaExceededException
* if the maximum number of {@link SoftwareModule}s is exceeded
* for the addressed {@link DistributionSet}.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSet assignSoftwareModules(long setId, @NotEmpty Collection<Long> moduleIds);
@@ -76,6 +82,7 @@ public interface DistributionSetManagement
* to assign for
* @param tagId
* to assign
*
* @return list of assigned ds
*
* @throws EntityNotFoundException
@@ -86,7 +93,7 @@ public interface DistributionSetManagement
List<DistributionSet> assignTag(@NotEmpty Collection<Long> setIds, long tagId);
/**
* creates a list of distribution set meta data entries.
* Creates a list of distribution set meta data entries.
*
* @param setId
* if the {@link DistributionSet} the metadata has to be created
@@ -97,15 +104,20 @@ public interface DistributionSetManagement
*
* @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 QuotaExceededException
* if the maximum number of {@link MetaData} entries is exceeded
* for the addressed {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
List<DistributionSetMetadata> createMetaData(long setId, @NotEmpty Collection<MetaData> metadata);
/**
* deletes a distribution set meta data entry.
* Deletes a distribution set meta data entry.
*
* @param setId
* where meta data has to be deleted
@@ -119,7 +131,7 @@ public interface DistributionSetManagement
void deleteMetaData(long setId, @NotEmpty String key);
/**
* retrieves the distribution set for a given action.
* Retrieves the distribution set for a given action.
*
* @param actionId
* the action associated with the distribution set
@@ -140,6 +152,7 @@ public interface DistributionSetManagement
*
* @param setId
* to look for.
*
* @return {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@@ -152,13 +165,14 @@ 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);
/**
* finds all meta data by the given distribution set id.
* Finds all meta data by the given distribution set id.
*
* @param pageable
* the page request to page the result
@@ -175,7 +189,7 @@ public interface DistributionSetManagement
Page<DistributionSetMetadata> findMetaDataByDistributionSetId(@NotNull Pageable pageable, long setId);
/**
* finds all meta data by the given distribution set id.
* Finds all meta data by the given distribution set id.
*
* @param pageable
* the page request to page the result
@@ -190,6 +204,7 @@ public interface DistributionSetManagement
* @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
*
@@ -201,7 +216,7 @@ public interface DistributionSetManagement
@NotNull String rsqlParam);
/**
* finds all {@link DistributionSet}s.
* Finds all {@link DistributionSet}s.
*
* @param pageable
* the pagination parameter
@@ -210,14 +225,13 @@ public interface DistributionSetManagement
* sets or <code>false</code> for only incomplete ones nor
* <code>null</code> to return both.
*
*
* @return all found {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSet> findByCompleted(@NotNull Pageable pageable, Boolean complete);
/**
* method retrieves all {@link DistributionSet}s from the repository in the
* Method retrieves all {@link DistributionSet}s from the repository in the
* following order:
* <p>
* 1) {@link DistributionSet}s which have the given {@link Target} as
@@ -235,6 +249,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)
@@ -242,7 +257,7 @@ public interface DistributionSetManagement
@NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled);
/**
* retrieves {@link DistributionSet}s by filtering on the given parameters.
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
*
* @param pageable
* page parameter
@@ -255,7 +270,7 @@ public interface DistributionSetManagement
@NotNull DistributionSetFilter distributionSetFilter);
/**
* retrieves {@link DistributionSet}s by filtering on the given parameters.
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
*
* @param pageable
* page parameter
@@ -266,6 +281,7 @@ public interface DistributionSetManagement
* @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
*
@@ -276,7 +292,7 @@ public interface DistributionSetManagement
Page<DistributionSet> findByTag(@NotNull Pageable pageable, long tagId);
/**
* retrieves {@link DistributionSet}s by filtering on the given parameters.
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
*
* @param pageable
* page parameter
@@ -293,7 +309,7 @@ public interface DistributionSetManagement
Page<DistributionSet> findByRsqlAndTag(@NotNull Pageable pageable, @NotNull String rsqlParam, long tagId);
/**
* finds a single distribution set meta data by its id.
* Finds a single distribution set meta data by its id.
*
* @param setId
* of the {@link DistributionSet}
@@ -375,7 +391,7 @@ public interface DistributionSetManagement
DistributionSet unAssignTag(long setId, long tagId);
/**
* updates a distribution set meta data value if corresponding entry exists.
* Updates a distribution set meta data value if corresponding entry exists.
*
* @param setId
* {@link DistributionSet} of the meta data entry to be updated

View File

@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.builder.DistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -63,6 +64,10 @@ public interface DistributionSetTypeManagement
* @throws EntityReadOnlyException
* if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
*
* @throws QuotaExceededException
* if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignOptionalSoftwareModuleTypes(long dsTypeId,
@@ -84,6 +89,10 @@ public interface DistributionSetTypeManagement
* @throws EntityReadOnlyException
* if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
*
* @throws QuotaExceededException
* if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignMandatorySoftwareModuleTypes(long dsTypeId,

View File

@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
public interface QuotaManagement {
/**
* @return Maximum number of {@link ActionStatus} entries that the
* @return maximum number of {@link ActionStatus} entries that the
* controller can report for an {@link Action}.
*/
int getMaxStatusEntriesPerAction();
@@ -43,4 +43,57 @@ public interface QuotaManagement {
*/
int getMaxMessagesPerActionStatus();
/**
* @return maximum number of meta data entries per software module
*/
int getMaxMetaDataEntriesPerSoftwareModule();
/**
* @return maximum number of meta data entries per distribution set
*/
int getMaxMetaDataEntriesPerDistributionSet();
/**
* @return maximum number of software modules per distribution set
*/
int getMaxSoftwareModulesPerDistributionSet();
/**
* @return the maximum number of software module types per distribution set
* type
*/
int getMaxSoftwareModuleTypesPerDistributionSetType();
/**
* @return the maximum number of artifacts per software module
*/
int getMaxArtifactsPerSoftwareModule();
/**
* @return the maximum number of targets per rollout group
*/
int getMaxTargetsPerRolloutGroup();
/**
* @return the maximum number of targets which for a manual distribution set
* assignment
*/
int getMaxTargetsPerManualAssignment();
/**
* @return the maximum number of targets for an automatic distribution set
* assignment
*/
int getMaxTargetsPerAutoAssignment();
/**
* @return the maximum number of actions per target
*/
int getMaxActionsPerTarget();
/**
* @return the maximum size of software artifacts in bytes
*/
long getMaxArtifactSize();
}

View File

@@ -22,6 +22,7 @@ import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.builder.RolloutUpdate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
@@ -123,6 +124,9 @@ public interface RolloutManagement {
* if given {@link DistributionSet} does not exist
* @throws ConstraintViolationException
* if rollout or group parameters are invalid.
* @throws QuotaExceededException
* if the maximum number of allowed targets per rollout group is
* exceeded.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE)
Rollout create(@NotNull RolloutCreate create, int amountGroup, @NotNull RolloutGroupConditions conditions);
@@ -157,6 +161,9 @@ public interface RolloutManagement {
* if given {@link DistributionSet} does not exist
* @throws ConstraintViolationException
* if rollout or group parameters are invalid
* @throws QuotaExceededException
* if the maximum number of allowed targets per rollout group is
* exceeded.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE)
Rollout create(@NotNull @Valid RolloutCreate rollout, @NotNull @Valid List<RolloutGroupCreate> groups,

View File

@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
@@ -60,37 +61,51 @@ public interface SoftwareModuleManagement
long countByTextAndType(String searchText, Long typeId);
/**
* creates a list of software module meta data entries.
* Creates a list of software module meta data entries.
*
* @param metadata
* the meta data entries to create
*
* @return the updated or created software module meta data entries
*
* @throws EntityAlreadyExistsException
* in case one of the meta data entry already exists for the
* specific key
*
* @throws EntityNotFoundException
* if software module with given ID does not exist
*
* @throws QuotaExceededException
* if the maximum number of {@link SoftwareModuleMetadata}
* entries is exceeded for the addressed {@link SoftwareModule}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
List<SoftwareModuleMetadata> createMetaData(@NotNull @Valid Collection<SoftwareModuleMetadataCreate> metadata);
/**
* creates or updates a single software module meta data entry.
* Creates or updates a single software module meta data entry.
*
* @param metadata
* the meta data entry to create
*
* @return the updated or created software module meta data entry
*
* @throws EntityAlreadyExistsException
* in case the meta data entry already exists for the specific
* key
*
* @throws EntityNotFoundException
* if software module with given ID does not exist
*
* @throws QuotaExceededException
* if the maximum number of {@link SoftwareModuleMetadata}
* entries is exceeded for the addressed {@link SoftwareModule}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
SoftwareModuleMetadata createMetaData(@NotNull @Valid SoftwareModuleMetadataCreate metadata);
/**
* deletes a software module meta data entry.
* Deletes a software module meta data entry.
*
* @param moduleId
* where meta data has to be deleted
@@ -104,12 +119,13 @@ public interface SoftwareModuleManagement
void deleteMetaData(long moduleId, @NotEmpty String key);
/**
* returns all modules assigned to given {@link DistributionSet}.
* Returns all modules assigned to given {@link DistributionSet}.
*
* @param pageable
* the page request to page the result set
* @param setId
* to search for
*
* @return all {@link SoftwareModule}s that are assigned to given
* {@link DistributionSet}.
*
@@ -130,6 +146,7 @@ public interface SoftwareModuleManagement
* to be filtered as "like" on {@link SoftwareModule#getName()}
* @param typeId
* to be filtered as "like" on {@link SoftwareModule#getType()}
*
* @return the page of found {@link SoftwareModule}
*
* @throws EntityNotFoundException
@@ -139,7 +156,7 @@ public interface SoftwareModuleManagement
Slice<SoftwareModule> findByTextAndType(@NotNull Pageable pageable, String searchText, Long typeId);
/**
* retrieves {@link SoftwareModule} by their name AND version AND type..
* Retrieves {@link SoftwareModule} by their name AND version AND type..
*
* @param name
* of the {@link SoftwareModule}
@@ -147,6 +164,7 @@ public interface SoftwareModuleManagement
* of the {@link SoftwareModule}
* @param typeId
* of the {@link SoftwareModule}
*
* @return the found {@link SoftwareModule}
*
* @throws EntityNotFoundException
@@ -156,7 +174,7 @@ public interface SoftwareModuleManagement
Optional<SoftwareModule> getByNameAndVersionAndType(@NotEmpty String name, @NotEmpty String version, long typeId);
/**
* finds a single software module meta data by its id.
* Finds a single software module meta data by its id.
*
* @param moduleId
* where meta data has to be found
@@ -171,7 +189,7 @@ public interface SoftwareModuleManagement
Optional<SoftwareModuleMetadata> getMetaDataBySoftwareModuleId(long moduleId, @NotEmpty String key);
/**
* finds all meta data by the given software module id.
* Finds all meta data by the given software module id.
*
* @param pageable
* the page request to page the result
@@ -188,7 +206,7 @@ public interface SoftwareModuleManagement
Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(@NotNull Pageable pageable, long moduleId);
/**
* finds all meta data by the given software module id where
* Finds all meta data by the given software module id where
* {@link SoftwareModuleMetadata#isTargetVisible()}.
*
* @param pageable
@@ -207,7 +225,7 @@ public interface SoftwareModuleManagement
long moduleId);
/**
* finds all meta data by the given software module id.
* Finds all meta data by the given software module id.
*
* @param pageable
* the page request to page the result
@@ -222,8 +240,10 @@ public interface SoftwareModuleManagement
* @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
* if software module with given ID does not exist
*/
@@ -249,6 +269,7 @@ public interface SoftwareModuleManagement
* filtered as "like" on {@link SoftwareModule#getName()}
* @param typeId
* filtered as "equal" on {@link SoftwareModule#getType()}
*
* @return the page of found {@link SoftwareModule}
*
* @throws EntityNotFoundException
@@ -259,13 +280,14 @@ public interface SoftwareModuleManagement
@NotNull Pageable pageable, long orderByDistributionId, String searchText, Long typeId);
/**
* retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType}
* Retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType}
* .
*
* @param pageable
* page parameters
* @param typeId
* to be filtered on
*
* @return the found {@link SoftwareModule}s
*
* @throws EntityNotFoundException
@@ -275,7 +297,7 @@ public interface SoftwareModuleManagement
Slice<SoftwareModule> findByType(@NotNull Pageable pageable, long typeId);
/**
* updates a distribution set meta data value if corresponding entry exists.
* Updates a distribution set meta data value if corresponding entry exists.
*
* @param update
* the meta data entry to be updated

View File

@@ -18,8 +18,10 @@ import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
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.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -32,20 +34,26 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface TargetFilterQueryManagement {
/**
* creating new {@link TargetFilterQuery}.
* Creates a new {@link TargetFilterQuery}.
*
* @param create
* to create
* @return the created {@link TargetFilterQuery}
*
* @return the new {@link TargetFilterQuery}
*
* @throws ConstraintViolationException
* if fields are not filled as specified. Check
* {@link TargetFilterQueryCreate} for field constraints.
*
* @throws QuotaExceededException
* if the maximum number of targets that is addressed by the
* given query is exceeded (auto-assignments only)
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
TargetFilterQuery create(@NotNull @Valid TargetFilterQueryCreate create);
/**
* Delete target filter query.
* Deletes the {@link TargetFilterQuery} with the given ID.
*
* @param targetFilterQueryId
* IDs of target filter query to be deleted
@@ -57,7 +65,7 @@ public interface TargetFilterQueryManagement {
void delete(long targetFilterQueryId);
/**
* Verifies provided filter syntax.
* Verifies the provided filter syntax.
*
* @param query
* to verify
@@ -67,6 +75,7 @@ public interface TargetFilterQueryManagement {
* @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
*/
@@ -75,7 +84,7 @@ public interface TargetFilterQueryManagement {
/**
*
* Retrieves all target filter query{@link TargetFilterQuery}.
* Retrieves all {@link TargetFilterQuery}s.
*
* @param pageable
* pagination parameter
@@ -85,7 +94,7 @@ public interface TargetFilterQueryManagement {
Page<TargetFilterQuery> findAll(@NotNull Pageable pageable);
/**
* Counts all target filter queries
* Counts all {@link TargetFilterQuery}s.
*
* @return the number of all target filter queries
*/
@@ -93,46 +102,46 @@ public interface TargetFilterQueryManagement {
long count();
/**
* Retrieves all target filter query which {@link TargetFilterQuery}.
*
* Retrieves all {@link TargetFilterQuery}s which match the given name
* filter.
*
* @param pageable
* pagination parameter
* @param name
* name filter
* @return the page with the found {@link TargetFilterQuery}
* @return the page with the found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findByName(@NotNull Pageable pageable, @NotNull String name);
/**
* Retrieves all target filter query which {@link TargetFilterQuery}.
*
* Retrieves all {@link TargetFilterQuery} which match the given RSQL
* filter.
*
* @param pageable
* pagination parameter
* @param rsqlFilter
* RSQL filter string
* @return the page with the found {@link TargetFilterQuery}
* @return the page with the found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findByRsql(@NotNull Pageable pageable, @NotNull String rsqlFilter);
/**
* Retrieves all target filter query which have exactly the provided query.
* Retrieves all {@link TargetFilterQuery}s which match the given query.
*
* @param pageable
* pagination parameter
* @param query
* the query saved in the target filter query
* @return the page with the found {@link TargetFilterQuery}
* @return the page with the found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findByQuery(@NotNull Pageable pageable, @NotNull String query);
/**
* Retrieves all target filter query which {@link TargetFilterQuery}.
*
* Retrieves all {@link TargetFilterQuery}s which match the given
* auto-assign distribution set and RSQL filter.
*
* @param pageable
* pagination parameter
@@ -140,28 +149,26 @@ public interface TargetFilterQueryManagement {
* the auto assign distribution set
* @param rsqlParam
* RSQL filter
* @return the page with the found {@link TargetFilterQuery}
* @return the page with the found {@link TargetFilterQuery}s
*
* @throws EntityNotFoundException
* if DS with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findByAutoAssignDSAndRsql(@NotNull Pageable pageable, long setId,
String rsqlParam);
Page<TargetFilterQuery> findByAutoAssignDSAndRsql(@NotNull Pageable pageable, long setId, String rsqlParam);
/**
* Retrieves all target filter query with auto assign DS which
* {@link TargetFilterQuery}.
* Retrieves all {@link TargetFilterQuery}s with an auto-assign distribution
* set.
*
*
* @return the page with the found {@link TargetFilterQuery}
* @return the page with the found {@link TargetFilterQuery}s
* @param pageable
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findWithAutoAssignDS(@NotNull Pageable pageable);
/**
* Find target filter query by id.
* Finds the {@link TargetFilterQuery} by id.
*
* @param targetFilterQueryId
* Target filter query id
@@ -172,7 +179,7 @@ public interface TargetFilterQueryManagement {
Optional<TargetFilterQuery> get(long targetFilterQueryId);
/**
* Find target filter query by name.
* Finds the {@link TargetFilterQuery} that matches the given name.
*
* @param targetFilterQueryName
* Target filter query name
@@ -183,7 +190,7 @@ public interface TargetFilterQueryManagement {
Optional<TargetFilterQuery> getByName(@NotNull String targetFilterQueryName);
/**
* updates the {@link TargetFilterQuery}.
* Updates the {@link TargetFilterQuery}.
*
* @param update
* to be updated
@@ -193,25 +200,36 @@ public interface TargetFilterQueryManagement {
* @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)
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
TargetFilterQuery update(@NotNull @Valid TargetFilterQueryUpdate update);
/**
* updates the {@link TargetFilterQuery#getAutoAssignDistributionSet()}.
* Updates the the auto-assign {@link DistributionSet} of the addressed
* {@link TargetFilterQuery}.
*
* @param queryId
* to be updated
* of the target filter query to be updated
* @param dsId
* to be updated or <code>null</code> in order to remove it
*
* @return the updated {@link TargetFilterQuery}
*
* @throws EntityNotFoundException
* if either {@link TargetFilterQuery} and/or autoAssignDs are
* provided but not found
*
* @throws QuotaExceededException
* if the query that is already associated with this filter
* query addresses too many targets (auto-assignments only)
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
TargetFilterQuery updateAutoAssignDS(long queryId, Long dsId);

View File

@@ -17,8 +17,11 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
*
*/
public final class QuotaExceededException extends AbstractServerRtException {
private static final long serialVersionUID = 1L;
private static final String ASSIGNMENT_QUOTA_EXCEEDED_MESSAGE = "Quota exceeded: Cannot assign %s more %s entities to %s '%s'. The maximum is %s.";
/**
* Creates a new QuotaExceededException with
* {@link SpServerError#SP_QUOTA_EXCEEDED} error.
@@ -28,11 +31,26 @@ public final class QuotaExceededException extends AbstractServerRtException {
}
/**
* Creates a new QuotaExceededException with a custom error message.
*
* @param message
* The custom error message.
*/
public QuotaExceededException(final String message) {
super(message, SpServerError.SP_QUOTA_EXCEEDED);
}
/**
* Creates a QuotaExceededException with a custom error message and a root
* cause.
*
* @param message
* The custom error message.
* @param cause
* for the exception
*/
public QuotaExceededException(final Throwable cause) {
super(SpServerError.SP_QUOTA_EXCEEDED, cause);
public QuotaExceededException(final String message, final Throwable cause) {
super(message, SpServerError.SP_QUOTA_EXCEEDED, cause);
}
/**
@@ -57,7 +75,55 @@ public final class QuotaExceededException extends AbstractServerRtException {
* that is defined by the repository
*/
public QuotaExceededException(final String type, final long inserted, final int quota) {
super("Request contains too many entries of {" + type + "}. {" + inserted + "} is bejond the permitted {"
super("Request contains too many entries of {" + type + "}. {" + inserted + "} is beyond the permitted {"
+ quota + "}.", SpServerError.SP_QUOTA_EXCEEDED);
}
/**
* Creates a QuotaExceededException which is to be thrown when an assignment
* quota is exceeded.
*
* @param type
* The type of the entities that shall be assigned to the
* specified parent entity.
* @param parentType
* The type of the parent entity.
* @param parentId
* The ID of the parent entity.
* @param requested
* The number of entities that shall be assigned to the specified
* parent entity.
* @param quota
* The maximum number of entities that can be assigned to the
* parent entity.
*/
public QuotaExceededException(final Class<?> type, final Class<?> parentType, final Long parentId,
final long requested, final long quota) {
this(type.getSimpleName(), parentType.getSimpleName(), parentId, requested, quota);
}
/**
* Creates a QuotaExceededException which is to be thrown when an assignment
* quota is exceeded.
*
* @param type
* The type of the entities that shall be assigned to the
* specified parent entity.
* @param parentType
* The type of the parent entity.
* @param parentId
* The ID of the parent entity.
* @param requested
* The number of entities that shall be assigned to the specified
* parent entity.
* @param quota
* The maximum number of entities that can be assigned to the
* parent entity.
*/
public QuotaExceededException(final String type, final String parentType, final Long parentId, final long requested,
final long quota) {
super(String.format(ASSIGNMENT_QUOTA_EXCEEDED_MESSAGE, requested, type, parentType,
parentId != null ? String.valueOf(parentId) : "<new>", quota), SpServerError.SP_QUOTA_EXCEEDED);
}
}

View File

@@ -21,12 +21,12 @@ public class RolloutGroupsValidation {
/**
* The total amount of targets in a {@link Rollout}
*/
private long totalTargets;
private final long totalTargets;
/**
* A list containing the count of targets for each {@link RolloutGroup}
*/
private List<Long> targetsPerGroup;
private final List<Long> targetsPerGroup;
/**
* Instantiates a new validation result

View File

@@ -28,8 +28,8 @@ public final class DurationHelper {
*
*/
public static final class DurationRangeValidator {
final Duration min;
final Duration max;
private final Duration min;
private final Duration max;
private DurationRangeValidator(final Duration min, final Duration max) {
this.min = min;