Fix upload quota check and provide better error message (#893)

* Adjusted upload quota check to include file size and show proper error message

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Fixed failing upload quota tests

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Moved quota check to stream, fixed review findings

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Added missing license header to QuotaInputStream

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Reworked uploadLock, ensured error messages may be translated, review fixes

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Added local artifactrepo to gitignore

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Fixed sonar issues and assignment quota message

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* PR review fixes

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Split quota exceptions, PR fixes

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Removed left over conversion method in quota helper

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>

* Made conversion helper class final

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch-si.com>
This commit is contained in:
Alexander Dobler
2019-10-30 11:24:33 +01:00
committed by Dominic Schabel
parent 9b8ab40c55
commit 09f2d8a481
43 changed files with 477 additions and 213 deletions

View File

@@ -25,7 +25,7 @@ import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
@@ -56,9 +56,9 @@ public interface ControllerManagement {
* @throws EntityAlreadyExistsException
* if a given entity already exists
*
* @throws QuotaExceededException
* if more than the allowed number of status entries or messages per
* entry are inserted
* @throws AssignmentQuotaExceededException
* if more than the allowed number of status entries or messages
* per entry are inserted
* @throws EntityNotFoundException
* if given action does not exist
* @throws ConstraintViolationException
@@ -101,9 +101,9 @@ public interface ControllerManagement {
*
* @return created {@link ActionStatus} entity
*
* @throws QuotaExceededException
* if more than the allowed number of status entries or messages per
* entry are inserted
* @throws AssignmentQuotaExceededException
* if more than the allowed number of status entries or messages
* per entry are inserted
* @throws EntityNotFoundException
* if given action does not exist
* @throws ConstraintViolationException
@@ -123,9 +123,9 @@ public interface ControllerManagement {
*
* @throws EntityAlreadyExistsException
* if a given entity already exists
* @throws QuotaExceededException
* if more than the allowed number of status entries or messages per
* entry are inserted
* @throws AssignmentQuotaExceededException
* if more than the allowed number of status entries or messages
* per entry are inserted
* @throws EntityNotFoundException
* if action status not exist
* @throws ConstraintViolationException
@@ -361,7 +361,7 @@ public interface ControllerManagement {
*
* @throws EntityNotFoundException
* if target that has to be updated could not be found
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if maximum number of attributes per target is exceeded
* @throws InvalidTargetAttributeException
* if attributes violate constraints

View File

@@ -23,7 +23,7 @@ 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.QuotaExceededException;
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;
@@ -66,7 +66,7 @@ public interface DeploymentManagement {
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
* @throws MultiAssignmentIsNotEnabledException
@@ -97,7 +97,7 @@ public interface DeploymentManagement {
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
* @throws MultiAssignmentIsNotEnabledException
@@ -151,7 +151,7 @@ public interface DeploymentManagement {
* if either provided {@link DistributionSet} or {@link Target}s
* do not exist
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of targets the distribution set can be
* assigned to at once is exceeded
*

View File

@@ -21,7 +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.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
@@ -67,7 +67,7 @@ public interface DistributionSetManagement
* if {@link SoftwareModule#getType()} is not supported by this
* {@link DistributionSet#getType()}.
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link SoftwareModule}s is exceeded
* for the addressed {@link DistributionSet}.
*/
@@ -109,7 +109,7 @@ public interface DistributionSetManagement
* in case one of the meta data entry already exists for the
* specific key
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link MetaData} entries is exceeded
* for the addressed {@link DistributionSet}
*/

View File

@@ -18,7 +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.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -65,7 +65,7 @@ public interface DistributionSetTypeManagement
* if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
*/
@@ -90,7 +90,7 @@ public interface DistributionSetTypeManagement
* if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
*/

View File

@@ -22,7 +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.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
@@ -124,7 +124,7 @@ public interface RolloutManagement {
* if given {@link DistributionSet} does not exist
* @throws ConstraintViolationException
* if rollout or group parameters are invalid.
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of allowed targets per rollout group is
* exceeded.
*/
@@ -161,7 +161,7 @@ public interface RolloutManagement {
* if given {@link DistributionSet} does not exist
* @throws ConstraintViolationException
* if rollout or group parameters are invalid
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of allowed targets per rollout group is
* exceeded.
*/

View File

@@ -0,0 +1,40 @@
/**
* 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;
/**
* Helper class that provides simple conversion of byte values to readable
* strings
*/
public final class SizeConversionHelper {
private static final String KB = "KB";
private static final String MB = "MB";
// do not allow to create instances
private SizeConversionHelper() {
}
/**
* Convert byte values to human readable strings with units
*
* @param byteValue
* Value to convert in bytes
*/
public static String byteValueToReadableString(final long byteValue) {
double outputValue = byteValue / 1024.0;
String unit = KB;
if (outputValue >= 1024) {
outputValue = outputValue / 1024.0;
unit = MB;
}
// We cut decimal places to avoid localization handling
return (long) outputValue + " " + unit;
}
}

View File

@@ -23,7 +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.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
@@ -75,7 +75,7 @@ public interface SoftwareModuleManagement
* @throws EntityNotFoundException
* if software module with given ID does not exist
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link SoftwareModuleMetadata}
* entries is exceeded for the addressed {@link SoftwareModule}
*/
@@ -97,7 +97,7 @@ public interface SoftwareModuleManagement
* @throws EntityNotFoundException
* if software module with given ID does not exist
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link SoftwareModuleMetadata}
* entries is exceeded for the addressed {@link SoftwareModule}
*/

View File

@@ -20,7 +20,7 @@ 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.QuotaExceededException;
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.ActionType;
@@ -48,7 +48,7 @@ public interface TargetFilterQueryManagement {
* if fields are not filled as specified. Check
* {@link TargetFilterQueryCreate} for field constraints.
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of targets that is addressed by the
* given query is exceeded (auto-assignments only)
*/
@@ -208,7 +208,7 @@ public interface TargetFilterQueryManagement {
* if fields are not filled as specified. Check
* {@link TargetFilterQueryUpdate} for field constraints.
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the update contains a new query which addresses too many
* targets (auto-assignments only)
*/
@@ -231,7 +231,7 @@ public interface TargetFilterQueryManagement {
* if either {@link TargetFilterQuery} and/or autoAssignDs are
* provided but not found
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the query that is already associated with this filter
* query addresses too many targets (auto-assignments only)
*
@@ -263,7 +263,7 @@ public interface TargetFilterQueryManagement {
* if either {@link TargetFilterQuery} and/or autoAssignDs are
* provided but not found
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the query that is already associated with this filter
* query addresses too many targets (auto-assignments only)
*

View File

@@ -23,7 +23,7 @@ import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate;
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.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -698,7 +698,7 @@ public interface TargetManagement {
* in case one of the meta data entry already exists for the
* specific key
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the maximum number of {@link MetaData} entries is exceeded
* for the addressed {@link Target}
*/

View File

@@ -13,44 +13,43 @@ import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.BaseEntity;
/**
* Thrown if too many entries are added to repository.
*
* Thrown if assignment quota is exceeded
*/
public final class QuotaExceededException extends AbstractServerRtException {
private static final long serialVersionUID = 1L;
public class AssignmentQuotaExceededException extends AbstractServerRtException {
private static final String ASSIGNMENT_QUOTA_EXCEEDED_MESSAGE = "Quota exceeded: Cannot assign %s more %s entities to %s '%s'. The maximum is %s.";
private static final SpServerError errorType = SpServerError.SP_QUOTA_EXCEEDED;
/**
* Creates a new QuotaExceededException with
* Creates a new AssignmentQuotaExceededException with
* {@link SpServerError#SP_QUOTA_EXCEEDED} error.
*/
public QuotaExceededException() {
super(SpServerError.SP_QUOTA_EXCEEDED);
public AssignmentQuotaExceededException() {
super(errorType);
}
/**
* Creates a new QuotaExceededException with a custom error message.
*
* Creates a new AssignmentQuotaExceededException with a custom error
* message.
*
* @param message
* The custom error message.
*/
public QuotaExceededException(final String message) {
super(message, SpServerError.SP_QUOTA_EXCEEDED);
public AssignmentQuotaExceededException(final String message) {
super(message, errorType);
}
/**
* Creates a QuotaExceededException with a custom error message and a root
* cause.
*
* Creates a AssignmentQuotaExceededException with a custom error message
* and a root cause.
*
* @param message
* The custom error message.
* @param cause
* for the exception
*/
public QuotaExceededException(final String message, final Throwable cause) {
super(message, SpServerError.SP_QUOTA_EXCEEDED, cause);
public AssignmentQuotaExceededException(final String message, final Throwable cause) {
super(message, errorType, cause);
}
/**
@@ -61,12 +60,13 @@ public final class QuotaExceededException extends AbstractServerRtException {
* @param quota
* that is defined by the repository
*/
public QuotaExceededException(final Class<? extends BaseEntity> type, final long inserted, final int quota) {
public AssignmentQuotaExceededException(final Class<? extends BaseEntity> type, final long inserted,
final int quota) {
this(type.getSimpleName(), inserted, quota);
}
/**
*
*
* @param type
* that hit quota
* @param inserted
@@ -74,15 +74,15 @@ public final class QuotaExceededException extends AbstractServerRtException {
* @param quota
* that is defined by the repository
*/
public QuotaExceededException(final String type, final long inserted, final int quota) {
public AssignmentQuotaExceededException(final String type, final long inserted, final int quota) {
super("Request contains too many entries of {" + type + "}. {" + inserted + "} is beyond the permitted {"
+ quota + "}.", SpServerError.SP_QUOTA_EXCEEDED);
+ quota + "}.", errorType);
}
/**
* Creates a QuotaExceededException which is to be thrown when an assignment
* quota is exceeded.
*
* Creates a AssignmentQuotaExceededException 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.
@@ -97,15 +97,15 @@ public final class QuotaExceededException extends AbstractServerRtException {
* The maximum number of entities that can be assigned to the
* parent entity.
*/
public QuotaExceededException(final Class<?> type, final Class<?> parentType, final Long parentId,
public AssignmentQuotaExceededException(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.
*
* Creates a AssignmentQuotaExceededException 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.
@@ -120,11 +120,9 @@ public final class QuotaExceededException extends AbstractServerRtException {
* The maximum number of entities that can be assigned to the
* parent entity.
*/
public QuotaExceededException(final String type, final String parentType, final Object parentId,
final long requested,
final long quota) {
public AssignmentQuotaExceededException(final String type, final String parentType, final Object 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);
parentId != null ? String.valueOf(parentId) : "<new>", quota), errorType);
}
}

View File

@@ -0,0 +1,49 @@
/**
* 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 static org.eclipse.hawkbit.repository.SizeConversionHelper.byteValueToReadableString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if file size quota is exceeded
*/
public class FileSizeQuotaExceededException extends AbstractServerRtException {
private static final String MAX_ARTIFACT_SIZE_EXCEEDED = "Maximum artifact size (%s) exceeded.";
private static final SpServerError errorType = SpServerError.SP_FILE_SIZE_QUOTA_EXCEEDED;
private final long exceededQuotaValue;
/**
* Creates a new FileSizeQuotaExceededException with a quota value.
*
* @param exceededQuotaValue
* Value by how much the quota was exceeded
*/
public FileSizeQuotaExceededException(final long exceededQuotaValue) {
super(createQuotaErrorMessage(exceededQuotaValue), errorType);
this.exceededQuotaValue = exceededQuotaValue;
}
/**
* Get a readable string of size quota including unit
*
* @return file size quota with unit
*/
public String getExceededQuotaValueString() {
return byteValueToReadableString(exceededQuotaValue);
}
private static String createQuotaErrorMessage(final long exceededQuotaValue) {
return String.format(MAX_ARTIFACT_SIZE_EXCEEDED, byteValueToReadableString(exceededQuotaValue));
}
}

View File

@@ -0,0 +1,49 @@
/**
* 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 static org.eclipse.hawkbit.repository.SizeConversionHelper.byteValueToReadableString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if storage quota is exceeded
*/
public class StorageQuotaExceededException extends AbstractServerRtException {
private static final String MAX_ARTIFACT_SIZE_TOTAL_EXCEEDED = "Storage quota exceeded, %s left.";
private static final SpServerError errorType = SpServerError.SP_STORAGE_QUOTA_EXCEEDED;
private final long exceededQuotaValue;
/**
* Creates a new StorageQuotaExceededException with a quota value.
*
* @param exceededQuotaValue
* Value by how much the quota was exceeded
*/
public StorageQuotaExceededException(final long exceededQuotaValue) {
super(createQuotaErrorMessage(exceededQuotaValue), errorType);
this.exceededQuotaValue = exceededQuotaValue;
}
/**
* Get a readable string of size quota including unit
*
* @return file size quota with unit
*/
public String getExceededQuotaValueString() {
return byteValueToReadableString(exceededQuotaValue);
}
private static String createQuotaErrorMessage(final long exceededQuotaValue) {
return String.format(MAX_ARTIFACT_SIZE_TOTAL_EXCEEDED, byteValueToReadableString(exceededQuotaValue));
}
}

View File

@@ -14,7 +14,7 @@ import java.util.stream.Collectors;
import javax.validation.ValidationException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
@@ -78,7 +78,7 @@ public final class RolloutHelper {
if (amountGroup <= 0) {
throw new ValidationException("The amount of groups cannot be lower than zero");
} else if (amountGroup > quotaManagement.getMaxRolloutGroupsPerRollout()) {
throw new QuotaExceededException(
throw new AssignmentQuotaExceededException(
"The amount of groups cannot be greater than " + quotaManagement.getMaxRolloutGroupsPerRollout());
}

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
@@ -23,11 +25,11 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException;
import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.jpa.utils.FileSizeAndStorageQuotaCheckingInputStream;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -53,10 +55,6 @@ public class JpaArtifactManagement implements ArtifactManagement {
private static final Logger LOG = LoggerFactory.getLogger(JpaArtifactManagement.class);
private static final String MAX_ARTIFACT_SIZE_EXCEEDED = "Quota exceeded: The artifact '%s' (%s bytes) which has been uploaded for software module '%s' exceeds the maximum artifact size of %s bytes.";
private static final String MAX_ARTIFACT_SIZE_TOTAL_EXCEEDED = "Quota exceeded: The artifact '%s' (%s bytes) cannot be uploaded. The maximum total artifact storage of %s bytes would be exceeded.";
private final LocalArtifactRepository localArtifactRepository;
private final SoftwareModuleRepository softwareModuleRepository;
@@ -105,8 +103,6 @@ public class JpaArtifactManagement implements ArtifactManagement {
final Artifact existing = checkForExistingArtifact(filename, artifactUpload.overrideExisting(), softwareModule);
assertArtifactQuota(moduleId, 1);
assertMaxArtifactSizeQuota(filename, moduleId, artifactUpload.getFilesize());
assertMaxArtifactStorageQuota(filename, artifactUpload.getFilesize());
return getOrCreateArtifact(artifactUpload)
.map(artifact -> storeArtifactMetadata(softwareModule, filename, artifact, existing)).orElse(null);
@@ -125,11 +121,12 @@ public class JpaArtifactManagement implements ArtifactManagement {
}
private AbstractDbArtifact storeArtifact(final ArtifactUpload artifactUpload) {
try {
return artifactRepository.store(tenantAware.getCurrentTenant(), artifactUpload.getInputStream(),
try(final InputStream quotaStream = wrapInQuotaStream(artifactUpload.getInputStream())) {
return artifactRepository.store(tenantAware.getCurrentTenant(), quotaStream,
artifactUpload.getFilename(), artifactUpload.getContentType(),
new DbArtifactHash(artifactUpload.getProvidedSha1Sum(), artifactUpload.getProvidedMd5Sum(), artifactUpload.getProvidedSha256Sum()));
} catch (final ArtifactStoreException e) {
new DbArtifactHash(artifactUpload.getProvidedSha1Sum(), artifactUpload.getProvidedMd5Sum(),
artifactUpload.getProvidedSha256Sum()));
} catch (final ArtifactStoreException | IOException e) {
throw new ArtifactUploadFailedException(e);
} catch (final HashNotMatchException e) {
if (e.getHashFunction().equals(HashNotMatchException.SHA1)) {
@@ -145,31 +142,13 @@ public class JpaArtifactManagement implements ArtifactManagement {
Artifact.class, SoftwareModule.class, localArtifactRepository::countBySoftwareModuleId);
}
private void assertMaxArtifactSizeQuota(final String filename, final long id, final long artifactSize) {
private InputStream wrapInQuotaStream(final InputStream in) {
final long maxArtifactSize = quotaManagement.getMaxArtifactSize();
if (maxArtifactSize <= 0) {
return;
}
if (artifactSize > maxArtifactSize) {
final String msg = String.format(MAX_ARTIFACT_SIZE_EXCEEDED, filename, artifactSize, id, maxArtifactSize);
LOG.warn(msg);
throw new QuotaExceededException(msg);
}
}
private void assertMaxArtifactStorageQuota(final String filename, final long artifactSize) {
final long currentlyUsed = localArtifactRepository.getSumOfUndeletedArtifactSize().orElse(0L);
final long maxArtifactSizeTotal = quotaManagement.getMaxArtifactStorage();
if (maxArtifactSizeTotal <= 0) {
return;
}
final Long currentlyUsed = localArtifactRepository.getSumOfUndeletedArtifactSize().orElse(0L);
if (currentlyUsed + artifactSize > maxArtifactSizeTotal) {
final String msg = String.format(MAX_ARTIFACT_SIZE_TOTAL_EXCEEDED, filename, artifactSize,
maxArtifactSizeTotal);
LOG.warn(msg);
throw new QuotaExceededException(msg);
}
return new FileSizeAndStorageQuotaCheckingInputStream(in, maxArtifactSize, maxArtifactSizeTotal - currentlyUsed);
}
@Override

View File

@@ -23,7 +23,7 @@ import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.builder.GenericDistributionSetTypeUpdate;
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.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
@@ -163,7 +163,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
* @param requested
* number of software module types to check
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the software module type quota is exceeded
*/
private void assertSoftwareModuleTypeQuota(final long id, final int requested) {

View File

@@ -0,0 +1,81 @@
/**
* 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.jpa.utils;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.hawkbit.repository.exception.FileSizeQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.StorageQuotaExceededException;
/**
* A FilterInputStream that ensures file size and storage quotas are enforced. It check during read operations if the
* quota will be exceeded and throws an QuotaExceededException if this happens.
*/
public class FileSizeAndStorageQuotaCheckingInputStream extends FilterInputStream {
private final long quota;
private final long sizeLimit;
private long size;
/**
* Creates a <code>QuotaInputStream</code> using the input stream in and a
* limiting quota
*
* @param in
* Inner InputStream that read operations will be forwarded to
* @param sizeLimit
* Quota file size limit in byte
* @param storageLeft
* Storage left until quota is reached
*/
public FileSizeAndStorageQuotaCheckingInputStream(final InputStream in, final long sizeLimit, final long storageLeft) {
super(in);
// only limit to lower bound to avoid two checks
this.quota = Math.min(sizeLimit, storageLeft);
this.sizeLimit = sizeLimit;
}
@Override
public int read() throws IOException {
final int read = super.read();
checkQuotaAndUpdateSize(read);
return read;
}
@Override
public int read(final byte[] b) throws IOException {
final int read = super.read(b);
checkQuotaAndUpdateSize(read);
return read;
}
@Override
public int read(final byte[] b, final int off, final int len) throws IOException {
final int read = super.read(b, off, len);
checkQuotaAndUpdateSize(read);
return read;
}
private void checkQuotaAndUpdateSize(final int read) {
if ((size + read) > quota) {
// pick exception based on quota type
if (quota == sizeLimit) {
throw new FileSizeQuotaExceededException(quota);
} else {
throw new StorageQuotaExceededException(quota);
}
} else if (read >= 0) {
size += read;
}
}
}

View File

@@ -12,12 +12,12 @@ import java.util.function.ToLongFunction;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Helper class to check assignment quotas.
* Helper class to check quotas.
*/
public final class QuotaHelper {
@@ -26,6 +26,8 @@ public final class QuotaHelper {
*/
private static final Logger LOG = LoggerFactory.getLogger(QuotaHelper.class);
private static final String MAX_ASSIGNMENT_QUOTA_EXCEEDED = "Quota exceeded: Cannot assign %s entities at once. The maximum is %s.";
private QuotaHelper() {
// no need to instantiate this class
}
@@ -44,7 +46,7 @@ public final class QuotaHelper {
* @param parentType
* The type of the parent entity.
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the assignment operation would cause the quota to be
* exceeded
*/
@@ -72,7 +74,7 @@ public final class QuotaHelper {
* Function to count the entities that are currently assigned to
* the parent entity.
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the assignment operation would cause the quota to be
* exceeded
*/
@@ -100,7 +102,7 @@ public final class QuotaHelper {
* Function to count the entities that are currently assigned to
* the parent entity.
*
* @throws QuotaExceededException
* @throws AssignmentQuotaExceededException
* if the assignment operation would cause the quota to be
* exceeded
*/
@@ -117,7 +119,7 @@ public final class QuotaHelper {
final String parentIdStr = parentId != null ? String.valueOf(parentId) : "<new>";
LOG.warn("Cannot assign {} {} entities to {} '{}' because of the configured quota limit {}.", requested,
type, parentType, parentIdStr, limit);
throw new QuotaExceededException(type, parentType, parentId, requested, limit);
throw new AssignmentQuotaExceededException(type, parentType, parentId, requested, limit);
}
if (parentId != null && countFct != null) {
@@ -126,7 +128,7 @@ public final class QuotaHelper {
LOG.warn(
"Cannot assign {} {} entities to {} '{}' because of the configured quota limit {}. Currently, there are {} {} entities assigned.",
requested, type, parentType, parentId, limit, currentCount, type);
throw new QuotaExceededException(type, parentType, parentId, requested, limit);
throw new AssignmentQuotaExceededException(type, parentType, parentId, requested, limit);
}
}
}
@@ -142,10 +144,9 @@ public final class QuotaHelper {
*/
public static void assertAssignmentRequestSizeQuota(final long requested, final long limit) {
if (requested > limit) {
final String message = String.format(
"Quota exceeded: Cannot assign %s entities at once. The maximum is %s.", requested, limit);
final String message = String.format(MAX_ASSIGNMENT_QUOTA_EXCEEDED, requested, limit);
LOG.warn(message);
throw new QuotaExceededException(message);
throw new AssignmentQuotaExceededException(message);
}
}
}

View File

@@ -30,8 +30,10 @@ import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.event.remote.SoftwareModuleDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.FileSizeQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.StorageQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.model.JpaArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.model.Artifact;
@@ -183,7 +185,7 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
assertThat(artifactRepository.findBySoftwareModuleId(PAGE, smId).getTotalElements()).isEqualTo(maxArtifacts);
// create one mode to trigger the quota exceeded error
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> createArtifactForSoftwareModule("file" + maxArtifacts, smId, artifactSize));
// delete one of the artifacts
@@ -217,7 +219,7 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
// upload one more artifact to trigger the quota exceeded error
final JpaSoftwareModule sm = softwareModuleRepository
.save(new JpaSoftwareModule(osType, "smd" + numArtifacts, "1.0", null, null));
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(StorageQuotaExceededException.class)
.isThrownBy(() -> createArtifactForSoftwareModule("file" + numArtifacts, sm.getId(), artifactSize));
// delete one of the artifacts
@@ -227,18 +229,6 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
createArtifactForSoftwareModule("fileXYZ", sm.getId(), artifactSize);
}
@Test
@Description("Verifies that the quota specifying the maximum artifact storage is enforced (across software modules).")
public void createArtifactWhichExceedsMaxStorage() throws IOException {
// create one artifact which exceeds the storage quota at once
final long maxBytes = quotaManagement.getMaxArtifactStorage();
final JpaSoftwareModule sm = softwareModuleRepository
.save(new JpaSoftwareModule(osType, "smd345", "1.0", null, null));
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(
() -> createArtifactForSoftwareModule("file345", sm.getId(), Math.toIntExact(maxBytes) + 128));
}
@Test
@Description("Verifies that you cannot create artifacts which exceed the configured maximum size.")
public void createArtifactFailsIfTooLarge() {
@@ -249,7 +239,7 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
// create an artifact that exceeds the configured quota
final long maxSize = quotaManagement.getMaxArtifactSize();
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(FileSizeQuotaExceededException.class)
.isThrownBy(() -> createArtifactForSoftwareModule("file", sm1.getId(), Math.toIntExact(maxSize) + 8));
}

View File

@@ -53,7 +53,7 @@ import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -989,7 +989,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
final int allowedAttributes = quotaManagement.getMaxAttributeEntriesPerTarget();
testdataFactory.createTarget(controllerId);
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> securityRule
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> securityRule
.runAs(WithSpringAuthorityRule.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
writeAttributes(controllerId, allowedAttributes + 1, "key", "value");
return null;
@@ -1008,7 +1008,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
assertThat(targetManagement.getControllerAttributes(controllerId)).hasSize(10);
// Now rite one more
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> securityRule
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> securityRule
.runAs(WithSpringAuthorityRule.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
writeAttributes(controllerId, 1, "additional", "value1");
return null;
@@ -1071,7 +1071,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
final Long actionId = createTargetAndAssignDs();
// Fails as one entry is already in there from the assignment
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> securityRule
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> securityRule
.runAs(WithSpringAuthorityRule.withController("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
writeStatus(actionId, allowStatusEntries);
return null;
@@ -1127,7 +1127,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
controllerManagement.addInformationalActionStatus(entityFactory.actionStatus().create(actionId1)
.status(Status.WARNING).message("Msg " + i).occurredAt(System.currentTimeMillis()));
}
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> controllerManagement
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> controllerManagement
.addInformationalActionStatus(entityFactory.actionStatus().create(actionId1).status(Status.WARNING)));
// test for update status (and mixed case)
@@ -1138,7 +1138,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
controllerManagement.addUpdateActionStatus(entityFactory.actionStatus().create(actionId2)
.status(Status.WARNING).message("Msg " + i).occurredAt(System.currentTimeMillis()));
}
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> controllerManagement
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> controllerManagement
.addInformationalActionStatus(entityFactory.actionStatus().create(actionId2).status(Status.WARNING)));
}
@@ -1165,7 +1165,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
entityFactory.actionStatus().create(actionId).messages(messages).status(Status.WARNING))).isNotNull();
messages.add("msg");
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> controllerManagement.addInformationalActionStatus(
entityFactory.actionStatus().create(actionId).messages(messages).status(Status.WARNING)));
@@ -1262,7 +1262,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
assertThat(actionRepository.activeActionExistsForControllerId(DEFAULT_CONTROLLER_ID)).isEqualTo(false);
}
@Test(expected = QuotaExceededException.class)
@Test(expected = AssignmentQuotaExceededException.class)
@Description("Verifies that quota is asserted when a controller reports too many DOWNLOADED events for a "
+ "DOWNLOAD_ONLY action.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@@ -1297,17 +1297,17 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
assertThat(actionId).isNotNull();
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.as("No QuotaExceededException thrown for too many DOWNLOADED updateActionStatus updates")
.isThrownBy(() -> IntStream.range(0, maxMessages).forEach(i -> controllerManagement
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Status.DOWNLOADED))));
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.as("No QuotaExceededException thrown for too many ERROR updateActionStatus updates")
.isThrownBy(() -> IntStream.range(0, maxMessages).forEach(i -> controllerManagement
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Status.ERROR))));
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.as("No QuotaExceededException thrown for too many FINISHED updateActionStatus updates")
.isThrownBy(() -> IntStream.range(0, maxMessages).forEach(i -> controllerManagement
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Status.FINISHED))));
@@ -1325,17 +1325,17 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
final Long actionId = createTargetAndAssignDs();
assertThat(actionId).isNotNull();
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.as("No QuotaExceededException thrown for too many DOWNLOADED updateActionStatus updates")
.isThrownBy( ()-> IntStream.range(0, maxMessages).forEach(i -> controllerManagement
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Status.DOWNLOADED))));
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.as("No QuotaExceededException thrown for too many ERROR updateActionStatus updates")
.isThrownBy(()->IntStream.range(0, maxMessages).forEach(i -> controllerManagement
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Status.ERROR))));
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.as("No QuotaExceededException thrown for too many FINISHED updateActionStatus updates")
.isThrownBy(()->IntStream.range(0, maxMessages).forEach(i -> controllerManagement
.addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Status.FINISHED))));

View File

@@ -39,7 +39,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
@@ -170,7 +170,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
.singletonList(new SimpleEntry<String, Long>(testTarget.getControllerId(), ds1.getId())));
}
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> assignDistributionSet(ds1, Collections.singletonList(testTarget)));
}
@@ -185,7 +185,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
assignDistributionSet(ds1, targets);
targets.add(testdataFactory.createTarget("assignmentTest2"));
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> assignDistributionSet(ds2, targets));
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> assignDistributionSet(ds2, targets));
}
@Test
@@ -671,7 +671,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
DeploymentManagement.deploymentRequest(controllerId, dsId).build());
enableMultiAssignments();
Assertions.assertThatExceptionOfType(QuotaExceededException.class)
Assertions.assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
assertThat(actionRepository.countByTargetControllerId(controllerId)).isEqualTo(0);
}

View File

@@ -34,7 +34,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
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.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
@@ -351,7 +351,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
}
// quota exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> createDistributionSetMetadata(ds1.getId(), createDistributionSetMetadata(ds1.getId(),
new JpaDistributionSetMetadata("k" + maxMetaData, ds1, "v" + maxMetaData))));
@@ -362,7 +362,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
metaData2.add(new JpaDistributionSetMetadata("k" + i, ds2, "v" + i));
}
// verify quota is exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> createDistributionSetMetadata(ds2.getId(), metaData2));
// add some meta data entries
@@ -378,7 +378,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
metaData3.add(new JpaDistributionSetMetadata("kk" + i, ds3, "vv" + i));
}
// verify quota is exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> createDistributionSetMetadata(ds3.getId(), metaData3));
}
@@ -510,7 +510,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
distributionSetManagement.assignSoftwareModules(ds1.getId(), Collections.singletonList(modules.get(i)));
}
// add one more to cause the quota to be exceeded
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> {
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> {
distributionSetManagement.assignSoftwareModules(ds1.getId(),
Collections.singletonList(modules.get(maxModules)));
});
@@ -518,7 +518,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// assign all software modules at once
final DistributionSet ds2 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds2", "1.0");
// verify quota is exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> distributionSetManagement.assignSoftwareModules(ds2.getId(), modules));
// assign some software modules
@@ -528,7 +528,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
distributionSetManagement.assignSoftwareModules(ds3.getId(), Collections.singletonList(modules.get(i)));
}
// assign the remaining modules to cause the quota to be exceeded
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> distributionSetManagement
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> distributionSetManagement
.assignSoftwareModules(ds3.getId(), modules.subList(firstHalf, modules.size())));
}

View File

@@ -28,7 +28,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeCre
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
@@ -242,9 +242,9 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
// assign all types at once
final DistributionSetType dsType1 = distributionSetTypeManagement
.create(entityFactory.distributionSetType().create().key("dst1").name("dst1"));
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(
() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(dsType1.getId(), moduleTypeIds));
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(
() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(dsType1.getId(), moduleTypeIds));
// assign as many mandatory modules as possible
@@ -256,7 +256,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
assertThat(distributionSetTypeManagement.get(dsType2.getId()).get().getMandatoryModuleTypes().size())
.isEqualTo(quota);
// assign one more to trigger the quota exceeded error
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(dsType2.getId(),
Collections.singletonList(moduleTypeIds.get(quota))));
@@ -269,7 +269,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
assertThat(distributionSetTypeManagement.get(dsType3.getId()).get().getOptionalModuleTypes().size())
.isEqualTo(quota);
// assign one more to trigger the quota exceeded error
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(dsType3.getId(),
Collections.singletonList(moduleTypeIds.get(quota))));

View File

@@ -42,7 +42,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
@@ -1348,7 +1348,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
amountGroups, conditions));
@@ -1376,7 +1376,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
.targetPercentage(100.0F);
// group1 exceeds the quota
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
Arrays.asList(group1, group2), conditions));
@@ -1388,7 +1388,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
.targetPercentage(100.0F);
// group4 exceeds the quota
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
Arrays.asList(group3, group4), conditions));
@@ -1571,7 +1571,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
final RolloutCreate rollout = generateTargetsAndRollout(rolloutName, targets);
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
.withMessageContaining("not be greater than " + maxGroups);

View File

@@ -24,7 +24,7 @@ import org.apache.commons.lang3.RandomUtils;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
@@ -676,7 +676,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
// quota exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata()
.create(module.getId()).key("k" + maxMetaData).value("v" + maxMetaData)));
@@ -687,7 +687,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
create.add(entityFactory.softwareModuleMetadata().create(module2.getId()).key("k" + i).value("v" + i));
}
// quota exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> softwareModuleManagement.createMetaData(create));
// add some meta data entries
@@ -704,7 +704,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
create2.add(entityFactory.softwareModuleMetadata().create(module3.getId()).key("kk" + i).value("vv" + i));
}
// quota exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> softwareModuleManagement.createMetaData(create2));
}

View File

@@ -28,7 +28,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryCreat
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -112,7 +112,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
final DistributionSet set = testdataFactory.createDistributionSet();
// creation is supposed to work as there is no distribution set
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create()
.name("testfilter").autoAssignDistributionSet(set.getId()).query("name==target*")));
}
@@ -282,7 +282,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
// assigning a distribution set is supposed to fail as the query
// addresses too many targets
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> targetFilterQueryManagement
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> targetFilterQueryManagement
.updateAutoAssignDS(targetFilterQuery.getId(), distributionSet.getId()));
}
@@ -300,7 +300,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
.create().name("testfilter").autoAssignDistributionSet(set.getId()).query("name==foo"));
// update with a query string that addresses too many targets
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> targetFilterQueryManagement
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> targetFilterQueryManagement
.update(entityFactory.targetFilterQuery().update(targetFilterQuery.getId()).query("name==target*")));
}

View File

@@ -41,7 +41,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetMetadata;
@@ -958,7 +958,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
}
// quota exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> insertTargetMetadata("k" + maxMetaData, "v" + maxMetaData, target1));
// add multiple meta data entries at once
@@ -968,7 +968,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
metaData2.add(new JpaTargetMetadata("k" + i, "v" + i, target2));
}
// verify quota is exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> targetManagement.createMetaData(target2.getControllerId(), metaData2));
// add some meta data entries
@@ -984,7 +984,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
metaData3.add(new JpaTargetMetadata("kk" + i, "vv" + i, target3));
}
// verify quota is exceeded
assertThatExceptionOfType(QuotaExceededException.class)
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> targetManagement.createMetaData(target3.getControllerId(), metaData3));
}