Fix default isolation and auto commit (#484)

* Switch to spring/DB default isolation.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fix dependency to uncommited isolation level in rollout management.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Corrected UQ checks

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Remove modifying annotation.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Disable autocommit on connection pool. Cleanups. Flush at commit.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Cleanups.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fix Rollout UI performance.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Typo fixed


Signed-off-by: Dominic Schabel <dominic.schabel@bosch-si.com>

* Remove empty lines

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-04-18 08:43:38 +02:00
committed by GitHub
parent 5958d1479c
commit f99da28185
56 changed files with 300 additions and 603 deletions

View File

@@ -32,6 +32,7 @@ endpoints.spring.cloud.bus.env.enabled=false
spring.jpa.database=H2 spring.jpa.database=H2
spring.jpa.show-sql=false spring.jpa.show-sql=false
spring.datasource.driverClassName=org.h2.Driver spring.datasource.driverClassName=org.h2.Driver
spring.datasource.tomcat.defaultAutoCommit=false
# Logging # Logging
spring.datasource.eclipselink.logging.logger=JavaLogger spring.datasource.eclipselink.logging.logger=JavaLogger
spring.jpa.properties.eclipselink.logging.level=off spring.jpa.properties.eclipselink.logging.level=off

View File

@@ -26,6 +26,7 @@ hawkbit.server.security.dos.maxAttributeEntriesPerTarget=10
spring.jpa.database=H2 spring.jpa.database=H2
spring.datasource.url=jdbc:h2:mem:sp-db;DB_CLOSE_ON_EXIT=FALSE spring.datasource.url=jdbc:h2:mem:sp-db;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver spring.datasource.driverClassName=org.h2.Driver
spring.datasource.tomcat.defaultAutoCommit=false
spring.datasource.username=sa spring.datasource.username=sa
spring.datasource.password=sa spring.datasource.password=sa

View File

@@ -286,19 +286,6 @@ public interface RolloutManagement {
*/ */
boolean exists(@NotNull Long rolloutId); boolean exists(@NotNull Long rolloutId);
/***
* Get finished percentage details for a specified group which is in running
* state.
*
* @param rolloutId
* the ID of the {@link Rollout}
* @param rolloutGroupId
* the ID of the {@link RolloutGroup}
* @return percentage finished
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
float getFinishedPercentForRunningGroup(@NotNull Long rolloutId, @NotNull Long rolloutGroupId);
/** /**
* Pauses a rollout which is currently running. The Rollout switches * Pauses a rollout which is currently running. The Rollout switches
* {@link RolloutStatus#PAUSED}. {@link RolloutGroup}s which are currently * {@link RolloutStatus#PAUSED}. {@link RolloutGroup}s which are currently

View File

@@ -104,6 +104,13 @@ public class TotalTargetCountStatus {
return count == null ? 0L : count; return count == null ? 0L : count;
} }
/**
* @return finished percentage of targets
*/
public float getFinishedPercent() {
return ((float) getTotalTargetCountByStatus(TotalTargetCountStatus.Status.FINISHED) / totalTargetCount) * 100;
}
/** /**
* Populate all target status to a the given map * Populate all target status to a the given map
* *

View File

@@ -28,7 +28,6 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
@@ -78,12 +77,11 @@ public abstract class AbstractRolloutManagement implements RolloutManagement {
this.lockRegistry = lockRegistry; this.lockRegistry = lockRegistry;
} }
protected int runInNewTransaction(final String transactionName, final TransactionCallback<Integer> action) { protected Long runInNewTransaction(final String transactionName, final TransactionCallback<Long> action) {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition(); final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName(transactionName); def.setName(transactionName);
def.setReadOnly(false); def.setReadOnly(false);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
def.setIsolationLevel(Isolation.READ_UNCOMMITTED.value());
return new TransactionTemplate(txManager, def).execute(action); return new TransactionTemplate(txManager, def).execute(action);
} }

View File

@@ -35,14 +35,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link Action} repository. * {@link Action} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>, JpaSpecificationExecutor<JpaAction> { public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>, JpaSpecificationExecutor<JpaAction> {
/** /**
* Retrieves an Action with all lazy attributes. * Retrieves an Action with all lazy attributes.
@@ -190,7 +189,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* the current status of the actions which are affected * the current status of the actions which are affected
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false") @Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false")
void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List<Long> targetIds, void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List<Long> targetIds,
@Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus); @Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus);
@@ -381,7 +380,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* id of {@link Rollout} * id of {@link Rollout}
* @return list of objects with status and target count * @return list of objects with status and target count
*/ */
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rollout.id IN ?1 GROUP BY a.rollout.id,a.status") @Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.id)) FROM JpaAction a WHERE a.rollout.id IN ?1 GROUP BY a.rollout.id,a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutId(List<Long> rolloutId); List<TotalTargetCountActionStatus> getStatusCountByRolloutId(List<Long> rolloutId);
/** /**
@@ -424,7 +423,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* the IDs of the actions to be deleted. * the IDs of the actions to be deleted.
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM JpaAction a WHERE a.id IN ?1") @Query("DELETE FROM JpaAction a WHERE a.id IN ?1")
void deleteByIdIn(final Collection<Long> actionIDs); void deleteByIdIn(final Collection<Long> actionIDs);

View File

@@ -17,14 +17,13 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType; import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link ActionStatus} repository. * {@link ActionStatus} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface ActionStatusRepository public interface ActionStatusRepository
extends BaseEntityRepository<JpaActionStatus, Long>, JpaSpecificationExecutor<JpaActionStatus> { extends BaseEntityRepository<JpaActionStatus, Long>, JpaSpecificationExecutor<JpaActionStatus> {

View File

@@ -17,7 +17,6 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
@@ -29,7 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
* of the entity type * of the entity type
*/ */
@NoRepositoryBean @NoRepositoryBean
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface BaseEntityRepository<T extends AbstractJpaTenantAwareBaseEntity, I extends Serializable> public interface BaseEntityRepository<T extends AbstractJpaTenantAwareBaseEntity, I extends Serializable>
extends PagingAndSortingRepository<T, I> { extends PagingAndSortingRepository<T, I> {
@@ -40,7 +39,7 @@ public interface BaseEntityRepository<T extends AbstractJpaTenantAwareBaseEntity
* to delete data from * to delete data from
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
void deleteByTenantIgnoreCase(String tenant); void deleteByTenantIgnoreCase(String tenant);
/** /**

View File

@@ -13,13 +13,12 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link DistributionSetMetadata} repository. * {@link DistributionSetMetadata} repository.
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface DistributionSetMetadataRepository public interface DistributionSetMetadataRepository
extends PagingAndSortingRepository<JpaDistributionSetMetadata, DsMetadataCompositeKey>, extends PagingAndSortingRepository<JpaDistributionSetMetadata, DsMetadataCompositeKey>,
JpaSpecificationExecutor<JpaDistributionSetMetadata> { JpaSpecificationExecutor<JpaDistributionSetMetadata> {

View File

@@ -23,14 +23,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link DistributionSet} repository. * {@link DistributionSet} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface DistributionSetRepository public interface DistributionSetRepository
extends BaseEntityRepository<JpaDistributionSet, Long>, JpaSpecificationExecutor<JpaDistributionSet> { extends BaseEntityRepository<JpaDistributionSet, Long>, JpaSpecificationExecutor<JpaDistributionSet> {
@@ -51,7 +50,7 @@ public interface DistributionSetRepository
* to be deleted * to be deleted
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Query("update JpaDistributionSet d set d.deleted = 1 where d.id in :ids") @Query("update JpaDistributionSet d set d.deleted = 1 where d.id in :ids")
void deleteDistributionSet(@Param("ids") Long... ids); void deleteDistributionSet(@Param("ids") Long... ids);
@@ -63,7 +62,7 @@ public interface DistributionSetRepository
* @return number of affected/deleted records * @return number of affected/deleted records
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM JpaDistributionSet d WHERE d.id IN ?1") @Query("DELETE FROM JpaDistributionSet d WHERE d.id IN ?1")
int deleteByIdIn(Collection<Long> ids); int deleteByIdIn(Collection<Long> ids);

View File

@@ -17,14 +17,13 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link TargetTag} repository. * {@link TargetTag} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface DistributionSetTagRepository public interface DistributionSetTagRepository
extends BaseEntityRepository<JpaDistributionSetTag, Long>, JpaSpecificationExecutor<JpaDistributionSetTag> { extends BaseEntityRepository<JpaDistributionSetTag, Long>, JpaSpecificationExecutor<JpaDistributionSetTag> {
/** /**
@@ -35,7 +34,7 @@ public interface DistributionSetTagRepository
* @return 1 if tag was deleted * @return 1 if tag was deleted
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
Long deleteByName(final String tagName); Long deleteByName(final String tagName);
/** /**

View File

@@ -15,14 +15,13 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link PagingAndSortingRepository} for {@link DistributionSetType}. * {@link PagingAndSortingRepository} for {@link DistributionSetType}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface DistributionSetTypeRepository public interface DistributionSetTypeRepository
extends BaseEntityRepository<JpaDistributionSetType, Long>, JpaSpecificationExecutor<JpaDistributionSetType> { extends BaseEntityRepository<JpaDistributionSetType, Long>, JpaSpecificationExecutor<JpaDistributionSetType> {

View File

@@ -32,8 +32,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -41,7 +39,7 @@ import org.springframework.validation.annotation.Validated;
* JPA based {@link ArtifactManagement} implementation. * JPA based {@link ArtifactManagement} implementation.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaArtifactManagement implements ArtifactManagement { public class JpaArtifactManagement implements ArtifactManagement {
@@ -72,8 +70,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Artifact createArtifact(final InputStream stream, final Long moduleId, final String filename, public Artifact createArtifact(final InputStream stream, final Long moduleId, final String filename,
final String providedMd5Sum, final String providedSha1Sum, final boolean overrideExisting, final String providedMd5Sum, final String providedSha1Sum, final boolean overrideExisting,
final String contentType) { final String contentType) {
@@ -103,8 +100,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public boolean clearArtifactBinary(final String sha1Hash, final Long moduleId) { public boolean clearArtifactBinary(final String sha1Hash, final Long moduleId) {
if (localArtifactRepository.existsWithSha1HashAndSoftwareModuleIdIsNot(sha1Hash, moduleId)) { if (localArtifactRepository.existsWithSha1HashAndSoftwareModuleIdIsNot(sha1Hash, moduleId)) {
@@ -122,8 +118,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteArtifact(final Long id) { public void deleteArtifact(final Long id) {
final JpaArtifact existing = (JpaArtifact) findArtifact(id) final JpaArtifact existing = (JpaArtifact) findArtifact(id)
.orElseThrow(() -> new EntityNotFoundException(Artifact.class, id)); .orElseThrow(() -> new EntityNotFoundException(Artifact.class, id));
@@ -190,8 +185,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Artifact createArtifact(final InputStream inputStream, final Long moduleId, final String filename, public Artifact createArtifact(final InputStream inputStream, final Long moduleId, final String filename,
final boolean overrideExisting) { final boolean overrideExisting) {
return createArtifact(inputStream, moduleId, filename, null, null, overrideExisting, null); return createArtifact(inputStream, moduleId, filename, null, null, overrideExisting, null);

View File

@@ -59,7 +59,6 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -68,7 +67,7 @@ import org.springframework.validation.annotation.Validated;
* JPA based {@link ControllerManagement} implementation. * JPA based {@link ControllerManagement} implementation.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaControllerManagement implements ControllerManagement { public class JpaControllerManagement implements ControllerManagement {
private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class); private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class);
@@ -126,8 +125,7 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateLastTargetQuery(final String controllerId, final URI address) { public Target updateLastTargetQuery(final String controllerId, final URI address) {
final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId) final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId)
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId)); .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
@@ -196,8 +194,7 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target findOrRegisterTargetIfItDoesNotexist(final String controllerId, final URI address) { public Target findOrRegisterTargetIfItDoesNotexist(final String controllerId, final URI address) {
final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb
.equal(targetRoot.get(JpaTarget_.controllerId), controllerId); .equal(targetRoot.get(JpaTarget_.controllerId), controllerId);
@@ -242,7 +239,6 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(isolation = Isolation.READ_COMMITTED)
public Action addCancelActionStatus(final ActionStatusCreate c) { public Action addCancelActionStatus(final ActionStatusCreate c) {
final JpaActionStatusCreate create = (JpaActionStatusCreate) c; final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
@@ -286,7 +282,6 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(isolation = Isolation.READ_COMMITTED)
public Action addUpdateActionStatus(final ActionStatusCreate c) { public Action addUpdateActionStatus(final ActionStatusCreate c) {
final JpaActionStatusCreate create = (JpaActionStatusCreate) c; final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
@@ -386,8 +381,7 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateControllerAttributes(final String controllerId, final Map<String, String> data) { public Target updateControllerAttributes(final String controllerId, final Map<String, String> data) {
final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId) final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId)
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId)); .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
@@ -407,8 +401,7 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action registerRetrieved(final Long actionId, final String message) { public Action registerRetrieved(final Long actionId, final String message) {
return handleRegisterRetrieved(actionId, message); return handleRegisterRetrieved(actionId, message);
} }
@@ -467,8 +460,7 @@ public class JpaControllerManagement implements ControllerManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public ActionStatus addInformationalActionStatus(final ActionStatusCreate c) { public ActionStatus addInformationalActionStatus(final ActionStatusCreate c) {
final JpaActionStatusCreate create = (JpaActionStatusCreate) c; final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId()); final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId());

View File

@@ -79,7 +79,6 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
@@ -94,7 +93,7 @@ import com.google.common.collect.Lists;
* JPA implementation for {@link DeploymentManagement}. * JPA implementation for {@link DeploymentManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaDeploymentManagement implements DeploymentManagement { public class JpaDeploymentManagement implements DeploymentManagement {
private static final Logger LOG = LoggerFactory.getLogger(JpaDeploymentManagement.class); private static final Logger LOG = LoggerFactory.getLogger(JpaDeploymentManagement.class);
@@ -141,8 +140,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
private PlatformTransactionManager txManager; private PlatformTransactionManager txManager;
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
// Exception squid:S2095: see // Exception squid:S2095: see
// https://jira.sonarsource.com/browse/SONARJAVA-1478 // https://jira.sonarsource.com/browse/SONARJAVA-1478
@SuppressWarnings({ "squid:S2095" }) @SuppressWarnings({ "squid:S2095" })
@@ -153,7 +151,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(isolation = Isolation.READ_COMMITTED)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets) { final Collection<TargetWithActionType> targets) {
@@ -161,7 +158,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(isolation = Isolation.READ_COMMITTED)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets, final String actionMessage) { final Collection<TargetWithActionType> targets, final String actionMessage) {
@@ -356,7 +352,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(isolation = Isolation.READ_COMMITTED)
public Action cancelAction(final Long actionId) { public Action cancelAction(final Long actionId) {
LOG.debug("cancelAction({})", actionId); LOG.debug("cancelAction({})", actionId);
@@ -399,7 +394,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(isolation = Isolation.READ_COMMITTED)
public Action forceQuitAction(final Long actionId) { public Action forceQuitAction(final Long actionId) {
final JpaAction action = actionRepository.findById(actionId) final JpaAction action = actionRepository.findById(actionId)
@@ -444,7 +438,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition(); final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("startScheduledActions-" + rolloutId); def.setName("startScheduledActions-" + rolloutId);
def.setReadOnly(false); def.setReadOnly(false);
def.setIsolationLevel(Isolation.READ_UNCOMMITTED.value());
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
return new TransactionTemplate(txManager, def).execute(status -> { return new TransactionTemplate(txManager, def).execute(status -> {
final Page<Action> rolloutGroupActions = findActionsByRolloutAndRolloutGroupParent(rolloutId, final Page<Action> rolloutGroupActions = findActionsByRolloutAndRolloutGroupParent(rolloutId,
@@ -631,8 +624,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action forceTargetAction(final Long actionId) { public Action forceTargetAction(final Long actionId) {
final JpaAction action = actionRepository.findById(actionId) final JpaAction action = actionRepository.findById(actionId)
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));

View File

@@ -68,8 +68,6 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -81,7 +79,7 @@ import com.google.common.collect.Lists;
* JPA implementation of {@link DistributionSetManagement}. * JPA implementation of {@link DistributionSetManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaDistributionSetManagement implements DistributionSetManagement { public class JpaDistributionSetManagement implements DistributionSetManagement {
@@ -138,8 +136,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<Long> dsIds, final String tagName) { public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<Long> dsIds, final String tagName) {
final List<JpaDistributionSet> sets = findDistributionSetListWithDetails(dsIds); final List<JpaDistributionSet> sets = findDistributionSetListWithDetails(dsIds);
@@ -186,8 +183,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet updateDistributionSet(final DistributionSetUpdate u) { public DistributionSet updateDistributionSet(final DistributionSetUpdate u) {
final GenericDistributionSetUpdate update = (GenericDistributionSetUpdate) u; final GenericDistributionSetUpdate update = (GenericDistributionSetUpdate) u;
@@ -237,8 +233,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSet(final Collection<Long> distributionSetIDs) { public void deleteDistributionSet(final Collection<Long> distributionSetIDs) {
final List<DistributionSet> setsFound = findDistributionSetAllById(distributionSetIDs); final List<DistributionSet> setsFound = findDistributionSetAllById(distributionSetIDs);
@@ -275,33 +270,24 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet createDistributionSet(final DistributionSetCreate c) { public DistributionSet createDistributionSet(final DistributionSetCreate c) {
final JpaDistributionSetCreate create = (JpaDistributionSetCreate) c; final JpaDistributionSetCreate create = (JpaDistributionSetCreate) c;
if (create.getType() == null) { if (create.getType() == null) {
create.type(systemManagement.getTenantMetadata().getDefaultDsType().getKey()); create.type(systemManagement.getTenantMetadata().getDefaultDsType().getKey());
} }
final JpaDistributionSet dSet = create.build(); return distributionSetRepository.save(create.build());
if (distributionSetRepository.countByNameAndVersion(dSet.getName(), dSet.getVersion()) > 0) {
throw new EntityAlreadyExistsException("DistributionSet with that name and version already exists.");
}
return distributionSetRepository.save(dSet);
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> createDistributionSets(final Collection<DistributionSetCreate> creates) { public List<DistributionSet> createDistributionSets(final Collection<DistributionSetCreate> creates) {
return creates.stream().map(this::createDistributionSet).collect(Collectors.toList()); return creates.stream().map(this::createDistributionSet).collect(Collectors.toList());
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet assignSoftwareModules(final Long setId, final Collection<Long> moduleIds) { public DistributionSet assignSoftwareModules(final Long setId, final Collection<Long> moduleIds) {
final Collection<JpaSoftwareModule> modules = softwareModuleRepository.findByIdIn(moduleIds); final Collection<JpaSoftwareModule> modules = softwareModuleRepository.findByIdIn(moduleIds);
@@ -320,8 +306,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet unassignSoftwareModule(final Long setId, final Long moduleId) { public DistributionSet unassignSoftwareModule(final Long setId, final Long moduleId) {
final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId); final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId);
final JpaSoftwareModule module = findSoftwareModuleAndThrowExceptionIfNotFound(moduleId); final JpaSoftwareModule module = findSoftwareModuleAndThrowExceptionIfNotFound(moduleId);
@@ -334,8 +319,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType updateDistributionSetType(final DistributionSetTypeUpdate u) { public DistributionSetType updateDistributionSetType(final DistributionSetTypeUpdate u) {
final GenericDistributionSetTypeUpdate update = (GenericDistributionSetTypeUpdate) u; final GenericDistributionSetTypeUpdate update = (GenericDistributionSetTypeUpdate) u;
@@ -361,8 +345,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType assignMandatorySoftwareModuleTypes(final Long dsTypeId, public DistributionSetType assignMandatorySoftwareModuleTypes(final Long dsTypeId,
final Collection<Long> softwareModulesTypeIds) { final Collection<Long> softwareModulesTypeIds) {
final Collection<JpaSoftwareModuleType> modules = softwareModuleTypeRepository final Collection<JpaSoftwareModuleType> modules = softwareModuleTypeRepository
@@ -382,8 +365,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType assignOptionalSoftwareModuleTypes(final Long dsTypeId, public DistributionSetType assignOptionalSoftwareModuleTypes(final Long dsTypeId,
final Collection<Long> softwareModulesTypeIds) { final Collection<Long> softwareModulesTypeIds) {
@@ -411,8 +393,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType unassignSoftwareModuleType(final Long dsTypeId, final Long softwareModuleTypeId) { public DistributionSetType unassignSoftwareModuleType(final Long dsTypeId, final Long softwareModuleTypeId) {
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId); final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId);
@@ -591,8 +572,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType createDistributionSetType(final DistributionSetTypeCreate c) { public DistributionSetType createDistributionSetType(final DistributionSetTypeCreate c) {
final JpaDistributionSetTypeCreate create = (JpaDistributionSetTypeCreate) c; final JpaDistributionSetTypeCreate create = (JpaDistributionSetTypeCreate) c;
@@ -600,8 +580,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSetType(final Long typeId) { public void deleteDistributionSetType(final Long typeId) {
final JpaDistributionSetType toDelete = distributionSetTypeRepository.findById(typeId) final JpaDistributionSetType toDelete = distributionSetTypeRepository.findById(typeId)
@@ -616,8 +595,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public List<DistributionSetMetadata> createDistributionSetMetadata(final Long dsId, final Collection<MetaData> md) { public List<DistributionSetMetadata> createDistributionSetMetadata(final Long dsId, final Collection<MetaData> md) {
md.forEach(meta -> checkAndThrowAlreadyIfDistributionSetMetadataExists( md.forEach(meta -> checkAndThrowAlreadyIfDistributionSetMetadataExists(
@@ -632,8 +610,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public DistributionSetMetadata updateDistributionSetMetadata(final Long dsId, final MetaData md) { public DistributionSetMetadata updateDistributionSetMetadata(final Long dsId, final MetaData md) {
// check if exists otherwise throw entity not found exception // check if exists otherwise throw entity not found exception
@@ -648,8 +625,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void deleteDistributionSetMetadata(final Long distributionSetId, final String key) { public void deleteDistributionSetMetadata(final Long distributionSetId, final String key) {
final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) findDistributionSetMetadata( final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) findDistributionSetMetadata(
distributionSetId, key).orElseThrow( distributionSetId, key).orElseThrow(
@@ -833,8 +809,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> assignTag(final Collection<Long> dsIds, final Long dsTagId) { public List<DistributionSet> assignTag(final Collection<Long> dsIds, final Long dsTagId) {
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds); final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
@@ -853,8 +828,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> unAssignAllDistributionSetsByTag(final Long dsTagId) { public List<DistributionSet> unAssignAllDistributionSetsByTag(final Long dsTagId) {
final DistributionSetTag distributionSetTag = tagManagement.findDistributionSetTagById(dsTagId) final DistributionSetTag distributionSetTag = tagManagement.findDistributionSetTagById(dsTagId)
@@ -868,8 +842,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet unAssignTag(final Long dsId, final Long dsTagId) { public DistributionSet unAssignTag(final Long dsId, final Long dsTagId) {
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(Arrays.asList(dsId)); final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(Arrays.asList(dsId));
@@ -891,16 +864,14 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSetType> createDistributionSetTypes(final Collection<DistributionSetTypeCreate> types) { public List<DistributionSetType> createDistributionSetTypes(final Collection<DistributionSetTypeCreate> types) {
return types.stream().map(this::createDistributionSetType).collect(Collectors.toList()); return types.stream().map(this::createDistributionSetType).collect(Collectors.toList());
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSet(final Long setId) { public void deleteDistributionSet(final Long setId) {
throwExceptionIfDistributionSetDoesNotExist(setId); throwExceptionIfDistributionSetDoesNotExist(setId);

View File

@@ -41,7 +41,6 @@ import org.eclipse.hawkbit.repository.report.model.SeriesTime;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -49,7 +48,7 @@ import org.springframework.validation.annotation.Validated;
* JPA implementation of {@link ReportManagement}. * JPA implementation of {@link ReportManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaReportManagement implements ReportManagement { public class JpaReportManagement implements ReportManagement {

View File

@@ -51,7 +51,6 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -59,7 +58,7 @@ import org.springframework.validation.annotation.Validated;
* JPA implementation of {@link RolloutGroupManagement}. * JPA implementation of {@link RolloutGroupManagement}.
*/ */
@Validated @Validated
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public class JpaRolloutGroupManagement implements RolloutGroupManagement { public class JpaRolloutGroupManagement implements RolloutGroupManagement {
@Autowired @Autowired

View File

@@ -17,6 +17,7 @@ import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import javax.persistence.EntityManager;
import javax.validation.ConstraintDeclarationException; import javax.validation.ConstraintDeclarationException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -35,7 +36,6 @@ import org.eclipse.hawkbit.repository.builder.RolloutUpdate;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.ConstraintViolationException; import org.eclipse.hawkbit.repository.exception.ConstraintViolationException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException; import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
@@ -78,13 +78,11 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.integration.support.locks.LockRegistry; import org.springframework.integration.support.locks.LockRegistry;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionException;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
@@ -96,7 +94,7 @@ import com.google.common.collect.Lists;
* JPA implementation of {@link RolloutManagement}. * JPA implementation of {@link RolloutManagement}.
*/ */
@Validated @Validated
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public class JpaRolloutManagement extends AbstractRolloutManagement { public class JpaRolloutManagement extends AbstractRolloutManagement {
private static final Logger LOGGER = LoggerFactory.getLogger(JpaRolloutManagement.class); private static final Logger LOGGER = LoggerFactory.getLogger(JpaRolloutManagement.class);
@@ -128,6 +126,9 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
@Autowired @Autowired
private AfterTransactionCommitExecutor afterCommit; private AfterTransactionCommitExecutor afterCommit;
@Autowired
private EntityManager entityManager;
JpaRolloutManagement(final TargetManagement targetManagement, final DeploymentManagement deploymentManagement, JpaRolloutManagement(final TargetManagement targetManagement, final DeploymentManagement deploymentManagement,
final RolloutGroupManagement rolloutGroupManagement, final RolloutGroupManagement rolloutGroupManagement,
final DistributionSetManagement distributionSetManagement, final ApplicationContext context, final DistributionSetManagement distributionSetManagement, final ApplicationContext context,
@@ -140,7 +141,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
@Override @Override
public Page<Rollout> findAll(final Pageable pageable, final boolean deleted) { public Page<Rollout> findAll(final Pageable pageable, final boolean deleted) {
final Specification<JpaRollout> spec = RolloutSpecification.isDeleted(deleted); final Specification<JpaRollout> spec = RolloutSpecification.isDeletedWithDistributionSet(deleted);
return JpaRolloutHelper.convertPage(rolloutRepository.findAll(spec, pageable), pageable); return JpaRolloutHelper.convertPage(rolloutRepository.findAll(spec, pageable), pageable);
} }
@@ -148,7 +149,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
public Page<Rollout> findAllByPredicate(final String rsqlParam, final Pageable pageable, final boolean deleted) { public Page<Rollout> findAllByPredicate(final String rsqlParam, final Pageable pageable, final boolean deleted) {
final List<Specification<JpaRollout>> specList = Lists.newArrayListWithExpectedSize(2); final List<Specification<JpaRollout>> specList = Lists.newArrayListWithExpectedSize(2);
specList.add(RSQLUtility.parse(rsqlParam, RolloutFields.class, virtualPropertyReplacer)); specList.add(RSQLUtility.parse(rsqlParam, RolloutFields.class, virtualPropertyReplacer));
specList.add(RolloutSpecification.isDeleted(deleted)); specList.add(RolloutSpecification.isDeletedWithDistributionSet(deleted));
return JpaRolloutHelper.convertPage(findByCriteriaAPI(pageable, specList), pageable); return JpaRolloutHelper.convertPage(findByCriteriaAPI(pageable, specList), pageable);
} }
@@ -171,8 +172,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public Rollout createRollout(final RolloutCreate rollout, final int amountGroup, public Rollout createRollout(final RolloutCreate rollout, final int amountGroup,
final RolloutGroupConditions conditions) { final RolloutGroupConditions conditions) {
RolloutHelper.verifyRolloutGroupParameter(amountGroup); RolloutHelper.verifyRolloutGroupParameter(amountGroup);
@@ -181,8 +181,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public Rollout createRollout(final RolloutCreate rollout, final List<RolloutGroupCreate> groups, public Rollout createRollout(final RolloutCreate rollout, final List<RolloutGroupCreate> groups,
final RolloutGroupConditions conditions) { final RolloutGroupConditions conditions) {
RolloutHelper.verifyRolloutGroupParameter(groups.size()); RolloutHelper.verifyRolloutGroupParameter(groups.size());
@@ -191,10 +190,6 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
private JpaRollout createRollout(final JpaRollout rollout) { private JpaRollout createRollout(final JpaRollout rollout) {
final Optional<Rollout> existingRollout = rolloutRepository.findByName(rollout.getName());
if (existingRollout.isPresent()) {
throw new EntityAlreadyExistsException(existingRollout.get().getName());
}
final Long totalTargets = targetManagement.countTargetByTargetFilterQuery(rollout.getTargetFilterQuery()); final Long totalTargets = targetManagement.countTargetByTargetFilterQuery(rollout.getTargetFilterQuery());
if (totalTargets == 0) { if (totalTargets == 0) {
@@ -346,10 +341,12 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout, RolloutGroupStatus.READY, final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout, RolloutGroupStatus.READY,
group); group);
final long targetsInGroupFilter = targetManagement final long targetsInGroupFilter = runInNewTransaction("countAllTargetsByTargetFilterQueryAndNotInRolloutGroups",
.countAllTargetsByTargetFilterQueryAndNotInRolloutGroups(readyGroups, groupTargetFilter); count -> targetManagement.countAllTargetsByTargetFilterQueryAndNotInRolloutGroups(readyGroups,
groupTargetFilter));
final long expectedInGroup = Math.round(group.getTargetPercentage() / 100 * (double) targetsInGroupFilter); final long expectedInGroup = Math.round(group.getTargetPercentage() / 100 * (double) targetsInGroupFilter);
final long currentlyInGroup = rolloutTargetGroupRepository.countByRolloutGroup(group); final long currentlyInGroup = runInNewTransaction("countRolloutTargetGroupByRolloutGroup",
count -> rolloutTargetGroupRepository.countByRolloutGroup(group));
// Switch the Group status to READY, when there are enough Targets in // Switch the Group status to READY, when there are enough Targets in
// the Group // the Group
@@ -369,7 +366,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} while (targetsLeftToAdd > 0); } while (targetsLeftToAdd > 0);
group.setStatus(RolloutGroupStatus.READY); group.setStatus(RolloutGroupStatus.READY);
group.setTotalTargets(rolloutTargetGroupRepository.countByRolloutGroup(group).intValue()); group.setTotalTargets(runInNewTransaction("countRolloutTargetGroupByRolloutGroup",
count -> rolloutTargetGroupRepository.countByRolloutGroup(group)).intValue());
return rolloutGroupRepository.save(group); return rolloutGroupRepository.save(group);
} catch (final TransactionException e) { } catch (final TransactionException e) {
@@ -378,7 +376,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
} }
private Integer assignTargetsToGroupInNewTransaction(final Rollout rollout, final RolloutGroup group, private Long assignTargetsToGroupInNewTransaction(final Rollout rollout, final RolloutGroup group,
final String targetFilter, final long limit) { final String targetFilter, final long limit) {
return runInNewTransaction("assignTargetsToRolloutGroup", status -> { return runInNewTransaction("assignTargetsToRolloutGroup", status -> {
@@ -390,7 +388,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
createAssignmentOfTargetsToGroup(targets, group); createAssignmentOfTargetsToGroup(targets, group);
return targets.getNumberOfElements(); return Long.valueOf(targets.getNumberOfElements());
}); });
} }
@@ -414,8 +412,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public Rollout startRollout(final Long rolloutId) { public Rollout startRollout(final Long rolloutId) {
LOGGER.debug("startRollout called for rollout {}", rolloutId); LOGGER.debug("startRollout called for rollout {}", rolloutId);
@@ -496,7 +493,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
return totalActionsCreated; return totalActionsCreated;
} }
private Integer createActionsForTargetsInNewTransaction(final long rolloutId, final long groupId, final int limit) { private Long createActionsForTargetsInNewTransaction(final long rolloutId, final long groupId, final int limit) {
return runInNewTransaction("createActionsForTargets", status -> { return runInNewTransaction("createActionsForTargets", status -> {
final PageRequest pageRequest = new PageRequest(0, limit); final PageRequest pageRequest = new PageRequest(0, limit);
final Rollout rollout = rolloutRepository.findOne(rolloutId); final Rollout rollout = rolloutRepository.findOne(rolloutId);
@@ -512,7 +509,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group); createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group);
} }
return targets.getNumberOfElements(); return Long.valueOf(targets.getNumberOfElements());
}); });
} }
@@ -545,8 +542,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void pauseRollout(final Long rolloutId) { public void pauseRollout(final Long rolloutId) {
final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId); final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId);
if (!RolloutStatus.RUNNING.equals(rollout.getStatus())) { if (!RolloutStatus.RUNNING.equals(rollout.getStatus())) {
@@ -563,8 +559,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void resumeRollout(final Long rolloutId) { public void resumeRollout(final Long rolloutId) {
final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId); final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId);
if (!(RolloutStatus.PAUSED.equals(rollout.getStatus()))) { if (!(RolloutStatus.PAUSED.equals(rollout.getStatus()))) {
@@ -660,6 +655,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
private boolean isRolloutComplete(final JpaRollout rollout) { private boolean isRolloutComplete(final JpaRollout rollout) {
// ensure that changes in the same transaction count
entityManager.flush();
final Long groupsActiveLeft = rolloutGroupRepository.countByRolloutIdAndStatusOrStatus(rollout.getId(), final Long groupsActiveLeft = rolloutGroupRepository.countByRolloutIdAndStatusOrStatus(rollout.getId(),
RolloutGroupStatus.RUNNING, RolloutGroupStatus.SCHEDULED); RolloutGroupStatus.RUNNING, RolloutGroupStatus.SCHEDULED);
return groupsActiveLeft == 0; return groupsActiveLeft == 0;
@@ -742,7 +739,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
} }
private int executeFittingHandler(final Long rolloutId) { private long executeFittingHandler(final Long rolloutId) {
LOGGER.debug("handle rollout {}", rolloutId); LOGGER.debug("handle rollout {}", rolloutId);
final JpaRollout rollout = rolloutRepository.findOne(rolloutId); final JpaRollout rollout = rolloutRepository.findOne(rolloutId);
@@ -788,8 +785,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void deleteRollout(final long rolloutId) { public void deleteRollout(final long rolloutId) {
final JpaRollout jpaRollout = rolloutRepository.findOne(rolloutId); final JpaRollout jpaRollout = rolloutRepository.findOne(rolloutId);
@@ -821,8 +817,12 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
deleteScheduledActions(rollout, scheduledActions); deleteScheduledActions(rollout, scheduledActions);
// avoid another scheduler round and re-check if all scheduled actions // avoid another scheduler round and re-check if all scheduled actions
// has been cleaned up // has been cleaned up. we flush first to ensure that the we include the
final boolean hasScheduledActionsLeft = findScheduledActionsByRollout(rollout).getNumberOfElements() > 0; // deletion above
entityManager.flush();
final boolean hasScheduledActionsLeft = actionRepository.countByRolloutIdAndStatus(rollout.getId(),
Status.SCHEDULED) > 0;
if (hasScheduledActionsLeft) { if (hasScheduledActionsLeft) {
return; return;
} }
@@ -870,7 +870,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
@Override @Override
public Long countRolloutsAll() { public Long countRolloutsAll() {
return rolloutRepository.count(RolloutSpecification.isDeleted(false)); return rolloutRepository.count(RolloutSpecification.isDeletedWithDistributionSet(false));
} }
@Override @Override
@@ -893,8 +893,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public Rollout updateRollout(final RolloutUpdate u) { public Rollout updateRollout(final RolloutUpdate u) {
final GenericRolloutUpdate update = (GenericRolloutUpdate) u; final GenericRolloutUpdate update = (GenericRolloutUpdate) u;
final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(update.getId()); final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(update.getId());
@@ -930,7 +929,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
@Override @Override
public Page<Rollout> findAllRolloutsWithDetailedStatus(final Pageable pageable, final boolean deleted) { public Page<Rollout> findAllRolloutsWithDetailedStatus(final Pageable pageable, final boolean deleted) {
Page<JpaRollout> rollouts; Page<JpaRollout> rollouts;
final Specification<JpaRollout> spec = RolloutSpecification.isDeleted(deleted); final Specification<JpaRollout> spec = RolloutSpecification.isDeletedWithDistributionSet(deleted);
rollouts = rolloutRepository.findAll(spec, pageable); rollouts = rolloutRepository.findAll(spec, pageable);
setRolloutStatusDetails(rollouts); setRolloutStatusDetails(rollouts);
return JpaRolloutHelper.convertPage(rollouts, pageable); return JpaRolloutHelper.convertPage(rollouts, pageable);
@@ -975,24 +974,6 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
} }
} }
@Override
public float getFinishedPercentForRunningGroup(final Long rolloutId, final Long rolloutGroupId) {
final RolloutGroup rolloutGroup = rolloutGroupRepository.findById(rolloutGroupId)
.orElseThrow(() -> new EntityNotFoundException(RolloutGroup.class, rolloutGroupId));
final long totalGroup = rolloutGroup.getTotalTargets();
if (totalGroup == 0) {
// in case e.g. targets has been deleted we don't have any actions
// left for this group, so the group is finished
return 100;
}
final Long finished = actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rolloutId,
rolloutGroup.getId(), Action.Status.FINISHED);
// calculate threshold
return ((float) finished / (float) totalGroup) * 100;
}
@Override @Override
public boolean exists(final Long rolloutId) { public boolean exists(final Long rolloutId) {
return rolloutRepository.exists(rolloutId); return rolloutRepository.exists(rolloutId);

View File

@@ -69,9 +69,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl; import org.springframework.data.domain.SliceImpl;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -83,7 +81,7 @@ import com.google.common.collect.Sets;
* JPA implementation of {@link SoftwareManagement}. * JPA implementation of {@link SoftwareManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaSoftwareManagement implements SoftwareManagement { public class JpaSoftwareManagement implements SoftwareManagement {
@@ -118,8 +116,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private VirtualPropertyReplacer virtualPropertyReplacer; private VirtualPropertyReplacer virtualPropertyReplacer;
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModule updateSoftwareModule(final SoftwareModuleUpdate u) { public SoftwareModule updateSoftwareModule(final SoftwareModuleUpdate u) {
final GenericSoftwareModuleUpdate update = (GenericSoftwareModuleUpdate) u; final GenericSoftwareModuleUpdate update = (GenericSoftwareModuleUpdate) u;
@@ -133,8 +130,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleTypeUpdate u) { public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleTypeUpdate u) {
final GenericSoftwareModuleTypeUpdate update = (GenericSoftwareModuleTypeUpdate) u; final GenericSoftwareModuleTypeUpdate update = (GenericSoftwareModuleTypeUpdate) u;
@@ -148,8 +144,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModule createSoftwareModule(final SoftwareModuleCreate c) { public SoftwareModule createSoftwareModule(final SoftwareModuleCreate c) {
final JpaSoftwareModuleCreate create = (JpaSoftwareModuleCreate) c; final JpaSoftwareModuleCreate create = (JpaSoftwareModuleCreate) c;
@@ -157,8 +152,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<SoftwareModule> createSoftwareModule(final Collection<SoftwareModuleCreate> swModules) { public List<SoftwareModule> createSoftwareModule(final Collection<SoftwareModuleCreate> swModules) {
return swModules.stream().map(this::createSoftwareModule).collect(Collectors.toList()); return swModules.stream().map(this::createSoftwareModule).collect(Collectors.toList());
} }
@@ -230,8 +224,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteSoftwareModules(final Collection<Long> ids) { public void deleteSoftwareModules(final Collection<Long> ids) {
final List<JpaSoftwareModule> swModulesToDelete = softwareModuleRepository.findByIdIn(ids); final List<JpaSoftwareModule> swModulesToDelete = softwareModuleRepository.findByIdIn(ids);
@@ -489,8 +482,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleTypeCreate c) { public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleTypeCreate c) {
final JpaSoftwareModuleTypeCreate create = (JpaSoftwareModuleTypeCreate) c; final JpaSoftwareModuleTypeCreate create = (JpaSoftwareModuleTypeCreate) c;
@@ -498,8 +490,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteSoftwareModuleType(final Long typeId) { public void deleteSoftwareModuleType(final Long typeId) {
final JpaSoftwareModuleType toDelete = softwareModuleTypeRepository.findById(typeId) final JpaSoftwareModuleType toDelete = softwareModuleTypeRepository.findById(typeId)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModuleType.class, typeId)); .orElseThrow(() -> new EntityNotFoundException(SoftwareModuleType.class, typeId));
@@ -523,8 +514,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public SoftwareModuleMetadata createSoftwareModuleMetadata(final Long moduleId, final MetaData md) { public SoftwareModuleMetadata createSoftwareModuleMetadata(final Long moduleId, final MetaData md) {
checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, md); checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, md);
@@ -540,8 +530,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public List<SoftwareModuleMetadata> createSoftwareModuleMetadata(final Long moduleId, public List<SoftwareModuleMetadata> createSoftwareModuleMetadata(final Long moduleId,
final Collection<MetaData> md) { final Collection<MetaData> md) {
md.forEach(meta -> checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, meta)); md.forEach(meta -> checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, meta));
@@ -555,8 +544,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public SoftwareModuleMetadata updateSoftwareModuleMetadata(final Long moduleId, final MetaData md) { public SoftwareModuleMetadata updateSoftwareModuleMetadata(final Long moduleId, final MetaData md) {
// check if exists otherwise throw entity not found exception // check if exists otherwise throw entity not found exception
@@ -600,8 +588,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void deleteSoftwareModuleMetadata(final Long moduleId, final String key) { public void deleteSoftwareModuleMetadata(final Long moduleId, final String key) {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findSoftwareModuleMetadata(moduleId, key) final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) findSoftwareModuleMetadata(moduleId, key)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, moduleId, key)); .orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, moduleId, key));
@@ -665,15 +652,13 @@ public class JpaSoftwareManagement implements SoftwareManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteSoftwareModule(final Long moduleId) { public void deleteSoftwareModule(final Long moduleId) {
deleteSoftwareModules(Sets.newHashSet(moduleId)); deleteSoftwareModules(Sets.newHashSet(moduleId));
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<SoftwareModuleType> createSoftwareModuleType(final Collection<SoftwareModuleTypeCreate> creates) { public List<SoftwareModuleType> createSoftwareModuleType(final Collection<SoftwareModuleTypeCreate> creates) {
return creates.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); return creates.stream().map(this::createSoftwareModuleType).collect(Collectors.toList());
} }

View File

@@ -32,10 +32,8 @@ import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.DefaultTransactionDefinition;
@@ -46,7 +44,7 @@ import org.springframework.validation.annotation.Validated;
* JPA implementation of {@link SystemManagement}. * JPA implementation of {@link SystemManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement { public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement {
@Autowired @Autowired
@@ -152,8 +150,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public TenantMetaData getTenantMetadata(final String tenant) { public TenantMetaData getTenantMetadata(final String tenant) {
final TenantMetaData result = tenantMetaDataRepository.findByTenantIgnoreCase(tenant); final TenantMetaData result = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
// Create if it does not exist // Create if it does not exist
@@ -188,11 +184,11 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
def.setName("initial-tenant-creation"); def.setName("initial-tenant-creation");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
def.setReadOnly(false); def.setReadOnly(false);
def.setIsolationLevel(Isolation.READ_UNCOMMITTED.value()); return systemSecurityContext
return systemSecurityContext.runAsSystemAsTenant( .runAsSystemAsTenant(() -> new TransactionTemplate(txManager, def).execute(status -> {
() -> new TransactionTemplate(txManager, def).execute(status -> tenantMetaDataRepository final DistributionSetType defaultDsType = createStandardSoftwareDataSetup();
.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant))), return tenantMetaDataRepository.save(new JpaTenantMetaData(defaultDsType, tenant));
tenant); }), tenant);
} }
@Override @Override
@@ -201,8 +197,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void deleteTenant(final String tenant) { public void deleteTenant(final String tenant) {
cacheManager.evictCaches(tenant); cacheManager.evictCaches(tenant);
tenantAware.runAsTenant(tenant, () -> { tenantAware.runAsTenant(tenant, () -> {
@@ -223,8 +218,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public TenantMetaData getTenantMetadata() { public TenantMetaData getTenantMetadata() {
if (tenantAware.getCurrentTenant() == null) { if (tenantAware.getCurrentTenant() == null) {
throw new IllegalStateException("Tenant not set"); throw new IllegalStateException("Tenant not set");
@@ -235,17 +228,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
@Override @Override
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null") @Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null")
// set transaction to not supported, due we call this in
// BaseEntity#prePersist methods
// and it seems that JPA committing the transaction when executing this
// transactional method,
// which then leads that the BaseEntity#prePersist is called again to
// persist the un-persisted
// entity and we landing again in the #currentTenant() method
// suspend the transaction here to do a read-request against the medata
// table, when the current
// tenant is not cached anyway already.
@Transactional(propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED)
public String currentTenant() { public String currentTenant() {
final String initialTenantCreation = currentTenantCacheKeyGenerator.getCreateInitialTenant().get(); final String initialTenantCreation = currentTenantCacheKeyGenerator.getCreateInitialTenant().get();
if (initialTenantCreation == null) { if (initialTenantCreation == null) {
@@ -257,8 +239,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public TenantMetaData updateTenantMetadata(final Long defaultDsType) { public TenantMetaData updateTenantMetadata(final Long defaultDsType) {
final JpaTenantMetaData data = (JpaTenantMetaData) getTenantMetadata(); final JpaTenantMetaData data = (JpaTenantMetaData) getTenantMetadata();

View File

@@ -19,7 +19,6 @@ import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.builder.GenericTagUpdate; import org.eclipse.hawkbit.repository.builder.GenericTagUpdate;
import org.eclipse.hawkbit.repository.builder.TagCreate; import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TagUpdate; import org.eclipse.hawkbit.repository.builder.TagUpdate;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagCreate; import org.eclipse.hawkbit.repository.jpa.builder.JpaTagCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
@@ -34,8 +33,6 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -43,7 +40,7 @@ import org.springframework.validation.annotation.Validated;
* JP>A implementation of {@link TagManagement}. * JP>A implementation of {@link TagManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaTagManagement implements TagManagement { public class JpaTagManagement implements TagManagement {
@@ -68,22 +65,15 @@ public class JpaTagManagement implements TagManagement {
} }
@Override @Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
public TargetTag createTargetTag(final TagCreate c) { public TargetTag createTargetTag(final TagCreate c) {
final JpaTagCreate create = (JpaTagCreate) c; final JpaTagCreate create = (JpaTagCreate) c;
final JpaTargetTag targetTag = create.buildTargetTag(); return targetTagRepository.save(create.buildTargetTag());
if (findTargetTag(targetTag.getName()).isPresent()) {
throw new EntityAlreadyExistsException();
}
return targetTagRepository.save(targetTag);
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<TargetTag> createTargetTags(final Collection<TagCreate> tt) { public List<TargetTag> createTargetTags(final Collection<TagCreate> tt) {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaTagCreate> targetTags = (Collection) tt; final Collection<JpaTagCreate> targetTags = (Collection) tt;
@@ -93,8 +83,7 @@ public class JpaTagManagement implements TagManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargetTag(final String targetTagName) { public void deleteTargetTag(final String targetTagName) {
final TargetTag tag = targetTagRepository.findByNameEquals(targetTagName) final TargetTag tag = targetTagRepository.findByNameEquals(targetTagName)
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagName)); .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagName));
@@ -131,8 +120,7 @@ public class JpaTagManagement implements TagManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetTag updateTargetTag(final TagUpdate u) { public TargetTag updateTargetTag(final TagUpdate u) {
final GenericTagUpdate update = (GenericTagUpdate) u; final GenericTagUpdate update = (GenericTagUpdate) u;
@@ -147,8 +135,8 @@ public class JpaTagManagement implements TagManagement {
} }
@Override @Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
public DistributionSetTag updateDistributionSetTag(final TagUpdate u) { public DistributionSetTag updateDistributionSetTag(final TagUpdate u) {
final GenericTagUpdate update = (GenericTagUpdate) u; final GenericTagUpdate update = (GenericTagUpdate) u;
@@ -168,23 +156,14 @@ public class JpaTagManagement implements TagManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTag createDistributionSetTag(final TagCreate c) { public DistributionSetTag createDistributionSetTag(final TagCreate c) {
final JpaTagCreate create = (JpaTagCreate) c; final JpaTagCreate create = (JpaTagCreate) c;
return distributionSetTagRepository.save(create.buildDistributionSetTag());
final JpaDistributionSetTag distributionSetTag = create.buildDistributionSetTag();
if (distributionSetTagRepository.findByNameEquals(distributionSetTag.getName()).isPresent()) {
throw new EntityAlreadyExistsException();
}
return distributionSetTagRepository.save(distributionSetTag);
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSetTag> createDistributionSetTags(final Collection<TagCreate> dst) { public List<DistributionSetTag> createDistributionSetTags(final Collection<TagCreate> dst) {
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@@ -196,8 +175,7 @@ public class JpaTagManagement implements TagManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSetTag(final String tagName) { public void deleteDistributionSetTag(final String tagName) {
final DistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName) final DistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName)
.orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName)); .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName));

View File

@@ -20,7 +20,6 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.builder.GenericTargetFilterQueryUpdate; import org.eclipse.hawkbit.repository.builder.GenericTargetFilterQueryUpdate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate; import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryUpdate; import org.eclipse.hawkbit.repository.builder.TargetFilterQueryUpdate;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryCreate; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
@@ -37,8 +36,6 @@ import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications; import org.springframework.data.jpa.domain.Specifications;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -49,7 +46,7 @@ import com.google.common.collect.Lists;
* JPA implementation of {@link TargetFilterQueryManagement}. * JPA implementation of {@link TargetFilterQueryManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement { public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement {
@@ -68,23 +65,16 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
this.distributionSetManagement = distributionSetManagement; this.distributionSetManagement = distributionSetManagement;
} }
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Override @Override
public TargetFilterQuery createTargetFilterQuery(final TargetFilterQueryCreate c) { public TargetFilterQuery createTargetFilterQuery(final TargetFilterQueryCreate c) {
final JpaTargetFilterQueryCreate create = (JpaTargetFilterQueryCreate) c; final JpaTargetFilterQueryCreate create = (JpaTargetFilterQueryCreate) c;
final JpaTargetFilterQuery query = create.build(); return targetFilterQueryRepository.save(create.build());
if (targetFilterQueryRepository.findByName(query.getName()).isPresent()) {
throw new EntityAlreadyExistsException(query.getName());
}
return targetFilterQueryRepository.save(query);
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargetFilterQuery(final Long targetFilterQueryId) { public void deleteTargetFilterQuery(final Long targetFilterQueryId) {
findTargetFilterQueryById(targetFilterQueryId) findTargetFilterQueryById(targetFilterQueryId)
.orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId)); .orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId));
@@ -178,8 +168,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetFilterQuery updateTargetFilterQuery(final TargetFilterQueryUpdate u) { public TargetFilterQuery updateTargetFilterQuery(final TargetFilterQueryUpdate u) {
final GenericTargetFilterQueryUpdate update = (GenericTargetFilterQueryUpdate) u; final GenericTargetFilterQueryUpdate update = (GenericTargetFilterQueryUpdate) u;
@@ -192,8 +181,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetFilterQuery updateTargetFilterQueryAutoAssignDS(final Long queryId, final Long dsId) { public TargetFilterQuery updateTargetFilterQueryAutoAssignDS(final Long queryId, final Long dsId) {
final JpaTargetFilterQuery targetFilterQuery = findTargetFilterQueryOrThrowExceptionIfNotFound(queryId); final JpaTargetFilterQuery targetFilterQuery = findTargetFilterQueryOrThrowExceptionIfNotFound(queryId);

View File

@@ -32,7 +32,6 @@ import org.eclipse.hawkbit.repository.TimestampCalculator;
import org.eclipse.hawkbit.repository.builder.TargetCreate; import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate; import org.eclipse.hawkbit.repository.builder.TargetUpdate;
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetCreate; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetUpdate; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetUpdate;
@@ -61,8 +60,6 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl; import org.springframework.data.domain.SliceImpl;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -72,7 +69,7 @@ import com.google.common.collect.Lists;
* JPA implementation of {@link TargetManagement}. * JPA implementation of {@link TargetManagement}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaTargetManagement implements TargetManagement { public class JpaTargetManagement implements TargetManagement {
@@ -116,8 +113,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override @Override
public List<Target> findTargetByControllerID(final Collection<String> controllerIDs) { public List<Target> findTargetByControllerID(final Collection<String> controllerIDs) {
return Collections.unmodifiableList(targetRepository return Collections.unmodifiableList(
.findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs))); targetRepository.findAll(TargetSpecifications.byControllerIdWithAssignedDsInJoin(controllerIDs)));
} }
@Override @Override
@@ -150,8 +147,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateTarget(final TargetUpdate u) { public Target updateTarget(final TargetUpdate u) {
final JpaTargetUpdate update = (JpaTargetUpdate) u; final JpaTargetUpdate update = (JpaTargetUpdate) u;
@@ -167,8 +163,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargets(final Collection<Long> targetIDs) { public void deleteTargets(final Collection<Long> targetIDs) {
final List<JpaTarget> targets = targetRepository.findAll(targetIDs); final List<JpaTarget> targets = targetRepository.findAll(targetIDs);
@@ -184,8 +179,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTarget(final String controllerID) { public void deleteTarget(final String controllerID) {
final Target target = targetRepository.findByControllerId(controllerID) final Target target = targetRepository.findByControllerId(controllerID)
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerID)); .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerID));
@@ -324,13 +318,12 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetTagAssignmentResult toggleTagAssignment(final Collection<String> controllerIds, final String tagName) { public TargetTagAssignmentResult toggleTagAssignment(final Collection<String> controllerIds, final String tagName) {
final TargetTag tag = targetTagRepository.findByNameEquals(tagName) final TargetTag tag = targetTagRepository.findByNameEquals(tagName)
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagName)); .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagName));
final List<JpaTarget> allTargets = targetRepository final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds)); .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds));
if (allTargets.size() < controllerIds.size()) { if (allTargets.size() < controllerIds.size()) {
throw new EntityNotFoundException(Target.class, controllerIds, throw new EntityNotFoundException(Target.class, controllerIds,
@@ -362,11 +355,10 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> assignTag(final Collection<String> controllerIds, final Long tagId) { public List<Target> assignTag(final Collection<String> controllerIds, final Long tagId) {
final List<JpaTarget> allTargets = targetRepository final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds)); .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds));
if (allTargets.size() < controllerIds.size()) { if (allTargets.size() < controllerIds.size()) {
throw new EntityNotFoundException(Target.class, controllerIds, throw new EntityNotFoundException(Target.class, controllerIds,
@@ -392,8 +384,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> unAssignAllTargetsByTag(final Long targetTagId) { public List<Target> unAssignAllTargetsByTag(final Long targetTagId) {
final TargetTag tag = targetTagRepository.findById(targetTagId) final TargetTag tag = targetTagRepository.findById(targetTagId)
@@ -407,8 +398,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target unAssignTag(final String controllerID, final Long targetTagId) { public Target unAssignTag(final String controllerID, final Long targetTagId) {
final Target target = targetRepository.findByControllerId(controllerID) final Target target = targetRepository.findByControllerId(controllerID)
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerID)); .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerID));
@@ -553,23 +543,14 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target createTarget(final TargetCreate c) { public Target createTarget(final TargetCreate c) {
final JpaTargetCreate create = (JpaTargetCreate) c; final JpaTargetCreate create = (JpaTargetCreate) c;
return targetRepository.save(create.build());
final JpaTarget target = create.build();
if (targetRepository.existsByControllerId(target.getControllerId())) {
throw new EntityAlreadyExistsException();
}
return targetRepository.save(target);
} }
@Override @Override
@Modifying @Transactional
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> createTargets(final Collection<TargetCreate> targets) { public List<Target> createTargets(final Collection<TargetCreate> targets) {
return targets.stream().map(this::createTarget).collect(Collectors.toList()); return targets.stream().map(this::createTarget).collect(Collectors.toList());
} }

View File

@@ -23,15 +23,13 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.ConfigurableConversionService;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
/** /**
* Central tenant configuration management operations of the SP server. * Central tenant configuration management operations of the SP server.
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
@Validated @Validated
public class JpaTenantConfigurationManagement implements TenantConfigurationManagement { public class JpaTenantConfigurationManagement implements TenantConfigurationManagement {
@@ -123,8 +121,7 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana
@Override @Override
@CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName")
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public <T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration( public <T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(
final String configurationKeyName, final T value) { final String configurationKeyName, final T value) {
@@ -162,8 +159,7 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana
@Override @Override
@CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName") @CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName")
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Modifying
public void deleteConfiguration(final String configurationKeyName) { public void deleteConfiguration(final String configurationKeyName) {
tenantConfigurationRepository.deleteByKey(configurationKeyName); tenantConfigurationRepository.deleteByKey(configurationKeyName);
} }

View File

@@ -12,7 +12,6 @@ import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.eclipse.hawkbit.repository.report.model.TenantUsage;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -37,7 +36,7 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
private TenantAware tenantAware; private TenantAware tenantAware;
@Override @Override
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED) @Transactional(propagation = Propagation.REQUIRES_NEW)
public TenantUsage getStatsOfTenant() { public TenantUsage getStatsOfTenant() {
final String tenant = tenantAware.getCurrentTenant(); final String tenant = tenantAware.getCurrentTenant();

View File

@@ -18,14 +18,13 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link Artifact} repository. * {@link Artifact} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface LocalArtifactRepository extends BaseEntityRepository<JpaArtifact, Long> { public interface LocalArtifactRepository extends BaseEntityRepository<JpaArtifact, Long> {
/** /**

View File

@@ -276,7 +276,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Override @Override
protected Map<String, Object> getVendorProperties() { protected Map<String, Object> getVendorProperties() {
final Map<String, Object> properties = Maps.newHashMapWithExpectedSize(4); final Map<String, Object> properties = Maps.newHashMapWithExpectedSize(5);
// Turn off dynamic weaving to disable LTW lookup in static weaving mode // Turn off dynamic weaving to disable LTW lookup in static weaving mode
properties.put("eclipselink.weaving", "false"); properties.put("eclipselink.weaving", "false");
// needed for reports // needed for reports
@@ -285,6 +285,8 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
properties.put("eclipselink.ddl-generation", "none"); properties.put("eclipselink.ddl-generation", "none");
// Embeed into hawkBit logging // Embeed into hawkBit logging
properties.put("eclipselink.logging.logger", "JavaLogger"); properties.put("eclipselink.logging.logger", "JavaLogger");
// Ensure that we flush only at the end of the transaction
properties.put("eclipselink.persistence-context.flush-mode", "COMMIT");
return properties; return properties;
} }

View File

@@ -21,13 +21,12 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* The repository interface for the {@link RolloutGroup} model. * The repository interface for the {@link RolloutGroup} model.
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface RolloutGroupRepository public interface RolloutGroupRepository
extends BaseEntityRepository<JpaRolloutGroup, Long>, JpaSpecificationExecutor<JpaRolloutGroup> { extends BaseEntityRepository<JpaRolloutGroup, Long>, JpaSpecificationExecutor<JpaRolloutGroup> {
@@ -119,7 +118,7 @@ public interface RolloutGroupRepository
* the status of the rolloutgroups * the status of the rolloutgroups
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Query("UPDATE JpaRolloutGroup g SET g.status = :status WHERE g.parent = :parent") @Query("UPDATE JpaRolloutGroup g SET g.status = :status WHERE g.parent = :parent")
void setStatusForCildren(@Param("status") RolloutGroupStatus status, @Param("parent") RolloutGroup parent); void setStatusForCildren(@Param("status") RolloutGroupStatus status, @Param("parent") RolloutGroup parent);

View File

@@ -17,13 +17,12 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* The repository interface for the {@link Rollout} model. * The repository interface for the {@link Rollout} model.
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface RolloutRepository public interface RolloutRepository
extends BaseEntityRepository<JpaRollout, Long>, JpaSpecificationExecutor<JpaRollout> { extends BaseEntityRepository<JpaRollout, Long>, JpaSpecificationExecutor<JpaRollout> {

View File

@@ -13,14 +13,13 @@ import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroupId; import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroupId;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Spring data repository for {@link RolloutTargetGroup}. * Spring data repository for {@link RolloutTargetGroup}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface RolloutTargetGroupRepository public interface RolloutTargetGroupRepository
extends CrudRepository<RolloutTargetGroup, RolloutTargetGroupId>, JpaSpecificationExecutor<RolloutTargetGroup> { extends CrudRepository<RolloutTargetGroup, RolloutTargetGroupId>, JpaSpecificationExecutor<RolloutTargetGroup> {

View File

@@ -15,14 +15,13 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link SoftwareModuleMetadata} repository. * {@link SoftwareModuleMetadata} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface SoftwareModuleMetadataRepository public interface SoftwareModuleMetadataRepository
extends PagingAndSortingRepository<JpaSoftwareModuleMetadata, SwMetadataCompositeKey>, extends PagingAndSortingRepository<JpaSoftwareModuleMetadata, SwMetadataCompositeKey>,
JpaSpecificationExecutor<JpaSoftwareModuleMetadata> { JpaSpecificationExecutor<JpaSoftwareModuleMetadata> {

View File

@@ -23,14 +23,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link SoftwareModule} repository. * {@link SoftwareModule} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface SoftwareModuleRepository public interface SoftwareModuleRepository
extends BaseEntityRepository<JpaSoftwareModule, Long>, JpaSpecificationExecutor<JpaSoftwareModule> { extends BaseEntityRepository<JpaSoftwareModule, Long>, JpaSpecificationExecutor<JpaSoftwareModule> {
@@ -70,7 +69,7 @@ public interface SoftwareModuleRepository
* *
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Query("UPDATE JpaSoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids") @Query("UPDATE JpaSoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids")
void deleteSoftwareModule(@Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy, void deleteSoftwareModule(@Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy,
@Param("ids") final Long... ids); @Param("ids") final Long... ids);

View File

@@ -18,14 +18,13 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Repository for {@link SoftwareModuleType}. * Repository for {@link SoftwareModuleType}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface SoftwareModuleTypeRepository public interface SoftwareModuleTypeRepository
extends BaseEntityRepository<JpaSoftwareModuleType, Long>, JpaSpecificationExecutor<JpaSoftwareModuleType> { extends BaseEntityRepository<JpaSoftwareModuleType, Long>, JpaSpecificationExecutor<JpaSoftwareModuleType> {

View File

@@ -17,14 +17,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* Spring data repositories for {@link TargetFilterQuery}s. * Spring data repositories for {@link TargetFilterQuery}s.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface TargetFilterQueryRepository public interface TargetFilterQueryRepository
extends BaseEntityRepository<JpaTargetFilterQuery, Long>, JpaSpecificationExecutor<JpaTargetFilterQuery> { extends BaseEntityRepository<JpaTargetFilterQuery, Long>, JpaSpecificationExecutor<JpaTargetFilterQuery> {
@@ -49,7 +48,7 @@ public interface TargetFilterQueryRepository
* distribution set ids to be set to null * distribution set ids to be set to null
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Query("update JpaTargetFilterQuery d set d.autoAssignDistributionSet = NULL where d.autoAssignDistributionSet in :ids") @Query("update JpaTargetFilterQuery d set d.autoAssignDistributionSet = NULL where d.autoAssignDistributionSet in :ids")
void unsetAutoAssignDistributionSet(@Param("ids") Long... dsIds); void unsetAutoAssignDistributionSet(@Param("ids") Long... dsIds);

View File

@@ -25,14 +25,13 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link Target} repository. * {@link Target} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>, JpaSpecificationExecutor<JpaTarget> { public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>, JpaSpecificationExecutor<JpaTarget> {
/** /**
@@ -50,7 +49,7 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
* to update * to update
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
@Query("UPDATE JpaTarget t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy, t.updateStatus = :status WHERE t.id IN :targets") @Query("UPDATE JpaTarget t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy, t.updateStatus = :status WHERE t.id IN :targets")
void setAssignedDistributionSetAndUpdateStatus(@Param("status") TargetUpdateStatus status, void setAssignedDistributionSetAndUpdateStatus(@Param("status") TargetUpdateStatus status,
@Param("set") JpaDistributionSet set, @Param("lastModifiedAt") Long modifiedAt, @Param("set") JpaDistributionSet set, @Param("lastModifiedAt") Long modifiedAt,
@@ -85,7 +84,7 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
* to be deleted * to be deleted
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM JpaTarget t WHERE t.id IN ?1") @Query("DELETE FROM JpaTarget t WHERE t.id IN ?1")
void deleteByIdIn(final Collection<Long> targetIDs); void deleteByIdIn(final Collection<Long> targetIDs);

View File

@@ -15,14 +15,13 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* {@link TargetTag} repository. * {@link TargetTag} repository.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface TargetTagRepository public interface TargetTagRepository
extends BaseEntityRepository<JpaTargetTag, Long>, JpaSpecificationExecutor<JpaTargetTag> { extends BaseEntityRepository<JpaTargetTag, Long>, JpaSpecificationExecutor<JpaTargetTag> {
@@ -34,7 +33,7 @@ public interface TargetTagRepository
* @return 1 if tag was deleted * @return 1 if tag was deleted
*/ */
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional
Long deleteByName(String tagName); Long deleteByName(String tagName);
/** /**

View File

@@ -10,14 +10,13 @@ package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration; import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* The spring-data repository for the entity {@link TenantConfiguration}. * The spring-data repository for the entity {@link TenantConfiguration}.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface TenantConfigurationRepository extends BaseEntityRepository<JpaTenantConfiguration, Long> { public interface TenantConfigurationRepository extends BaseEntityRepository<JpaTenantConfiguration, Long> {
/** /**

View File

@@ -12,15 +12,16 @@ import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData; import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.model.TenantMetaData;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/** /**
* repository for operations on {@link TenantMetaData} entity. * repository for operations on {@link TenantMetaData} entity.
* *
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public interface TenantMetaDataRepository extends PagingAndSortingRepository<JpaTenantMetaData, Long> { public interface TenantMetaDataRepository extends PagingAndSortingRepository<JpaTenantMetaData, Long> {
/** /**
@@ -30,6 +31,7 @@ public interface TenantMetaDataRepository extends PagingAndSortingRepository<Jpa
* to search for * to search for
* @return found {@link TenantMetaData} or <code>null</code> * @return found {@link TenantMetaData} or <code>null</code>
*/ */
@Transactional(propagation = Propagation.REQUIRES_NEW)
TenantMetaData findByTenantIgnoreCase(String tenant); TenantMetaData findByTenantIgnoreCase(String tenant);
@Override @Override
@@ -38,6 +40,8 @@ public interface TenantMetaDataRepository extends PagingAndSortingRepository<Jpa
/** /**
* @param tenant * @param tenant
*/ */
@Transactional
@Modifying
void deleteByTenantIgnoreCase(String tenant); void deleteByTenantIgnoreCase(String tenant);
} }

View File

@@ -20,7 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
* A TenantAwareEvent entity manager, which loads an entity by id and type for * A TenantAwareEvent entity manager, which loads an entity by id and type for
* remote events. * remote events.
*/ */
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
public class JpaEventEntityManager implements EventEntityManager { public class JpaEventEntityManager implements EventEntityManager {
private final TenantAware tenantAware; private final TenantAware tenantAware;

View File

@@ -8,6 +8,8 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.specifications; package org.eclipse.hawkbit.repository.jpa.specifications;
import javax.persistence.criteria.Predicate;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_; import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout;
@@ -25,15 +27,21 @@ public final class RolloutSpecification {
/** /**
* {@link Specification} for retrieving {@link Rollout}s by its DELETED * {@link Specification} for retrieving {@link Rollout}s by its DELETED
* attribute. * attribute. Includes fetch for stuff that is required for {@link Rollout}
* queries.
* *
* @param isDeleted * @param isDeleted
* TRUE/FALSE are compared to the attribute DELETED. If NULL the * TRUE/FALSE are compared to the attribute DELETED. If NULL the
* attribute is ignored * attribute is ignored
* @return the {@link Rollout} {@link Specification} * @return the {@link Rollout} {@link Specification}
*/ */
public static Specification<JpaRollout> isDeleted(final Boolean isDeleted) { public static Specification<JpaRollout> isDeletedWithDistributionSet(final Boolean isDeleted) {
return (root, query, cb) -> cb.equal(root.<Boolean> get(JpaRollout_.deleted), isDeleted); return (root, query, cb) -> {
final Predicate predicate = cb.equal(root.<Boolean> get(JpaRollout_.deleted), isDeleted);
root.fetch(JpaRollout_.distributionSet);
return predicate;
};
} }

View File

@@ -50,15 +50,14 @@ public final class TargetSpecifications {
/** /**
* {@link Specification} for retrieving {@link Target}s including * {@link Specification} for retrieving {@link Target}s including
* {@link TargetTag}s and {@link TargetStatus}. * {@link TargetTag}s.
* *
* @param controllerIDs * @param controllerIDs
* to search for * to search for
* *
* @return the {@link Target} {@link Specification} * @return the {@link Target} {@link Specification}
*/ */
public static Specification<JpaTarget> byControllerIdWithStatusAndTagsInJoin( public static Specification<JpaTarget> byControllerIdWithTagsInJoin(final Collection<String> controllerIDs) {
final Collection<String> controllerIDs) {
return (targetRoot, query, cb) -> { return (targetRoot, query, cb) -> {
final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs); final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs);
targetRoot.fetch(JpaTarget_.tags, JoinType.LEFT); targetRoot.fetch(JpaTarget_.tags, JoinType.LEFT);
@@ -68,16 +67,15 @@ public final class TargetSpecifications {
} }
/** /**
* {@link Specification} for retrieving {@link Target}s including { * {@link Specification} for retrieving {@link JpaTarget}s including
* {@link TargetStatus}. * {@link JpaTarget#getAssignedDistributionSet()}.
* *
* @param controllerIDs * @param controllerIDs
* to search for * to search for
* *
* @return the {@link Target} {@link Specification} * @return the {@link Target} {@link Specification}
*/ */
public static Specification<JpaTarget> byControllerIdWithStatusAndAssignedInJoin( public static Specification<JpaTarget> byControllerIdWithAssignedDsInJoin(final Collection<String> controllerIDs) {
final Collection<String> controllerIDs) {
return (targetRoot, query, cb) -> { return (targetRoot, query, cb) -> {
final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs); final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs);
@@ -92,9 +90,7 @@ public final class TargetSpecifications {
* *
* @param updateStatus * @param updateStatus
* to be filtered on * to be filtered on
* @param fetch *
* {@code true} to fetch the {@link TargetInfo} otherwise only
* join it.
* @return the {@link Target} {@link Specification} * @return the {@link Target} {@link Specification}
*/ */
public static Specification<JpaTarget> hasTargetUpdateStatus(final Collection<TargetUpdateStatus> updateStatus) { public static Specification<JpaTarget> hasTargetUpdateStatus(final Collection<TargetUpdateStatus> updateStatus) {

View File

@@ -0,0 +1,2 @@
alter table sp_target_filter_query
add constraint uk_tenant_custom_filter_name unique (name, tenant);

View File

@@ -0,0 +1,2 @@
alter table sp_target_filter_query
add constraint uk_tenant_custom_filter_name unique (name, tenant);

View File

@@ -97,7 +97,7 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
@Autowired @Autowired
protected TenantConfigurationProperties tenantConfigurationProperties; protected TenantConfigurationProperties tenantConfigurationProperties;
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) @Transactional(readOnly = true)
protected List<Action> findActionsByRolloutAndStatus(final Rollout rollout, final Action.Status actionStatus) { protected List<Action> findActionsByRolloutAndStatus(final Rollout rollout, final Action.Status actionStatus) {
return Lists.newArrayList(actionRepository.findByRolloutIdAndStatus(pageReq, rollout.getId(), actionStatus)); return Lists.newArrayList(actionRepository.findByRolloutIdAndStatus(pageReq, rollout.getId(), actionStatus));
} }

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.util.ArrayList; import java.util.ArrayList;
@@ -327,6 +328,17 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
} }
@Test
@Description("Verifies that a DS cannot be created if another DS with same name and version exists.")
public void createDistributionSetWithDuplicateNameAndVersionFails() {
distributionSetManagement
.createDistributionSet(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> distributionSetManagement
.createDistributionSet(entityFactory.distributionSet().create().name("newtypesoft").version("1")));
}
@Test @Test
@Description("Verifies that multiple DS are of default type if not specified explicitly at creation time.") @Description("Verifies that multiple DS are of default type if not specified explicitly at creation time.")
public void createMultipleDistributionSetsWithImplicitType() { public void createMultipleDistributionSetsWithImplicitType() {

View File

@@ -133,7 +133,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
+ " by means of throwing EntityNotFoundException.") + " by means of throwing EntityNotFoundException.")
@ExpectEvents({ @Expect(type = RolloutDeletedEvent.class, count = 0), @ExpectEvents({ @Expect(type = RolloutDeletedEvent.class, count = 0),
@Expect(type = RolloutGroupCreatedEvent.class, count = 10), @Expect(type = RolloutGroupCreatedEvent.class, count = 10),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 20), @Expect(type = RolloutGroupUpdatedEvent.class, count = 10),
@Expect(type = DistributionSetCreatedEvent.class, count = 1), @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = RolloutUpdatedEvent.class, count = 1), @Expect(type = RolloutUpdatedEvent.class, count = 1),
@@ -143,12 +143,6 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(() -> rolloutManagement.deleteRollout(NOT_EXIST_IDL), "Rollout"); verifyThrownExceptionBy(() -> rolloutManagement.deleteRollout(NOT_EXIST_IDL), "Rollout");
verifyThrownExceptionBy(() -> rolloutManagement.getFinishedPercentForRunningGroup(NOT_EXIST_IDL, NOT_EXIST_IDL),
"Rollout");
verifyThrownExceptionBy(
() -> rolloutManagement.getFinishedPercentForRunningGroup(createdRollout.getId(), NOT_EXIST_IDL),
"RolloutGroup");
verifyThrownExceptionBy(() -> rolloutManagement.pauseRollout(NOT_EXIST_IDL), "Rollout"); verifyThrownExceptionBy(() -> rolloutManagement.pauseRollout(NOT_EXIST_IDL), "Rollout");
verifyThrownExceptionBy(() -> rolloutManagement.resumeRollout(NOT_EXIST_IDL), "Rollout"); verifyThrownExceptionBy(() -> rolloutManagement.resumeRollout(NOT_EXIST_IDL), "Rollout");
verifyThrownExceptionBy(() -> rolloutManagement.startRollout(NOT_EXIST_IDL), "Rollout"); verifyThrownExceptionBy(() -> rolloutManagement.startRollout(NOT_EXIST_IDL), "Rollout");
@@ -1005,23 +999,24 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
myRollout = rolloutManagement.findRolloutById(myRollout.getId()).get(); myRollout = rolloutManagement.findRolloutById(myRollout.getId()).get();
float percent = rolloutManagement.getFinishedPercentForRunningGroup(myRollout.getId(), float percent = rolloutGroupManagement
myRollout.getRolloutGroups().get(0).getId()); .findRolloutGroupWithDetailedStatus(myRollout.getRolloutGroups().get(0).getId()).get()
.getTotalTargetCountStatus().getFinishedPercent();
assertThat(percent).isEqualTo(40); assertThat(percent).isEqualTo(40);
changeStatusForRunningActions(myRollout, Status.FINISHED, 3); changeStatusForRunningActions(myRollout, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
percent = rolloutManagement.getFinishedPercentForRunningGroup(myRollout.getId(), percent = rolloutGroupManagement.findRolloutGroupWithDetailedStatus(myRollout.getRolloutGroups().get(0).getId())
myRollout.getRolloutGroups().get(0).getId()); .get().getTotalTargetCountStatus().getFinishedPercent();
assertThat(percent).isEqualTo(100); assertThat(percent).isEqualTo(100);
changeStatusForRunningActions(myRollout, Status.FINISHED, 4); changeStatusForRunningActions(myRollout, Status.FINISHED, 4);
changeStatusForAllRunningActions(myRollout, Status.ERROR); changeStatusForAllRunningActions(myRollout, Status.ERROR);
rolloutManagement.handleRollouts(); rolloutManagement.handleRollouts();
percent = rolloutManagement.getFinishedPercentForRunningGroup(myRollout.getId(), percent = rolloutGroupManagement.findRolloutGroupWithDetailedStatus(myRollout.getRolloutGroups().get(1).getId())
myRollout.getRolloutGroups().get(1).getId()); .get().getTotalTargetCountStatus().getFinishedPercent();
assertThat(percent).isEqualTo(80); assertThat(percent).isEqualTo(80);
} }
@@ -1465,7 +1460,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = RolloutUpdatedEvent.class, count = 2), @Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = RolloutUpdatedEvent.class, count = 2),
@Expect(type = RolloutGroupCreatedEvent.class, count = 5), @Expect(type = RolloutGroupCreatedEvent.class, count = 5),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 10) }) @Expect(type = RolloutGroupUpdatedEvent.class, count = 5) })
public void deleteRolloutWhichHasNeverStartedIsHardDeleted() { public void deleteRolloutWhichHasNeverStartedIsHardDeleted() {
final int amountTargetsForRollout = 10; final int amountTargetsForRollout = 10;
final int amountOtherTargets = 15; final int amountOtherTargets = 15;
@@ -1488,7 +1483,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
@ExpectEvents({ @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), @ExpectEvents({ @Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 16), @Expect(type = RolloutGroupUpdatedEvent.class, count = 10),
@Expect(type = RolloutUpdatedEvent.class, count = 6), @Expect(type = RolloutUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1), @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = TargetUpdatedEvent.class, count = 2),

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@@ -192,6 +193,16 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
} }
} }
@Test
@Description("Verify that a target with same controller ID than another device cannot be created.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
public void createTargetThatViolatesUniqueConstraintFails() {
targetManagement.createTarget(entityFactory.target().create().controllerId("123"));
assertThatExceptionOfType(EntityAlreadyExistsException.class)
.isThrownBy(() -> targetManagement.createTarget(entityFactory.target().create().controllerId("123")));
}
@Test @Test
@Description("Verify that a target with whitespaces in controller id cannot be created") @Description("Verify that a target with whitespaces in controller id cannot be created")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) }) @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })

View File

@@ -9,6 +9,7 @@
logging.level.=INFO logging.level.=INFO
logging.level.org.eclipse.persistence=ERROR logging.level.org.eclipse.persistence=ERROR
logging.level.org.eclipse.hawkbit.repository.test.matcher.EventVerifier=ERROR
spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value} spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value}
spring.data.mongodb.port=28017 spring.data.mongodb.port=28017
@@ -22,6 +23,7 @@ hawkbit.server.security.dos.maxAttributeEntriesPerTarget=10
spring.jpa.database=H2 spring.jpa.database=H2
spring.datasource.url=jdbc:h2:mem:sp-db;DB_CLOSE_ON_EXIT=FALSE spring.datasource.url=jdbc:h2:mem:sp-db;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver spring.datasource.driverClassName=org.h2.Driver
spring.datasource.tomcat.default-auto-commit=false
spring.datasource.username=sa spring.datasource.username=sa
spring.datasource.password=sa spring.datasource.password=sa

View File

@@ -23,6 +23,8 @@ import org.junit.Assert;
import org.junit.rules.TestRule; import org.junit.rules.TestRule;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.junit.runners.model.Statement; import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.bus.event.RemoteApplicationEvent; import org.springframework.cloud.bus.event.RemoteApplicationEvent;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
@@ -38,6 +40,7 @@ import com.jayway.awaitility.core.ConditionTimeoutException;
* Test rule to setup and verify the event count for a method. * Test rule to setup and verify the event count for a method.
*/ */
public class EventVerifier implements TestRule { public class EventVerifier implements TestRule {
private static final Logger LOGGER = LoggerFactory.getLogger(EventVerifier.class);
private EventCaptor eventCaptor; private EventCaptor eventCaptor;
@@ -116,6 +119,7 @@ public class EventVerifier implements TestRule {
@Override @Override
public void onApplicationEvent(final RemoteApplicationEvent event) { public void onApplicationEvent(final RemoteApplicationEvent event) {
LOGGER.debug("Received event {}", event.getClass().getSimpleName());
capturedEvents.add(event.getClass()); capturedEvents.add(event.getClass());
} }

View File

@@ -270,7 +270,7 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware {
@Before @Before
public void before() throws Exception { public void before() throws Exception {
mvc = createMvcWebAppContext().build(); mvc = createMvcWebAppContext().build();
final String description = "Updated description to have lastmodified available in tests"; final String description = "Updated description.";
osType = securityRule osType = securityRule
.runAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_OS)); .runAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_OS));

View File

@@ -15,7 +15,6 @@ import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
public class JpaTestRepositoryManagement implements TestRepositoryManagement { public class JpaTestRepositoryManagement implements TestRepositoryManagement {
@@ -45,13 +44,11 @@ public class JpaTestRepositoryManagement implements TestRepositoryManagement {
} }
@Override @Override
@Transactional
public void clearTestRepository() { public void clearTestRepository() {
deleteAllRepos(); deleteAllRepos();
cacheManager.getDirectCacheNames().forEach(name -> cacheManager.getDirectCache(name).clear()); cacheManager.getDirectCacheNames().forEach(name -> cacheManager.getDirectCache(name).clear());
} }
@Transactional
public void deleteAllRepos() { public void deleteAllRepos() {
final List<String> tenants = systemSecurityContext.runAsSystem(() -> systemManagement.findTenants()); final List<String> tenants = systemSecurityContext.runAsSystem(() -> systemManagement.findTenants());
tenants.forEach(tenant -> { tenants.forEach(tenant -> {

View File

@@ -8,11 +8,7 @@
*/ */
package org.eclipse.hawkbit.ui.rollout.rollout; package org.eclipse.hawkbit.ui.rollout.rollout;
import java.util.Set;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData; import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
@@ -30,99 +26,24 @@ public class ProxyRollout {
private String modifiedDate; private String modifiedDate;
private Integer numberOfGroups; private int numberOfGroups;
private Boolean isActionRecieved = Boolean.FALSE; private Boolean isActionRecieved = Boolean.FALSE;
private Boolean isRequiredMigrationStep = Boolean.FALSE;
private String totalTargetsCount; private String totalTargetsCount;
private RolloutRendererData rolloutRendererData; private RolloutRendererData rolloutRendererData;
private String discription;
private String type;
private Set<SoftwareModule> swModules;
private Long id; private Long id;
private String name; private String name;
private String version; private String version;
private String description; private String description;
private DistributionSet distributionSet;
private String createdBy; private String createdBy;
private String lastModifiedBy; private String lastModifiedBy;
private long forcedTime; private long forcedTime;
private RolloutStatus status; private RolloutStatus status;
private TotalTargetCountStatus totalTargetCountStatus; private TotalTargetCountStatus totalTargetCountStatus;
/**
* @return the isRequiredMigrationStep
*/
public Boolean getIsRequiredMigrationStep() {
return isRequiredMigrationStep;
}
/**
* @param isRequiredMigrationStep
* the isRequiredMigrationStep to set
*/
public void setIsRequiredMigrationStep(final Boolean isRequiredMigrationStep) {
this.isRequiredMigrationStep = isRequiredMigrationStep;
}
/**
* @return the discription
*/
public String getDiscription() {
return discription;
}
/**
* @param discription
* the discription to set
*/
public void setDiscription(final String discription) {
this.discription = discription;
}
/**
* @return the type
*/
public String getType() {
return type;
}
/**
* @param type
* the type to set
*/
public void setType(final String type) {
this.type = type;
}
/**
*
* @return the Set of Software modules
*/
public Set<SoftwareModule> getSwModules() {
return swModules;
}
/**
* @param swModules
* Set<SoftwareModule> to set
*/
public void setSwModules(final Set<SoftwareModule> swModules) {
this.swModules = swModules;
}
public RolloutRendererData getRolloutRendererData() { public RolloutRendererData getRolloutRendererData() {
return rolloutRendererData; return rolloutRendererData;
} }
@@ -149,7 +70,7 @@ public class ProxyRollout {
/** /**
* @return the numberOfGroups * @return the numberOfGroups
*/ */
public Integer getNumberOfGroups() { public int getNumberOfGroups() {
return numberOfGroups; return numberOfGroups;
} }
@@ -157,7 +78,7 @@ public class ProxyRollout {
* @param numberOfGroups * @param numberOfGroups
* the numberOfGroups to set * the numberOfGroups to set
*/ */
public void setNumberOfGroups(final Integer numberOfGroups) { public void setNumberOfGroups(final int numberOfGroups) {
this.numberOfGroups = numberOfGroups; this.numberOfGroups = numberOfGroups;
} }
@@ -257,14 +178,6 @@ public class ProxyRollout {
this.description = description; this.description = description;
} }
public DistributionSet getDistributionSet() {
return distributionSet;
}
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = distributionSet;
}
public String getCreatedBy() { public String getCreatedBy() {
return createdBy; return createdBy;
} }

View File

@@ -10,9 +10,9 @@ package org.eclipse.hawkbit.ui.rollout.rollout;
import static org.apache.commons.lang3.ArrayUtils.isEmpty; import static org.apache.commons.lang3.ArrayUtils.isEmpty;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -104,36 +104,30 @@ public class RolloutBeanQuery extends AbstractBeanQuery<ProxyRollout> {
} }
private static List<ProxyRollout> getProxyRolloutList(final Slice<Rollout> rolloutBeans) { private static List<ProxyRollout> getProxyRolloutList(final Slice<Rollout> rolloutBeans) {
final List<ProxyRollout> proxyRolloutList = new ArrayList<>(); return rolloutBeans.getContent().stream().map(RolloutBeanQuery::createProxy).collect(Collectors.toList());
for (final Rollout rollout : rolloutBeans) { }
final ProxyRollout proxyRollout = new ProxyRollout();
proxyRollout.setName(rollout.getName());
proxyRollout.setDescription(rollout.getDescription());
final DistributionSet distributionSet = rollout.getDistributionSet();
proxyRollout.setDistributionSetNameVersion(
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
proxyRollout.setDistributionSet(distributionSet);
proxyRollout.setNumberOfGroups(Integer.valueOf(rollout.getRolloutGroups().size()));
proxyRollout.setCreatedDate(SPDateTimeUtil.getFormattedDate(rollout.getCreatedAt()));
proxyRollout.setModifiedDate(SPDateTimeUtil.getFormattedDate(rollout.getLastModifiedAt()));
proxyRollout.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(rollout));
proxyRollout.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(rollout));
proxyRollout.setForcedTime(rollout.getForcedTime());
proxyRollout.setId(rollout.getId());
proxyRollout.setStatus(rollout.getStatus());
proxyRollout
.setRolloutRendererData(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
final TotalTargetCountStatus totalTargetCountActionStatus = rollout.getTotalTargetCountStatus(); private static ProxyRollout createProxy(final Rollout rollout) {
proxyRollout.setTotalTargetCountStatus(totalTargetCountActionStatus); final ProxyRollout proxyRollout = new ProxyRollout();
proxyRollout.setTotalTargetsCount(String.valueOf(rollout.getTotalTargets())); proxyRollout.setName(rollout.getName());
proxyRollout.setType(distributionSet.getType().getName()); proxyRollout.setDescription(rollout.getDescription());
proxyRollout.setIsRequiredMigrationStep(distributionSet.isRequiredMigrationStep()); final DistributionSet distributionSet = rollout.getDistributionSet();
proxyRollout.setSwModules(distributionSet.getModules()); proxyRollout.setDistributionSetNameVersion(
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
proxyRollout.setNumberOfGroups(rollout.getRolloutGroupsCreated());
proxyRollout.setCreatedDate(SPDateTimeUtil.getFormattedDate(rollout.getCreatedAt()));
proxyRollout.setModifiedDate(SPDateTimeUtil.getFormattedDate(rollout.getLastModifiedAt()));
proxyRollout.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(rollout));
proxyRollout.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(rollout));
proxyRollout.setForcedTime(rollout.getForcedTime());
proxyRollout.setId(rollout.getId());
proxyRollout.setStatus(rollout.getStatus());
proxyRollout.setRolloutRendererData(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
proxyRolloutList.add(proxyRollout); final TotalTargetCountStatus totalTargetCountActionStatus = rollout.getTotalTargetCountStatus();
} proxyRollout.setTotalTargetCountStatus(totalTargetCountActionStatus);
return proxyRolloutList; proxyRollout.setTotalTargetsCount(String.valueOf(rollout.getTotalTargets()));
return proxyRollout;
} }
@Override @Override

View File

@@ -17,7 +17,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
@@ -26,7 +25,6 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status;
import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.SpPermissionChecker;
@@ -84,10 +82,6 @@ public class RolloutListGrid extends AbstractGrid<LazyQueryContainer> {
private static final String DELETE_OPTION = "Delete"; private static final String DELETE_OPTION = "Delete";
private static final String DS_TYPE = "type";
private static final String SW_MODULES = "swModules";
private static final String IS_REQUIRED_MIGRATION_STEP = "isRequiredMigrationStep"; private static final String IS_REQUIRED_MIGRATION_STEP = "isRequiredMigrationStep";
private static final String ROLLOUT_RENDERER_DATA = "rolloutRendererData"; private static final String ROLLOUT_RENDERER_DATA = "rolloutRendererData";
@@ -223,8 +217,6 @@ public class RolloutListGrid extends AbstractGrid<LazyQueryContainer> {
protected void addContainerProperties() { protected void addContainerProperties() {
final LazyQueryContainer rolloutGridContainer = (LazyQueryContainer) getContainerDataSource(); final LazyQueryContainer rolloutGridContainer = (LazyQueryContainer) getContainerDataSource();
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", false, false); rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", false, false);
rolloutGridContainer.addContainerProperty(DS_TYPE, String.class, null, false, false);
rolloutGridContainer.addContainerProperty(SW_MODULES, Set.class, null, false, false);
rolloutGridContainer.addContainerProperty(ROLLOUT_RENDERER_DATA, RolloutRendererData.class, null, false, false); rolloutGridContainer.addContainerProperty(ROLLOUT_RENDERER_DATA, RolloutRendererData.class, null, false, false);
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, null, false, false); rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, null, false, false);
rolloutGridContainer.addContainerProperty(IS_REQUIRED_MIGRATION_STEP, boolean.class, null, false, false); rolloutGridContainer.addContainerProperty(IS_REQUIRED_MIGRATION_STEP, boolean.class, null, false, false);
@@ -307,8 +299,6 @@ public class RolloutListGrid extends AbstractGrid<LazyQueryContainer> {
@Override @Override
protected void setColumnHeaderNames() { protected void setColumnHeaderNames() {
getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.getMessage("header.name")); getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.getMessage("header.name"));
getColumn(DS_TYPE).setHeaderCaption(i18n.getMessage("header.type"));
getColumn(SW_MODULES).setHeaderCaption(i18n.getMessage("header.swmodules"));
getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption(i18n.getMessage("header.migrations.step")); getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption(i18n.getMessage("header.migrations.step"));
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION) getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION)
.setHeaderCaption(i18n.getMessage("header.distributionset")); .setHeaderCaption(i18n.getMessage("header.distributionset"));
@@ -362,8 +352,6 @@ public class RolloutListGrid extends AbstractGrid<LazyQueryContainer> {
final List<Object> columnList = new ArrayList<>(); final List<Object> columnList = new ArrayList<>();
columnList.add(ROLLOUT_RENDERER_DATA); columnList.add(ROLLOUT_RENDERER_DATA);
columnList.add(SPUILabelDefinitions.VAR_DIST_NAME_VERSION); columnList.add(SPUILabelDefinitions.VAR_DIST_NAME_VERSION);
columnList.add(DS_TYPE);
columnList.add(SW_MODULES);
columnList.add(IS_REQUIRED_MIGRATION_STEP); columnList.add(IS_REQUIRED_MIGRATION_STEP);
columnList.add(SPUILabelDefinitions.VAR_STATUS); columnList.add(SPUILabelDefinitions.VAR_STATUS);
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS); columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
@@ -400,8 +388,6 @@ public class RolloutListGrid extends AbstractGrid<LazyQueryContainer> {
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_BY); columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_BY);
columnsToBeHidden.add(SPUILabelDefinitions.VAR_DESC); columnsToBeHidden.add(SPUILabelDefinitions.VAR_DESC);
columnsToBeHidden.add(IS_REQUIRED_MIGRATION_STEP); columnsToBeHidden.add(IS_REQUIRED_MIGRATION_STEP);
columnsToBeHidden.add(DS_TYPE);
columnsToBeHidden.add(SW_MODULES);
for (final Object propertyId : columnsToBeHidden) { for (final Object propertyId : columnsToBeHidden) {
getColumn(propertyId).setHidden(true); getColumn(propertyId).setHidden(true);
} }
@@ -561,51 +547,11 @@ public class RolloutListGrid extends AbstractGrid<LazyQueryContainer> {
description = ((RolloutRendererData) cell.getProperty().getValue()).getName(); description = ((RolloutRendererData) cell.getProperty().getValue()).getName();
} else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) { } else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) {
description = getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap()); description = getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap());
} else if (SPUILabelDefinitions.VAR_DIST_NAME_VERSION.equals(cell.getPropertyId())) {
description = getDSDetails(cell.getItem());
} }
return description; return description;
} }
private static String getDSDetails(final Item rolloutItem) {
final StringBuilder swModuleNames = new StringBuilder();
final StringBuilder swModuleVendors = new StringBuilder();
@SuppressWarnings("unchecked")
final Set<SoftwareModule> swModules = (Set<SoftwareModule>) rolloutItem.getItemProperty(SW_MODULES).getValue();
swModules.forEach(swModule -> {
swModuleNames.append(swModule.getName());
swModuleNames.append(" , ");
swModuleVendors.append(swModule.getVendor());
swModuleVendors.append(" , ");
});
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(HawkbitCommonUtil.HTML_UL_OPEN_TAG);
stringBuilder.append(HawkbitCommonUtil.HTML_LI_OPEN_TAG);
stringBuilder.append(" DistributionSet Description : ")
.append((String) rolloutItem.getItemProperty(SPUILabelDefinitions.VAR_DESC).getValue());
stringBuilder.append(HawkbitCommonUtil.HTML_LI_CLOSE_TAG);
stringBuilder.append(HawkbitCommonUtil.HTML_LI_OPEN_TAG);
stringBuilder.append(" DistributionSet Type : ")
.append((String) rolloutItem.getItemProperty(DS_TYPE).getValue());
stringBuilder.append(HawkbitCommonUtil.HTML_LI_CLOSE_TAG);
stringBuilder.append(HawkbitCommonUtil.HTML_LI_OPEN_TAG);
stringBuilder.append("Required Migration step : ")
.append((boolean) rolloutItem.getItemProperty(IS_REQUIRED_MIGRATION_STEP).getValue() ? "Yes" : "No");
stringBuilder.append(HawkbitCommonUtil.HTML_LI_CLOSE_TAG);
stringBuilder.append(HawkbitCommonUtil.HTML_LI_OPEN_TAG);
stringBuilder.append("SoftWare Modules : ").append(swModuleNames.toString());
stringBuilder.append(HawkbitCommonUtil.HTML_LI_CLOSE_TAG);
stringBuilder.append(HawkbitCommonUtil.HTML_LI_OPEN_TAG);
stringBuilder.append("Vendor(s) : ").append(swModuleVendors.toString());
stringBuilder.append(HawkbitCommonUtil.HTML_LI_CLOSE_TAG);
stringBuilder.append(HawkbitCommonUtil.HTML_UL_CLOSE_TAG);
return stringBuilder.toString();
}
private static class RollouStatusCellStyleGenerator implements CellStyleGenerator { private static class RollouStatusCellStyleGenerator implements CellStyleGenerator {
private static final List<RolloutStatus> DELETE_COPY_BUTTON_ENABLED = Arrays.asList(RolloutStatus.CREATING, private static final List<RolloutStatus> DELETE_COPY_BUTTON_ENABLED = Arrays.asList(RolloutStatus.CREATING,

View File

@@ -15,6 +15,7 @@ import static org.springframework.data.domain.Sort.Direction.DESC;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutManagement;
@@ -113,38 +114,34 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery<ProxyRolloutGroup>
} }
private List<ProxyRolloutGroup> getProxyRolloutGroupList(final List<RolloutGroup> rolloutGroupBeans) { private List<ProxyRolloutGroup> getProxyRolloutGroupList(final List<RolloutGroup> rolloutGroupBeans) {
final List<ProxyRolloutGroup> proxyRolloutGroupsList = new ArrayList<>(); return rolloutGroupBeans.stream().map(RolloutGroupBeanQuery::createProxy).collect(Collectors.toList());
for (final RolloutGroup rolloutGroup : rolloutGroupBeans) {
final ProxyRolloutGroup proxyRolloutGroup = new ProxyRolloutGroup();
proxyRolloutGroup.setName(rolloutGroup.getName());
proxyRolloutGroup.setDescription(rolloutGroup.getDescription());
proxyRolloutGroup.setCreatedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getCreatedAt()));
proxyRolloutGroup.setModifiedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getLastModifiedAt()));
proxyRolloutGroup.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(rolloutGroup));
proxyRolloutGroup.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(rolloutGroup));
proxyRolloutGroup.setId(rolloutGroup.getId());
proxyRolloutGroup.setStatus(rolloutGroup.getStatus());
proxyRolloutGroup.setErrorAction(rolloutGroup.getErrorAction());
proxyRolloutGroup.setErrorActionExp(rolloutGroup.getErrorActionExp());
proxyRolloutGroup.setErrorCondition(rolloutGroup.getErrorCondition());
proxyRolloutGroup.setErrorConditionExp(rolloutGroup.getErrorConditionExp());
proxyRolloutGroup.setSuccessCondition(rolloutGroup.getSuccessCondition());
proxyRolloutGroup.setSuccessConditionExp(rolloutGroup.getSuccessConditionExp());
proxyRolloutGroup.setFinishedPercentage(calculateFinishedPercentage(rolloutGroup));
proxyRolloutGroup.setRolloutRendererData(new RolloutRendererData(rolloutGroup.getName(), null));
proxyRolloutGroup.setTotalTargetsCount(String.valueOf(rolloutGroup.getTotalTargets()));
proxyRolloutGroup.setTotalTargetCountStatus(rolloutGroup.getTotalTargetCountStatus());
proxyRolloutGroupsList.add(proxyRolloutGroup);
}
return proxyRolloutGroupsList;
} }
private String calculateFinishedPercentage(final RolloutGroup rolloutGroup) { private static ProxyRolloutGroup createProxy(final RolloutGroup rolloutGroup) {
return HawkbitCommonUtil.formattingFinishedPercentage(rolloutGroup, getRolloutManagement() final ProxyRolloutGroup proxyRolloutGroup = new ProxyRolloutGroup();
.getFinishedPercentForRunningGroup(rolloutGroup.getRollout().getId(), rolloutGroup.getId())); proxyRolloutGroup.setName(rolloutGroup.getName());
proxyRolloutGroup.setDescription(rolloutGroup.getDescription());
proxyRolloutGroup.setCreatedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getCreatedAt()));
proxyRolloutGroup.setModifiedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getLastModifiedAt()));
proxyRolloutGroup.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(rolloutGroup));
proxyRolloutGroup.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(rolloutGroup));
proxyRolloutGroup.setId(rolloutGroup.getId());
proxyRolloutGroup.setStatus(rolloutGroup.getStatus());
proxyRolloutGroup.setErrorAction(rolloutGroup.getErrorAction());
proxyRolloutGroup.setErrorActionExp(rolloutGroup.getErrorActionExp());
proxyRolloutGroup.setErrorCondition(rolloutGroup.getErrorCondition());
proxyRolloutGroup.setErrorConditionExp(rolloutGroup.getErrorConditionExp());
proxyRolloutGroup.setSuccessCondition(rolloutGroup.getSuccessCondition());
proxyRolloutGroup.setSuccessConditionExp(rolloutGroup.getSuccessConditionExp());
proxyRolloutGroup.setFinishedPercentage(HawkbitCommonUtil.formattingFinishedPercentage(rolloutGroup,
rolloutGroup.getTotalTargetCountStatus().getFinishedPercent()));
proxyRolloutGroup.setRolloutRendererData(new RolloutRendererData(rolloutGroup.getName(), null));
proxyRolloutGroup.setTotalTargetsCount(String.valueOf(rolloutGroup.getTotalTargets()));
proxyRolloutGroup.setTotalTargetCountStatus(rolloutGroup.getTotalTargetCountStatus());
return proxyRolloutGroup;
} }
@Override @Override