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));
}
}