true if the artifact binary can be overridden
+ * if it already exists
+ *
+ * @return uploaded {@link LocalArtifact}
+ *
+ * @throw ArtifactUploadFailedException if upload fails
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
+ LocalArtifact createLocalArtifact(@NotNull InputStream inputStream, @NotNull Long moduleId, final String filename,
+ final boolean overrideExisting);
+
+ /**
+ * Persists artifact binary as provided by given InputStream. assign the
+ * artifact in addition to given {@link SoftwareModule}.
+ *
+ * @param inputStream
+ * to read from for artifact binary
+ * @param moduleId
+ * to assign the new artifact to
+ * @param filename
+ * of the artifact
+ * @param overrideExisting
+ * to true if the artifact binary can be overridden
+ * if it already exists
+ * @param contentType
+ * the contentType of the file
+ *
+ * @return uploaded {@link LocalArtifact}
+ *
+ * @throw ArtifactUploadFailedException if upload fails
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
+ LocalArtifact createLocalArtifact(@NotNull InputStream inputStream, @NotNull Long moduleId,
+ @NotNull String filename, final boolean overrideExisting, @NotNull String contentType);
+
+ /**
+ * Persists artifact binary as provided by given InputStream. assign the
+ * artifact in addition to given {@link SoftwareModule}.
+ *
+ * @param stream
+ * to read from for artifact binary
+ * @param moduleId
+ * to assign the new artifact to
+ * @param filename
+ * of the artifact
+ * @param providedSha1Sum
+ * optional sha1 checksum to check the new file against
+ * @param providedMd5Sum
+ * optional md5 checksum to check the new file against
+ * @param overrideExisting
+ * to true if the artifact binary can be overdiden
+ * if it already exists
+ * @param contentType
+ * the contentType of the file
+ * @return uploaded {@link LocalArtifact}
+ *
+ * @throws EntityNotFoundException
+ * if given software module does not exist
+ * @throws EntityAlreadyExistsException
+ * if File with that name already exists in the Software Module
+ * @throws ArtifactUploadFailedException
+ * if upload fails with internal server errors
+ * @throws InvalidMD5HashException
+ * if check against provided MD5 checksum failed
+ * @throws InvalidSHA1HashException
+ * if check against provided SHA1 checksum failed
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY)
+ LocalArtifact createLocalArtifact(@NotNull InputStream stream, @NotNull Long moduleId, @NotEmpty String filename,
+ String providedMd5Sum, String providedSha1Sum, boolean overrideExisting, String contentType);
+
+ /**
+ * Deletes {@link Artifact} based on given id.
+ *
+ * @param id
+ * of the {@link Artifact} that has to be deleted.
+ * @throws ArtifactDeleteFailedException
+ * if deletion failed (MongoDB is not available)
+ *
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
+ void deleteExternalArtifact(@NotNull Long id);
+
+ /**
+ * Deletes a local artifact.
+ *
+ * @param existing
+ * the related local artifact
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
+ void deleteLocalArtifact(@NotNull LocalArtifact existing);
+
+ /**
+ * Deletes {@link Artifact} based on given id.
+ *
+ * @param id
+ * of the {@link Artifact} that has to be deleted.
+ * @throws ArtifactDeleteFailedException
+ * if deletion failed (MongoDB is not available)
+ *
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
+ void deleteLocalArtifact(@NotNull Long id);
+
+ /**
+ * Searches for {@link Artifact} with given {@link Identifiable}.
+ *
+ * @param id
+ * to search for
+ * @return found {@link Artifact} or null is it could not be
+ * found.
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ Artifact findArtifact(@NotNull Long id);
+
+ /**
+ * Find by artifact by software module id and filename.
+ *
+ * @param filename
+ * file name
+ * @param softwareModuleId
+ * software module id.
+ * @return LocalArtifact if artifact present
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ + SpringEvalExpressions.IS_CONTROLLER)
+ Listnull if not
+ * found.
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
+ + SpringEvalExpressions.IS_CONTROLLER)
+ SoftwareModule findSoftwareModuleById(@NotNull Long id);
+
+ /**
+ * Retrieves software module including details (
+ * {@link SoftwareModule#getArtifacts()}).
+ *
+ * @param id
+ * parameter
+ * @param isDeleted
+ * parameter
+ * @return the found {@link SoftwareModule}s
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id);
+
+ /**
+ * Loads {@link DbArtifact} from store for given {@link LocalArtifact}.
+ *
+ * @param artifact
+ * to search for
+ * @return loaded {@link DbArtifact}
+ *
+ * @throws GridFSDBFileNotFoundException
+ * if file could not be found in store
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR
+ + SpringEvalExpressions.HAS_CONTROLLER_DOWNLOAD)
+ DbArtifact loadLocalArtifactBinary(@NotNull LocalArtifact artifact);
+
+}
diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/Constants.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/Constants.java
new file mode 100644
index 000000000..9a1e442b0
--- /dev/null
+++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/Constants.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.repository;
+
+import org.eclipse.hawkbit.repository.model.DistributionSetType;
+import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
+
+/**
+ * Repository API constants.
+ *
+ */
+public final class Constants {
+ /**
+ * {@link SoftwareModuleType#getKey()} of a {@link SoftwareModuleType}
+ * generated by repository for every new account for Firmware/Operating
+ * System.
+ */
+ public static final String SMT_DEFAULT_OS_KEY = "os";
+ /**
+ * {@link SoftwareModuleType#getKey()} of a {@link SoftwareModuleType}
+ * generated by repository for every new account for applications.
+ */
+ public static final String SMT_DEFAULT_APP_KEY = "application";
+
+ /**
+ * {@link SoftwareModuleType#getName()} of a {@link SoftwareModuleType}
+ * generated by repository for every new account for "Firmware/Operating
+ * System" .
+ */
+ public static final String SMT_DEFAULT_OS_NAME = "Firmware";
+ /**
+ * {@link SoftwareModuleType#getName()} of a {@link SoftwareModuleType}
+ * generated by repository for every new account for "applications/apps".
+ */
+ public static final String SMT_DEFAULT_APP_NAME = "Application";
+
+ /**
+ * {@link DistributionSetType#getKey()} of a {@link DistributionSetType}
+ * generated by repository for every new account that includes
+ * {@link #SMT_DEFAULT_OS_KEY} as mandatory module and optional
+ * {@link #SMT_DEFAULT_APP_KEY}s.
+ */
+ public static final String DST_DEFAULT_OS_WITH_APPS_KEY = "os_app";
+
+ /**
+ * {@link DistributionSetType#getName()} of a {@link DistributionSetType}
+ * generated by repository for every new account that includes
+ * {@link #SMT_DEFAULT_OS_KEY} as mandatory module and optional
+ * {@link #SMT_DEFAULT_APP_KEY}s.
+ */
+ public static final String DST_DEFAULT_OS_WITH_APPS_NAME = "OS with app(s)";
+
+ /**
+ * {@link DistributionSetType#getKey()} of a {@link DistributionSetType}
+ * generated by repository for every new account that includes only
+ * {@link #SMT_DEFAULT_OS_KEY} as mandatory module.
+ */
+ public static final String DST_DEFAULT_OS_ONLY_KEY = "os";
+
+ /**
+ * {@link DistributionSetType#getName()} of a {@link DistributionSetType}
+ * generated by repository for every new account that includes only
+ * {@link #SMT_DEFAULT_OS_KEY} as mandatory module.
+ */
+ public static final String DST_DEFAULT_OS_ONLY_NAME = "OS only";
+
+ private Constants() {
+ // Utility class.
+ }
+}
diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java
new file mode 100644
index 000000000..531da8819
--- /dev/null
+++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java
@@ -0,0 +1,283 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.repository;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.validation.constraints.NotNull;
+
+import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
+import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
+import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
+import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
+import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
+import org.eclipse.hawkbit.repository.exception.ToManyStatusEntriesException;
+import org.eclipse.hawkbit.repository.model.Action;
+import org.eclipse.hawkbit.repository.model.Action.Status;
+import org.eclipse.hawkbit.repository.model.ActionStatus;
+import org.eclipse.hawkbit.repository.model.DistributionSet;
+import org.eclipse.hawkbit.repository.model.LocalArtifact;
+import org.eclipse.hawkbit.repository.model.SoftwareModule;
+import org.eclipse.hawkbit.repository.model.Target;
+import org.eclipse.hawkbit.repository.model.TargetInfo;
+import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
+import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
+import org.hibernate.validator.constraints.NotEmpty;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+import com.google.common.eventbus.EventBus;
+
+/**
+ * Service layer for all operations of the DDI API (with access permissions only
+ * for the controller).
+ *
+ */
+public interface ControllerManagement {
+
+ /**
+ * Adds an {@link ActionStatus} for a cancel {@link Action} including
+ * potential state changes for the target and the {@link Action} itself.
+ *
+ * @param actionStatus
+ * to be added
+ * @return the persisted {@link Action}
+ *
+ * @throws EntityAlreadyExistsException
+ * if a given entity already exists
+ *
+ */
+ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
+ Action addCancelActionStatus(@NotNull ActionStatus actionStatus);
+
+ /**
+ * Sends the download progress in percentage and notifies the
+ * {@link EventBus} with a {@link DownloadProgressEvent}.
+ *
+ * @param statusId
+ * the ID of the {@link ActionStatus}
+ * @param progressPercent
+ * the progress in percentage which must be between 0-100
+ */
+ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
+ void downloadProgressPercent(long statusId, int progressPercent);
+
+ /**
+ * Simple addition of a new {@link ActionStatus} entry to the {@link Action}
+ * . No state changes.
+ *
+ * @param statusMessage
+ * to add to the action
+ */
+ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
+ void addInformationalActionStatus(@NotNull ActionStatus statusMessage);
+
+ /**
+ * Adds an {@link ActionStatus} entry for an update {@link Action} including
+ * potential state changes for the target and the {@link Action} itself.
+ *
+ * @param actionStatus
+ * to be added
+ * @return the updated {@link Action}
+ *
+ * @throws EntityAlreadyExistsException
+ * if a given entity already exists
+ * @throws ToManyStatusEntriesException
+ * if more than the allowed number of status entries are
+ * inserted
+ */
+ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
+ Action addUpdateActionStatus(@NotNull ActionStatus actionStatus);
+
+ /**
+ * Retrieves all {@link Action}s which are active and assigned to a
+ * {@link Target}.
+ *
+ * @param target
+ * the target to retrieve the actions from
+ * @return a list of actions assigned to given target which are active
+ */
+ @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
+ Listnull if not active on
+ * given {@link Target}.
+ * @throws CancelActionNotAllowedException
+ * in case the given action is not active or is already a cancel
+ * action
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
+ Action cancelAction(@NotNull Action action, @NotNull Target target);
+
+ /**
+ * counts all actions associated to a specific target.
+ *
+ * @param rsqlParam
+ * rsql query string
+ * @param target
+ * the target associated to the actions to count
+ * @return the count value of found actions associated to the target
+ *
+ * @throws RSQLParameterUnsupportedFieldException
+ * if a field in the RSQL string is used but not provided by the
+ * given {@code fieldNameProvider}
+ * @throws RSQLParameterSyntaxException
+ * if the RSQL syntax is wrong
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
+ Long countActionsByTarget(@NotNull String rsqlParam, @NotNull Target target);
+
+ /**
+ * @return the total amount of stored action status
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
+ Long countActionStatusAll();
+
+ /**
+ * @return the total amount of stored actions
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
+ Long countActionsAll();
+
+ /**
+ * counts all actions associated to a specific target.
+ *
+ * @param target
+ * the target associated to the actions to count
+ * @return the count value of found actions associated to the target
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
+ Long countActionsByTarget(@NotNull Target target);
+
+ /**
+ * Creates an action entry into the action repository. In case of existing
+ * scheduled actions the scheduled actions gets canceled. A scheduled action
+ * is created in-active.
+ *
+ * @param targets
+ * the targets to create scheduled actions for
+ * @param distributionSet
+ * the distribution set for the actions
+ * @param actionType
+ * the action type for the action
+ * @param forcedTime
+ * the forcedTime of the action
+ * @param rollout
+ * the roll out for this action
+ * @param rolloutGroup
+ * the roll out group for this action
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
+ void createScheduledAction(@NotEmpty Collectiontrue if {@link ActionStatus#getMessages()}
+ * need to be fetched.
+ * @return the corresponding {@link Page} of {@link ActionStatus}
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
+ Pagenull if not active on
+ * {@link Target}.
+ * @throws CancelActionNotAllowedException
+ * in case the given action is not active
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
+ Action forceQuitAction(@NotNull Action action);
+
+ /**
+ * Updates a {@link Action} and forces the {@link Action} if it's not
+ * already forced.
+ *
+ * @param targetId
+ * the ID of the target
+ * @param actionId
+ * the ID of the action
+ * @return the updated or the found {@link Action}
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
+ Action forceTargetAction(@NotNull Long actionId);
+
+ /**
+ * Starting an action which is scheduled, e.g. in case of roll out a
+ * scheduled action must be started now.
+ *
+ * @param action
+ * the action to start now.
+ * @return the action which has been started
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ + SpringEvalExpressions.IS_SYSTEM_CODE)
+ Action startScheduledAction(@NotNull Action action);
+
+ /**
+ * All {@link ActionStatus} entries in the repository.
+ *
+ * @param pageable
+ * the pagination parameter
+ * @return {@link Page} of {@link ActionStatus} entries
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
+ Page+ * {@link DistributionSet} can be deleted/erased from the repository if they + * have never been assigned to any {@link UpdateAction} or {@link Target}. + *
+ * + *+ * If they have been assigned that need to be marked as deleted which as a + * result means that they cannot be assigned anymore to any targets. (define + * e.g. findByDeletedFalse()) + *
+ * + * @param set + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotNull DistributionSet set); + + /** + * Deleted {@link DistributionSet}s by their IDs. That is either a soft + * delete of the entities have been linked to an {@link UpdateAction} before + * or a hard delete if not. + * + * @param distributionSetIDs + * to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); + + /** + * deletes a distribution set meta data entry. + * + * @param id + * the ID of the distribution set meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); + + /** + * Deletes or mark as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSetType(@NotNull DistributionSetType type); + + /** + * retrieves the distribution set for a given action. + * + * @param action + * the action associated with the distribution set + * @return the distribution set which is associated with the action + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByAction(@NotNull Action action); + + /** + * Find {@link DistributionSet} based on given ID without details, e.g. + * {@link DistributionSet#getAgentHub()}. + * + * @param distid + * to look for. + * @return {@link DistributionSet} ornull if it does not exist
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ DistributionSet findDistributionSetById(@NotNull Long distid);
+
+ /**
+ * Find {@link DistributionSet} based on given ID including (lazy loaded)
+ * details, e.g. {@link DistributionSet#getAgentHub()}.
+ *
+ * Note: for performance reasons it is recommended to use
+ * {@link #findDistributionSetById(Long)} if details are not necessary.
+ *
+ * @param distid
+ * to look for.
+ * @return {@link DistributionSet} or null if it does not exist
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid);
+
+ /**
+ * Find distribution set by name and version.
+ *
+ * @param distributionName
+ * name of {@link DistributionSet}; case insensitive
+ * @param version
+ * version of {@link DistributionSet}
+ * @return the page with the found {@link DistributionSet}
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version);
+
+ /**
+ * finds all meta data by the given distribution set id.
+ *
+ * @param distributionSetId
+ * the distribution set id to retrieve the meta data from
+ * @param pageable
+ * the page request to page the result
+ * @return a paged result of all meta data entries for a given distribution
+ * set id
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ Pagenull if both are to be returned
+ * @param complete
+ * to true for returning only completed distribution
+ * sets or false for only incomplete ones nor
+ * null to return both.
+ * @param complete
+ * set to if false incomplete DS should also be
+ * shown.
+ *
+ *
+ * @return all found {@link DistributionSet}s
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ Pagenull if both are to be returned
+ * @return all found {@link DistributionSet}s
+ *
+ * @throws RSQLParameterUnsupportedFieldException
+ * if a field in the RSQL string is used but not provided by the
+ * given {@code fieldNameProvider}
+ * @throws RSQLParameterSyntaxException
+ * if the RSQL syntax is wrong
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ Page+ * 1) {@link DistributionSet}s which have the given {@link Target} as + * {@link TargetStatus#getInstalledDistributionSet()} + *
+ * 2) {@link DistributionSet}s which have the given {@link Target} as + * {@link Target#getAssignedDistributionSet()} + *
+ * 3) {@link DistributionSet}s which have no connection to the given
+ * {@link Target} ordered by ID of the DistributionSet.
+ *
+ * @param pageable
+ * the page request to page the result set *
+ * @param distributionSetFilterBuilder
+ * has details of filters to be applied
+ * @param assignedOrInstalled
+ * the controllerID of the Target to be ordered by
+ * @return
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ Pagenull if not
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ DistributionSetType findDistributionSetTypeById(@NotNull Long id);
+
+ /**
+ * @param key
+ * as {@link DistributionSetType#getKey()}
+ * @return {@link DistributionSetType} if found or null if not
+ */
+
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ DistributionSetType findDistributionSetTypeByKey(@NotNull String key);
+
+ /**
+ * @param name
+ * as {@link DistributionSetType#getName()}
+ * @return {@link DistributionSetType} if found or null if not
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ DistributionSetType findDistributionSetTypeByName(@NotEmpty String name);
+
+ /**
+ * @param pageable
+ * parameter
+ * @return all {@link DistributionSetType}s in the repository.
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ Pagetrue if in use
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
+ boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet);
+
+ /**
+ * {@link Entity} based method call for
+ * {@link #toggleTagAssignment(Collection, String)}.
+ *
+ * @param sets
+ * to toggle for
+ * @param tag
+ * to toggle
+ * @return {@link DistributionSetTagAssignmentResult} with all meta data of
+ * the assignment outcome.
+ */
+ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
+ DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection