diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java index c2192c4b3..9243655dd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTagRepository.java @@ -71,9 +71,9 @@ public interface DistributionSetTagRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java index 8b9a6e3b9..5c7f765f4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeRepository.java @@ -64,9 +64,9 @@ public interface DistributionSetTypeRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java index 160898f96..67293f212 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaArtifactManagement.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException; import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaArtifact; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.Artifact; @@ -30,8 +31,11 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -71,6 +75,8 @@ public class JpaArtifactManagement implements ArtifactManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Artifact createArtifact(final InputStream stream, final Long moduleId, final String filename, final String providedMd5Sum, final String providedSha1Sum, final boolean overrideExisting, final String contentType) { @@ -101,6 +107,8 @@ public class JpaArtifactManagement implements ArtifactManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public boolean clearArtifactBinary(final String sha1Hash, final Long moduleId) { if (localArtifactRepository.existsWithSha1HashAndSoftwareModuleIdIsNot(sha1Hash, moduleId)) { @@ -119,6 +127,8 @@ public class JpaArtifactManagement implements ArtifactManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteArtifact(final Long id) { final JpaArtifact existing = (JpaArtifact) findArtifact(id) .orElseThrow(() -> new EntityNotFoundException(Artifact.class, id)); @@ -186,6 +196,8 @@ public class JpaArtifactManagement implements ArtifactManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Artifact createArtifact(final InputStream inputStream, final Long moduleId, final String filename, final boolean overrideExisting) { return createArtifact(inputStream, moduleId, filename, null, null, overrideExisting, null); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index 9bb5ba76f..1326f6fb0 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -33,6 +33,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException; import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException; import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; @@ -56,9 +57,12 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.jpa.domain.Specification; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -126,6 +130,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target updateLastTargetQuery(final String controllerId, final URI address) { final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId) .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId)); @@ -195,6 +201,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target findOrRegisterTargetIfItDoesNotexist(final String controllerId, final URI address) { final Specification spec = (targetRoot, query, cb) -> cb .equal(targetRoot.get(JpaTarget_.controllerId), controllerId); @@ -240,6 +248,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional(isolation = Isolation.READ_COMMITTED) + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action addCancelActionStatus(final ActionStatusCreate c) { final JpaActionStatusCreate create = (JpaActionStatusCreate) c; @@ -283,6 +293,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional(isolation = Isolation.READ_COMMITTED) + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action addUpdateActionStatus(final ActionStatusCreate c) { final JpaActionStatusCreate create = (JpaActionStatusCreate) c; final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId()); @@ -381,6 +393,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target updateControllerAttributes(final String controllerId, final Map data) { final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId) .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId)); @@ -401,6 +415,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action registerRetrieved(final Long actionId, final String message) { return handleRegisterRetrieved(actionId, message); } @@ -460,6 +476,8 @@ public class JpaControllerManagement implements ControllerManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public ActionStatus addInformationalActionStatus(final ActionStatusCreate c) { final JpaActionStatusCreate create = (JpaActionStatusCreate) c; final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index c8cae34dd..5ca02376c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -67,6 +67,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -74,6 +75,8 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Isolation; @@ -136,6 +139,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) // Exception squid:S2095: see // https://jira.sonarsource.com/browse/SONARJAVA-1478 @SuppressWarnings({ "squid:S2095" }) @@ -147,6 +152,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override @Transactional(isolation = Isolation.READ_COMMITTED) + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, final Collection targets) { return assignDistributionSet(dsID, targets, null); @@ -154,6 +161,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override @Transactional(isolation = Isolation.READ_COMMITTED) + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, final Collection targets, final String actionMessage) { final JpaDistributionSet set = distributionSetRepository.findOne(dsID); @@ -348,6 +357,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override @Transactional(isolation = Isolation.READ_COMMITTED) + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action cancelAction(final Long actionId) { LOG.debug("cancelAction({})", actionId); @@ -390,6 +401,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override @Transactional(isolation = Isolation.READ_COMMITTED) + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action forceQuitAction(final Long actionId) { final JpaAction action = actionRepository.findById(actionId) .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); @@ -595,6 +608,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action forceTargetAction(final Long actionId) { final JpaAction action = actionRepository.findById(actionId) .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 4650e4fda..8bf2e3798 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -36,6 +35,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetCreate; import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetTypeCreate; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata; @@ -64,10 +64,13 @@ import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.validation.annotation.Validated; @@ -140,6 +143,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection dsIds, final String tagName) { final List sets = findDistributionSetListWithDetails(dsIds); @@ -187,6 +192,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet updateDistributionSet(final DistributionSetUpdate u) { final GenericDistributionSetUpdate update = (GenericDistributionSetUpdate) u; @@ -237,6 +244,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteDistributionSet(final Collection distributionSetIDs) { final List setsFound = findDistributionSetsById(distributionSetIDs); @@ -274,6 +283,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet createDistributionSet(final DistributionSetCreate c) { final JpaDistributionSetCreate create = (JpaDistributionSetCreate) c; if (create.getType() == null) { @@ -285,12 +296,16 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createDistributionSets(final Collection creates) { return creates.stream().map(this::createDistributionSet).collect(Collectors.toList()); } @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet assignSoftwareModules(final Long setId, final Collection moduleIds) { final Collection modules = softwareModuleRepository.findByIdIn(moduleIds); @@ -310,6 +325,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet unassignSoftwareModule(final Long setId, final Long moduleId) { final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId); final JpaSoftwareModule module = findSoftwareModuleAndThrowExceptionIfNotFound(moduleId); @@ -323,6 +340,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetType updateDistributionSetType(final DistributionSetTypeUpdate u) { final GenericDistributionSetTypeUpdate update = (GenericDistributionSetTypeUpdate) u; @@ -349,6 +368,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetType assignMandatorySoftwareModuleTypes(final Long dsTypeId, final Collection softwareModulesTypeIds) { final Collection modules = softwareModuleTypeRepository @@ -369,6 +390,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetType assignOptionalSoftwareModuleTypes(final Long dsTypeId, final Collection softwareModulesTypeIds) { @@ -397,6 +420,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetType unassignSoftwareModuleType(final Long dsTypeId, final Long softwareModuleTypeId) { final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId); @@ -581,6 +606,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetType createDistributionSetType(final DistributionSetTypeCreate c) { final JpaDistributionSetTypeCreate create = (JpaDistributionSetTypeCreate) c; @@ -589,6 +616,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteDistributionSetType(final Long typeId) { final JpaDistributionSetType toDelete = distributionSetTypeRepository.findById(typeId) @@ -604,6 +633,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createDistributionSetMetadata(final Long dsId, final Collection md) { md.forEach(meta -> checkAndThrowAlreadyIfDistributionSetMetadataExists( @@ -619,6 +650,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetMetadata updateDistributionSetMetadata(final Long dsId, final MetaData md) { // check if exists otherwise throw entity not found exception @@ -634,6 +667,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteDistributionSetMetadata(final Long distributionSetId, final String key) { final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) findDistributionSetMetadata( distributionSetId, key).orElseThrow( @@ -818,6 +853,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List assignTag(final Collection dsIds, final Long dsTagId) { final List allDs = findDistributionSetListWithDetails(dsIds); @@ -831,41 +868,46 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { allDs.forEach(ds -> ds.addTag(distributionSetTag)); - return Collections + final List result = Collections .unmodifiableList(allDs.stream().map(distributionSetRepository::save).collect(Collectors.toList())); + + // No reason to save the tag + entityManager.detach(distributionSetTag); + return result; } @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet unAssignTag(final Long dsId, final Long dsTagId) { - final List allDs = findDistributionSetListWithDetails(Arrays.asList(dsId)); - - if (allDs.isEmpty()) { - throw new EntityNotFoundException(DistributionSet.class, dsId); - } + final JpaDistributionSet set = (JpaDistributionSet) findDistributionSetByIdWithDetails(dsId) + .orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, dsId)); final DistributionSetTag distributionSetTag = tagManagement.findDistributionSetTagById(dsTagId) .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId)); - final List unAssignTag = unAssignTag(allDs, distributionSetTag); - return unAssignTag.isEmpty() ? null : unAssignTag.get(0); - } - private List unAssignTag(final Collection distributionSets, - final DistributionSetTag tag) { - distributionSets.forEach(ds -> ds.removeTag(tag)); - return Collections.unmodifiableList( - distributionSets.stream().map(distributionSetRepository::save).collect(Collectors.toList())); + set.removeTag(distributionSetTag); + + final JpaDistributionSet result = distributionSetRepository.save(set); + + // No reason to save the tag + entityManager.detach(distributionSetTag); + return result; } @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createDistributionSetTypes(final Collection types) { - return types.stream().map(this::createDistributionSetType).collect(Collectors.toList()); } @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteDistributionSet(final Long setId) { throwExceptionIfDistributionSetDoesNotExist(setId); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index 613cb81b1..15402d8e6 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -40,6 +40,7 @@ import org.eclipse.hawkbit.repository.exception.ConstraintViolationException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; @@ -74,6 +75,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -82,6 +84,8 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.jpa.domain.Specification; import org.springframework.integration.support.locks.LockRegistry; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.transaction.PlatformTransactionManager; @@ -179,6 +183,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Rollout createRollout(final RolloutCreate rollout, final int amountGroup, final RolloutGroupConditions conditions) { RolloutHelper.verifyRolloutGroupParameter(amountGroup, quotaManagement); @@ -188,6 +194,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Rollout createRollout(final RolloutCreate rollout, final List groups, final RolloutGroupConditions conditions) { RolloutHelper.verifyRolloutGroupParameter(groups.size(), quotaManagement); @@ -422,6 +430,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Rollout startRollout(final Long rolloutId) { LOGGER.debug("startRollout called for rollout {}", rolloutId); @@ -552,6 +562,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void pauseRollout(final Long rolloutId) { final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId); if (!RolloutStatus.RUNNING.equals(rollout.getStatus())) { @@ -569,6 +581,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void resumeRollout(final Long rolloutId) { final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId); if (!(RolloutStatus.PAUSED.equals(rollout.getStatus()))) { @@ -795,6 +809,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteRollout(final long rolloutId) { final JpaRollout jpaRollout = rolloutRepository.findOne(rolloutId); @@ -903,6 +919,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Rollout updateRollout(final RolloutUpdate u) { final GenericRolloutUpdate update = (GenericRolloutUpdate) u; final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(update.getId()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index b3bcef388..b3d943066 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -42,6 +42,7 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleCreate; import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleTypeCreate; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; @@ -62,6 +63,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -69,6 +71,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; import org.springframework.data.jpa.domain.Specification; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -117,6 +121,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModule updateSoftwareModule(final SoftwareModuleUpdate u) { final GenericSoftwareModuleUpdate update = (GenericSoftwareModuleUpdate) u; @@ -131,6 +137,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleTypeUpdate u) { final GenericSoftwareModuleTypeUpdate update = (GenericSoftwareModuleTypeUpdate) u; @@ -145,6 +153,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModule createSoftwareModule(final SoftwareModuleCreate c) { final JpaSoftwareModuleCreate create = (JpaSoftwareModuleCreate) c; @@ -153,6 +163,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createSoftwareModule(final Collection swModules) { return swModules.stream().map(this::createSoftwareModule).collect(Collectors.toList()); } @@ -225,6 +237,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteSoftwareModules(final Collection ids) { final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); @@ -483,6 +497,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleTypeCreate c) { final JpaSoftwareModuleTypeCreate create = (JpaSoftwareModuleTypeCreate) c; @@ -491,6 +507,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteSoftwareModuleType(final Long typeId) { final JpaSoftwareModuleType toDelete = softwareModuleTypeRepository.findById(typeId) .orElseThrow(() -> new EntityNotFoundException(SoftwareModuleType.class, typeId)); @@ -515,6 +533,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModuleMetadata createSoftwareModuleMetadata(final Long moduleId, final MetaData md) { checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, md); @@ -531,6 +551,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createSoftwareModuleMetadata(final Long moduleId, final Collection md) { md.forEach(meta -> checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, meta)); @@ -545,6 +567,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModuleMetadata updateSoftwareModuleMetadata(final Long moduleId, final MetaData md) { // check if exists otherwise throw entity not found exception @@ -589,6 +613,8 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteSoftwareModuleMetadata(final Long moduleId, final String key) { final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findSoftwareModuleMetadata(moduleId, key) .orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, moduleId, key)); @@ -653,12 +679,16 @@ public class JpaSoftwareManagement implements SoftwareManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteSoftwareModule(final Long moduleId) { deleteSoftwareModules(Sets.newHashSet(moduleId)); } @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createSoftwareModuleType(final Collection creates) { return creates.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java index e5e7bc20d..932dd03dc 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSystemManagement.java @@ -17,9 +17,9 @@ import java.util.stream.Collectors; import javax.persistence.EntityManager; import org.eclipse.hawkbit.cache.TenancyCacheManager; -import org.eclipse.hawkbit.repository.Constants; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantStatsManagement; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; @@ -34,10 +34,13 @@ import org.eclipse.persistence.config.PersistenceUnitProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.annotation.Propagation; @@ -211,6 +214,8 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteTenant(final String t) { final String tenant = t.toUpperCase(); cacheManager.evictCaches(tenant); @@ -254,6 +259,8 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public TenantMetaData updateTenantMetadata(final Long defaultDsType) { final JpaTenantMetaData data = (JpaTenantMetaData) getTenantMetadata(); @@ -264,20 +271,26 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst private DistributionSetType createStandardSoftwareDataSetup() { final SoftwareModuleType app = softwareModuleTypeRepository - .save(new JpaSoftwareModuleType(Constants.SMT_DEFAULT_APP_KEY, Constants.SMT_DEFAULT_APP_NAME, - "Application Addons", Integer.MAX_VALUE)); + .save(new JpaSoftwareModuleType(org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_APP_KEY, + org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_APP_NAME, "Application Addons", + Integer.MAX_VALUE)); final SoftwareModuleType os = softwareModuleTypeRepository.save(new JpaSoftwareModuleType( - Constants.SMT_DEFAULT_OS_KEY, Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operationg system", 1)); + org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_KEY, + org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operationg system", 1)); // make sure the module types get their IDs entityManager.flush(); - distributionSetTypeRepository.save(new JpaDistributionSetType(Constants.DST_DEFAULT_OS_ONLY_KEY, - Constants.DST_DEFAULT_OS_ONLY_NAME, "Default type with Firmware/OS only.").addMandatoryModuleType(os)); + distributionSetTypeRepository + .save(new JpaDistributionSetType(org.eclipse.hawkbit.repository.Constants.DST_DEFAULT_OS_ONLY_KEY, + org.eclipse.hawkbit.repository.Constants.DST_DEFAULT_OS_ONLY_NAME, + "Default type with Firmware/OS only.").addMandatoryModuleType(os)); - return distributionSetTypeRepository.save(new JpaDistributionSetType(Constants.DST_DEFAULT_OS_WITH_APPS_KEY, - Constants.DST_DEFAULT_OS_WITH_APPS_NAME, "Default type with Firmware/OS and optional app(s).") - .addMandatoryModuleType(os).addOptionalModuleType(app)); + return distributionSetTypeRepository + .save(new JpaDistributionSetType(org.eclipse.hawkbit.repository.Constants.DST_DEFAULT_OS_WITH_APPS_KEY, + org.eclipse.hawkbit.repository.Constants.DST_DEFAULT_OS_WITH_APPS_NAME, + "Default type with Firmware/OS and optional app(s).").addMandatoryModuleType(os) + .addOptionalModuleType(app)); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java index c5b9fb802..b9165dd55 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTagManagement.java @@ -21,6 +21,7 @@ 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.jpa.builder.JpaTagCreate; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; @@ -31,10 +32,13 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -68,6 +72,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public TargetTag createTargetTag(final TagCreate c) { final JpaTagCreate create = (JpaTagCreate) c; @@ -76,6 +82,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createTargetTags(final Collection tt) { @SuppressWarnings({ "unchecked", "rawtypes" }) final Collection targetTags = (Collection) tt; @@ -86,6 +94,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteTargetTag(final String targetTagName) { if (!targetTagRepository.existsByName(targetTagName)) { throw new EntityNotFoundException(TargetTag.class, targetTagName); @@ -118,6 +128,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public TargetTag updateTargetTag(final TagUpdate u) { final GenericTagUpdate update = (GenericTagUpdate) u; @@ -132,8 +144,9 @@ public class JpaTagManagement implements TagManagement { } @Override - @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetTag updateDistributionSetTag(final TagUpdate u) { final GenericTagUpdate update = (GenericTagUpdate) u; @@ -154,6 +167,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetTag createDistributionSetTag(final TagCreate c) { final JpaTagCreate create = (JpaTagCreate) c; return distributionSetTagRepository.save(create.buildDistributionSetTag()); @@ -161,6 +176,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createDistributionSetTags(final Collection dst) { @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -173,6 +190,8 @@ public class JpaTagManagement implements TagManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteDistributionSetTag(final String tagName) { if (!distributionSetTagRepository.existsByName(tagName)) { throw new EntityNotFoundException(DistributionSetTag.class, tagName); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java index 93f9a0220..f82e0444c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetFilterQueryManagement.java @@ -22,6 +22,7 @@ import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate; import org.eclipse.hawkbit.repository.builder.TargetFilterQueryUpdate; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryCreate; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; @@ -31,11 +32,14 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specifications; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -65,8 +69,10 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme this.distributionSetManagement = distributionSetManagement; } - @Transactional @Override + @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public TargetFilterQuery createTargetFilterQuery(final TargetFilterQueryCreate c) { final JpaTargetFilterQueryCreate create = (JpaTargetFilterQueryCreate) c; @@ -75,6 +81,8 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteTargetFilterQuery(final Long targetFilterQueryId) { findTargetFilterQueryById(targetFilterQueryId) .orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId)); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 6c2fbd0b4..6d1ff0a1e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -36,6 +36,7 @@ import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetCreate; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetUpdate; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; @@ -55,12 +56,15 @@ import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.SliceImpl; import org.springframework.data.jpa.domain.Specification; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -149,6 +153,8 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target updateTarget(final TargetUpdate u) { final JpaTargetUpdate update = (JpaTargetUpdate) u; @@ -165,6 +171,8 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteTargets(final Collection targetIDs) { final List targets = targetRepository.findAll(targetIDs); @@ -183,6 +191,8 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteTarget(final String controllerID) { final Target target = targetRepository.findByControllerId(controllerID) .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerID)); @@ -322,6 +332,8 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public TargetTagAssignmentResult toggleTagAssignment(final Collection controllerIds, final String tagName) { final TargetTag tag = targetTagRepository.findByNameEquals(tagName) .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagName)); @@ -359,7 +371,10 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List assignTag(final Collection controllerIds, final Long tagId) { + final List allTargets = targetRepository .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds)); @@ -372,12 +387,19 @@ public class JpaTargetManagement implements TargetManagement { .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagId)); allTargets.forEach(target -> target.addTag(tag)); - return Collections + + final List result = Collections .unmodifiableList(allTargets.stream().map(targetRepository::save).collect(Collectors.toList())); + + // No reason to save the tag + entityManager.detach(tag); + return result; } @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target unAssignTag(final String controllerID, final Long targetTagId) { final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerID) .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerID)); @@ -387,7 +409,11 @@ public class JpaTargetManagement implements TargetManagement { target.removeTag(tag); - return targetRepository.save(target); + final Target result = targetRepository.save(target); + + // No reason to save the tag + entityManager.detach(tag); + return result; } @Override @@ -524,6 +550,8 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target createTarget(final TargetCreate c) { final JpaTargetCreate create = (JpaTargetCreate) c; return targetRepository.save(create.build()); @@ -531,6 +559,8 @@ public class JpaTargetManagement implements TargetManagement { @Override @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List createTargets(final Collection targets) { return targets.stream().map(this::createTarget).collect(Collectors.toList()); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java index 4c5e93702..80a7f6f99 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTenantConfigurationManagement.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.io.Serializable; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; @@ -23,6 +24,9 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.context.ApplicationContext; import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.dao.ConcurrencyFailureException; +import org.springframework.retry.annotation.Backoff; +import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -122,6 +126,8 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana @Override @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public TenantConfigurationValue addOrUpdateConfiguration( final String configurationKeyName, final T value) { @@ -160,6 +166,8 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana @Override @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void deleteConfiguration(final String configurationKeyName) { tenantConfigurationRepository.deleteByKey(configurationKeyName); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java index 96db9a4e9..828fc1822 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java @@ -19,12 +19,12 @@ import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.PropertiesQuotaManagement; import org.eclipse.hawkbit.repository.ReportManagement; import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; -import org.eclipse.hawkbit.repository.PropertiesQuotaManagement; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; @@ -69,6 +69,7 @@ import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; +import org.eclipse.persistence.config.PersistenceUnitProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -89,6 +90,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.integration.support.locks.LockRegistry; import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; +import org.springframework.retry.annotation.EnableRetry; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -110,6 +112,7 @@ import com.google.common.collect.Maps; @EnableConfigurationProperties({ RepositoryProperties.class, ControllerPollProperties.class, TenantConfigurationProperties.class }) @EnableScheduling +@EnableRetry @EntityScan("org.eclipse.hawkbit.repository.jpa.model") public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { @@ -283,17 +286,22 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { @Override protected Map getVendorProperties() { - final Map properties = Maps.newHashMapWithExpectedSize(5); + final Map properties = Maps.newHashMapWithExpectedSize(7); // Turn off dynamic weaving to disable LTW lookup in static weaving mode - properties.put("eclipselink.weaving", "false"); + properties.put(PersistenceUnitProperties.WEAVING, "false"); // needed for reports - properties.put("eclipselink.jdbc.allow-native-sql-queries", "true"); + properties.put(PersistenceUnitProperties.ALLOW_NATIVE_SQL_QUERIES, "true"); // flyway - properties.put("eclipselink.ddl-generation", "none"); + properties.put(PersistenceUnitProperties.DDL_GENERATION, "none"); // Embeed into hawkBit logging - properties.put("eclipselink.logging.logger", "JavaLogger"); + properties.put(PersistenceUnitProperties.LOGGING_LOGGER, "JavaLogger"); // Ensure that we flush only at the end of the transaction - properties.put("eclipselink.persistence-context.flush-mode", "COMMIT"); + properties.put(PersistenceUnitProperties.PERSISTENCE_CONTEXT_FLUSH_MODE, "COMMIT"); + + // Enable batch writing + properties.put(PersistenceUnitProperties.BATCH_WRITING, "JDBC"); + // Batch size + properties.put(PersistenceUnitProperties.BATCH_WRITING_SIZE, "500"); return properties; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java index fcb028dc3..1356225d4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RolloutRepository.java @@ -53,9 +53,9 @@ public interface RolloutRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java index 77ecf049e..4f4e57768 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleRepository.java @@ -113,9 +113,9 @@ public interface SoftwareModuleRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java index 046d948c0..abd0b4939 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeRepository.java @@ -82,9 +82,9 @@ public interface SoftwareModuleTypeRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java index ddce2750c..9b8d07fee 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetFilterQueryRepository.java @@ -57,9 +57,9 @@ public interface TargetFilterQueryRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java index 9e2cac6d0..905de08e5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetRepository.java @@ -217,9 +217,9 @@ public interface TargetRepository extends BaseEntityRepository, /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java index 4bb28f0de..b242865af 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TargetTagRepository.java @@ -70,9 +70,9 @@ public interface TargetTagRepository /** * Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety - * reasons (this is a "delete everything" query after all) we add the tenant manually to - * query even if this will by done by {@link EntityManager} anyhow. The DB - * should take care of optimizing this away. + * reasons (this is a "delete everything" query after all) we add the tenant + * manually to query even if this will by done by {@link EntityManager} + * anyhow. The DB should take care of optimizing this away. * * @param tenant * to delete data from diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java index c96c36b4e..b01ed21b3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/TenantConfigurationRepository.java @@ -46,9 +46,9 @@ public interface TenantConfigurationRepository extends BaseEntityRepository