Fine grained repository permissions (#2562)

1. Introduce @PrreAuthorize check based on hasPermission - allowing custom processing (compared with non-modifiable hasAuthority/Role processing)
2. Dedicated permissions could be implemented on management api level. Check is made by plugged in PermissionEvaluator
3. Thus common XXX_REPOSITORY permissions could differ for extending services
4. Change create/update entity builder pattern - not via EntityFactory but via clean static lombok based builders (with fine fluent api).
5. Implement abstract repository management jpa class that handles the boilerplate code from extending classes in single place consistently -> AbsreactJpaRepositoryManagement
6. Register management api-s as **Sevice**-s instead of **Bean**-s in order to make easier maintainable and get away from heavy argument forwading
7. Simplify custom hawkbit repository registration + adding proxy to handle exception mapping at lower level - thus not depending on Aspects for converting exceptions
8. Implemented general purpose 'copy' utility (ObjectCopyUtil) that using getter/setter patterns is able to copy (e.g. Create/Update) objects to other objects (e.g. JPA entity objects)
This commit is contained in:
Avgustin Marinov
2025-07-28 14:57:33 +03:00
committed by GitHub
parent 8cdbe54cbe
commit 2b66449ff1
214 changed files with 3456 additions and 4416 deletions

View File

@@ -40,7 +40,7 @@ public interface ArtifactManagement {
* @return the total amount of local artifacts stored in the artifact
* management
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long count();
/**
@@ -56,7 +56,7 @@ public interface ArtifactManagement {
* @throws InvalidSHA1HashException if check against provided SHA1 checksum failed
* @throws ConstraintViolationException if {@link ArtifactUpload} contains invalid values
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
Artifact create(@NotNull @Valid ArtifactUpload artifactUpload);
/**
@@ -66,7 +66,7 @@ public interface ArtifactManagement {
* @throws ArtifactDeleteFailedException if deletion failed (MongoDB is not available)
* @throws EntityNotFoundException if artifact with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY)
void delete(long id);
/**
@@ -75,7 +75,7 @@ public interface ArtifactManagement {
* @param id to search for
* @return found {@link Artifact}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> get(long id);
@@ -87,7 +87,7 @@ public interface ArtifactManagement {
* @return found {@link Artifact}
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> getByFilenameAndSoftwareModule(@NotNull String filename, long softwareModuleId);
@@ -97,7 +97,7 @@ public interface ArtifactManagement {
* @param sha1 the sha1
* @return the first local artifact
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> findFirstBySHA1(@NotNull String sha1);
@@ -107,7 +107,7 @@ public interface ArtifactManagement {
* @param filename to search for
* @return found List of {@link Artifact}s.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
Optional<Artifact> getByFilename(@NotNull String filename);
@@ -119,7 +119,7 @@ public interface ArtifactManagement {
* @return Page<Artifact>
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<Artifact> findBySoftwareModule(long softwareModuleId, @NotNull Pageable pageable);
/**
@@ -129,7 +129,7 @@ public interface ArtifactManagement {
* @return count by software module
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countBySoftwareModule(long softwareModuleId);
/**

View File

@@ -1,25 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository;
/**
* Provider that returns a base repository implementation dynamically based on repository type
*/
@FunctionalInterface
public interface BaseRepositoryTypeProvider {
/**
* Return a base repository implementation that shall be used based on provided repository type
*
* @param repositoryType type of repository
* @return base repository implementation class
*/
Class<?> getBaseRepositoryType(final Class<?> repositoryType);
}

View File

@@ -26,6 +26,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
*/
public interface ConfirmationManagement {
String CONFIRMATION_CODE_MSG_PREFIX = "Confirmation status code: %d";
/**
* Activate auto confirmation for a given controller ID. In case auto confirmation is active already, this method will fail with an exception.
*

View File

@@ -121,7 +121,7 @@ public interface DeploymentManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(Collection<Entry<String, Long>> assignments, String initiatedBy);
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(Collection<Entry<String, Long>> assignments);
/**

View File

@@ -9,20 +9,25 @@
*/
package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_UPDATE_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_UPDATE_REPOSITORY;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetUpdate;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
@@ -35,6 +40,9 @@ import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThis
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Statistic;
import org.springframework.data.domain.Page;
@@ -45,7 +53,14 @@ import org.springframework.security.access.prepost.PreAuthorize;
/**
* Management service for {@link DistributionSet}s.
*/
public interface DistributionSetManagement extends RepositoryManagement<DistributionSet, DistributionSetCreate, DistributionSetUpdate> {
public interface DistributionSetManagement<T extends DistributionSet>
extends RepositoryManagement<T, DistributionSetManagement.Create, DistributionSetManagement.Update> {
@Override
default String permissionGroup() {
return "DISTRIBUTION_SET";
}
/**
* Find {@link DistributionSet} based on given ID including (lazy loaded) details, e.g. {@link DistributionSet#getModules()}. <br/>
@@ -54,8 +69,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id to look for.
* @return {@link DistributionSet}
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Optional<DistributionSet> getWithDetails(long id);
@PreAuthorize(HAS_READ_REPOSITORY)
Optional<T> getWithDetails(long id);
/**
* Find distribution set by id and throw an exception if it is (soft) deleted.
@@ -64,16 +79,16 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return the found valid {@link DistributionSet}
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
DistributionSet getOrElseThrowException(long id);
@PreAuthorize(HAS_READ_REPOSITORY)
T getOrElseThrowException(long id);
/**
* Sets the specified {@link DistributionSet} as invalidated.
*
* @param distributionSet the ID of the {@link DistributionSet} to be set to invalid
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
void invalidate(DistributionSet distributionSet);
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void invalidate(T distributionSet);
/**
* Assigns {@link SoftwareModule} to existing {@link DistributionSet}.
@@ -88,8 +103,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModule}s is exceeded for the addressed
* {@link DistributionSet}.
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
DistributionSet assignSoftwareModules(long id, @NotEmpty Collection<Long> moduleIds);
@PreAuthorize(HAS_UPDATE_REPOSITORY)
T assignSoftwareModules(long id, @NotEmpty Collection<Long> moduleIds);
/**
* Unassigns a {@link SoftwareModule} form an existing {@link DistributionSet}.
@@ -100,8 +115,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @throws EntityNotFoundException if given module or DS does not exist
* @throws EntityReadOnlyException if use tries to change the {@link DistributionSet} s while the DS is already in use.
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
DistributionSet unassignSoftwareModule(long id, long moduleId);
@PreAuthorize(HAS_UPDATE_REPOSITORY)
T unassignSoftwareModule(long id, long moduleId);
/**
* Assign a {@link DistributionSetTag} assignment to given {@link DistributionSet}s.
@@ -111,8 +126,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return list of assigned ds
* @throws EntityNotFoundException if tag with given ID does not exist or (at least one) of the distribution sets.
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
List<DistributionSet> assignTag(@NotEmpty Collection<Long> ids, long tagId);
@PreAuthorize(HAS_UPDATE_REPOSITORY)
List<T> assignTag(@NotEmpty Collection<Long> ids, long tagId);
/**
* Unassign a {@link DistributionSetTag} assignment to given {@link DistributionSet}s.
@@ -122,8 +137,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return list of assigned ds
* @throws EntityNotFoundException if tag with given ID does not exist or (at least one) of the distribution sets.
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
List<DistributionSet> unassignTag(@NotEmpty Collection<Long> ids, long tagId);
@PreAuthorize(HAS_UPDATE_REPOSITORY)
List<T> unassignTag(@NotEmpty Collection<Long> ids, long tagId);
/**
* Creates a map of distribution set meta-data entries.
@@ -134,7 +149,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @throws EntityAlreadyExistsException in case one of the meta-data entry already exists for the specific key
* @throws AssignmentQuotaExceededException if the maximum number of meta-data entries is exceeded for the addressed {@link DistributionSet}
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void createMetadata(long id, @NotEmpty Map<String, String> metadata);
/**
@@ -144,7 +159,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return a paged result of all meta-data entries for a given distribution set id
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
Map<String, String> getMetadata(long id);
/**
@@ -155,7 +170,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param value meta data-entry to be new value
* @throws EntityNotFoundException in case the meta-data entry does not exist and cannot be updated
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void updateMetadata(long id, @NotNull String key, @NotNull String value);
/**
@@ -165,7 +180,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param key of the meta-data element
* @throws EntityNotFoundException if given set does not exist
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void deleteMetadata(long id, @NotEmpty String key);
/**
@@ -174,7 +189,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id the distribution set id
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void lock(final long id);
/**
@@ -185,7 +200,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id the distribution set id
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_UPDATE_DISTRIBUTION_SET)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void unlock(final long id);
/**
@@ -196,8 +211,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @throws EntityNotFoundException if distribution set with given ID does not exist
* @throws InvalidDistributionSetException if distribution set with given ID is invalidated
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
DistributionSet getValid(long id);
@PreAuthorize(HAS_READ_REPOSITORY)
T getValid(long id);
/**
* Find distribution set by id and throw an exception if it is deleted, incomplete or invalidated.
@@ -208,8 +223,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @throws InvalidDistributionSetException if distribution set with given ID is invalidated
* @throws IncompleteDistributionSetException if distribution set with given ID is incomplete
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
DistributionSet getValidAndComplete(long id);
@PreAuthorize(HAS_READ_REPOSITORY)
T getValidAndComplete(long id);
/**
* Retrieves the distribution set for a given action.
@@ -218,8 +233,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return the distribution set which is associated with the action
* @throws EntityNotFoundException if action with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Optional<DistributionSet> findByAction(long actionId);
@PreAuthorize(HAS_READ_REPOSITORY)
Optional<T> findByAction(long actionId);
/**
* Find distribution set by name and version.
@@ -228,8 +243,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param version version of {@link DistributionSet}
* @return the page with the found {@link DistributionSet}
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Optional<DistributionSet> findByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version);
@PreAuthorize(HAS_READ_REPOSITORY)
Optional<T> findByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version);
/**
* Finds all {@link DistributionSet}s based on completeness.
@@ -239,8 +254,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param pageable the pagination parameter
* @return all found {@link DistributionSet}s
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Slice<DistributionSet> findByCompleted(Boolean complete, @NotNull Pageable pageable);
@PreAuthorize(HAS_READ_REPOSITORY)
Slice<T> findByCompleted(Boolean complete, @NotNull Pageable pageable);
/**
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
@@ -249,8 +264,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param pageable page parameter
* @return the page of found {@link DistributionSet}
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Slice<DistributionSet> findByDistributionSetFilter(@NotNull DistributionSetFilter distributionSetFilter, @NotNull Pageable pageable);
@PreAuthorize(HAS_READ_REPOSITORY)
Slice<T> findByDistributionSetFilter(@NotNull DistributionSetFilter distributionSetFilter, @NotNull Pageable pageable);
/**
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
@@ -263,8 +278,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
* @throws EntityNotFoundException of distribution set tag with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Page<DistributionSet> findByTag(long tagId, @NotNull Pageable pageable);
@PreAuthorize(HAS_READ_REPOSITORY)
Page<T> findByTag(long tagId, @NotNull Pageable pageable);
/**
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
@@ -275,8 +290,8 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return the page of found {@link DistributionSet}
* @throws EntityNotFoundException of distribution set tag with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
Page<DistributionSet> findByRsqlAndTag(@NotNull String rsql, long tagId, @NotNull Pageable pageable);
@PreAuthorize(HAS_READ_REPOSITORY)
Page<T> findByRsqlAndTag(@NotNull String rsql, long tagId, @NotNull Pageable pageable);
/**
* Counts all {@link DistributionSet}s based on completeness.
@@ -285,7 +300,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* nor <code>null</code> to count both.
* @return count of all found {@link DistributionSet}s
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
long countByCompleted(Boolean complete);
/**
@@ -294,7 +309,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param distributionSetFilter has details of filters to be applied.
* @return count of {@link DistributionSet}s
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
long countByDistributionSetFilter(@NotNull DistributionSetFilter distributionSetFilter);
/**
@@ -305,7 +320,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @return number of {@link DistributionSet}s
* @throws EntityNotFoundException if type with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
long countByTypeId(long typeId);
/**
@@ -315,7 +330,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id to check
* @return <code>true</code> if in use
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
boolean isInUse(long id);
/**
@@ -325,7 +340,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id to look for
* @return List of Statistics for {@link org.eclipse.hawkbit.repository.model.Rollout}s status counts
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
List<Statistic> countRolloutsByStatusForDistributionSet(@NotNull Long id);
/**
@@ -335,7 +350,7 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id to look for
* @return List of Statistics for {@link org.eclipse.hawkbit.repository.model.Action}s status counts
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
List<Statistic> countActionsByStatusForDistributionSet(@NotNull Long id);
/**
@@ -345,6 +360,60 @@ public interface DistributionSetManagement extends RepositoryManagement<Distribu
* @param id to look for
* @return number of {@link org.eclipse.hawkbit.repository.builder.AutoAssignDistributionSetUpdate}s
*/
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET)
@PreAuthorize(HAS_READ_REPOSITORY)
Long countAutoAssignmentsForDistributionSet(@NotNull Long id);
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Create extends UpdateCreate {
@NotNull
private DistributionSetType type;
@Builder.Default
private Set<? extends SoftwareModule> modules = Set.of();
public Create setType(@NotEmpty DistributionSetType type) {
this.type = Objects.requireNonNull(type, "type must not be null");
return this;
}
public boolean isValid() {
return true;
}
}
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull
private Long id;
@Builder.Default
private Boolean locked = false;
}
@SuperBuilder
@Getter
class UpdateCreate {
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull(groups = Create.class)
private String name;
@ValidString
@Size(min = 1, max = NamedVersionedEntity.VERSION_MAX_SIZE)
@NotNull(groups = Create.class)
private String version;
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@Builder.Default
private Boolean requiredMigrationStep = false;
}
}

View File

@@ -13,13 +13,18 @@ import java.util.Optional;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TagUpdate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.data.domain.Page;
@@ -29,7 +34,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
/**
* Management service for {@link DistributionSetTag}s.
*/
public interface DistributionSetTagManagement extends RepositoryManagement<DistributionSetTag, TagCreate, TagUpdate> {
public interface DistributionSetTagManagement<T extends DistributionSetTag>
extends RepositoryManagement<T, DistributionSetTagManagement.Create, DistributionSetTagManagement.Update> {
/**
* Find {@link DistributionSet} based on given name.
@@ -37,8 +43,8 @@ public interface DistributionSetTagManagement extends RepositoryManagement<Distr
* @param name to look for.
* @return {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetTag> findByName(@NotEmpty String name);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByName(@NotEmpty String name);
/**
* Finds all {@link TargetTag} assigned to given {@link Target}.
@@ -48,8 +54,8 @@ public interface DistributionSetTagManagement extends RepositoryManagement<Distr
* @return page of the found {@link TargetTag}s
* @throws EntityNotFoundException if {@link DistributionSet} with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSetTag> findByDistributionSet(long distributionSetId, @NotNull Pageable pageable);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<T> findByDistributionSet(long distributionSetId, @NotNull Pageable pageable);
/**
* Deletes {@link DistributionSetTag} by given
@@ -58,6 +64,40 @@ public interface DistributionSetTagManagement extends RepositoryManagement<Distr
* @param tagName to be deleted
* @throws EntityNotFoundException if tag with given name does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY)
void delete(@NotEmpty String tagName);
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Create extends UpdateCreate {}
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull
private Long id;
}
@SuperBuilder
@Getter
class UpdateCreate {
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull(groups = Create.class)
private String name;
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@ValidString
@Size(max = Tag.COLOUR_MAX_SIZE)
private String colour;
}
}

View File

@@ -11,31 +11,39 @@ package org.eclipse.hawkbit.repository;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
import org.springframework.security.access.prepost.PreAuthorize;
/**
* Management service for {@link DistributionSetType}s.
*/
public interface DistributionSetTypeManagement
extends RepositoryManagement<DistributionSetType, DistributionSetTypeCreate, DistributionSetTypeUpdate> {
public interface DistributionSetTypeManagement<T extends DistributionSetType>
extends RepositoryManagement<T, DistributionSetTypeManagement.Create, DistributionSetTypeManagement.Update> {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetType> findByKey(@NotEmpty String key);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByKey(@NotEmpty String key);
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetType> findByName(@NotEmpty String name);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByName(@NotEmpty String name);
/**
* Assigns {@link DistributionSetType#getMandatoryModuleTypes()}.
@@ -48,8 +56,8 @@ public interface DistributionSetTypeManagement
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is exceeded for the addressed
* {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignOptionalSoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
T assignOptionalSoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
/**
* Assigns {@link DistributionSetType#getOptionalModuleTypes()}.
@@ -62,8 +70,8 @@ public interface DistributionSetTypeManagement
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is exceeded for the addressed
* {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignMandatorySoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
T assignMandatorySoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
/**
* Unassigns a {@link SoftwareModuleType} from the {@link DistributionSetType}. Does nothing if {@link SoftwareModuleType}
@@ -75,6 +83,49 @@ public interface DistributionSetTypeManagement
* @throws EntityNotFoundException in case the {@link DistributionSetType} does not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use by a {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType unassignSoftwareModuleType(long id, long softwareModuleTypeId);
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
T unassignSoftwareModuleType(long id, long softwareModuleTypeId);
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Create extends UpdateCreate {
@Size(min = 1, max = Type.KEY_MAX_SIZE)
@NotNull
private String key;
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull
private String name;
}
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull
private Long id;
}
@SuperBuilder
@Getter
class UpdateCreate {
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@ValidString
@Size(max = Type.COLOUR_MAX_SIZE)
private String colour;
@Builder.Default
private Set<? extends SoftwareModuleType> mandatoryModuleTypes = Set.of();
@Builder.Default
private Set<? extends SoftwareModuleType> optionalModuleTypes = Set.of();
}
}

View File

@@ -10,18 +10,15 @@
package org.eclipse.hawkbit.repository;
import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeBuilder;
import org.eclipse.hawkbit.repository.builder.TagBuilder;
import org.eclipse.hawkbit.repository.builder.TargetBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.builder.TargetTypeBuilder;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* central {@link BaseEntity} generation service. Objects are created but not
@@ -34,11 +31,6 @@ public interface EntityFactory {
*/
ActionStatusBuilder actionStatus();
/**
* @return {@link DistributionSetBuilder} object
*/
DistributionSetBuilder distributionSet();
/**
* @return {@link SoftwareModuleMetadataBuilder} object
*/
@@ -47,33 +39,18 @@ public interface EntityFactory {
/**
* @return {@link TagBuilder} object
*/
TagBuilder tag();
TagBuilder<Tag> tag();
/**
* @return {@link RolloutGroupBuilder} object
*/
RolloutGroupBuilder rolloutGroup();
/**
* @return {@link DistributionSetTypeBuilder} object
*/
DistributionSetTypeBuilder distributionSetType();
/**
* @return {@link RolloutBuilder} object
*/
RolloutBuilder rollout();
/**
* @return {@link SoftwareModuleBuilder} object
*/
SoftwareModuleBuilder softwareModule();
/**
* @return {@link SoftwareModuleTypeBuilder} object
*/
SoftwareModuleTypeBuilder softwareModuleType();
/**
* @return {@link TargetBuilder} object
*/

View File

@@ -33,70 +33,30 @@ import org.springframework.security.access.prepost.PreAuthorize;
* Generic management methods common to (software) repository content.
*
* @param <T> type of the {@link BaseEntity}
* @param <C> entity create builder
* @param <U> entity update builder
* @param <C> type of the create request
* @param <U> type of the update request
*/
public interface RepositoryManagement<T, C, U> {
/**
* Creates multiple {@link BaseEntity}s.
*
* @param creates to create
* @return created Entity
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link BaseEntity} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
List<T> create(@NotNull @Valid Collection<C> creates);
public interface RepositoryManagement<T extends BaseEntity, C, U extends Identifiable<Long>> {
/**
* Creates new {@link BaseEntity}.
*
* @param create to create
* @param create bean with properties of the object to create
* @return created Entity
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link BaseEntity} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
T create(@NotNull @Valid C create);
/**
* Updates existing {@link BaseEntity}.
* Creates multiple {@link BaseEntity}s.
*
* @param update to update
* @return updated Entity
* @throws EntityReadOnlyException if the {@link BaseEntity} cannot be updated (e.g. is already in use)
* @throws EntityNotFoundException in case the {@link BaseEntity} does not exist and cannot be updated
* @param create beans with properties of the object to create
* @return created Entity
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link BaseEntity} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
T update(@NotNull @Valid U update);
/**
* Deletes or marks as delete in case the {@link BaseEntity} is in use.
*
* @param id to delete
* @throws EntityNotFoundException BaseEntity with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
void delete(long id);
/**
* Delete {@link BaseEntity}s by their IDs. That is either a soft delete of the entities have been linked to another entity before or a hard
* delete if not.
*
* @param ids to be deleted
* @throws EntityNotFoundException if (at least one) given distribution set does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
void delete(@NotEmpty Collection<Long> ids);
/**
* Retrieves all {@link BaseEntity}s without details.
*
* @param ids the ids to for
* @return the found {@link BaseEntity}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
List<T> get(@NotEmpty Collection<Long> ids);
@PreAuthorize(SpringEvalExpressions.HAS_CREATE_REPOSITORY)
List<T> create(@NotNull @Valid Collection<C> create);
/**
* Retrieve {@link BaseEntity}
@@ -104,16 +64,25 @@ public interface RepositoryManagement<T, C, U> {
* @param id to search for
* @return {@link BaseEntity} in the repository with given {@link BaseEntity#getId()}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> get(long id);
/**
* Retrieves all {@link BaseEntity}s without details.
*
* @param ids the ids to for
* @return the found {@link BaseEntity}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<T> get(@NotEmpty Collection<Long> ids);
/**
* Retrieves {@link Page} of all {@link BaseEntity} of given type.
*
* @param pageable paging parameter
* @return all {@link BaseEntity}s in the repository.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<T> findAll(@NotNull Pageable pageable);
/**
@@ -126,7 +95,7 @@ public interface RepositoryManagement<T, C, U> {
* {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<T> findByRsql(@NotNull String rsql, @NotNull Pageable pageable);
/**
@@ -135,12 +104,56 @@ public interface RepositoryManagement<T, C, U> {
* @param id of entity to check existence
* @return <code>true</code> if entity with given ID exists
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
boolean exists(long id);
/**
* @return number of {@link BaseEntity}s in the repository.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long count();
/**
* Counts the number of {@link BaseEntity}s matching the given RSQL filter.
*
* @param rsql filter definition in RSQL syntax
* @return number of matching {@link BaseEntity}s in the repository.
*/
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countByRsql(String rsql);
/**
* Updates existing {@link BaseEntity}.
*
* @param update bean with properties of the object to update
* @return updated Entity
* @throws EntityReadOnlyException if the {@link BaseEntity} cannot be updated (e.g. is already in use)
* @throws EntityNotFoundException in case the {@link BaseEntity} does not exist and cannot be updated
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link BaseEntity} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
T update(@NotNull @Valid U update);
/**
* Deletes or marks as delete in case the {@link BaseEntity} is in use.
*
* @param id to delete
* @throws EntityNotFoundException BaseEntity with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY)
void delete(long id);
/**
* Delete {@link BaseEntity}s by their IDs. That is either a soft delete of the entities have been linked to another entity before or a hard
* delete if not.
*
* @param ids to be deleted
* @throws EntityNotFoundException if (at least one) given distribution set does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY)
void delete(@NotEmpty Collection<Long> ids);
default String permissionGroup() {
return "REPOSITORY";
}
}

View File

@@ -17,19 +17,26 @@ import java.util.Optional;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@@ -38,19 +45,24 @@ import org.springframework.security.access.prepost.PreAuthorize;
/**
* Service for managing {@link SoftwareModule}s.
*/
public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareModule, SoftwareModuleCreate, SoftwareModuleUpdate> {
public interface SoftwareModuleManagement<T extends SoftwareModule>
extends RepositoryManagement<T, SoftwareModuleManagement.Create, SoftwareModuleManagement.Update> {
@Override
default String permissionGroup() {
return "SOFTWARE_MODULE";
}
/**
* 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 AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleMetadata} entries is exceeded for the addressed
* {@link SoftwareModule}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void createMetadata(@NotNull @Valid Collection<SoftwareModuleMetadataCreate> metadata);
/**
@@ -60,7 +72,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return a paged result of all meta-data entries for a given software module id
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
List<SoftwareModuleMetadata> getMetadata(long id);
/**
@@ -71,7 +83,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return a paged result of all meta-data entries for a given software module id
* @throws EntityNotFoundException if software module with given ID does not exist ot the
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
SoftwareModuleMetadata getMetadata(long id, String key);
/**
@@ -82,7 +94,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return a paged result of all meta-data entries for a given software module id
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleIdAndTargetVisible(long id, @NotNull Pageable pageable);
/**
@@ -95,7 +107,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleMetadata}
* entries is exceeded for the addressed {@link SoftwareModule}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
SoftwareModuleMetadata updateMetadata(@NotNull @Valid SoftwareModuleMetadataCreate metadata);
/**
@@ -105,7 +117,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return the updated meta-data entry
* @throws EntityNotFoundException in case the meta-data entry does not exist and cannot be updated
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
SoftwareModuleMetadata updateMetadata(@NotNull @Valid SoftwareModuleMetadataUpdate update);
/**
@@ -113,10 +125,10 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
*
* @param id where meta-data has to be deleted
* @param key of the meta-data element
* @throws EntityNotFoundException if software module with given ID does not exist or the key is not found
* @return true if really deleted, false if not
* @throws EntityNotFoundException if software module with given ID does not exist or the key is not found
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void deleteMetadata(long id, @NotEmpty String key);
/**
@@ -125,7 +137,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @param id the software module id
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void lock(long id);
/**
@@ -136,7 +148,7 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @param id the software module id
* @throws EntityNotFoundException if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_UPDATE_REPOSITORY)
void unlock(long id);
/**
@@ -147,8 +159,8 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return all {@link SoftwareModule}s that are assigned to given {@link DistributionSet}.
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<SoftwareModule> findByAssignedTo(long distributionSetId, @NotNull Pageable pageable);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Page<T> findByAssignedTo(long distributionSetId, @NotNull Pageable pageable);
/**
* Filter {@link SoftwareModule}s with given {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()}
@@ -160,8 +172,8 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return the page of found {@link SoftwareModule}
* @throws EntityNotFoundException if given software module type does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Slice<SoftwareModule> findByTextAndType(String searchText, Long typeId, @NotNull Pageable pageable);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<T> findByTextAndType(String searchText, Long typeId, @NotNull Pageable pageable);
/**
* Retrieves {@link SoftwareModule} by their name AND version AND type.
@@ -172,8 +184,8 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return the found {@link SoftwareModule}
* @throws EntityNotFoundException if software module type with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<SoftwareModule> findByNameAndVersionAndType(@NotEmpty String name, @NotEmpty String version, long typeId);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByNameAndVersionAndType(@NotEmpty String name, @NotEmpty String version, long typeId);
/**
* Retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType}
@@ -183,10 +195,10 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return the found {@link SoftwareModule}s
* @throws EntityNotFoundException if software module type with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Slice<SoftwareModule> findByType(long typeId, @NotNull Pageable pageable);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<T> findByType(long typeId, @NotNull Pageable pageable);
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Map<Long, List<SoftwareModuleMetadata>> findMetaDataBySoftwareModuleIdsAndTargetVisible(Collection<Long> moduleIds);
/**
@@ -196,6 +208,48 @@ public interface SoftwareModuleManagement extends RepositoryManagement<SoftwareM
* @return count of {@link SoftwareModule}s that are assigned to given {@link DistributionSet}.
* @throws EntityNotFoundException if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
long countByAssignedTo(long distributionSetId);
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Create extends UpdateCreate {
private boolean encrypted;
}
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull
private Long id;
@Builder.Default
private Boolean locked = false;
}
@SuperBuilder
@Getter
class UpdateCreate {
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull(groups = Create.class)
private String name;
@ValidString
@Size(min = 1, max = NamedVersionedEntity.VERSION_MAX_SIZE)
@NotNull(groups = Create.class)
private String version;
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@ValidString
@Size(max = SoftwareModule.VENDOR_MAX_SIZE)
private String vendor;
private SoftwareModuleType type;
}
}

View File

@@ -12,30 +12,78 @@ package org.eclipse.hawkbit.repository;
import java.util.Optional;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeUpdate;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
import org.springframework.security.access.prepost.PreAuthorize;
/**
* Service for managing {@link SoftwareModuleType}s.
*/
public interface SoftwareModuleTypeManagement
extends RepositoryManagement<SoftwareModuleType, SoftwareModuleTypeCreate, SoftwareModuleTypeUpdate> {
public interface SoftwareModuleTypeManagement<T extends SoftwareModuleType>
extends RepositoryManagement<T, SoftwareModuleTypeManagement.Create, SoftwareModuleTypeManagement.Update> {
/**
* @param key to search for
* @return {@link SoftwareModuleType} in the repository with given {@link SoftwareModuleType#getKey()}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<SoftwareModuleType> findByKey(@NotEmpty String key);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByKey(@NotEmpty String key);
/**
* @param name to search for
* @return all {@link SoftwareModuleType}s in the repository with given {@link SoftwareModuleType#getName()}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<SoftwareModuleType> findByName(@NotEmpty String name);
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Optional<T> findByName(@NotEmpty String name);
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Create extends UpdateCreate {
@Size(min = 1, max = Type.KEY_MAX_SIZE)
@NotNull
private String key;
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull
private String name;
@Builder.Default
private int maxAssignments = 1;
}
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull
private Long id;
}
@SuperBuilder
@Getter
class UpdateCreate {
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@ValidString
@Size(max = Type.COLOUR_MAX_SIZE)
private String colour;
}
}

View File

@@ -76,7 +76,7 @@ public interface SystemManagement {
/**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
@@ -85,7 +85,7 @@ public interface SystemManagement {
/**
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} without details ({@link TenantMetaData#getDefaultDsType()})
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
@@ -118,4 +118,4 @@ public interface SystemManagement {
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
TenantMetaData getTenantMetadata(long tenantId);
}
}

View File

@@ -15,12 +15,12 @@ import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AU
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_CREATE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_DELETE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_READ_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_SUFFIX;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_UPDATE_REPOSITORY;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET;
import java.util.Collection;
@@ -752,7 +752,7 @@ public interface TargetManagement {
* @throws EntityAlreadyExistsException in case one of the metad-ata entry already exists for the specific key
* @throws AssignmentQuotaExceededException if the maximum number of meta-data entries is exceeded for the addressed {@link Target}
*/
@PreAuthorize(HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void createMetadata(@NotEmpty String controllerId, @NotEmpty Map<String, String> metadata);
/**
@@ -762,7 +762,7 @@ public interface TargetManagement {
* @return the found target meta-data
* @throws EntityNotFoundException if target with given ID does not exist
*/
@PreAuthorize(HAS_AUTH_READ_REPOSITORY)
@PreAuthorize(HAS_READ_REPOSITORY)
Map<String, String> getMetadata(@NotEmpty String controllerId);
/**
@@ -773,7 +773,7 @@ public interface TargetManagement {
* @param value meta data-entry to be new value
* @throws EntityNotFoundException in case the meta-data entry does not exist and cannot be updated
*/
@PreAuthorize(HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void updateMetadata(@NotEmpty String controllerId, @NotNull String key, @NotNull String value);
/**
@@ -783,6 +783,6 @@ public interface TargetManagement {
* @param key of the meta data element
* @throws EntityNotFoundException if given target does not exist
*/
@PreAuthorize(HAS_AUTH_UPDATE_REPOSITORY)
@PreAuthorize(HAS_UPDATE_REPOSITORY)
void deleteMetadata(@NotEmpty String controllerId, @NotEmpty String key);
}

View File

@@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.data.domain.Page;
@@ -53,7 +54,7 @@ public interface TargetTagManagement {
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link TagCreate} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
TargetTag create(@NotNull @Valid TagCreate create);
TargetTag create(@NotNull @Valid TagCreate<Tag> create);
/**
* Created multiple {@link TargetTag}s.
@@ -64,7 +65,7 @@ public interface TargetTagManagement {
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link TagCreate} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
List<TargetTag> create(@NotNull @Valid Collection<TagCreate> creates);
List<TargetTag> create(@NotNull @Valid Collection<TagCreate<Tag>> creates);
/**
* Deletes {@link TargetTag} with given name.

View File

@@ -25,7 +25,7 @@ public interface TenantStatsManagement {
* @return collected statistics
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION_READ + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_SYSTEM_CODE)

View File

@@ -1,29 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Builder for {@link DistributionSet}.
*/
public interface DistributionSetBuilder {
/**
* @param id of the updatable entity
* @return builder instance
*/
DistributionSetUpdate update(long id);
/**
* @return builder instance
*/
DistributionSetCreate create();
}

View File

@@ -1,79 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import java.util.Collection;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to create a new {@link DistributionSet} entry. Defines all fields
* that can be set at creation time. Other fields are set by the repository
* automatically, e.g. {@link BaseEntity#getCreatedAt()}.
*/
public interface DistributionSetCreate {
/**
* @param name for {@link DistributionSet#getName()}
* @return updated builder instance
*/
DistributionSetCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param version for {@link DistributionSet#getVersion()}
* @return updated builder instance
*/
DistributionSetCreate version(@Size(min = 1, max = NamedVersionedEntity.VERSION_MAX_SIZE) @NotNull String version);
/**
* @param description for {@link DistributionSet#getDescription()}
* @return updated builder instance
*/
DistributionSetCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param typeKey for {@link DistributionSet#getType()}
* @return updated builder instance
*/
DistributionSetCreate type(@Size(min = 1, max = Type.KEY_MAX_SIZE) @NotNull String typeKey);
/**
* @param type for {@link DistributionSet#getType()}
* @return updated builder instance
*/
default DistributionSetCreate type(@NotNull final DistributionSetType type) {
return type(type.getKey());
}
/**
* @param modules for {@link DistributionSet#getModules()}
* @return updated builder instance
*/
DistributionSetCreate modules(Collection<Long> modules);
/**
* @param requiredMigrationStep for {@link DistributionSet#isRequiredMigrationStep()}
* @return updated builder instance
*/
DistributionSetCreate requiredMigrationStep(Boolean requiredMigrationStep);
/**
* @return peek on current state of {@link DistributionSet} in the builder
*/
DistributionSet build();
}

View File

@@ -1,29 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
/**
* Builder for {@link DistributionSetType}.
*/
public interface DistributionSetTypeBuilder {
/**
* @param id of the updatable entity
* @return builder instance
*/
DistributionSetTypeUpdate update(long id);
/**
* @return builder instance
*/
DistributionSetTypeCreate create();
}

View File

@@ -1,104 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to create a new {@link DistributionSetType} entry. Defines all fields
* that can be set at creation time. Other fields are set by the repository
* automatically, e.g. {@link BaseEntity#getCreatedAt()}.
*/
public interface DistributionSetTypeCreate {
/**
* @param key for {@link DistributionSetType#getKey()}
* @return updated builder instance
*/
DistributionSetTypeCreate key(@Size(min = 1, max = Type.KEY_MAX_SIZE) @NotNull String key);
/**
* @param name for {@link DistributionSetType#getName()}
* @return updated builder instance
*/
DistributionSetTypeCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param description for {@link DistributionSetType#getDescription()}
* @return updated builder instance
*/
DistributionSetTypeCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link DistributionSetType#getColour()}
* @return updated builder instance
*/
DistributionSetTypeCreate colour(@Size(max = Type.COLOUR_MAX_SIZE) String colour);
/**
* @param mandatory for {@link DistributionSetType#getMandatoryModuleTypes()}
* @return updated builder instance
*/
DistributionSetTypeCreate mandatory(Collection<Long> mandatory);
/**
* @param mandatory for {@link DistributionSetType#getMandatoryModuleTypes()}
* @return updated builder instance
*/
default DistributionSetTypeCreate mandatory(final Long mandatory) {
return mandatory(Collections.singletonList(mandatory));
}
/**
* @param mandatory for {@link DistributionSetType#getOptionalModuleTypes()}
* @return updated builder instance
*/
default DistributionSetTypeCreate mandatory(final SoftwareModuleType mandatory) {
return mandatory(Optional.ofNullable(mandatory).map(SoftwareModuleType::getId).orElse(null));
}
/**
* @param optional for {@link DistributionSetType#getOptionalModuleTypes()}
* @return updated builder instance
*/
DistributionSetTypeCreate optional(Collection<Long> optional);
/**
* @param optional for {@link DistributionSetType#getOptionalModuleTypes()}
* @return updated builder instance
*/
default DistributionSetTypeCreate optional(final Long optional) {
return optional(Collections.singletonList(optional));
}
/**
* @param optional for {@link DistributionSetType#getOptionalModuleTypes()}
* @return updated builder instance
*/
default DistributionSetTypeCreate optional(final SoftwareModuleType optional) {
return optional(Optional.ofNullable(optional).map(SoftwareModuleType::getId).orElse(null));
}
/**
* @return peek on current state of {@link DistributionSetType} in the builder
*/
DistributionSetType build();
}

View File

@@ -1,49 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import java.util.Collection;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to update an existing {@link DistributionSetType} entry. Defines all
* fields that can be updated.
*/
public interface DistributionSetTypeUpdate {
/**
* @param description for {@link DistributionSetType#getDescription()}
* @return updated builder instance
*/
DistributionSetTypeUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link DistributionSetType#getColour()}
* @return updated builder instance
*/
DistributionSetTypeUpdate colour(@Size(max = Type.COLOUR_MAX_SIZE) String colour);
/**
* @param mandatory for {@link DistributionSetType#getMandatoryModuleTypes()}
* @return updated builder instance
*/
DistributionSetTypeUpdate mandatory(Collection<Long> mandatory);
/**
* @param optional for {@link DistributionSetType#getOptionalModuleTypes()}
* @return updated builder instance
*/
DistributionSetTypeUpdate optional(Collection<Long> optional);
}

View File

@@ -1,54 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
/**
* Builder to update an existing {@link DistributionSet} entry. Defines all fields that can be updated.
*/
public interface DistributionSetUpdate {
/**
* @param name for {@link DistributionSet#getName()}
* @return updated builder instance
*/
DistributionSetUpdate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param version for {@link DistributionSet#getVersion()}
* @return updated builder instance
*/
DistributionSetUpdate version(@Size(min = 1, max = NamedVersionedEntity.VERSION_MAX_SIZE) @NotNull String version);
/**
* @param description for {@link DistributionSet#getDescription()}
* @return updated builder instance
*/
DistributionSetUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param locked update request if any. If not empty shall be <code>true</code>
* @return updated builder instance
*/
DistributionSetUpdate locked(@Null Boolean locked);
/**
* @param requiredMigrationStep for {@link DistributionSet#isRequiredMigrationStep()}
* @return updated builder instance
*/
DistributionSetUpdate requiredMigrationStep(Boolean requiredMigrationStep);
}

View File

@@ -1,29 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* Builder for {@link SoftwareModule}.
*/
public interface SoftwareModuleBuilder {
/**
* @param id of the updatable entity
* @return builder instance
*/
SoftwareModuleUpdate update(long id);
/**
* @return builder instance
*/
SoftwareModuleCreate create();
}

View File

@@ -1,77 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to create a new {@link SoftwareModule} entry. Defines all fields that
* can be set at creation time. Other fields are set by the repository
* automatically, e.g. {@link BaseEntity#getCreatedAt()}.
*/
public interface SoftwareModuleCreate {
/**
* @param name for {@link SoftwareModule#getName()}
* @return updated builder instance
*/
SoftwareModuleCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param version for {@link SoftwareModule#getVersion()}
* @return updated builder instance
*/
SoftwareModuleCreate version(@Size(min = 1, max = NamedVersionedEntity.VERSION_MAX_SIZE) @NotNull String version);
/**
* @param description for {@link SoftwareModule#getDescription()}
* @return updated builder instance
*/
SoftwareModuleCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param vendor for {@link SoftwareModule#getVendor()}
* @return updated builder instance
*/
SoftwareModuleCreate vendor(@Size(max = SoftwareModule.VENDOR_MAX_SIZE) String vendor);
/**
* @param typeKey for {@link SoftwareModule#getType()}
* @return updated builder instance
*/
SoftwareModuleCreate type(@Size(min = 1, max = Type.KEY_MAX_SIZE) @NotNull String typeKey);
/**
* @param type for {@link SoftwareModule#getType()}
* @return updated builder instance
*/
default SoftwareModuleCreate type(@NotNull final SoftwareModuleType type) {
return type(type.getKey());
}
/**
* @param encrypted if should be encrypted
* @return updated builder instance
*/
SoftwareModuleCreate encrypted(boolean encrypted);
/**
* @return peek on current state of {@link SoftwareModule} in the builder
*/
SoftwareModule build();
}

View File

@@ -1,29 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* Builder for {@link SoftwareModuleType}.
*/
public interface SoftwareModuleTypeBuilder {
/**
* @param id of the updatable entity
* @return builder instance
*/
SoftwareModuleTypeUpdate update(long id);
/**
* @return builder instance
*/
SoftwareModuleTypeCreate create();
}

View File

@@ -1,62 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to create a new {@link SoftwareModuleType} entry. Defines all fields
* that can be set at creation time. Other fields are set by the repository
* automatically, e.g. {@link BaseEntity#getCreatedAt()}.
*/
public interface SoftwareModuleTypeCreate {
/**
* @param key for {@link SoftwareModuleType#getKey()}
* @return updated builder instance
*/
SoftwareModuleTypeCreate key(@Size(min = 1, max = Type.KEY_MAX_SIZE) @NotNull String key);
/**
* @param name for {@link SoftwareModuleType#getName()}
* @return updated builder instance
*/
SoftwareModuleTypeCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param description for {@link SoftwareModuleType#getDescription()}
* @return updated builder instance
*/
SoftwareModuleTypeCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link SoftwareModuleType#getColour()}
* @return updated builder instance
*/
SoftwareModuleTypeCreate colour(@Size(max = Type.COLOUR_MAX_SIZE) String colour);
/**
* @param maxAssignments for {@link SoftwareModuleType#getMaxAssignments()}
* @return updated builder instance
*/
SoftwareModuleTypeCreate maxAssignments(int maxAssignments);
/**
* @return peek on current state of {@link SoftwareModuleType} in the
* builder
*/
SoftwareModuleType build();
}

View File

@@ -1,35 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to update an existing {@link SoftwareModuleType} entry. Defines all
* fields that can be updated.
*/
public interface SoftwareModuleTypeUpdate {
/**
* @param description for {@link SoftwareModuleType#getDescription()}
* @return updated builder instance
*/
SoftwareModuleTypeUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link SoftwareModuleType#getColour()}
* @return updated builder instance
*/
SoftwareModuleTypeUpdate colour(@Size(max = Type.COLOUR_MAX_SIZE) String colour);
}

View File

@@ -1,41 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.builder;
import jakarta.validation.constraints.Null;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* Builder to update an existing {@link SoftwareModule} entry. Defines all
* fields that can be updated.
*/
public interface SoftwareModuleUpdate {
/**
* @param description for {@link SoftwareModule#getDescription()}
* @return updated builder instance
*/
SoftwareModuleUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param vendor for {@link SoftwareModule#getVendor()}
* @return updated builder instance
*/
SoftwareModuleUpdate vendor(@Size(max = SoftwareModule.VENDOR_MAX_SIZE) String vendor);
/**
* @param locked update request if any. If not empty shall be <code>true</code>
* @return updated builder instance
*/
SoftwareModuleUpdate locked(@Null Boolean locked);
}

View File

@@ -14,7 +14,7 @@ import org.eclipse.hawkbit.repository.model.Tag;
/**
* Builder for {@link Tag}.
*/
public interface TagBuilder {
public interface TagBuilder<T extends Tag> {
/**
* @param id of the updatable entity
@@ -25,5 +25,5 @@ public interface TagBuilder {
/**
* @return builder instance
*/
TagCreate create();
TagCreate<T> create();
}

View File

@@ -21,28 +21,28 @@ import org.eclipse.hawkbit.repository.model.Tag;
* at creation time. Other fields are set by the repository automatically, e.g.
* {@link BaseEntity#getCreatedAt()}.
*/
public interface TagCreate {
public interface TagCreate<T extends Tag> {
/**
* @param name for {@link Tag#getName()}
* @return updated builder instance
*/
TagCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
TagCreate<T> name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param description for {@link Tag#getDescription()}
* @return updated builder instance
*/
TagCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
TagCreate<T> description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link Tag#getColour()}
* @return updated builder instance
*/
TagCreate colour(@Size(max = Tag.COLOUR_MAX_SIZE) String colour);
TagCreate<T> colour(@Size(max = Tag.COLOUR_MAX_SIZE) String colour);
/**
* @return peek on current state of {@link Tag} in the builder
*/
Tag build();
T build();
}

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -19,6 +21,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
* Exception indicating that an artifact's binary does not exist anymore. This
* might be caused due to the soft deletion of a {@link SoftwareModule}.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ArtifactBinaryNoLongerExistsException extends AbstractServerRtException {
@Serial

View File

@@ -11,9 +11,13 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ArtifactBinaryNotFoundException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if artifact deletion failed.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ArtifactDeleteFailedException extends AbstractServerRtException {
@Serial

View File

@@ -11,9 +11,13 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ArtifactUploadFailedException extends AbstractServerRtException {
@Serial

View File

@@ -9,6 +9,8 @@
*/
package org.eclipse.hawkbit.repository.exception;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.BaseEntity;
@@ -16,6 +18,8 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
/**
* Thrown if assignment quota is exceeded
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
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.";

View File

@@ -11,15 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* The {@link AutoConfirmationAlreadyActiveException} is thrown when auto
* confirmation is already active for a device but the
* {@link org.eclipse.hawkbit.repository.ConfirmationManagement#activateAutoConfirmation}
* is getting called.
* The {@link AutoConfirmationAlreadyActiveException} is thrown when auto confirmation is already active for a device but the
* {@link org.eclipse.hawkbit.repository.ConfirmationManagement#activateAutoConfirmation} is getting called.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AutoConfirmationAlreadyActiveException extends AbstractServerRtException {
@Serial

View File

@@ -11,15 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if cancellation of action is requested where the action cannot be
* cancelled (e.g. the action is not active or is already a canceled action) or
* controller provides cancellation feedback on an action that is actually not
* in canceling state.
* Thrown if cancellation of action is requested where the action cannot be cancelled (e.g. the action is not active or is already a canceled
* action) or controller provides cancellation feedback on an action that is actually not in canceling state.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class CancelActionNotAllowedException extends AbstractServerRtException {
@Serial

View File

@@ -11,14 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* {@link ConcurrentModificationException} is thrown when a given entity in's
* actual and cannot be stored within the current session. Reason could be that
* it has been changed within another session.
* {@link ConcurrentModificationException} is thrown when a given entity in's actual and cannot be stored within the current session.
* Reason could be that it has been changed within another session.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ConcurrentModificationException extends AbstractServerRtException {
@Serial

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.BaseEntity;
@@ -18,6 +20,8 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
/**
* Thrown if assignment quota is exceeded
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DeletedException extends AbstractServerRtException {
@Serial

View File

@@ -11,15 +11,18 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
/**
* Thrown if the user tries to assign modules to a {@link DistributionSet} that
* has to {@link DistributionSetType} defined.
* Thrown if the user tries to assign modules to a {@link DistributionSet} that has to {@link DistributionSetType} defined.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class DistributionSetTypeUndefinedException extends AbstractServerRtException {
@Serial

View File

@@ -11,13 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* the {@link EntityAlreadyExistsException} is thrown when an entity is tried to
* be saved which already exists or which violates unique key constraints.
* the {@link EntityAlreadyExistsException} is thrown when an entity is tried to be saved which already exists or which violates unique key
* constraints.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class EntityAlreadyExistsException extends AbstractServerRtException {
@Serial

View File

@@ -14,7 +14,10 @@ import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.BaseEntity;
@@ -22,14 +25,18 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
/**
* the {@link EntityNotFoundException} is thrown when a entity queried but not found.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Getter
public class EntityNotFoundException extends AbstractServerRtException {
@Serial
private static final long serialVersionUID = 1L;
public static final String KEY = "key";
public static final String ENTITY_ID = "entityId";
public static final String TYPE = "type";
@Serial
private static final long serialVersionUID = 1L;
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_NOT_EXISTS;
private static final int ENTITY_STRING_MAX_LENGTH = 100;

View File

@@ -11,13 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* the {@link EntityReadOnlyException} is thrown when a entity is in read only
* mode and a user tries to change it.
* the {@link EntityReadOnlyException} is thrown when a entity is in read only mode and a user tries to change it.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class EntityReadOnlyException extends AbstractServerRtException {
@Serial

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.exception;
import static org.eclipse.hawkbit.repository.SizeConversionHelper.byteValueToReadableString;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@@ -19,6 +20,7 @@ import org.eclipse.hawkbit.exception.SpServerError;
* Thrown if file size quota is exceeded
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class FileSizeQuotaExceededException extends AbstractServerRtException {
private static final String MAX_ARTIFACT_SIZE_EXCEEDED = "Maximum artifact size (%s) exceeded.";

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown when force quitting an actions is not allowed. e.g. the action is not active, or it is not canceled before.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class ForceQuitActionNotAllowedException extends AbstractServerRtException {
@Serial

View File

@@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.Collections;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -24,6 +25,7 @@ import org.eclipse.hawkbit.repository.model.TargetType;
* Thrown if user tries to assign a {@link DistributionSet} to a {@link Target} that has an incompatible {@link TargetType}
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class IncompatibleTargetTypeException extends AbstractServerRtException {
@Serial

View File

@@ -11,13 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if a distribution set is assigned to a a target that is incomplete
* (i.e. mandatory modules are missing).
* Thrown if a distribution set is assigned to a target that is incomplete (i.e. mandatory modules are missing).
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class IncompleteDistributionSetException extends AbstractServerRtException {
@Serial

View File

@@ -11,35 +11,30 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception which is thrown in case the current security context object does
* not hold a required authority/permission.
* Exception which is thrown in case the current security context object does not hold a required authority/permission.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InsufficientPermissionException extends AbstractServerRtException {
@Serial
private static final long serialVersionUID = 1L;
/**
* creates new InsufficientPermissionException.
*
* @param cause the cause of the exception
*/
public InsufficientPermissionException(final Throwable cause) {
super(SpServerError.SP_INSUFFICIENT_PERMISSION, cause);
}
/**
* creates new InsufficientPermissionException.
*/
public InsufficientPermissionException(final String message) {
super(message, SpServerError.SP_INSUFFICIENT_PERMISSION);
}
public InsufficientPermissionException() {
super(SpServerError.SP_INSUFFICIENT_PERMISSION, null);
this((String)null);
}
}
}

View File

@@ -12,12 +12,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if an action type for auto-assignment is neither 'forced', nor 'soft'.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidAutoAssignActionTypeException extends AbstractServerRtException {
@Serial

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@@ -20,6 +21,7 @@ import org.eclipse.hawkbit.exception.SpServerError;
* listed as enum {@link Reason}.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidConfirmationFeedbackException extends AbstractServerRtException {
@Serial

View File

@@ -11,9 +11,13 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidDistributionSetException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if MD5 checksum check fails.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidMD5HashException extends AbstractServerRtException {
@Serial

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@@ -21,6 +22,7 @@ import org.eclipse.hawkbit.exception.SpServerError;
* time.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidMaintenanceScheduleException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if SHA1 checksum check fails.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidSHA1HashException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if SHA256 checksum check fails.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidSHA256HashException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception which is thrown when trying to set an invalid target address.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidTargetAddressException extends AbstractServerRtException {
@Serial

View File

@@ -12,9 +12,13 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidTargetAttributeException extends AbstractServerRtException {
@Serial

View File

@@ -11,13 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* The {@link #InvalidTenantConfigurationKeyException} is thrown when an invalid
* configuration key is used.
* The {@link #InvalidTenantConfigurationKeyException} is thrown when an invalid configuration key is used.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class InvalidTenantConfigurationKeyException extends AbstractServerRtException {
@Serial

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.BaseEntity;
@@ -18,6 +20,8 @@ import org.eclipse.hawkbit.repository.model.BaseEntity;
/**
* Thrown if there is attempt to functionally modify a locked entity
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class LockedException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if repository operation is no longer supported.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public final class MethodNotSupportedException extends AbstractServerRtException {
@Serial

View File

@@ -11,13 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* This exception is thrown if an operation requires multiassignments, but the
* feature is not enabled.
* This exception is thrown if an operation requires multi-assignments, but the feature is not enabled.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class MultiAssignmentIsNotEnabledException extends AbstractServerRtException {
@Serial

View File

@@ -11,13 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* This exception is thrown if multi assignments is enabled and an target
* distribution set assignment request does not contain a weight value
* This exception is thrown if multi assignments is enabled and a target distribution set assignment request does not contain a weight value
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class NoWeightProvidedInMultiAssignmentModeException extends AbstractServerRtException {
@Serial

View File

@@ -19,8 +19,8 @@ import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception used by the REST API in case of RSQL search filter query.
*/
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RSQLParameterSyntaxException extends AbstractServerRtException {
@Serial

View File

@@ -19,8 +19,8 @@ import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception used by the REST API in case of invalid field name in the rsql search parameter.
*/
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RSQLParameterUnsupportedFieldException extends AbstractServerRtException {
@Serial

View File

@@ -11,14 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* the {@link RolloutIllegalStateException} is thrown when a rollout is changing
* it's state which is not valid. E.g. trying to start a already running
* rollout, or trying to resume a already finished rollout.
* the {@link RolloutIllegalStateException} is thrown when a rollout is changing it's state which is not valid. E.g. trying to start an already
* running rollout, or trying to resume a already finished rollout.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RolloutIllegalStateException extends AbstractServerRtException {
@Serial

View File

@@ -12,6 +12,8 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import java.lang.annotation.Target;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -19,6 +21,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
* the {@link SoftwareModuleNotAssignedToTargetException} is thrown when a {@link SoftwareModule} is requested as part of an {@link Action}
* that has however never been assigned to the {@link Target}.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SoftwareModuleNotAssignedToTargetException extends EntityNotFoundException {
@Serial

View File

@@ -11,16 +11,18 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* the {@link SoftwareModuleTypeNotInDistributionSetTypeException} is thrown
* when a {@link SoftwareModuleType} is requested as part of a
* {@link DistributionSetType} but actually neither
* {@link DistributionSetType#getMandatoryModuleTypes()} or
* The {@link SoftwareModuleTypeNotInDistributionSetTypeException} is thrown when a {@link SoftwareModuleType} is requested as part of a
* {@link DistributionSetType} but actually neither {@link DistributionSetType#getMandatoryModuleTypes()} or
* {@link DistributionSetType#getOptionalModuleTypes()}.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class SoftwareModuleTypeNotInDistributionSetTypeException extends EntityNotFoundException {
@Serial

View File

@@ -11,14 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* {@link StopRolloutException} is thrown when an error occurs while stopping
* the rollout (due to an invalidation of distribution set). This could be
* caused by a long ongoing creation of a rollout.
* {@link StopRolloutException} is thrown when an error occurs while stopping the rollout (due to an invalidation of distribution set).
* This could be caused by a long ongoing creation of a rollout.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class StopRolloutException extends AbstractServerRtException {
@Serial

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.exception;
import static org.eclipse.hawkbit.repository.SizeConversionHelper.byteValueToReadableString;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
@@ -19,6 +20,7 @@ import org.eclipse.hawkbit.exception.SpServerError;
* Thrown if storage quota is exceeded
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class StorageQuotaExceededException extends AbstractServerRtException {
private static final String MAX_ARTIFACT_SIZE_TOTAL_EXCEEDED = "Storage quota exceeded, %s left.";

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if target type is assigned
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TargetTypeInUseException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Thrown if tried creation of type with no key nor name.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TargetTypeKeyOrNameRequiredException extends AbstractServerRtException {
@Serial

View File

@@ -11,13 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception which is thrown, when the validation of the configuration value has
* not been successful.
* Exception which is thrown, when the validation of the configuration value has not been successful.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TenantConfigurationValidatorException extends AbstractServerRtException {
@Serial

View File

@@ -11,12 +11,16 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* Exception which is supposed to be thrown if a property value is valid but cannot be set in the current context.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TenantConfigurationValueChangeNotAllowedException extends AbstractServerRtException {
@Serial

View File

@@ -11,15 +11,17 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
/**
* the {@link TenantNotExistException} is thrown when e.g. a controller tries to
* register itself at SP as plug'n play target and the tenant specified in the
* URL for this target does not exist. To avoid that targets could register
* automatically new tenants.
* The {@link TenantNotExistException} is thrown when e.g. a controller tries to register itself at SP as plug'n play target and the tenant
* specified in the URL for this target does not exist. To avoid that targets could register automatically new tenants.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TenantNotExistException extends AbstractServerRtException {
@Serial

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository.exception;
import java.io.Serial;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.eclipse.hawkbit.exception.AbstractServerRtException;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -18,10 +20,10 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* Thrown if user tries to add a {@link SoftwareModule} to a
* {@link DistributionSet} that is not defined by the
* {@link DistributionSetType}.
* Thrown if user tries to add a {@link SoftwareModule} to a {@link DistributionSet} that is not defined by the {@link DistributionSetType}.
*/
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class UnsupportedSoftwareModuleForThisDistributionSetException extends AbstractServerRtException {
@Serial

View File

@@ -74,14 +74,4 @@ public interface DistributionSet extends NamedVersionedEntity {
* and not automatically canceled if overridden by a newer update.
*/
boolean isRequiredMigrationStep();
/**
* Searches through modules for the given type.
*
* @param type to search for
* @return SoftwareModule of given type
*/
default Optional<SoftwareModule> findFirstModuleByType(final SoftwareModuleType type) {
return getModules().stream().filter(module -> module.getType().equals(type)).findAny();
}
}