Make entities immutable and create proper update methods that state by signature what can be updated. (#342)

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-11-17 20:07:23 +01:00
committed by GitHub
parent b6834e9ee2
commit ca63106d5c
314 changed files with 7699 additions and 6914 deletions

View File

@@ -28,6 +28,11 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
import org.eclipse.hawkbit.repository.jpa.JpaArtifactManagement;
@@ -48,6 +53,11 @@ import org.eclipse.hawkbit.repository.jpa.JpaTenantStatsManagement;
import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignScheduler;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetTypeBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
import org.eclipse.hawkbit.repository.jpa.event.JpaEventEntityManager;
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
@@ -56,6 +66,11 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHol
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParserValidationOracle;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
@@ -102,6 +117,63 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return new RsqlParserValidationOracle();
}
/**
* @param distributionSetManagement
* to loading the {@link DistributionSetType}
* @param softwareManagement
* for loading {@link DistributionSet#getModules()}
* @return DistributionSetBuilder bean
*/
@Bean
public DistributionSetBuilder distributionSetBuilder(final DistributionSetManagement distributionSetManagement,
final SoftwareManagement softwareManagement) {
return new JpaDistributionSetBuilder(distributionSetManagement, softwareManagement);
}
/**
* @param softwareManagement
* for loading
* {@link DistributionSetType#getMandatoryModuleTypes()} and
* {@link DistributionSetType#getOptionalModuleTypes()}
* @return DistributionSetTypeBuilder bean
*/
@Bean
public DistributionSetTypeBuilder distributionSetTypeBuilder(final SoftwareManagement softwareManagement) {
return new JpaDistributionSetTypeBuilder(softwareManagement);
}
/**
* @param softwareManagement
* for loading {@link SoftwareModule#getType()}
* @return SoftwareModuleBuilder bean
*/
@Bean
public SoftwareModuleBuilder softwareModuleBuilder(final SoftwareManagement softwareManagement) {
return new JpaSoftwareModuleBuilder(softwareManagement);
}
/**
* @param distributionSetManagement
* for loading {@link Rollout#getDistributionSet()}
* @return RolloutBuilder bean
*/
@Bean
public RolloutBuilder rolloutBuilder(final DistributionSetManagement distributionSetManagement) {
return new JpaRolloutBuilder(distributionSetManagement);
}
/**
* @param distributionSetManagement
* for loading
* {@link TargetFilterQuery#getAutoAssignDistributionSet()}
* @return TargetFilterQueryBuilder bean
*/
@Bean
public TargetFilterQueryBuilder targetFilterQueryBuilder(
final DistributionSetManagement distributionSetManagement) {
return new JpaTargetFilterQueryBuilder(distributionSetManagement);
}
/**
* @return the {@link SystemSecurityContext} singleton bean which make it
* accessible in beans which cannot access the service directly,

View File

@@ -26,7 +26,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@@ -95,7 +94,9 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
/**
* Retrieves the oldest {@link Action} that is active and referring to the
* given {@link Target}.
*
*
* @param sort
* order
* @param target
* the target to find assigned actions
* @param active
@@ -107,7 +108,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
Optional<Action> findFirstByTargetAndActive(final Sort sort, final JpaTarget target, boolean active);
/**
* Retrieves latest {@link UpdateAction} for given target and
* Retrieves latest {@link Action} for given target and
* {@link SoftwareModule}.
*
* @param targetId
@@ -122,7 +123,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
@Param("module") JpaSoftwareModule module);
/**
* Retrieves all {@link UpdateAction}s which are referring the given
* Retrieves all {@link Action}s which are referring the given
* {@link DistributionSet} and {@link Target}.
*
* @param pageable
@@ -131,10 +132,10 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* is the assigned target
* @param ds
* the {@link DistributionSet} on which will be filtered
* @return the found {@link UpdateAction}s
* @return the found {@link Action}s
*/
@Query("Select a from JpaAction a where a.target = :target and a.distributionSet = :ds order by a.id")
Page<Action> findByTargetAndDistributionSet(final Pageable pageable, @Param("target") final JpaTarget target,
Page<JpaAction> findByTargetAndDistributionSet(final Pageable pageable, @Param("target") final JpaTarget target,
@Param("ds") JpaDistributionSet ds);
/**
@@ -146,24 +147,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* @return a list of actions according to the searched target
*/
@Query("Select a from JpaAction a where a.target = :target order by a.id")
List<Action> findByTarget(@Param("target") JpaTarget target);
/**
* Retrieves all {@link Action}s of a specific target and given active flag
* ordered by action ID.
*
* @param pageable
* the pagination parameter
* @param target
* to search for
* @param active
* {@code true} for all actions which are currently active,
* {@code false} for inactive
* @return a paged list of actions ordered by action ID
*/
@Query("Select a from JpaAction a where a.target = :target and a.active= :active order by a.id")
Page<Action> findByActiveAndTarget(Pageable pageable, @Param("target") JpaTarget target,
@Param("active") boolean active);
List<JpaAction> findByTarget(@Param("target") Target target);
/**
* Retrieves all {@link Action}s of a specific target and given active flag
@@ -181,20 +165,6 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
@Query("Select a from JpaAction a where a.target = :target and a.active= :active order by a.id")
List<Action> findByActiveAndTarget(@Param("target") JpaTarget target, @Param("active") boolean active);
/**
* Updates all {@link Action} to inactive for all targets with given ID.
*
* @param keySet
* the list of actions to set inactive
* @param targetsIds
* the IDs of the targets according to the action to set in
* active
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE JpaAction a SET a.active = false WHERE a IN :keySet AND a.target IN :targetsIds")
void setToInactive(@Param("keySet") List<JpaAction> keySet, @Param("targetsIds") List<Long> targetsIds);
/**
* Switches the status of actions from one specific status into another,
* only if the actions are in a specific status. This should be a atomar
@@ -215,26 +185,6 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List<Long> targetIds,
@Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus);
/**
* Switches the status of actions from one specific status into another,
* only if the actions are in a specific status. This should be a atomar
* operation.
*
* @param statusToSet
* the new status the actions should get
* @param rollout
* the rollout of the actions which are affected
* @param active
* the active flag of the actions which should be affected
* @param currentStatus
* the current status of the actions which are affected
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.rollout = :rollout AND a.active = :active AND a.status = :currentStatus")
void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("rollout") JpaRollout rollout,
@Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus);
/**
*
* Retrieves all {@link Action}s which are active and referring to the given
@@ -259,14 +209,6 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
*/
Long countByTarget(JpaTarget target);
@Override
@CacheEvict(value = "feedbackReceivedOverTime", allEntries = true)
<S extends JpaAction> List<S> save(Iterable<S> entities);
@Override
@CacheEvict(value = "feedbackReceivedOverTime", allEntries = true)
<S extends JpaAction> S save(S entity);
/**
* Counts all {@link Action}s referring to the given DistributionSet.
*
@@ -276,15 +218,6 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
*/
Long countByDistributionSet(JpaDistributionSet distributionSet);
/**
* Counts all {@link Action}s referring to the given rollout.
*
* @param rollout
* the rollout to count the {@link Action}s from
* @return the count of actions referring to the given rollout
*/
Long countByRollout(JpaRollout rollout);
/**
* Counts all actions referring to a given rollout and rolloutgroup which
* are currently not in the given status. An in-clause statement does not
@@ -367,22 +300,6 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
Page<Action> findByRolloutAndRolloutGroupParentIsNullAndStatus(Pageable pageable, JpaRollout rollout,
Status actionStatus);
/**
* Retrieving all actions referring to a given rollout group with a specific
* a specific status.
*
* @param rollout
* the rollout the actions belong to
* @param rolloutGroupParent
* the parent rollout group the actions should reference
* @param actionStatus
* the status the actions have
* @return the actions ids referring a specific rollout group and a specific
* status
*/
List<Long> findByRolloutAndRolloutGroupAndStatus(JpaRollout rollout,
JpaRolloutGroup rolloutGroupParent, Status actionStatus);
/**
* Retrieves all actions for a specific rollout and in a specific status.
*

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -39,18 +38,6 @@ public interface ActionStatusRepository
*/
Long countByAction(JpaAction action);
/**
* Counts {@link ActionStatus} entries of given {@link Action} with given
* {@link Status} in repository.
*
* @param action
* to count status entries
* @param status
* to filter for
* @return number of actions in repository
*/
Long countByActionAndStatus(JpaAction action, Status status);
/**
* Retrieves all {@link ActionStatus} entries from repository of given
* {@link Action}.

View File

@@ -14,7 +14,6 @@ import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
@@ -71,7 +70,7 @@ public final class DeploymentHelper {
* the action which is set to canceled
* @param actionRepository
* for the operation
* @param targetManagement
* @param targetRepository
* for the operation
* @param entityManager
* for the operation
@@ -79,7 +78,7 @@ public final class DeploymentHelper {
* for the operation
*/
static void successCancellation(final JpaAction action, final ActionRepository actionRepository,
final TargetManagement targetManagement, final TargetInfoRepository targetInfoRepository,
final TargetRepository targetRepository, final TargetInfoRepository targetInfoRepository,
final EntityManager entityManager) {
// set action inactive
@@ -96,7 +95,8 @@ public final class DeploymentHelper {
} else {
target.setAssignedDistributionSet(nextActiveActions.get(0).getDistributionSet());
}
targetManagement.updateTarget(target);
target.setNew(false);
targetRepository.save(target);
}
}

View File

@@ -57,9 +57,6 @@ public interface DistributionSetRepository
@Query("update JpaDistributionSet d set d.deleted = 1 where d.id in :ids")
void deleteDistributionSet(@Param("ids") Long... ids);
@Override
List<JpaDistributionSet> findAll(Iterable<Long> ids);
/**
* deletes {@link DistributionSet}s by the given IDs.
*
@@ -81,7 +78,7 @@ public interface DistributionSetRepository
* to search for
* @return {@link List} of found {@link DistributionSet}s
*/
List<DistributionSet> findByModules(JpaSoftwareModule module);
Long countByModules(JpaSoftwareModule module);
/**
* Finds {@link DistributionSet}s based on given ID that are assigned yet to
@@ -105,19 +102,6 @@ public interface DistributionSetRepository
@Query("select ra.distributionSet.id from JpaRollout ra where ra.distributionSet.id in :ids")
List<Long> findAssignedToRolloutDistributionSetsById(@Param("ids") Long... ids);
/**
* Saves all given {@link DistributionSet}s.
*
* @param entities
* @return the saved entities
* @throws IllegalArgumentException
* in case the given entity is (@literal null}.
*
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
*/
@Override
<S extends JpaDistributionSet> List<S> save(Iterable<S> entities);
/**
* Finds the distribution set for a specific action.
*

View File

@@ -53,7 +53,4 @@ public interface DistributionSetTagRepository
*/
@Override
List<JpaDistributionSetTag> findAll();
@Override
<S extends JpaDistributionSetTag> List<S> save(Iterable<S> entities);
}

View File

@@ -16,7 +16,6 @@ import javax.persistence.Query;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
@@ -48,7 +47,6 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
public <S extends JpaTargetInfo> S save(final S entity) {
if (entity.isNew()) {

View File

@@ -196,15 +196,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
final boolean overrideExisting) {
return createArtifact(inputStream, moduleId, filename, null, null, overrideExisting, null);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Artifact createArtifact(final InputStream inputStream, final Long moduleId, final String filename,
final boolean overrideExisting, final String contentType) {
return createArtifact(inputStream, moduleId, filename, null, null, overrideExisting, contentType);
}
@Override
public Long countArtifactsAll() {
return localArtifactRepository.count();

View File

@@ -19,14 +19,19 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus_;
@@ -108,12 +113,18 @@ public class JpaControllerManagement implements ControllerManagement {
@Autowired
private SystemSecurityContext systemSecurityContext;
@Autowired
private EntityFactory entityFactory;
@Autowired
private ApplicationEventPublisher eventPublisher;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private AfterTransactionCommitExecutor afterCommit;
@Override
public String getPollingTime() {
final TenantConfigurationKey configurationKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
@@ -170,11 +181,6 @@ public class JpaControllerManagement implements ControllerManagement {
return actionRepository.count(ActionSpecifications.hasTargetAssignedArtifact(target, localArtifact)) > 0;
}
@Override
public List<Action> findActiveActionByTarget(final Target target) {
return actionRepository.findByTargetAndActiveOrderByIdAsc((JpaTarget) target, true);
}
@Override
public Optional<Action> findOldestActiveActionByTarget(final Target target) {
// used in favorite to findFirstByTargetAndActiveOrderByIdAsc due to
@@ -184,7 +190,7 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
public Action findActionWithDetails(final Long actionId) {
return actionRepository.findById(actionId);
return getActionAndThrowExceptionIfNotFound(actionId);
}
@Override
@@ -194,14 +200,13 @@ public class JpaControllerManagement implements ControllerManagement {
final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb
.equal(targetRoot.get(JpaTarget_.controllerId), controllerId);
JpaTarget target = targetRepository.findOne(spec);
final JpaTarget target = targetRepository.findOne(spec);
if (target == null) {
target = new JpaTarget(controllerId);
target.setDescription("Plug and Play target: " + controllerId);
target.setName(controllerId);
return targetManagement.createTarget(target, TargetUpdateStatus.REGISTERED, System.currentTimeMillis(),
address);
return targetManagement.createTarget(entityFactory.target().create().controllerId(controllerId)
.description("Plug and Play target: " + controllerId).name(controllerId)
.status(TargetUpdateStatus.REGISTERED).lastTargetQuery(System.currentTimeMillis())
.address(Optional.ofNullable(address).map(URI::toString).orElse(null)));
}
return updateLastTargetQuery(target.getTargetInfo(), address).getTarget();
@@ -225,6 +230,8 @@ public class JpaControllerManagement implements ControllerManagement {
if (mtargetInfo.getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
mtargetInfo.setUpdateStatus(TargetUpdateStatus.REGISTERED);
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetUpdatedEvent(mtargetInfo.getTarget(), applicationContext.getId())));
}
return targetInfoRepository.save(mtargetInfo);
@@ -233,8 +240,11 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public Action addCancelActionStatus(final ActionStatus actionStatus) {
final JpaAction action = (JpaAction) actionStatus.getAction();
public Action addCancelActionStatus(final ActionStatusCreate c) {
final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId());
final JpaActionStatus actionStatus = create.build();
checkForToManyStatusEntries(action);
action.setStatus(actionStatus.getStatus());
@@ -254,27 +264,28 @@ public class JpaControllerManagement implements ControllerManagement {
default:
// do nothing
}
actionRepository.save(action);
actionStatusRepository.save((JpaActionStatus) actionStatus);
actionStatus.setAction(actionRepository.save(action));
actionStatusRepository.save(actionStatus);
return action;
}
private void handleFinishedCancelation(final ActionStatus actionStatus, final JpaAction action) {
private void handleFinishedCancelation(final JpaActionStatus actionStatus, final JpaAction action) {
// in case of successful cancellation we also report the success at
// the canceled action itself.
actionStatus.addMessage(
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Cancellation completion is finished sucessfully.");
DeploymentHelper.successCancellation(action, actionRepository, targetManagement, targetInfoRepository,
DeploymentHelper.successCancellation(action, actionRepository, targetRepository, targetInfoRepository,
entityManager);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public Action addUpdateActionStatus(final ActionStatus actionStatus) {
final Action action = actionStatus.getAction();
final Long actionId = action.getId();
public Action addUpdateActionStatus(final ActionStatusCreate c) {
final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId());
final JpaActionStatus actionStatus = create.build();
// if action is already closed we accept further status updates if
// permitted so by configuration. This is especially useful if the
@@ -283,10 +294,10 @@ public class JpaControllerManagement implements ControllerManagement {
// close messages.
if (actionIsNotActiveButIntermediateFeedbackStillAllowed(actionStatus, action.isActive())) {
LOG.debug("Update of actionStatus {} for action {} not possible since action not active anymore.",
actionStatus.getStatus(), actionId);
actionStatus.getStatus(), action.getId());
return action;
}
return handleAddUpdateActionStatus((JpaActionStatus) actionStatus, actionId);
return handleAddUpdateActionStatus(actionStatus, action);
}
private boolean actionIsNotActiveButIntermediateFeedbackStillAllowed(final ActionStatus actionStatus,
@@ -302,10 +313,9 @@ public class JpaControllerManagement implements ControllerManagement {
* @param action
* @return
*/
private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final Long actionId) {
LOG.debug("addUpdateActionStatus for action {}", actionId);
private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final JpaAction action) {
LOG.debug("addUpdateActionStatus for action {}", action.getId());
final JpaAction action = actionRepository.findById(actionId);
JpaTarget target = (JpaTarget) action.getTarget();
// check for a potential DOS attack
checkForToManyStatusEntries(action);
@@ -326,10 +336,13 @@ public class JpaControllerManagement implements ControllerManagement {
break;
}
actionStatus.setAction(action);
actionStatusRepository.save(actionStatus);
LOG.debug("addUpdateActionStatus {} for target {} is finished.", action, target.getId());
action.setStatus(actionStatus.getStatus());
return actionRepository.save(action);
}
@@ -337,7 +350,9 @@ public class JpaControllerManagement implements ControllerManagement {
mergedAction.setActive(false);
mergedAction.setStatus(Status.ERROR);
mergedTarget.setAssignedDistributionSet(null);
targetManagement.updateTarget(mergedTarget);
mergedTarget.setNew(false);
targetRepository.save(mergedTarget);
}
private void checkForToManyStatusEntries(final JpaAction action) {
@@ -372,6 +387,10 @@ public class JpaControllerManagement implements ControllerManagement {
}
targetInfoRepository.save(targetInfo);
afterCommit.afterCommit(
() -> eventPublisher.publishEvent(new TargetUpdatedEvent(target, applicationContext.getId())));
entityManager.detach(ds);
}
@@ -398,7 +417,13 @@ public class JpaControllerManagement implements ControllerManagement {
targetInfo.setLastTargetQuery(System.currentTimeMillis());
targetInfo.setRequestControllerAttributes(false);
return targetRepository.save(target);
final Target result = targetInfoRepository.save(targetInfo).getTarget();
afterCommit.afterCommit(
() -> eventPublisher.publishEvent(new TargetUpdatedEvent(result, applicationContext.getId())));
return result;
}
@Override
@@ -464,8 +489,20 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public ActionStatus addInformationalActionStatus(final ActionStatus statusMessage) {
return actionStatusRepository.save((JpaActionStatus) statusMessage);
public ActionStatus addInformationalActionStatus(final ActionStatusCreate c) {
final JpaActionStatusCreate create = (JpaActionStatusCreate) c;
final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId());
final JpaActionStatus statusMessage = create.build();
statusMessage.setAction(action);
checkForToManyStatusEntries(action);
return actionStatusRepository.save(statusMessage);
}
private JpaAction getActionAndThrowExceptionIfNotFound(final Long actionId) {
return Optional.ofNullable(actionRepository.findById(actionId))
.orElseThrow(() -> new EntityNotFoundException("Action with ID " + actionId + " not found!"));
}
@Override

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -34,6 +33,7 @@ import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
@@ -72,7 +72,6 @@ import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.AuditorAware;
@@ -147,45 +146,21 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Autowired
private PlatformTransactionManager txManager;
@Override
@Transactional(isolation = Isolation.READ_COMMITTED)
@Modifying
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final DistributionSet pset,
final List<Target> targets) {
return assignDistributionSetByTargetId((JpaDistributionSet) pset,
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()),
ActionType.FORCED, org.eclipse.hawkbit.repository.model.RepositoryModelConstants.NO_FORCE_TIME);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, final String... targetIDs) {
return assignDistributionSet(dsID, ActionType.FORCED,
org.eclipse.hawkbit.repository.model.RepositoryModelConstants.NO_FORCE_TIME, targetIDs);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
// Exception squid:S2095: see
// https://jira.sonarsource.com/browse/SONARJAVA-1478
@SuppressWarnings({ "squid:S2095" })
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID, final ActionType actionType,
final long forcedTimestamp, final String... targetIDs) {
return assignDistributionSet(dsID, Arrays.stream(targetIDs)
final long forcedTimestamp, final Collection<String> targetIDs) {
return assignDistributionSet(dsID, targetIDs.stream()
.map(t -> new TargetWithActionType(t, actionType, forcedTimestamp)).collect(Collectors.toList()));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets) {
return assignDistributionSet(dsID, targets, null);
@@ -194,7 +169,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets, final String actionMessage) {
final JpaDistributionSet set = distributoinSetRepository.findOne(dsID);
@@ -209,7 +183,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets, final Rollout rollout, final RolloutGroup rolloutGroup) {
final JpaDistributionSet set = distributoinSetRepository.findOne(dsID);
@@ -250,13 +223,13 @@ public class JpaDeploymentManagement implements DeploymentManagement {
"Distribution set of type " + set.getType().getKey() + " is incomplete: " + set.getId());
}
final List<String> controllerIDs = targetsWithActionType.stream().map(TargetWithActionType::getTargetId)
final List<String> controllerIDs = targetsWithActionType.stream().map(TargetWithActionType::getControllerId)
.collect(Collectors.toList());
LOG.debug("assignDistribution({}) to {} targets", set, controllerIDs.size());
final Map<String, TargetWithActionType> targetsWithActionMap = targetsWithActionType.stream()
.collect(Collectors.toMap(TargetWithActionType::getTargetId, Function.identity()));
.collect(Collectors.toMap(TargetWithActionType::getControllerId, Function.identity()));
// split tIDs length into max entries in-statement because many database
// have constraint of max entries in in-statements e.g. Oracle with
@@ -302,10 +275,9 @@ public class JpaDeploymentManagement implements DeploymentManagement {
targetIds.forEach(tIds -> targetRepository.setAssignedDistributionSet(set, System.currentTimeMillis(),
currentUser, tIds));
targetIds.forEach(tIds -> targetInfoRepository.setTargetUpdateStatus(TargetUpdateStatus.PENDING, tIds));
final Map<String, JpaAction> targetIdsToActions = actionRepository
.save(targets.stream().map(t -> createTargetAction(targetsWithActionMap, t, set, rollout, rolloutGroup))
.collect(Collectors.toList()))
.stream().collect(Collectors.toMap(a -> a.getTarget().getControllerId(), Function.identity()));
final Map<String, JpaAction> targetIdsToActions = targets.stream().map(
t -> actionRepository.save(createTargetAction(targetsWithActionMap, t, set, rollout, rolloutGroup)))
.collect(Collectors.toMap(a -> a.getTarget().getControllerId(), Function.identity()));
// create initial action status when action is created so we remember
// the initial running status because we will change the status
@@ -317,7 +289,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
entityManager.flush();
// collect updated target and actions IDs in order to return them
final DistributionSetAssignmentResult result = new DistributionSetAssignmentResult(
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()), targets.size(),
targets.stream().map(Target::getControllerId).collect(Collectors.toList()), targets.size(),
controllerIDs.size() - targets.size(),
targetIdsToActions.values().stream().map(Action::getId).collect(Collectors.toList()), targetManagement);
@@ -356,6 +328,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
private void assignDistributionSetEvent(final Action action) {
((JpaTargetInfo) action.getTarget().getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetUpdatedEvent(action.getTarget(), applicationContext.getId())));
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetAssignDistributionSetEvent(action, applicationContext.getId())));
}
@@ -374,22 +348,20 @@ public class JpaDeploymentManagement implements DeploymentManagement {
final List<JpaAction> activeActions = actionRepository
.findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep(targetsIds,
Action.Status.CANCELING);
final Set<Long> cancelledTargetIds = activeActions.stream().map(action -> {
return activeActions.stream().map(action -> {
action.setStatus(Status.CANCELING);
// document that the status has been retrieved
actionStatusRepository.save(new JpaActionStatus(action, Status.CANCELING, System.currentTimeMillis(),
"manual cancelation requested"));
actionRepository.save(action);
cancelAssignDistributionSetEvent(action.getTarget(), action.getId());
return action.getTarget().getId();
}).collect(Collectors.toSet());
actionRepository.save(activeActions);
return cancelledTargetIds;
}
private DistributionSetAssignmentResult assignDistributionSetByTargetId(@NotNull final JpaDistributionSet set,
@@ -463,7 +435,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
actionStatusRepository.save(new JpaActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(),
"A force quit has been performed."));
DeploymentHelper.successCancellation(mergedAction, actionRepository, targetManagement, targetInfoRepository,
DeploymentHelper.successCancellation(mergedAction, actionRepository, targetRepository, targetInfoRepository,
entityManager);
return actionRepository.save(mergedAction);
@@ -528,9 +500,9 @@ public class JpaDeploymentManagement implements DeploymentManagement {
private Page<Action> findActionsByRolloutAndRolloutGroupParent(final Rollout rollout,
final RolloutGroup rolloutGroupParent, final int limit) {
JpaRollout jpaRollout = (JpaRollout) rollout;
JpaRolloutGroup jpaRolloutGroup = (JpaRolloutGroup) rolloutGroupParent;
PageRequest pageRequest = new PageRequest(0, limit);
final JpaRollout jpaRollout = (JpaRollout) rollout;
final JpaRolloutGroup jpaRolloutGroup = (JpaRolloutGroup) rolloutGroupParent;
final PageRequest pageRequest = new PageRequest(0, limit);
if (rolloutGroupParent == null) {
return actionRepository.findByRolloutAndRolloutGroupParentIsNullAndStatus(pageRequest, jpaRollout,
Action.Status.SCHEDULED);
@@ -624,7 +596,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
public List<Action> findActionsByTarget(final Target target) {
return actionRepository.findByTarget((JpaTarget) target);
return Collections.unmodifiableList(actionRepository.findByTarget(target));
}
@Override
@@ -673,11 +645,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return actionRepository.findByTarget(pageable, (JpaTarget) foundTarget);
}
@Override
public Page<Action> findActiveActionsByTarget(final Pageable pageable, final Target target) {
return actionRepository.findByActiveAndTarget(pageable, (JpaTarget) target, true);
}
@Override
public List<Action> findActiveActionsByTarget(final Target target) {
return actionRepository.findByActiveAndTarget((JpaTarget) target, true);
@@ -688,11 +655,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return actionRepository.findByActiveAndTarget((JpaTarget) target, false);
}
@Override
public Page<Action> findInActiveActionsByTarget(final Pageable pageable, final Target target) {
return actionRepository.findByActiveAndTarget(pageable, (JpaTarget) target, false);
}
@Override
public Long countActionsByTarget(final Target target) {
return actionRepository.countByTarget((JpaTarget) target);

View File

@@ -8,30 +8,34 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.DistributionSetFields;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
import org.eclipse.hawkbit.repository.DistributionSetTypeFields;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.builder.DistributionSetUpdate;
import org.eclipse.hawkbit.repository.builder.GenericDistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.builder.GenericDistributionSetUpdate;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityLockedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -40,8 +44,9 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
@@ -53,7 +58,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.MetaData;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -117,6 +123,12 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@Autowired
private SoftwareModuleRepository softwareModuleRepository;
@Autowired
private SoftwareModuleTypeRepository softwareModuleTypeRepository;
@Override
public DistributionSet findDistributionSetByIdWithDetails(final Long distid) {
return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid));
@@ -149,10 +161,14 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0,
toBeChangedDSs.size(), Collections.emptyList(),
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag);
Collections.unmodifiableList(
toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())),
myTag);
} else {
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(),
0, Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)),
0,
Collections.unmodifiableList(
toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())),
Collections.emptyList(), myTag);
}
@@ -168,11 +184,68 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet updateDistributionSet(final DistributionSet ds) {
checkNotNull(ds.getId());
final DistributionSet persisted = findDistributionSetByIdWithDetails(ds.getId());
checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, persisted.getModules());
return distributionSetRepository.save((JpaDistributionSet) ds);
public DistributionSet updateDistributionSet(final DistributionSetUpdate u) {
final GenericDistributionSetUpdate update = (GenericDistributionSetUpdate) u;
final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(update.getId());
update.getName().ifPresent(set::setName);
update.getDescription().ifPresent(set::setDescription);
update.getVersion().ifPresent(set::setVersion);
if (update.isRequiredMigrationStep() != null
&& !update.isRequiredMigrationStep().equals(set.isRequiredMigrationStep())) {
checkDistributionSetIsAssignedToTargets(set);
set.setRequiredMigrationStep(update.isRequiredMigrationStep());
}
if (update.getType() != null) {
final DistributionSetType type = findDistributionSetTypeWithExceptionIfNotFound(update.getType());
if (!type.getId().equals(set.getType().getId())) {
checkDistributionSetIsAssignedToTargets(set);
set.setType(type);
}
}
return distributionSetRepository.save(set);
}
private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final String distributionSetTypekey) {
final DistributionSetType module = findDistributionSetTypeByKey(distributionSetTypekey);
if (module == null) {
throw new EntityNotFoundException(
"DistributionSetType with key {" + distributionSetTypekey + "} does not exist");
}
return module;
}
private JpaDistributionSetType findDistributionSetTypeAndThrowExceptionIfNotFound(final Long setId) {
final JpaDistributionSetType set = (JpaDistributionSetType) findDistributionSetTypeById(setId);
if (set == null) {
throw new EntityNotFoundException("Distribution set type cannot be updated as it does not exixt" + setId);
}
return set;
}
private JpaDistributionSet findDistributionSetAndThrowExceptionIfNotFound(final Long setId) {
final JpaDistributionSet set = (JpaDistributionSet) findDistributionSetByIdWithDetails(setId);
if (set == null) {
throw new EntityNotFoundException("Distribution set cannot be updated as it does not exixt" + setId);
}
return set;
}
private JpaSoftwareModule findSoftwareModuleAndThrowExceptionIfNotFound(final Long moduleId) {
final JpaSoftwareModule module = softwareModuleRepository.findOne(moduleId);
if (module == null) {
throw new EntityNotFoundException("Distribution set cannot be updated as it does not exixt" + moduleId);
}
return module;
}
@Override
@@ -208,87 +281,155 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet createDistributionSet(final DistributionSet dSet) {
prepareDsSave(dSet);
if (dSet.getType() == null) {
dSet.setType(systemManagement.getTenantMetadata().getDefaultDsType());
public DistributionSet createDistributionSet(final DistributionSetCreate c) {
final JpaDistributionSetCreate create = (JpaDistributionSetCreate) c;
if (create.getType() == null) {
create.type(systemManagement.getTenantMetadata().getDefaultDsType().getKey());
}
return distributionSetRepository.save((JpaDistributionSet) dSet);
}
private void prepareDsSave(final DistributionSet dSet) {
if (dSet.getId() != null) {
throw new EntityAlreadyExistsException("Parameter seems to be an existing, already persisted entity");
}
final JpaDistributionSet dSet = 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
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> createDistributionSets(final Collection<DistributionSet> distributionSets) {
for (final DistributionSet ds : distributionSets) {
prepareDsSave(ds);
if (ds.getType() == null) {
ds.setType(systemManagement.getTenantMetadata().getDefaultDsType());
}
public List<DistributionSet> createDistributionSets(final Collection<DistributionSetCreate> creates) {
return creates.stream().map(this::createDistributionSet).collect(Collectors.toList());
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet assignSoftwareModules(final Long setId, final Collection<Long> moduleIds) {
final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId);
final Collection<JpaSoftwareModule> modules = softwareModuleRepository.findByIdIn(moduleIds);
if (modules.size() < moduleIds.size()) {
throw new EntityNotFoundException("Not all given software modules where found.");
}
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaDistributionSet> toSave = (Collection) distributionSets;
checkDistributionSetIsAssignedToTargets(set);
return Collections.unmodifiableList(distributionSetRepository.save(toSave));
modules.forEach(set::addModule);
return distributionSetRepository.save(set);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet assignSoftwareModules(final DistributionSet ds, final Set<SoftwareModule> softwareModules) {
checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, softwareModules);
for (final SoftwareModule softwareModule : softwareModules) {
ds.addModule(softwareModule);
}
return distributionSetRepository.save((JpaDistributionSet) ds);
public DistributionSet unassignSoftwareModule(final Long setId, final Long moduleId) {
final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId);
final JpaSoftwareModule module = findSoftwareModuleAndThrowExceptionIfNotFound(moduleId);
checkDistributionSetIsAssignedToTargets(set);
set.removeModule(module);
return distributionSetRepository.save(set);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet unassignSoftwareModule(final DistributionSet ds, final SoftwareModule softwareModule) {
final Set<SoftwareModule> softwareModules = new HashSet<>();
softwareModules.add(softwareModule);
ds.removeModule(softwareModule);
checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, softwareModules);
return distributionSetRepository.save((JpaDistributionSet) ds);
}
public DistributionSetType updateDistributionSetType(final DistributionSetTypeUpdate u) {
final GenericDistributionSetTypeUpdate update = (GenericDistributionSetTypeUpdate) u;
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType updateDistributionSetType(final DistributionSetType dsType) {
checkNotNull(dsType.getId());
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(update.getId());
final JpaDistributionSetType persisted = distributionSetTypeRepository.findOne(dsType.getId());
update.getDescription().ifPresent(type::setDescription);
update.getColour().ifPresent(type::setColour);
// throw exception if user tries to update a DS type that is already in
// use
if (!persisted.areModuleEntriesIdentical(dsType) && distributionSetRepository.countByType(persisted) > 0) {
throw new EntityReadOnlyException(
String.format("distribution set type %s set is already assigned to targets and cannot be changed",
dsType.getName()));
if (hasModules(update)) {
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
update.getMandatory().ifPresent(
mand -> softwareModuleTypeRepository.findByIdIn(mand).forEach(type::addMandatoryModuleType));
update.getOptional().ifPresent(
opt -> softwareModuleTypeRepository.findByIdIn(opt).forEach(type::addOptionalModuleType));
}
return distributionSetTypeRepository.save((JpaDistributionSetType) dsType);
return distributionSetTypeRepository.save(type);
}
private static boolean hasModules(final GenericDistributionSetTypeUpdate update) {
return update.getOptional().isPresent() || update.getMandatory().isPresent();
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType assignMandatorySoftwareModuleTypes(final Long dsTypeId,
final Collection<Long> softwareModulesTypeIds) {
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId);
final Collection<JpaSoftwareModuleType> modules = softwareModuleTypeRepository
.findByIdIn(softwareModulesTypeIds);
if (modules.size() < softwareModulesTypeIds.size()) {
throw new EntityNotFoundException("Not all given software module types where found.");
}
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
modules.forEach(type::addMandatoryModuleType);
return distributionSetTypeRepository.save(type);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType assignOptionalSoftwareModuleTypes(final Long dsTypeId,
final Collection<Long> softwareModulesTypeIds) {
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId);
final Collection<JpaSoftwareModuleType> modules = softwareModuleTypeRepository
.findByIdIn(softwareModulesTypeIds);
if (modules.size() < softwareModulesTypeIds.size()) {
throw new EntityNotFoundException("Not all given software module types where found.");
}
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
modules.forEach(type::addOptionalModuleType);
return distributionSetTypeRepository.save(type);
}
private void checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(final JpaDistributionSetType type) {
if (distributionSetRepository.countByType(type) > 0) {
throw new EntityReadOnlyException(String.format(
"distribution set type %s is already assigned to distribution sets and cannot be changed",
type.getName()));
}
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType unassignSoftwareModuleType(final Long dsTypeId, final Long softwareModuleTypeId) {
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId);
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
type.removeModuleType(softwareModuleTypeId);
return distributionSetTypeRepository.save(type);
}
@Override
public Page<DistributionSetType> findDistributionSetTypesAll(final String rsqlParam, final Pageable pageable) {
final Specification<JpaDistributionSetType> spec = RSQLUtility.parse(rsqlParam,
DistributionSetTypeFields.class, virtualPropertyReplacer);
final Specification<JpaDistributionSetType> spec = RSQLUtility.parse(rsqlParam, DistributionSetTypeFields.class,
virtualPropertyReplacer);
return convertDsTPage(distributionSetTypeRepository.findAll(spec, pageable));
}
@@ -452,12 +593,10 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetType createDistributionSetType(final DistributionSetType type) {
if (type.getId() != null) {
throw new EntityAlreadyExistsException("Given type contains an Id!");
}
public DistributionSetType createDistributionSetType(final DistributionSetTypeCreate c) {
final JpaDistributionSetTypeCreate create = (JpaDistributionSetTypeCreate) c;
return distributionSetTypeRepository.save((JpaDistributionSetType) type);
return distributionSetTypeRepository.save(create.build());
}
@Override
@@ -478,70 +617,60 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public DistributionSetMetadata createDistributionSetMetadata(final DistributionSetMetadata md) {
final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) md;
public List<DistributionSetMetadata> createDistributionSetMetadata(final Long dsId, final Collection<MetaData> md) {
if (distributionSetMetadataRepository.exists(metadata.getId())) {
throwMetadataKeyAlreadyExists(metadata.getId().getKey());
}
md.forEach(meta -> checkAndThrowAlreadyIfDistributionSetMetadataExists(
new DsMetadataCompositeKey(dsId, meta.getKey())));
touch(metadata.getDistributionSet());
return distributionSetMetadataRepository.save(metadata);
final JpaDistributionSet set = touch(dsId);
return Collections.unmodifiableList(md.stream()
.map(meta -> distributionSetMetadataRepository
.save(new JpaDistributionSetMetadata(meta.getKey(), set, meta.getValue())))
.collect(Collectors.toList()));
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public List<DistributionSetMetadata> createDistributionSetMetadata(final Collection<DistributionSetMetadata> md) {
@SuppressWarnings({ "rawtypes", "unchecked" })
final Collection<JpaDistributionSetMetadata> metadata = (Collection) md;
for (final JpaDistributionSetMetadata distributionSetMetadata : metadata) {
checkAndThrowAlreadyIfDistributionSetMetadataExists(distributionSetMetadata.getId());
}
metadata.forEach(m -> touch(m.getDistributionSet()));
return new ArrayList<>(
(Collection<? extends DistributionSetMetadata>) distributionSetMetadataRepository.save(metadata));
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public DistributionSetMetadata updateDistributionSetMetadata(final DistributionSetMetadata md) {
final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) md;
public DistributionSetMetadata updateDistributionSetMetadata(final Long dsId, final MetaData md) {
// check if exists otherwise throw entity not found exception
findOne(metadata.getDistributionSet(), metadata.getKey());
final JpaDistributionSetMetadata toUpdate = (JpaDistributionSetMetadata) findDistributionSetMetadata(dsId,
md.getKey());
toUpdate.setValue(md.getValue());
// touch it to update the lock revision because we are modifying the
// DS indirectly
touch(metadata.getDistributionSet());
return distributionSetMetadataRepository.save(metadata);
touch(dsId);
return distributionSetMetadataRepository.save(toUpdate);
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) {
public void deleteDistributionSetMetadata(final Long distributionSet, final String key) {
touch(distributionSet);
distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key));
}
/**
* Method to get the latest distribution set based on ds ID after the
* Method to get the latest distribution set based on DS ID after the
* metadata changes for that distribution set.
*
* @param distributionSet
* @param distId
* Distribution set
*/
private void touch(final DistributionSet distributionSet) {
final DistributionSet latestDistributionSet = findDistributionSetById(distributionSet.getId());
private JpaDistributionSet touch(final Long distId) {
final DistributionSet latestDistributionSet = findDistributionSetAndThrowExceptionIfNotFound(distId);
// merge base distribution set so optLockRevision gets updated and audit
// log written because
// modifying metadata is modifying the base distribution set itself for
// auditing purposes.
entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L);
final JpaDistributionSet result = entityManager.merge((JpaDistributionSet) latestDistributionSet);
result.setLastModifiedAt(0L);
return result;
}
@Override
@@ -584,7 +713,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
@Override
public DistributionSetMetadata findOne(final DistributionSet distributionSet, final String key) {
public DistributionSetMetadata findDistributionSetMetadata(final Long distributionSet, final String key) {
final DistributionSetMetadata findOne = distributionSetMetadataRepository
.findOne(new DsMetadataCompositeKey(distributionSet, key));
if (findOne == null) {
@@ -605,7 +734,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private static List<Specification<JpaDistributionSet>> buildDistributionSetSpecifications(
final DistributionSetFilter distributionSetFilter) {
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(7);
final List<Specification<JpaDistributionSet>> specList = Lists.newArrayListWithExpectedSize(7);
Specification<JpaDistributionSet> spec;
@@ -645,28 +774,20 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return specList;
}
private void checkDistributionSetSoftwareModulesIsAllowedToModify(final JpaDistributionSet distributionSet,
final Set<SoftwareModule> softwareModules) {
if (!new HashSet<SoftwareModule>(distributionSet.getModules()).equals(softwareModules)
&& actionRepository.countByDistributionSet(distributionSet) > 0) {
throw new EntityLockedException(
private void checkDistributionSetIsAssignedToTargets(final JpaDistributionSet distributionSet) {
if (actionRepository.countByDistributionSet(distributionSet) > 0) {
throw new EntityReadOnlyException(
String.format("distribution set %s:%s is already assigned to targets and cannot be changed",
distributionSet.getName(), distributionSet.getVersion()));
}
}
private static Boolean isDSWithNoTagSelected(final DistributionSetFilter distributionSetFilter) {
if (distributionSetFilter.getSelectDSWithNoTag() != null && distributionSetFilter.getSelectDSWithNoTag()) {
return true;
}
return false;
return distributionSetFilter.getSelectDSWithNoTag() != null && distributionSetFilter.getSelectDSWithNoTag();
}
private static Boolean isTagsSelected(final DistributionSetFilter distributionSetFilter) {
if (distributionSetFilter.getTagNames() != null && !distributionSetFilter.getTagNames().isEmpty()) {
return true;
}
return false;
return !CollectionUtils.isEmpty(distributionSetFilter.getTagNames());
}
/**
@@ -696,10 +817,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
}
private static void throwMetadataKeyAlreadyExists(final String metadataKey) {
throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists");
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@@ -708,7 +825,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
allDs.forEach(ds -> ds.addTag(tag));
return Collections.unmodifiableList(distributionSetRepository.save(allDs));
return Collections
.unmodifiableList(allDs.stream().map(distributionSetRepository::save).collect(Collectors.toList()));
}
@Override
@@ -734,13 +852,15 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private List<JpaDistributionSet> unAssignTag(final Collection<JpaDistributionSet> distributionSets,
final DistributionSetTag tag) {
distributionSets.forEach(ds -> ds.removeTag(tag));
return distributionSetRepository.save(distributionSets);
return Collections.unmodifiableList(
distributionSets.stream().map(distributionSetRepository::save).collect(Collectors.toList()));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSetType> createDistributionSetTypes(final Collection<DistributionSetType> types) {
public List<DistributionSetType> createDistributionSetTypes(final Collection<DistributionSetTypeCreate> types) {
return types.stream().map(this::createDistributionSetType).collect(Collectors.toList());
}
@@ -756,11 +876,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<DistributionSet> sets,
final DistributionSetTag tag) {
return toggleTagAssignment(sets.stream().map(ds -> ds.getId()).collect(Collectors.toList()), tag.getName());
return toggleTagAssignment(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()),
tag.getName());
}
@Override
public Long countDistributionSetsByType(final DistributionSetType type) {
return distributionSetRepository.countByType((JpaDistributionSetType) type);
}
}

View File

@@ -8,41 +8,25 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeBuilder;
import org.eclipse.hawkbit.repository.builder.TagBuilder;
import org.eclipse.hawkbit.repository.builder.TargetBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleTypeBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetBuilder;
import org.eclipse.hawkbit.repository.jpa.model.JpaMetaData;
import org.eclipse.hawkbit.repository.model.MetaData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
/**
@@ -52,177 +36,74 @@ import org.springframework.validation.annotation.Validated;
@Validated
public class JpaEntityFactory implements EntityFactory {
@Autowired
private DistributionSetBuilder distributionSetBuilder;
@Autowired
private DistributionSetTypeBuilder distributionSetTypeBuilder;
@Autowired
private SoftwareModuleBuilder softwareModuleBuilder;
@Autowired
private RolloutBuilder rolloutBuilder;
@Autowired
private TargetFilterQueryBuilder targetFilterQueryBuilder;
@Override
public DistributionSetType generateDistributionSetType() {
return new JpaDistributionSetType();
public MetaData generateMetadata(final String key, final String value) {
return new JpaMetaData(key, value);
}
@Override
public DistributionSet generateDistributionSet() {
return new JpaDistributionSet();
public DistributionSetTypeBuilder distributionSetType() {
return distributionSetTypeBuilder;
}
@Override
public DistributionSetMetadata generateDistributionSetMetadata() {
return new JpaDistributionSetMetadata();
public DistributionSetBuilder distributionSet() {
return distributionSetBuilder;
}
@Override
public DistributionSetMetadata generateDistributionSetMetadata(final DistributionSet distributionSet,
final String key, final String value) {
return new JpaDistributionSetMetadata(key, distributionSet, value);
public TargetBuilder target() {
return new JpaTargetBuilder();
}
@Override
public DistributionSetType generateDistributionSetType(final String key, final String name,
final String description) {
return new JpaDistributionSetType(key, name, description);
public TagBuilder tag() {
return new JpaTagBuilder();
}
@Override
public DistributionSet generateDistributionSet(final String name, final String version, final String description,
final DistributionSetType type, final Collection<SoftwareModule> moduleList) {
return new JpaDistributionSet(name, version, description, type, moduleList);
public TargetFilterQueryBuilder targetFilterQuery() {
return targetFilterQueryBuilder;
}
@Override
public Target generateTarget(final String controllerId) {
return new JpaTarget(controllerId);
public SoftwareModuleBuilder softwareModule() {
return softwareModuleBuilder;
}
@Override
public Target generateTarget(final String controllerId, final String securityToken) {
if (StringUtils.isEmpty(securityToken)) {
return new JpaTarget(controllerId);
}
return new JpaTarget(controllerId, securityToken);
public SoftwareModuleTypeBuilder softwareModuleType() {
return new JpaSoftwareModuleTypeBuilder();
}
@Override
public TargetTag generateTargetTag() {
return new JpaTargetTag();
public ActionStatusBuilder actionStatus() {
return new JpaActionStatusBuilder();
}
@Override
public DistributionSetTag generateDistributionSetTag() {
return new JpaDistributionSetTag();
public RolloutBuilder rollout() {
return rolloutBuilder;
}
@Override
public TargetTag generateTargetTag(final String name, final String description, final String colour) {
return new JpaTargetTag(name, description, colour);
}
@Override
public DistributionSetTag generateDistributionSetTag(final String name, final String description,
final String colour) {
return new JpaDistributionSetTag(name, description, colour);
}
@Override
public TargetTag generateTargetTag(final String name) {
return new JpaTargetTag(name);
}
@Override
public DistributionSetTag generateDistributionSetTag(final String name) {
return new JpaDistributionSetTag(name);
}
@Override
public TargetFilterQuery generateTargetFilterQuery() {
return new JpaTargetFilterQuery();
}
@Override
public TargetFilterQuery generateTargetFilterQuery(final String name, final String query) {
return new JpaTargetFilterQuery(name, query);
}
@Override
public TargetFilterQuery generateTargetFilterQuery(final String name, final String query,
final DistributionSet autoAssignDS) {
return new JpaTargetFilterQuery(name, query, (JpaDistributionSet) autoAssignDS);
}
@Override
public SoftwareModuleType generateSoftwareModuleType() {
return new JpaSoftwareModuleType();
}
@Override
public SoftwareModule generateSoftwareModule() {
return new JpaSoftwareModule();
}
@Override
public SoftwareModule generateSoftwareModule(final SoftwareModuleType type, final String name, final String version,
final String description, final String vendor) {
return new JpaSoftwareModule(type, name, version, description, vendor);
}
@Override
public SoftwareModuleMetadata generateSoftwareModuleMetadata() {
return new JpaSoftwareModuleMetadata();
}
@Override
public SoftwareModuleMetadata generateSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key,
final String value) {
return new JpaSoftwareModuleMetadata(key, softwareModule, value);
}
@Override
public SoftwareModuleType generateSoftwareModuleType(final String key, final String name, final String description,
final int maxAssignments) {
return new JpaSoftwareModuleType(key, name, description, maxAssignments);
}
@Override
public Rollout generateRollout() {
return new JpaRollout();
}
@Override
public RolloutGroup generateRolloutGroup() {
return new JpaRolloutGroup();
}
@Override
public Action generateAction() {
return new JpaAction();
}
@Override
public ActionStatus generateActionStatus() {
return new JpaActionStatus();
}
@Override
public ActionStatus generateActionStatus(final Action action, final Status status, final Long occurredAt,
final String message) {
return new JpaActionStatus((JpaAction) action, status, occurredAt, message);
}
@Override
public ActionStatus generateActionStatus(final Action action, final Status status, final Long occurredAt,
final Collection<String> messages) {
final ActionStatus result = new JpaActionStatus((JpaAction) action, status, occurredAt, null);
messages.forEach(result::addMessage);
return result;
}
@Override
public ActionStatus generateActionStatus(final Action action, final Status status, final Long occurredAt) {
return new JpaActionStatus(action, status, occurredAt);
}
@Override
public Artifact generateArtifact() {
return new JpaArtifact();
public RolloutGroupBuilder rolloutGroup() {
return new JpaRolloutGroupBuilder();
}
}

View File

@@ -118,7 +118,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
final Map<Long, List<TotalTargetCountActionStatus>> allStatesForRollout = getStatusCountItemForRolloutGroup(
rolloutGroupIds);
for (final RolloutGroup rolloutGroup : rolloutGroups) {
for (final JpaRolloutGroup rolloutGroup : rolloutGroups) {
final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(
allStatesForRollout.get(rolloutGroup.getId()), Long.valueOf(rolloutGroup.getTotalTargets()));
rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus);
@@ -129,7 +129,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
@Override
public RolloutGroup findRolloutGroupWithDetailedStatus(final Long rolloutGroupId) {
final RolloutGroup rolloutGroup = findRolloutGroupById(rolloutGroupId);
final JpaRolloutGroup rolloutGroup = (JpaRolloutGroup) findRolloutGroupById(rolloutGroupId);
final List<TotalTargetCountActionStatus> rolloutStatusCountItems = actionRepository
.getStatusCountByRolloutGroupId(rolloutGroupId);

View File

@@ -11,9 +11,12 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.validation.ConstraintDeclarationException;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.DeploymentManagement;
@@ -21,10 +24,14 @@ import org.eclipse.hawkbit.repository.RolloutFields;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.builder.GenericRolloutUpdate;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.builder.RolloutUpdate;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.repository.exception.ConstraintViolationException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.exception.RolloutVerificationException;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
@@ -69,7 +76,6 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
/**
@@ -81,7 +87,8 @@ public class JpaRolloutManagement implements RolloutManagement {
private static final Logger LOGGER = LoggerFactory.getLogger(RolloutManagement.class);
/**
* Maximum amount of targets that are assigned to a Rollout Group in one transaction.
* Maximum amount of targets that are assigned to a Rollout Group in one
* transaction.
*/
private static final long TRANSACTION_TARGETS = 1000;
@@ -159,33 +166,32 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public Rollout createRollout(final Rollout rollout, final int amountGroup,
public Rollout createRollout(final RolloutCreate rollout, final int amountGroup,
final RolloutGroupConditions conditions) {
RolloutHelper.verifyRolloutGroupParameter(amountGroup);
final JpaRollout savedRollout = createRollout((JpaRollout) rollout);
final JpaRollout savedRollout = createRollout((JpaRollout) rollout.build());
return createRolloutGroups(amountGroup, conditions, savedRollout);
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public Rollout createRollout(final Rollout rollout,
final List<RolloutGroup> groups,
final RolloutGroupConditions conditions) {
public Rollout createRollout(final RolloutCreate rollout, final List<RolloutGroupCreate> groups,
final RolloutGroupConditions conditions) {
RolloutHelper.verifyRolloutGroupParameter(groups.size());
final JpaRollout savedRollout = createRollout((JpaRollout) rollout);
final JpaRollout savedRollout = createRollout((JpaRollout) rollout.build());
return createRolloutGroups(groups, conditions, savedRollout);
}
private JpaRollout createRollout(final JpaRollout rollout) {
JpaRollout existingRollout = rolloutRepository.findByName(rollout.getName());
if(existingRollout != null) {
final JpaRollout existingRollout = rolloutRepository.findByName(rollout.getName());
if (existingRollout != null) {
throw new EntityAlreadyExistsException(existingRollout.getName());
}
final Long totalTargets = targetManagement.countTargetByTargetFilterQuery(rollout.getTargetFilterQuery());
if(totalTargets == 0) {
throw new RolloutVerificationException("Rollout does not match any existing targets");
if (totalTargets == 0) {
throw new ConstraintViolationException("Rollout does not match any existing targets");
}
rollout.setTotalTargets(totalTargets);
return rolloutRepository.save(rollout);
@@ -231,14 +237,14 @@ public class JpaRolloutManagement implements RolloutManagement {
return rolloutRepository.save(savedRollout);
}
private Rollout createRolloutGroups(final List<RolloutGroup> groupList, final RolloutGroupConditions conditions,
final Rollout rollout) {
private Rollout createRolloutGroups(final List<RolloutGroupCreate> groupList,
final RolloutGroupConditions conditions, final Rollout rollout) {
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.CREATING);
final JpaRollout savedRollout = (JpaRollout) rollout;
// Preparing the groups
final List<RolloutGroup> groups = groupList.stream().map(
group -> RolloutHelper.prepareRolloutGroupWithDefaultConditions(group, conditions))
final List<RolloutGroup> groups = groupList.stream()
.map(group -> RolloutHelper.prepareRolloutGroupWithDefaultConditions(group, conditions))
.collect(Collectors.toList());
groups.forEach(RolloutHelper::verifyRolloutGroupHasConditions);
@@ -289,14 +295,16 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void fillRolloutGroupsWithTargets(final Rollout rollout) {
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.CREATING);
final JpaRollout jpaRollout = (JpaRollout) rollout;
public void fillRolloutGroupsWithTargets(final Long rolloutId) {
final JpaRollout rollout = Optional.ofNullable(rolloutRepository.findOne(rolloutId))
.orElseThrow(() -> new EntityNotFoundException("Rollout with id " + rolloutId + " not found."));
List<RolloutGroup> rolloutGroups = RolloutHelper.getOrderedGroups(rollout);
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.CREATING);
final List<RolloutGroup> rolloutGroups = RolloutHelper.getOrderedGroups(rollout);
int readyGroups = 0;
int totalTargets = 0;
for (RolloutGroup group : rolloutGroups) {
for (final RolloutGroup group : rolloutGroups) {
if (group.getStatus() != RolloutGroupStatus.CREATING) {
readyGroups++;
totalTargets += group.getTotalTargets();
@@ -304,25 +312,26 @@ public class JpaRolloutManagement implements RolloutManagement {
}
final RolloutGroup filledGroup = fillRolloutGroupWithTargets(rollout, group);
if(filledGroup.getStatus() == RolloutGroupStatus.READY) {
if (filledGroup.getStatus() == RolloutGroupStatus.READY) {
readyGroups++;
totalTargets += filledGroup.getTotalTargets();
}
}
// When all groups are ready the rollout status can be changed to be ready, too.
if(readyGroups == rolloutGroups.size()) {
jpaRollout.setStatus(RolloutStatus.READY);
jpaRollout.setLastCheck(0);
jpaRollout.setTotalTargets(totalTargets);
rolloutRepository.save(jpaRollout);
// When all groups are ready the rollout status can be changed to be
// ready, too.
if (readyGroups == rolloutGroups.size()) {
rollout.setStatus(RolloutStatus.READY);
rollout.setLastCheck(0);
rollout.setTotalTargets(totalTargets);
rolloutRepository.save(rollout);
}
}
private RolloutGroup fillRolloutGroupWithTargets(final Rollout rollout, final RolloutGroup group1) {
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.CREATING);
JpaRolloutGroup group = (JpaRolloutGroup) group1;
final JpaRolloutGroup group = (JpaRolloutGroup) group1;
final String baseFilter = RolloutHelper.getTargetFilterQuery(rollout);
final String groupTargetFilter;
@@ -361,13 +370,13 @@ public class JpaRolloutManagement implements RolloutManagement {
group.setTotalTargets(rolloutTargetGroupRepository.countByRolloutGroup(group).intValue());
return rolloutGroupRepository.save(group);
} catch (TransactionException e) {
} catch (final TransactionException e) {
LOGGER.warn("Transaction assigning Targets to RolloutGroup failed", e);
return group;
}
}
private Long runInNewCountingTransaction(final String transactionName, TransactionCallback<Long> action) {
private Long runInNewCountingTransaction(final String transactionName, final TransactionCallback<Long> action) {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName(transactionName);
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
@@ -381,8 +390,8 @@ public class JpaRolloutManagement implements RolloutManagement {
final PageRequest pageRequest = new PageRequest(0, Math.toIntExact(limit));
final List<RolloutGroup> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout,
RolloutGroupStatus.READY, group);
Page<Target> targets = targetManagement.findAllTargetsByTargetFilterQueryAndNotInRolloutGroups(pageRequest,
readyGroups, targetFilter);
final Page<Target> targets = targetManagement
.findAllTargetsByTargetFilterQueryAndNotInRolloutGroups(pageRequest, readyGroups, targetFilter);
createAssignmentOfTargetsToGroup(targets, group);
@@ -398,7 +407,7 @@ public class JpaRolloutManagement implements RolloutManagement {
final String baseFilter = RolloutHelper.getTargetFilterQuery(rollout);
final long totalTargets = targetManagement.countTargetByTargetFilterQuery(baseFilter);
if (totalTargets == 0) {
throw new RolloutVerificationException("Rollout target filter does not match any targets");
throw new ConstraintDeclarationException("Rollout target filter does not match any targets");
}
long targetCount = totalTargets;
@@ -412,7 +421,8 @@ public class JpaRolloutManagement implements RolloutManagement {
final long overlappingTargets = countOverlappingTargetsWithPreviousGroups(baseFilter, groups, group, i);
final long realTargetsInGroup;
// Assume that targets which were not used in the previous groups are used in this group
// Assume that targets which were not used in the previous groups
// are used in this group
if (overlappingTargets > 0 && unusedTargetsCount > 0) {
realTargetsInGroup = targetsInGroupFilter - overlappingTargets + unusedTargetsCount;
unusedTargetsCount = 0;
@@ -435,15 +445,14 @@ public class JpaRolloutManagement implements RolloutManagement {
if (StringUtils.isEmpty(group.getTargetFilterQuery())) {
return baseFilterCount;
} else {
return targetManagement
.countTargetByTargetFilterQuery(baseFilter + ";" + group.getTargetFilterQuery());
return targetManagement.countTargetByTargetFilterQuery(baseFilter + ";" + group.getTargetFilterQuery());
}
}
private long countOverlappingTargetsWithPreviousGroups(final String baseFilter, final List<RolloutGroup> groups,
final RolloutGroup group, final int groupIndex) {
// there can't be overlapping targets in the first group
if(groupIndex == 0) {
if (groupIndex == 0) {
return 0;
}
final List<RolloutGroup> previousGroups = groups.subList(0, groupIndex);
@@ -536,7 +545,7 @@ public class JpaRolloutManagement implements RolloutManagement {
totalActionsCreated += actionsCreated;
} while (actionsCreated > 0);
} catch (TransactionException e) {
} catch (final TransactionException e) {
LOGGER.warn("Transaction assigning Targets to RolloutGroup failed", e);
return 0;
}
@@ -553,7 +562,7 @@ public class JpaRolloutManagement implements RolloutManagement {
final ActionType actionType = rollout.getActionType();
final long forceTime = rollout.getForcedTime();
Page<Target> targets = targetManagement.findAllTargetsInRolloutGroupWithoutAction(pageRequest, group);
final Page<Target> targets = targetManagement.findAllTargetsInRolloutGroupWithoutAction(pageRequest, group);
if (targets.getTotalElements() > 0) {
deploymentManagement.createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime,
rollout, group);
@@ -759,19 +768,19 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void checkCreatingRollouts(long delayBetweenChecks) {
public void checkCreatingRollouts(final long delayBetweenChecks) {
final long lastCheck = System.currentTimeMillis();
final int updated = rolloutRepository.updateLastCheck(lastCheck, delayBetweenChecks, RolloutStatus.CREATING);
if (updated == 0) {
// nothing to check, maybe another instance already checked in
// between
LOGGER.debug("No rollouts creating check necessary for current scheduled check {}, next check at {}", lastCheck,
lastCheck + delayBetweenChecks);
LOGGER.debug("No rollouts creating check necessary for current scheduled check {}, next check at {}",
lastCheck, lastCheck + delayBetweenChecks);
return;
}
final List<JpaRollout> rolloutsToCheck = rolloutRepository.findByLastCheckAndStatus(lastCheck,
RolloutStatus.CREATING);
final List<Long> rolloutsToCheck = rolloutRepository.findByLastCheckAndStatus(lastCheck, RolloutStatus.CREATING)
.stream().map(Rollout::getId).collect(Collectors.toList());
LOGGER.info("Found {} creating rollouts to check", rolloutsToCheck.size());
rolloutsToCheck.forEach(this::fillRolloutGroupsWithTargets);
@@ -781,14 +790,14 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void checkStartingRollouts(long delayBetweenChecks) {
public void checkStartingRollouts(final long delayBetweenChecks) {
final long lastCheck = System.currentTimeMillis();
final int updated = rolloutRepository.updateLastCheck(lastCheck, delayBetweenChecks, RolloutStatus.STARTING);
if (updated == 0) {
// nothing to check, maybe another instance already checked in
// between
LOGGER.debug("No rollouts starting check necessary for current scheduled check {}, next check at {}", lastCheck,
lastCheck + delayBetweenChecks);
LOGGER.debug("No rollouts starting check necessary for current scheduled check {}, next check at {}",
lastCheck, lastCheck + delayBetweenChecks);
return;
}
@@ -797,7 +806,7 @@ public class JpaRolloutManagement implements RolloutManagement {
LOGGER.info("Found {} starting rollouts to check", rolloutsToCheck.size());
rolloutsToCheck.forEach(rollout -> {
if(ensureAllGroupsAreScheduled(rollout)) {
if (ensureAllGroupsAreScheduled(rollout)) {
startFirstRolloutGroup(rollout);
}
});
@@ -837,31 +846,20 @@ public class JpaRolloutManagement implements RolloutManagement {
return rolloutRepository.findByName(rolloutName);
}
/**
* Update rollout details.
*
* @param rollout
* rollout to be updated
*
* @return Rollout updated rollout
*/
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public Rollout updateRollout(final Rollout rollout) {
Assert.notNull(rollout.getId());
return rolloutRepository.save((JpaRollout) rollout);
public Rollout updateRollout(final RolloutUpdate u) {
final GenericRolloutUpdate update = (GenericRolloutUpdate) u;
final JpaRollout rollout = Optional.ofNullable(rolloutRepository.findOne(update.getId()))
.orElseThrow(() -> new EntityNotFoundException("Rollout with id " + update.getId() + " not found."));
update.getName().ifPresent(rollout::setName);
update.getDescription().ifPresent(rollout::setDescription);
return rolloutRepository.save(rollout);
}
/**
* Get count of targets in different status in rollout.
*
* @param pageable
* the page request to sort and limit the result
* @return a list of rollouts with details of targets count for different
* statuses
*
*/
@Override
public Page<Rollout> findAllRolloutsWithDetailedStatus(final Pageable pageable) {
final Page<JpaRollout> rollouts = rolloutRepository.findAll(pageable);

View File

@@ -8,15 +8,13 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -34,8 +32,16 @@ import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields;
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleTypeUpdate;
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleTypeCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
@@ -50,6 +56,7 @@ import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.MetaData;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -113,80 +120,65 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModule updateSoftwareModule(final SoftwareModule sm) {
checkNotNull(sm.getId());
public SoftwareModule updateSoftwareModule(final SoftwareModuleUpdate u) {
final GenericSoftwareModuleUpdate update = (GenericSoftwareModuleUpdate) u;
final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId());
final JpaSoftwareModule module = Optional.ofNullable(softwareModuleRepository.findOne(update.getId()))
.orElseThrow(() -> new EntityNotFoundException(
"Software module cannot be updated as it does not exixt" + update.getId()));
boolean updated = false;
if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) {
module.setDescription(sm.getDescription());
updated = true;
}
if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) {
module.setVendor(sm.getVendor());
updated = true;
}
update.getDescription().ifPresent(module::setDescription);
update.getVendor().ifPresent(module::setVendor);
return updated ? softwareModuleRepository.save(module) : module;
return softwareModuleRepository.save(module);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) {
checkNotNull(sm.getId());
public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleTypeUpdate u) {
final GenericSoftwareModuleTypeUpdate update = (GenericSoftwareModuleTypeUpdate) u;
final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId());
final JpaSoftwareModuleType type = findSoftwareModuleTypeAndThrowExceptionIfNotFound(update.getId());
boolean updated = false;
if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) {
type.setDescription(sm.getDescription());
updated = true;
update.getDescription().ifPresent(type::setDescription);
update.getColour().ifPresent(type::setColour);
return softwareModuleTypeRepository.save(type);
}
private JpaSoftwareModuleType findSoftwareModuleTypeAndThrowExceptionIfNotFound(final Long smTypeid) {
final JpaSoftwareModuleType set = softwareModuleTypeRepository.findOne(smTypeid);
if (set == null) {
throw new EntityNotFoundException("Software module type cannot be updated as it does not exixt" + smTypeid);
}
if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) {
type.setColour(sm.getColour());
updated = true;
}
return updated ? softwareModuleTypeRepository.save(type) : type;
return set;
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModule createSoftwareModule(final SoftwareModule swModule) {
if (null != swModule.getId()) {
throw new EntityAlreadyExistsException();
}
return softwareModuleRepository.save((JpaSoftwareModule) swModule);
public SoftwareModule createSoftwareModule(final SoftwareModuleCreate c) {
final JpaSoftwareModuleCreate create = (JpaSoftwareModuleCreate) c;
return softwareModuleRepository.save(create.build());
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<SoftwareModule> createSoftwareModule(final Collection<SoftwareModule> swModules) {
swModules.forEach(swModule -> {
if (null != swModule.getId()) {
throw new EntityAlreadyExistsException();
}
});
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaSoftwareModule> jpaCast = (Collection) swModules;
return Collections.unmodifiableList(softwareModuleRepository.save(jpaCast));
public List<SoftwareModule> createSoftwareModule(final Collection<SoftwareModuleCreate> swModules) {
return swModules.stream().map(this::createSoftwareModule).collect(Collectors.toList());
}
@Override
public Slice<SoftwareModule> findSoftwareModulesByType(final Pageable pageable, final Long typeId) {
final List<Specification<JpaSoftwareModule>> specList = new LinkedList<>();
final List<Specification<JpaSoftwareModule>> specList = Lists.newArrayListWithExpectedSize(2);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.equalType(typeId);
specList.add(spec);
spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
specList.add(SoftwareModuleSpecification.equalType(typeId));
specList.add(SoftwareModuleSpecification.isDeletedFalse());
return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable);
}
@@ -218,7 +210,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
private boolean isUnassigned(final JpaSoftwareModule bsmMerged) {
return distributionSetRepository.findByModules(bsmMerged).isEmpty();
return distributionSetRepository.countByModules(bsmMerged) <= 0;
}
private Slice<JpaSoftwareModule> findSwModuleByCriteriaAPI(final Pageable pageable,
@@ -423,7 +415,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private static List<Specification<JpaSoftwareModule>> buildSpecificationList(final String searchText,
final Long typeId) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(3);
final List<Specification<JpaSoftwareModule>> specList = Lists.newArrayListWithExpectedSize(3);
if (!Strings.isNullOrEmpty(searchText)) {
specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText));
}
@@ -491,12 +483,10 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) {
if (type.getId() != null) {
throw new EntityAlreadyExistsException("Given type contains an Id!");
}
public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleTypeCreate c) {
final JpaSoftwareModuleTypeCreate create = (JpaSoftwareModuleTypeCreate) c;
return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type);
return softwareModuleTypeRepository.save(create.build());
}
@Override
@@ -523,53 +513,74 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md;
public SoftwareModuleMetadata createSoftwareModuleMetadata(final Long moduleId, final MetaData md) {
if (softwareModuleMetadataRepository.exists(metadata.getId())) {
throwMetadataKeyAlreadyExists(metadata.getId().getKey());
checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, md);
return softwareModuleMetadataRepository
.save(new JpaSoftwareModuleMetadata(md.getKey(), touch(moduleId), md.getValue()));
}
private void checkAndThrowAlreadyIfSoftwareModuleMetadataExists(final Long moduleId, final MetaData md) {
if (softwareModuleMetadataRepository.exists(new SwMetadataCompositeKey(moduleId, md.getKey()))) {
throwMetadataKeyAlreadyExists(md.getKey());
}
// merge base software module so optLockRevision gets updated and audit
// log written because
// modifying metadata is modifying the base software module itself for
// auditing purposes.
entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L);
return softwareModuleMetadataRepository.save(metadata);
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public List<SoftwareModuleMetadata> createSoftwareModuleMetadata(final Collection<SoftwareModuleMetadata> md) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaSoftwareModuleMetadata> metadata = (Collection) md;
public List<SoftwareModuleMetadata> createSoftwareModuleMetadata(final Long moduleId,
final Collection<MetaData> md) {
md.forEach(meta -> checkAndThrowAlreadyIfSoftwareModuleMetadataExists(moduleId, meta));
for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) {
checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId());
}
metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L));
return Collections.unmodifiableList(softwareModuleMetadataRepository.save(metadata));
final JpaSoftwareModule module = touch(moduleId);
return Collections.unmodifiableList(md.stream()
.map(meta -> softwareModuleMetadataRepository
.save(new JpaSoftwareModuleMetadata(meta.getKey(), module, meta.getValue())))
.collect(Collectors.toList()));
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md;
public SoftwareModuleMetadata updateSoftwareModuleMetadata(final Long moduleId, final MetaData md) {
// check if exists otherwise throw entity not found exception
findSoftwareModuleMetadata(metadata.getId());
// touch it to update the lock revision because we are modifying the
// software module
// indirectly
entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L);
final JpaSoftwareModuleMetadata metadata = findSoftwareModuleMetadata(
new SwMetadataCompositeKey(moduleId, md.getKey()));
metadata.setValue(md.getValue());
touch(moduleId);
return softwareModuleMetadataRepository.save(metadata);
}
/**
* Method to get the latest module based on ID after the metadata changes
* for that module.
*
* @param distributionSet
* Distribution set
*/
private JpaSoftwareModule touch(final Long moduleId) {
final JpaSoftwareModule latestModule = softwareModuleRepository.findOne(moduleId);
// merge base distribution set so optLockRevision gets updated and audit
// log written because
// modifying metadata is modifying the base distribution set itself for
// auditing purposes.
final JpaSoftwareModule result = entityManager.merge(latestModule);
result.setLastModifiedAt(0L);
return result;
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void deleteSoftwareModuleMetadata(final Long moduleId, final String key) {
touch(moduleId);
softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(moduleId, key));
}
@@ -609,8 +620,8 @@ public class JpaSoftwareManagement implements SoftwareManagement {
return findSoftwareModuleMetadata(new SwMetadataCompositeKey(moduleId, key));
}
private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) {
final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id);
private JpaSoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) {
final JpaSoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id);
if (findOne == null) {
throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist");
}
@@ -638,9 +649,13 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<SoftwareModuleType> createSoftwareModuleType(final Collection<SoftwareModuleType> types) {
public List<SoftwareModuleType> createSoftwareModuleType(final Collection<SoftwareModuleTypeCreate> creates) {
return creates.stream().map(this::createSoftwareModuleType).collect(Collectors.toList());
}
return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList());
@Override
public List<SoftwareModuleType> findSoftwareModuleTypesById(final Collection<Long> ids) {
return Collections.unmodifiableList(softwareModuleTypeRepository.findByIdIn(ids));
}
}

View File

@@ -18,7 +18,6 @@ import org.eclipse.hawkbit.cache.TenancyCacheManager;
import org.eclipse.hawkbit.repository.Constants;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
@@ -205,7 +204,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
@Override
public List<String> findTenants() {
return tenantMetaDataRepository.findAll().stream().map(md -> md.getTenant()).collect(Collectors.toList());
return tenantMetaDataRepository.findAll().stream().map(TenantMetaData::getTenant).collect(Collectors.toList());
}
@Override
@@ -270,12 +269,12 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public TenantMetaData updateTenantMetadata(final TenantMetaData metaData) {
if (!tenantMetaDataRepository.exists(metaData.getId())) {
throw new EntityNotFoundException("Metadata does not exist: " + metaData.getId());
}
public TenantMetaData updateTenantMetadata(final Long defaultDsType) {
final JpaTenantMetaData data = (JpaTenantMetaData) getTenantMetadata();
return tenantMetaDataRepository.save((JpaTenantMetaData) metaData);
data.setDefaultDsType(distributionSetTypeRepository.findOne(defaultDsType));
return tenantMetaDataRepository.save(data);
}
private DistributionSetType createStandardSoftwareDataSetup() {
@@ -285,19 +284,19 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
final SoftwareModuleType os = softwareModuleTypeRepository.save(new JpaSoftwareModuleType(
Constants.SMT_DEFAULT_OS_KEY, Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operationg system", 1));
distributionSetTypeRepository
.save((JpaDistributionSetType) new JpaDistributionSetType(Constants.DST_DEFAULT_OS_ONLY_KEY,
Constants.DST_DEFAULT_OS_ONLY_NAME, "Default type with Firmware/OS only.")
.addMandatoryModuleType(os));
// make sure the module types get their IDs
entityManager.flush();
return distributionSetTypeRepository
.save((JpaDistributionSetType) new JpaDistributionSetType(Constants.DST_DEFAULT_OS_WITH_APPS_KEY,
Constants.DST_DEFAULT_OS_WITH_APPS_NAME, "Default type with Firmware/OS and optional app(s).")
.addMandatoryModuleType(os).addOptionalModuleType(app));
distributionSetTypeRepository.save(new JpaDistributionSetType(Constants.DST_DEFAULT_OS_ONLY_KEY,
Constants.DST_DEFAULT_OS_ONLY_NAME, "Default type with Firmware/OS only.").addMandatoryModuleType(os));
return distributionSetTypeRepository.save(new JpaDistributionSetType(Constants.DST_DEFAULT_OS_WITH_APPS_KEY,
Constants.DST_DEFAULT_OS_WITH_APPS_NAME, "Default type with Firmware/OS and optional app(s).")
.addMandatoryModuleType(os).addOptionalModuleType(app));
}
@Override
public TenantMetaData getTenantMetadata(final Long tenantId) {
return tenantMetaDataRepository.findOne(tenantId);
}
}
}

View File

@@ -8,15 +8,17 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.builder.GenericTagUpdate;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TagUpdate;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
@@ -24,16 +26,16 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpda
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagCreate;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -78,7 +80,7 @@ public class JpaTagManagement implements TagManagement {
@Autowired
private TenantAware tenantAware;
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@@ -89,16 +91,16 @@ public class JpaTagManagement implements TagManagement {
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetTag createTargetTag(final TargetTag targetTag) {
if (null != targetTag.getId()) {
throw new EntityAlreadyExistsException();
}
public TargetTag createTargetTag(final TagCreate c) {
final JpaTagCreate create = (JpaTagCreate) c;
final JpaTargetTag targetTag = create.buildTargetTag();
if (findTargetTag(targetTag.getName()) != null) {
throw new EntityAlreadyExistsException();
}
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
final TargetTag save = targetTagRepository.save(targetTag);
afterCommit.afterCommit(
() -> eventPublisher.publishEvent(new TargetTagCreatedEvent(save, applicationContext.getId())));
@@ -109,17 +111,12 @@ public class JpaTagManagement implements TagManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<TargetTag> createTargetTags(final Collection<TargetTag> tt) {
public List<TargetTag> createTargetTags(final Collection<TagCreate> tt) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaTargetTag> targetTags = (Collection) tt;
final Collection<JpaTagCreate> targetTags = (Collection) tt;
targetTags.forEach(tag -> {
if (tag.getId() != null) {
throw new EntityAlreadyExistsException();
}
});
final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags));
final List<TargetTag> save = Collections.unmodifiableList(targetTags.stream()
.map(ttc -> targetTagRepository.save(ttc.buildTargetTag())).collect(Collectors.toList()));
afterCommit.afterCommit(() -> save.forEach(
tag -> eventPublisher.publishEvent(new TargetTagCreatedEvent(tag, applicationContext.getId()))));
return save;
@@ -131,14 +128,10 @@ public class JpaTagManagement implements TagManagement {
public void deleteTargetTag(final String targetTagName) {
final JpaTargetTag tag = targetTagRepository.findByNameEquals(targetTagName);
final List<JpaTarget> changed = new LinkedList<>();
for (final JpaTarget target : targetRepository.findByTag(tag)) {
target.removeTag(tag);
changed.add(target);
}
// save association delete
targetRepository.save(changed);
targetRepository.findByTag(tag).forEach(set -> {
set.removeTag(tag);
targetRepository.save(set);
});
// finally delete the tag itself
targetTagRepository.deleteByName(targetTagName);
@@ -177,15 +170,42 @@ public class JpaTagManagement implements TagManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetTag updateTargetTag(final TargetTag targetTag) {
checkNotNull(targetTag.getName());
checkNotNull(targetTag.getId());
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
public TargetTag updateTargetTag(final TagUpdate u) {
final GenericTagUpdate update = (GenericTagUpdate) u;
final JpaTargetTag tag = Optional.ofNullable(targetTagRepository.findOne(update.getId()))
.orElseThrow(() -> new EntityNotFoundException("Target tag with ID " + update.getId() + " not found"));
update.getName().ifPresent(tag::setName);
update.getDescription().ifPresent(tag::setDescription);
update.getColour().ifPresent(tag::setColour);
final TargetTag save = targetTagRepository.save(tag);
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
return save;
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTag updateDistributionSetTag(final TagUpdate u) {
final GenericTagUpdate update = (GenericTagUpdate) u;
final JpaDistributionSetTag tag = Optional.ofNullable(distributionSetTagRepository.findOne(update.getId()))
.orElseThrow(() -> new EntityNotFoundException(
"Distribution set tag with ID " + update.getId() + " not found"));
update.getName().ifPresent(tag::setName);
update.getDescription().ifPresent(tag::setDescription);
update.getColour().ifPresent(tag::setColour);
final DistributionSetTag save = distributionSetTagRepository.save(tag);
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
new DistributionSetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
return save;
}
@Override
public DistributionSetTag findDistributionSetTag(final String name) {
return distributionSetTagRepository.findByNameEquals(name);
@@ -194,16 +214,16 @@ public class JpaTagManagement implements TagManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTag createDistributionSetTag(final DistributionSetTag distributionSetTag) {
if (null != distributionSetTag.getId()) {
throw new EntityAlreadyExistsException();
}
public DistributionSetTag createDistributionSetTag(final TagCreate c) {
final JpaTagCreate create = (JpaTagCreate) c;
final JpaDistributionSetTag distributionSetTag = create.buildDistributionSetTag();
if (distributionSetTagRepository.findByNameEquals(distributionSetTag.getName()) != null) {
throw new EntityAlreadyExistsException();
}
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag);
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new DistributionSetTagCreatedEvent(save, applicationContext.getId())));
@@ -213,18 +233,14 @@ public class JpaTagManagement implements TagManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSetTag> createDistributionSetTags(final Collection<DistributionSetTag> dst) {
public List<DistributionSetTag> createDistributionSetTags(final Collection<TagCreate> dst) {
@SuppressWarnings({ "rawtypes", "unchecked" })
final Collection<JpaDistributionSetTag> distributionSetTags = (Collection) dst;
final Collection<JpaTagCreate> creates = (Collection) dst;
for (final DistributionSetTag dsTag : distributionSetTags) {
if (dsTag.getId() != null) {
throw new EntityAlreadyExistsException();
}
}
final List<DistributionSetTag> save = Collections
.unmodifiableList(distributionSetTagRepository.save(distributionSetTags));
final List<DistributionSetTag> save = Collections.unmodifiableList(
creates.stream().map(create -> distributionSetTagRepository.save(create.buildDistributionSetTag()))
.collect(Collectors.toList()));
afterCommit.afterCommit(() -> save.forEach(tag -> eventPublisher
.publishEvent(new DistributionSetTagCreatedEvent(tag, applicationContext.getId()))));
return save;
@@ -236,14 +252,10 @@ public class JpaTagManagement implements TagManagement {
public void deleteDistributionSetTag(final String tagName) {
final JpaDistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName);
final List<JpaDistributionSet> changed = new LinkedList<>();
for (final JpaDistributionSet set : distributionSetRepository.findByTag(tag)) {
distributionSetRepository.findByTag(tag).forEach(set -> {
set.removeTag(tag);
changed.add(set);
}
// save association delete
distributionSetRepository.save(changed);
distributionSetRepository.save(set);
});
distributionSetTagRepository.deleteByName(tagName);
@@ -252,19 +264,6 @@ public class JpaTagManagement implements TagManagement {
tag.getId(), applicationContext.getId())));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTag updateDistributionSetTag(final DistributionSetTag distributionSetTag) {
checkNotNull(distributionSetTag.getName());
checkNotNull(distributionSetTag.getId());
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
new DistributionSetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
return save;
}
@Override
public List<DistributionSetTag> findAllDistributionSetTags() {
return Collections.unmodifiableList(distributionSetTagRepository.findAll());

View File

@@ -11,20 +11,28 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetFilterQueryFields;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.builder.GenericTargetFilterQueryUpdate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
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.jpa.builder.JpaTargetFilterQueryCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
@@ -34,7 +42,6 @@ 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.util.Assert;
import org.springframework.validation.annotation.Validated;
import com.google.common.base.Strings;
@@ -53,15 +60,21 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@Autowired
private DistributionSetManagement distributionSetManagement;
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetFilterQuery createTargetFilterQuery(final TargetFilterQuery customTargetFilter) {
public TargetFilterQuery createTargetFilterQuery(final TargetFilterQueryCreate c) {
final JpaTargetFilterQueryCreate create = (JpaTargetFilterQueryCreate) c;
if (targetFilterQueryRepository.findByName(customTargetFilter.getName()) != null) {
throw new EntityAlreadyExistsException(customTargetFilter.getName());
final JpaTargetFilterQuery query = create.build();
if (targetFilterQueryRepository.findByName(query.getName()) != null) {
throw new EntityAlreadyExistsException(query.getName());
}
return targetFilterQueryRepository.save((JpaTargetFilterQuery) customTargetFilter);
return targetFilterQueryRepository.save(query);
}
@Override
@@ -96,7 +109,8 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull Pageable pageable, String rsqlFilter) {
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull final Pageable pageable,
final String rsqlFilter) {
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
if (!Strings.isNullOrEmpty(rsqlFilter)) {
specList = Collections.singletonList(
@@ -106,14 +120,14 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull Pageable pageable,
DistributionSet distributionSet) {
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull final Pageable pageable,
final DistributionSet distributionSet) {
return findTargetFilterQueryByAutoAssignDS(pageable, distributionSet, null);
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull Pageable pageable,
DistributionSet distributionSet, String rsqlFilter) {
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull final Pageable pageable,
final DistributionSet distributionSet, final String rsqlFilter) {
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>(2);
if (distributionSet != null) {
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
@@ -125,7 +139,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryWithAutoAssignDS(@NotNull Pageable pageable) {
public Page<TargetFilterQuery> findTargetFilterQueryWithAutoAssignDS(@NotNull final Pageable pageable) {
final List<Specification<JpaTargetFilterQuery>> specList = Collections
.singletonList(TargetFilterQuerySpecification.withAutoAssignDS());
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
@@ -154,9 +168,42 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetFilterQuery updateTargetFilterQuery(final TargetFilterQuery targetFilterQuery) {
Assert.notNull(targetFilterQuery.getId());
return targetFilterQueryRepository.save((JpaTargetFilterQuery) targetFilterQuery);
public TargetFilterQuery updateTargetFilterQuery(final TargetFilterQueryUpdate u) {
final GenericTargetFilterQueryUpdate update = (GenericTargetFilterQueryUpdate) u;
final JpaTargetFilterQuery targetFilterQuery = findTargetFilterQueryOrThrowExceptionIfNotFound(update.getId());
update.getName().ifPresent(targetFilterQuery::setName);
update.getQuery().ifPresent(targetFilterQuery::setQuery);
return targetFilterQueryRepository.save(targetFilterQuery);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetFilterQuery updateTargetFilterQueryAutoAssignDS(final Long queryId, final Long dsId) {
final JpaTargetFilterQuery targetFilterQuery = findTargetFilterQueryOrThrowExceptionIfNotFound(queryId);
targetFilterQuery.setAutoAssignDistributionSet(
Optional.ofNullable(dsId).map(this::findDistributionSetAndThrowExceptionIfNotFound).orElse(null));
return targetFilterQueryRepository.save(targetFilterQuery);
}
private JpaDistributionSet findDistributionSetAndThrowExceptionIfNotFound(final Long setId) {
final JpaDistributionSet set = (JpaDistributionSet) distributionSetManagement
.findDistributionSetByIdWithDetails(setId);
if (set == null) {
throw new EntityNotFoundException("Distribution set cannot be updated as it does not exixt" + setId);
}
return set;
}
private JpaTargetFilterQuery findTargetFilterQueryOrThrowExceptionIfNotFound(final Long queryId) {
return Optional.ofNullable(targetFilterQueryRepository.findOne(queryId)).orElseThrow(
() -> new EntityNotFoundException("TargetFilterQuery with given ID " + queryId + " not found!"));
}
@Override

View File

@@ -8,12 +8,12 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
@@ -32,10 +32,14 @@ import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TimestampCalculator;
import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate;
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.jpa.builder.JpaTargetCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetUpdate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
@@ -43,19 +47,18 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetIdName;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
@@ -69,7 +72,6 @@ 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.util.Assert;
import org.springframework.validation.annotation.Validated;
import com.google.common.collect.Lists;
@@ -106,9 +108,6 @@ public class JpaTargetManagement implements TargetManagement {
@Autowired
private TenantAware tenantAware;
@Autowired
private AfterTransactionCommitExecutor afterCommit;
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@@ -163,8 +162,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Slice<Target> findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) {
return findTargetsBySpec(
RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyReplacer),
pageable);
RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyReplacer), pageable);
}
@Override
@@ -188,25 +186,21 @@ public class JpaTargetManagement implements TargetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateTarget(final Target target) {
Assert.notNull(target.getId());
public Target updateTarget(final TargetUpdate u) {
final JpaTargetUpdate update = (JpaTargetUpdate) u;
final JpaTarget toUpdate = (JpaTarget) target;
toUpdate.setNew(false);
return targetRepository.save(toUpdate);
}
final JpaTarget target = Optional.ofNullable(targetRepository.findByControllerId(update.getControllerId()))
.orElseThrow(() -> new EntityNotFoundException(
"Target with ID " + update.getControllerId() + " not found."));
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> updateTargets(final Collection<Target> targets) {
target.setNew(false);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaTarget> toUpdate = (Collection) targets;
update.getName().ifPresent(target::setName);
update.getDescription().ifPresent(target::setDescription);
update.getAddress().ifPresent(address -> ((JpaTargetInfo) target.getTargetInfo()).setAddress(address));
update.getSecurityToken().ifPresent(target::setSecurityToken);
toUpdate.forEach(target -> target.setNew(false));
return Collections.unmodifiableList(targetRepository.save(toUpdate));
return targetRepository.save(target);
}
@Override
@@ -235,8 +229,7 @@ public class JpaTargetManagement implements TargetManagement {
public Page<Target> findTargetByAssignedDistributionSet(final Long distributionSetID, final String rsqlParam,
final Pageable pageReq) {
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class,
virtualPropertyReplacer);
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class, virtualPropertyReplacer);
return convertPage(
targetRepository
@@ -264,8 +257,7 @@ public class JpaTargetManagement implements TargetManagement {
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId, final String rsqlParam,
final Pageable pageable) {
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class,
virtualPropertyReplacer);
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class, virtualPropertyReplacer);
return convertPage(
targetRepository
@@ -294,8 +286,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Long countTargetByFilters(final Collection<TargetUpdateStatus> status, final Boolean overdueState,
final String searchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final String... tagNames) {
final String searchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final String... tagNames) {
final List<Specification<JpaTarget>> specList = buildSpecificationList(
new FilterParams(installedOrAssignedDistributionSetId, status, overdueState, searchText,
selectTargetWithNoTag, tagNames),
@@ -304,19 +296,17 @@ public class JpaTargetManagement implements TargetManagement {
}
private static List<Specification<JpaTarget>> buildSpecificationList(final FilterParams filterParams,
final boolean fetch) {
final boolean fetch) {
final List<Specification<JpaTarget>> specList = new ArrayList<>();
if (filterParams.getFilterByStatus() != null && !filterParams.getFilterByStatus().isEmpty()) {
specList.add(TargetSpecifications.hasTargetUpdateStatus(filterParams.getFilterByStatus(), fetch));
}
if (filterParams.getOverdueState() != null) {
specList.add(
TargetSpecifications.isOverdue(TimestampCalculator.calculateOverdueTimestamp()));
specList.add(TargetSpecifications.isOverdue(TimestampCalculator.calculateOverdueTimestamp()));
}
if (filterParams.getFilterByDistributionId() != null) {
specList.add(
TargetSpecifications
.hasInstalledOrAssignedDistributionSet(filterParams.getFilterByDistributionId()));
specList.add(TargetSpecifications
.hasInstalledOrAssignedDistributionSet(filterParams.getFilterByDistributionId()));
}
if (StringUtils.isNotEmpty(filterParams.getFilterBySearchText())) {
specList.add(TargetSpecifications.likeNameOrDescriptionOrIp(filterParams.getFilterBySearchText()));
@@ -363,7 +353,8 @@ public class JpaTargetManagement implements TargetManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetTagAssignmentResult toggleTagAssignment(final Collection<String> targetIds, final String tagName) {
final TargetTag tag = targetTagRepository.findByNameEquals(tagName);
final List<Target> alreadyAssignedTargets = targetRepository.findByTagNameAndControllerIdIn(tagName, targetIds);
final List<JpaTarget> alreadyAssignedTargets = targetRepository.findByTagNameAndControllerIdIn(tagName,
targetIds);
final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
@@ -371,7 +362,7 @@ public class JpaTargetManagement implements TargetManagement {
if (alreadyAssignedTargets.size() == allTargets.size()) {
alreadyAssignedTargets.forEach(target -> target.removeTag(tag));
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(0, 0, alreadyAssignedTargets.size(),
Collections.emptyList(), alreadyAssignedTargets, tag);
Collections.emptyList(), Collections.unmodifiableList(alreadyAssignedTargets), tag);
return result;
}
@@ -380,7 +371,9 @@ public class JpaTargetManagement implements TargetManagement {
// some or none are assigned -> assign
allTargets.forEach(target -> target.addTag(tag));
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(),
allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)),
allTargets.size(), 0,
Collections
.unmodifiableList(allTargets.stream().map(targetRepository::save).collect(Collectors.toList())),
Collections.emptyList(), tag);
// no reason to persist the tag
@@ -396,7 +389,8 @@ public class JpaTargetManagement implements TargetManagement {
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds));
allTargets.forEach(target -> target.addTag(tag));
return Collections.unmodifiableList(targetRepository.save(allTargets));
return Collections
.unmodifiableList(allTargets.stream().map(targetRepository::save).collect(Collectors.toList()));
}
private List<Target> unAssignTag(final Collection<Target> targets, final TargetTag tag) {
@@ -405,7 +399,8 @@ public class JpaTargetManagement implements TargetManagement {
toUnassign.forEach(target -> target.removeTag(tag));
return Collections.unmodifiableList(targetRepository.save(toUnassign));
return Collections
.unmodifiableList(toUnassign.stream().map(targetRepository::save).collect(Collectors.toList()));
}
@Override
@@ -451,8 +446,7 @@ public class JpaTargetManagement implements TargetManagement {
// build the specifications and then to predicates necessary by the
// given filters
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
buildSpecificationList(filterParams, true),
targetRoot, query, cb);
buildSpecificationList(filterParams, true), targetRoot, query, cb);
// if we have some predicates then add it to the where clause of the
// multiselect
@@ -508,9 +502,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public List<TargetIdName> findAllTargetIdsByFilters(final Pageable pageRequest,
final Collection<TargetUpdateStatus> filterByStatus, final Boolean overdueState,
final String filterBySearchText,
final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag,
final String... filterByTagNames) {
final String filterBySearchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final String... filterByTagNames) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
@@ -526,8 +519,7 @@ public class JpaTargetManagement implements TargetManagement {
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
buildSpecificationList(new FilterParams(installedOrAssignedDistributionSetId, filterByStatus,
overdueState, filterBySearchText,
selectTargetWithNoTag, filterByTagNames), false),
overdueState, filterBySearchText, selectTargetWithNoTag, filterByTagNames), false),
targetRoot, multiselect, cb);
// if we have some predicates then add it to the where clause of the
@@ -588,7 +580,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findAllTargetsByTargetFilterQueryAndNotInRolloutGroups(@NotNull final Pageable pageRequest,
final List<RolloutGroup> groups, @NotNull final String targetFilterQuery) {
final List<RolloutGroup> groups, @NotNull final String targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
@@ -608,7 +600,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Long countAllTargetsByTargetFilterQueryAndNotInRolloutGroups(final List<RolloutGroup> groups,
@NotNull final String targetFilterQuery) {
@NotNull final String targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
@@ -622,7 +614,7 @@ public class JpaTargetManagement implements TargetManagement {
public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId,
@NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
virtualPropertyReplacer);
virtualPropertyReplacer);
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
specList.add(spec);
specList.add(TargetSpecifications.hasNotDistributionSetInActions(distributionSetId));
@@ -633,52 +625,30 @@ public class JpaTargetManagement implements TargetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetsCreatedOverPeriod" }, allEntries = true)
public Target createTarget(final Target t, final TargetUpdateStatus status, final Long lastTargetQuery,
final URI address) {
final JpaTarget target = (JpaTarget) t;
public Target createTarget(final TargetCreate c) {
final JpaTargetCreate create = (JpaTargetCreate) c;
final JpaTarget target = create.build();
if (targetRepository.findByControllerId(target.getControllerId()) != null) {
throw new EntityAlreadyExistsException(target.getControllerId());
throw new EntityAlreadyExistsException();
}
target.setNew(true);
final JpaTarget savedTarget = targetRepository.save(target);
final JpaTargetInfo targetInfo = (JpaTargetInfo) savedTarget.getTargetInfo();
targetInfo.setUpdateStatus(status);
if (lastTargetQuery != null) {
targetInfo.setLastTargetQuery(lastTargetQuery);
}
if (address != null) {
targetInfo.setAddress(address.toString());
}
targetInfo.setNew(true);
final Target targetToReturn = targetInfoRepository.save(targetInfo).getTarget();
targetInfo.setNew(false);
return targetToReturn;
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetsCreatedOverPeriod" }, allEntries = true)
public Target createTarget(final Target target) {
return createTarget(target, TargetUpdateStatus.UNKNOWN, null, null);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> createTargets(final Collection<Target> targets) {
if (!targets.isEmpty() && targetRepository.countByControllerIdIn(
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
throw new EntityAlreadyExistsException();
}
return targets.stream()
.map(t -> createTarget(t, TargetUpdateStatus.UNKNOWN, null, t.getTargetInfo().getAddress()))
.collect(Collectors.toList());
public List<Target> createTargets(final Collection<TargetCreate> targets) {
return targets.stream().map(this::createTarget).collect(Collectors.toList());
}
@Override

View File

@@ -53,28 +53,6 @@ public interface RolloutGroupRepository
*/
List<JpaRolloutGroup> findByRolloutAndStatus(final Rollout rollout, final RolloutGroupStatus status);
/**
* Counts all {@link RolloutGroup} referring a specific rollout.
*
* @param rollout
* the rollout the rolloutgroup belong to
* @return the count of the rollout groups for a specific rollout
*/
Long countByRollout(final JpaRollout rollout);
/**
* Counts all {@link RolloutGroup} referring a specific rollout in a
* specific {@link RolloutGroupStatus}.
*
* @param rollout
* the rollout the rolloutgroup belong to
* @param rolloutGroupStatus
* the status of the rollout groups
* @return the count of rollout groups belonging to a rollout in a specific
* status
*/
Long countByRolloutAndStatus(JpaRollout rollout, RolloutGroupStatus rolloutGroupStatus);
/**
* Counts all {@link RolloutGroup} referring a specific rollout in specific
* {@link RolloutGroupStatus}s. An in-clause statement does not work with

View File

@@ -8,16 +8,19 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.exception.ConstraintViolationException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.exception.RolloutVerificationException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import java.util.List;
import java.util.stream.Collectors;
/**
* A collection of static helper methods for the {@link JpaRolloutManagement}
*/
@@ -33,26 +36,31 @@ final class RolloutHelper {
*/
static void verifyRolloutGroupConditions(final RolloutGroupConditions conditions) {
if (conditions.getSuccessCondition() == null) {
throw new RolloutVerificationException("Rollout group is missing success condition");
throw new ConstraintViolationException("Rollout group is missing success condition");
}
if (conditions.getSuccessAction() == null) {
throw new RolloutVerificationException("Rollout group is missing success action");
throw new ConstraintViolationException("Rollout group is missing success action");
}
}
/**
* Verifies that the group has the required success condition and action.
* Verifies that the group has the required success condition and action and
* a falid target percentage.
*
* @param group
* the input group
* @return the verified group
*/
static RolloutGroup verifyRolloutGroupHasConditions(final RolloutGroup group) {
if (group.getTargetPercentage() < 1F || group.getTargetPercentage() > 100F) {
throw new ConstraintViolationException("Target percentage has to be between 1 and 100");
}
if (group.getSuccessCondition() == null) {
throw new RolloutVerificationException("Rollout group is missing success condition");
throw new ConstraintViolationException("Rollout group is missing success condition");
}
if (group.getSuccessAction() == null) {
throw new RolloutVerificationException("Rollout group is missing success action");
throw new ConstraintViolationException("Rollout group is missing success action");
}
return group;
}
@@ -65,10 +73,11 @@ final class RolloutHelper {
* group to check
* @param conditions
* default conditions and actions
* @return group with all conditions and actions
*/
static RolloutGroup prepareRolloutGroupWithDefaultConditions(final RolloutGroup group,
static JpaRolloutGroup prepareRolloutGroupWithDefaultConditions(final RolloutGroupCreate create,
final RolloutGroupConditions conditions) {
final JpaRolloutGroup group = ((JpaRolloutGroupCreate) create).build();
if (group.getSuccessCondition() == null) {
group.setSuccessCondition(conditions.getSuccessCondition());
}
@@ -94,6 +103,7 @@ final class RolloutHelper {
if (group.getErrorActionExp() == null) {
group.setErrorActionExp(conditions.getErrorActionExp());
}
return group;
}
@@ -105,9 +115,9 @@ final class RolloutHelper {
*/
static void verifyRolloutGroupParameter(final int amountGroup) {
if (amountGroup <= 0) {
throw new RolloutVerificationException("the amountGroup must be greater than zero");
throw new ConstraintViolationException("the amountGroup must be greater than zero");
} else if (amountGroup > 500) {
throw new RolloutVerificationException("the amountGroup must not be greater than 500");
throw new ConstraintViolationException("the amountGroup must not be greater than 500");
}
}
@@ -119,9 +129,9 @@ final class RolloutHelper {
*/
static void verifyRolloutGroupTargetPercentage(final float percentage) {
if (percentage <= 0) {
throw new RolloutVerificationException("the percentage must be greater than zero");
throw new ConstraintViolationException("the percentage must be greater than zero");
} else if (percentage > 100) {
throw new RolloutVerificationException("the percentage must not be greater than 100");
throw new ConstraintViolationException("the percentage must not be greater than 100");
}
}
@@ -193,11 +203,13 @@ final class RolloutHelper {
}
/**
* Creates an RSQL expression that matches all targets in the provided groups.
* Links all target filter queries with OR.
* Creates an RSQL expression that matches all targets in the provided
* groups. Links all target filter queries with OR.
*
* @param groups the rollout groups
* @return RSQL string without base filter of the Rollout. Can be an empty string.
* @param groups
* the rollout groups
* @return RSQL string without base filter of the Rollout. Can be an empty
* string.
*/
static String getAllGroupsTargetFilter(final List<RolloutGroup> groups) {
if (groups.stream().anyMatch(group -> StringUtils.isEmpty(group.getTargetFilterQuery()))) {
@@ -207,12 +219,15 @@ final class RolloutHelper {
}
/**
* Creates an RSQL Filter that matches all targets that are in the provided group and
* in the provided groups.
* Creates an RSQL Filter that matches all targets that are in the provided
* group and in the provided groups.
*
* @param groups the rollout groups
* @param group the group
* @return RSQL string without base filter of the Rollout. Can be an empty string.
* @param groups
* the rollout groups
* @param group
* the group
* @return RSQL string without base filter of the Rollout. Can be an empty
* string.
*/
static String getOverlappingWithGroupsTargetFilter(final List<RolloutGroup> groups, final RolloutGroup group) {
final String previousGroupFilters = getAllGroupsTargetFilter(groups);
@@ -235,11 +250,11 @@ final class RolloutHelper {
*/
static void verifyRemainingTargets(final long targetCount) {
if (targetCount > 0) {
throw new RolloutVerificationException(
throw new ConstraintViolationException(
"Rollout groups don't match all targets that are targeted by the rollout");
}
if (targetCount != 0) {
throw new RolloutVerificationException("Rollout groups target count verification failed");
throw new ConstraintViolationException("Rollout groups target count verification failed");
}
}

View File

@@ -13,8 +13,6 @@ import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
@@ -62,18 +60,6 @@ public interface RolloutRepository
*/
List<JpaRollout> findByLastCheckAndStatus(long lastCheck, RolloutStatus status);
/**
* Retrieves all {@link Rollout} for a specific {@code name}.
*
* @param pageable
* for paging information
*
* @param name
* the rollout name
* @return {@link Rollout} for specific name
*/
Page<JpaRollout> findByName(final Pageable pageable, String name);
/**
* Retrieves all {@link Rollout} for a specific {@code name}
*
@@ -82,13 +68,4 @@ public interface RolloutRepository
* @return {@link Rollout} for specific name
*/
JpaRollout findByName(String name);
/**
* Retrieves all {@link Rollout} for a specific status.
*
* @param status
* the status of the rollouts to retrieve
* @return a list of {@link Rollout} having the given status
*/
List<JpaRollout> findByStatus(final RolloutStatus status);
}

View File

@@ -8,8 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
@@ -29,17 +27,6 @@ public interface SoftwareModuleMetadataRepository
extends PagingAndSortingRepository<JpaSoftwareModuleMetadata, SwMetadataCompositeKey>,
JpaSpecificationExecutor<JpaSoftwareModuleMetadata> {
/**
* Saves all given entities.
*
* @param entities
* @return the saved entities
* @throws IllegalArgumentException
* in case the given entity is (@literal null}.
*/
@Override
<S extends JpaSoftwareModuleMetadata> List<S> save(Iterable<S> entities);
/**
* finds all software module meta data of the given software module id.
*

View File

@@ -18,8 +18,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
@@ -86,17 +84,6 @@ public interface SoftwareModuleRepository
*/
Page<SoftwareModule> findByAssignedTo(Pageable pageable, JpaDistributionSet set);
/**
*
*
* @param setId
* to search for
* @return all {@link SoftwareModule}s that are assigned to given
* {@link DistributionSet}
*/
@EntityGraph(value = "SoftwareModule.artifacts", type = EntityGraphType.LOAD)
List<JpaSoftwareModule> findByAssignedToId(Long setId);
/**
* @param pageable
* the page request to page the result set
@@ -109,23 +96,6 @@ public interface SoftwareModuleRepository
*/
Page<SoftwareModule> findByAssignedToAndType(Pageable pageable, JpaDistributionSet set, SoftwareModuleType type);
/**
* retrieves all software modules with a given {@link SoftwareModuleType}
* and {@link SoftwareModule#getId()}.
*
* @param ids
* to search for
* @param type
* to search for
* @return {@link List} of found {@link SoftwareModule}s
*/
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("SELECT sm FROM JpaSoftwareModule sm WHERE sm.id IN ?1 and sm.type = ?2")
List<SoftwareModule> findByIdInAndType(Iterable<Long> ids, JpaSoftwareModuleType type);
@Override
<S extends JpaSoftwareModule> List<S> save(Iterable<S> entities);
/**
* retrieves all software modules with a given
* {@link SoftwareModule#getId()}.

View File

@@ -8,11 +8,15 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
@@ -58,4 +62,16 @@ public interface SoftwareModuleTypeRepository
* {@link SoftwareModuleType#getName()}
*/
JpaSoftwareModuleType findByName(String name);
/**
* retrieves all software module types with a given
* {@link SoftwareModuleType#getId()}.
*
* @param ids
* to search for
* @return {@link List} of found {@link SoftwareModule}s
*/
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("SELECT sm FROM JpaSoftwareModuleType sm WHERE sm.id IN ?1")
List<JpaSoftwareModuleType> findByIdIn(Iterable<Long> ids);
}

View File

@@ -40,11 +40,6 @@ public interface TargetFilterQueryRepository
@Override
Page<JpaTargetFilterQuery> findAll();
@Override
@Modifying
@Transactional
<S extends JpaTargetFilterQuery> S save(S entity);
/**
* Sets the auto assign distribution sets to null which match the ds ids.
*

View File

@@ -52,5 +52,7 @@ public interface TargetInfoRepository {
*
* @return persisted or updated {@link Entity}
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
<S extends JpaTargetInfo> S save(S entity);
}

View File

@@ -18,9 +18,8 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TargetWithActionStatus;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.EntityGraph;
@@ -49,15 +48,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
@EntityGraph(value = "Target.detail", type = EntityGraphType.LOAD)
JpaTarget findByControllerId(String controllerID);
/**
* Finds targets by given list of {@link Target#getControllerId()}s.
*
* @param controllerIDs
* to serach for
* @return list of found {@link Target}s
*/
List<Target> findByControllerIdIn(String... controllerIDs);
/**
* Deletes the {@link Target}s with the given target IDs.
*
@@ -68,7 +58,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM JpaTarget t WHERE t.id IN ?1")
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
void deleteByIdIn(final Collection<Long> targetIDs);
/**
@@ -92,7 +81,7 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
* @return {@link List} of found {@link Target}s.
*/
@Query(value = "SELECT DISTINCT t from JpaTarget t JOIN t.tags tt WHERE tt.name = :tagname AND t.controllerId IN :targets")
List<Target> findByTagNameAndControllerIdIn(@Param("tagname") final String tag,
List<JpaTarget> findByTagNameAndControllerIdIn(@Param("tagname") final String tag,
@Param("targets") final Collection<String> controllerIds);
/**
@@ -107,18 +96,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
*/
Page<Target> findByTargetInfoUpdateStatus(final Pageable pageable, final TargetUpdateStatus status);
/**
* Finds all targets that have defined {@link DistributionSet} installed.
*
* @param pageable
* for page configuration
* @param set
* is the {@link DistributionSet} to filter for.
*
* @return found targets
*/
Page<Target> findByTargetInfoInstalledDistributionSet(final Pageable pageable, final JpaDistributionSet set);
/**
* retrieves the {@link Target}s which has the {@link DistributionSet}
* installed with the given ID.
@@ -131,48 +108,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
*/
Page<Target> findByTargetInfoInstalledDistributionSetId(final Pageable pageable, final Long setID);
/**
* Finds all targets that have defined {@link DistributionSet} assigned.
*
* @param pageable
* for page configuration
* @param set
* is the {@link DistributionSet} to filter for.
*
* @return found targets
*/
Page<Target> findByAssignedDistributionSet(final Pageable pageable, final JpaDistributionSet set);
/**
* Saves all given {@link Target}s.
*
* @param entities
* @return the saved entities
* @throws IllegalArgumentException
* in case the given entity is (@literal null}.
*
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
*/
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends JpaTarget> List<S> save(Iterable<S> entities);
/**
* Saves a given entity. Use the returned instance for further operations as
* the save operation might have changed the entity instance completely.
*
* @param entity
* the target to save
* @return the saved entity
*/
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends JpaTarget> S save(S entity);
/**
* Finds all targets that have defined {@link DistributionSet} assigned.
*
@@ -196,18 +131,9 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
*/
Long countByAssignedDistributionSetId(final Long distId);
/**
* @param ids
* of count in DB
* @return number of found {@link Target}s with given
* {@link Target#getControllerId()}s
*/
@Query("SELECT COUNT(t) FROM JpaTarget t WHERE t.controllerId IN ?1")
Long countByControllerIdIn(final Collection<String> ids);
/**
* Counts number of targets with given
* {@link TargetStatus#getInstalledDistributionSet()}.
* {@link TargetInfo#getInstalledDistributionSet()}.
*
* @param distId
* to search for
@@ -215,41 +141,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
*/
Long countByTargetInfoInstalledDistributionSetId(final Long distId);
/**
* Finds all targets that have defined {@link DistributionSet} assigned or
* installed.
*
* @param pageable
* for page configuration
* @param assigned
* {@link DistributionSet} filter for; please note: must not be
* null
* @param installed
* {@link DistributionSet} filter for; please note: must not be
* null
*
* @return found targets
*/
Page<Target> findByAssignedDistributionSetOrTargetInfoInstalledDistributionSet(final Pageable pageable,
final JpaDistributionSet assigned, final JpaDistributionSet installed);
/**
* Finds all targets that have defined {@link DistributionSet} assigned or
* installed.
*
* @param pageable
* for page configuration
* @param assigned
* {@link DistributionSet} filter for; please note: must not be
* null
* @param installed
* {@link DistributionSet} filter for; please note: must not be
* null
* @return found targets
*/
Page<Target> findByAssignedDistributionSetIdOrTargetInfoInstalledDistributionSetId(final Pageable pageable,
final Long assigned, final Long installed);
/**
* Finds all {@link Target}s in the repository.
*
@@ -283,8 +174,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
void setAssignedDistributionSet(@Param("set") JpaDistributionSet set, @Param("lastModifiedAt") Long modifiedAt,
@Param("lastModifiedBy") String modifiedBy, @Param("targets") Collection<Long> targets);
List<Target> findByRolloutTargetGroupRolloutGroup(final JpaRolloutGroup rolloutGroup);
/**
*
* Finds all targets of a rollout group.
@@ -308,17 +197,4 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
* @return a page of all targets related to a rollout group
*/
Page<Target> findByActionsRolloutGroup(JpaRolloutGroup rolloutGroup, Pageable page);
/**
* Find all targets with action status for a specific group.
*
* @param pageable
* the page request parameter
* @param rolloutGroupId
* the ID of the rollout group
* @return targets with action status
*/
@Query("select DISTINCT NEW org.eclipse.hawkbit.repository.model.TargetWithActionStatus(a.target,a.status) from JpaAction a inner join fetch a.target t where a.rolloutGroup.id = :rolloutGroupId")
Page<TargetWithActionStatus> findTargetsWithActionStatusByRolloutGroupId(final Pageable pageable,
@Param("rolloutGroupId") Long rolloutGroupId);
}

View File

@@ -28,7 +28,7 @@ public interface TargetTagRepository
/**
* deletes the {@link TargetTag}s with the given tag names.
*
* @param tagNames
* @param tagName
* to be deleted
* @return 1 if tag was deleted
*/
@@ -52,7 +52,4 @@ public interface TargetTagRepository
*/
@Override
List<JpaTargetTag> findAll();
@Override
<S extends JpaTargetTag> List<S> save(Iterable<S> entities);
}

View File

@@ -8,8 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.springframework.transaction.annotation.Isolation;
@@ -31,9 +29,6 @@ public interface TenantConfigurationRepository extends BaseEntityRepository<JpaT
*/
JpaTenantConfiguration findByKey(String configurationKey);
@Override
List<JpaTenantConfiguration> findAll();
/**
* Deletes a tenant configuration by tenant and key.
*

View File

@@ -32,16 +32,6 @@ public interface TenantMetaDataRepository extends PagingAndSortingRepository<Jpa
*/
TenantMetaData findByTenantIgnoreCase(String tenant);
/**
* Counts the tenant by the tenant field which is either a count of one or a
* count of zero, this is mostly to check if the tenant exists.
*
* @param tenant
* the name of the tenant to check if it is exists
* @return the count of the tenant by name which is either one or zero
*/
Long countByTenantIgnoreCase(String tenant);
@Override
List<JpaTenantMetaData> findAll();

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.model.ActionStatus;
/**
* Builder implementation for {@link ActionStatus}.
*
*/
public class JpaActionStatusBuilder implements ActionStatusBuilder {
@Override
public ActionStatusCreate create(final long actionId) {
return new JpaActionStatusCreate(actionId);
}
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.AbstractActionStatusCreate;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
/**
* Create/build implementation.
*
*/
public class JpaActionStatusCreate extends AbstractActionStatusCreate<ActionStatusCreate>
implements ActionStatusCreate {
JpaActionStatusCreate(final Long actionId) {
super.actionId = actionId;
}
@Override
public JpaActionStatus build() {
final JpaActionStatus result = new JpaActionStatus(status, getOccurredAt().orElse(System.currentTimeMillis()));
if (messages != null) {
messages.forEach(result::addMessage);
}
return result;
}
}

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetUpdate;
import org.eclipse.hawkbit.repository.builder.GenericDistributionSetUpdate;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Builder implementation for {@link DistributionSet}.
*
*/
public class JpaDistributionSetBuilder implements DistributionSetBuilder {
private final DistributionSetManagement distributionSetManagement;
private final SoftwareManagement softwareManagement;
public JpaDistributionSetBuilder(final DistributionSetManagement distributionSetManagement,
final SoftwareManagement softwareManagement) {
this.distributionSetManagement = distributionSetManagement;
this.softwareManagement = softwareManagement;
}
@Override
public DistributionSetUpdate update(final long id) {
return new GenericDistributionSetUpdate(id);
}
@Override
public DistributionSetCreate create() {
return new JpaDistributionSetCreate(distributionSetManagement, softwareManagement);
}
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.builder.AbstractDistributionSetUpdateCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* Create/build implementation.
*
*/
public class JpaDistributionSetCreate extends AbstractDistributionSetUpdateCreate<DistributionSetCreate>
implements DistributionSetCreate {
private final DistributionSetManagement distributionSetManagement;
private final SoftwareManagement softwareManagement;
JpaDistributionSetCreate(final DistributionSetManagement distributionSetManagement,
final SoftwareManagement softwareManagement) {
this.distributionSetManagement = distributionSetManagement;
this.softwareManagement = softwareManagement;
}
@Override
public JpaDistributionSet build() {
return new JpaDistributionSet(name, version, description,
Optional.ofNullable(type).map(this::findDistributionSetTypeWithExceptionIfNotFound).orElse(null),
findSoftwareModuleWithExceptionIfNotFound(modules),
Optional.ofNullable(requiredMigrationStep).orElse(Boolean.FALSE));
}
private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final String distributionSetTypekey) {
final DistributionSetType module = distributionSetManagement
.findDistributionSetTypeByKey(distributionSetTypekey);
if (module == null) {
throw new EntityNotFoundException(
"DistributionSetType with key {" + distributionSetTypekey + "} does not exist");
}
return module;
}
private Collection<SoftwareModule> findSoftwareModuleWithExceptionIfNotFound(
final Collection<Long> softwareModuleId) {
if (CollectionUtils.isEmpty(softwareModuleId)) {
return Collections.emptyList();
}
final Collection<SoftwareModule> module = softwareManagement.findSoftwareModulesById(softwareModuleId);
if (module.size() < softwareModuleId.size()) {
throw new EntityNotFoundException(
"Some SoftwareModules out of the range {" + softwareModuleId + "} due not exist");
}
return module;
}
}

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.builder.GenericDistributionSetTypeUpdate;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
/**
* Builder implementation for {@link DistributionSetType}.
*
*/
public class JpaDistributionSetTypeBuilder implements DistributionSetTypeBuilder {
private final SoftwareManagement softwareManagement;
public JpaDistributionSetTypeBuilder(final SoftwareManagement softwareManagement) {
this.softwareManagement = softwareManagement;
}
@Override
public DistributionSetTypeUpdate update(final long id) {
return new GenericDistributionSetTypeUpdate(id);
}
@Override
public DistributionSetTypeCreate create() {
return new JpaDistributionSetTypeCreate(softwareManagement);
}
}

View File

@@ -0,0 +1,61 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import java.util.Collection;
import java.util.Collections;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.builder.AbstractDistributionSetTypeUpdateCreate;
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* Create/build implementation.
*
*/
public class JpaDistributionSetTypeCreate extends AbstractDistributionSetTypeUpdateCreate<DistributionSetTypeCreate>
implements DistributionSetTypeCreate {
private final SoftwareManagement softwareManagement;
JpaDistributionSetTypeCreate(final SoftwareManagement softwareManagement) {
this.softwareManagement = softwareManagement;
}
@Override
public JpaDistributionSetType build() {
final JpaDistributionSetType result = new JpaDistributionSetType(key, name, description, colour);
findSoftwareModuleTypeWithExceptionIfNotFound(mandatory).forEach(result::addMandatoryModuleType);
findSoftwareModuleTypeWithExceptionIfNotFound(optional).forEach(result::addOptionalModuleType);
return result;
}
private Collection<SoftwareModuleType> findSoftwareModuleTypeWithExceptionIfNotFound(
final Collection<Long> softwareModuleTypeId) {
if (CollectionUtils.isEmpty(softwareModuleTypeId)) {
return Collections.emptyList();
}
final Collection<SoftwareModuleType> module = softwareManagement
.findSoftwareModuleTypesById(softwareModuleTypeId);
if (module.size() < softwareModuleTypeId.size()) {
throw new EntityNotFoundException(
"SoftwareModules types out of the range {" + softwareModuleTypeId + "} due not exist");
}
return module;
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.builder.GenericRolloutUpdate;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
import org.eclipse.hawkbit.repository.builder.RolloutUpdate;
import org.eclipse.hawkbit.repository.model.Rollout;
/**
* Builder implementation for {@link Rollout}.
*
*/
public class JpaRolloutBuilder implements RolloutBuilder {
private final DistributionSetManagement distributionSetManagement;
public JpaRolloutBuilder(final DistributionSetManagement distributionSetManagement) {
this.distributionSetManagement = distributionSetManagement;
}
@Override
public RolloutUpdate update(final long id) {
return new GenericRolloutUpdate(id);
}
@Override
public RolloutCreate create() {
return new JpaRolloutCreate(distributionSetManagement);
}
}

View File

@@ -0,0 +1,53 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.builder.AbstractRolloutUpdateCreate;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.model.DistributionSet;
public class JpaRolloutCreate extends AbstractRolloutUpdateCreate<RolloutCreate> implements RolloutCreate {
private final DistributionSetManagement distributionSetManagement;
JpaRolloutCreate(final DistributionSetManagement distributionSetManagement) {
this.distributionSetManagement = distributionSetManagement;
}
@Override
public JpaRollout build() {
final JpaRollout rollout = new JpaRollout();
rollout.setName(name);
rollout.setDescription(description);
rollout.setDistributionSet(findDistributionSetAndThrowExceptionIfNotFound(set));
rollout.setTargetFilterQuery(targetFilterQuery);
if (actionType != null) {
rollout.setActionType(actionType);
}
if (forcedTime != null) {
rollout.setForcedTime(forcedTime);
}
return rollout;
}
private DistributionSet findDistributionSetAndThrowExceptionIfNotFound(final Long setId) {
final DistributionSet set = distributionSetManagement.findDistributionSetById(setId);
if (set == null) {
throw new EntityNotFoundException("Distribution set cannot be set as it does not exixt" + setId);
}
return set;
}
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
/**
* Builder implementation for {@link RolloutGroup}.
*
*/
public class JpaRolloutGroupBuilder implements RolloutGroupBuilder {
@Override
public RolloutGroupCreate create() {
return new JpaRolloutGroupCreate();
}
}

View File

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.AbstractRolloutGroupCreate;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
public class JpaRolloutGroupCreate extends AbstractRolloutGroupCreate<RolloutGroupCreate>
implements RolloutGroupCreate {
@Override
public JpaRolloutGroup build() {
final JpaRolloutGroup group = new JpaRolloutGroup();
group.setName(name);
group.setDescription(description);
group.setTargetFilterQuery(targetFilterQuery);
if (targetPercentage == null) {
targetPercentage = 100F;
}
group.setTargetPercentage(targetPercentage);
if (conditions != null) {
group.setSuccessCondition(conditions.getSuccessCondition());
group.setSuccessConditionExp(conditions.getSuccessConditionExp());
group.setSuccessAction(conditions.getSuccessAction());
group.setSuccessActionExp(conditions.getSuccessActionExp());
group.setErrorCondition(conditions.getErrorCondition());
group.setErrorConditionExp(conditions.getErrorConditionExp());
group.setErrorAction(conditions.getErrorAction());
group.setErrorActionExp(conditions.getErrorActionExp());
}
return group;
}
}

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleUpdate;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* Builder implementation for {@link SoftwareModule}.
*
*/
public class JpaSoftwareModuleBuilder implements SoftwareModuleBuilder {
private final SoftwareManagement softwareManagement;
public JpaSoftwareModuleBuilder(final SoftwareManagement softwareManagement) {
this.softwareManagement = softwareManagement;
}
@Override
public SoftwareModuleUpdate update(final long id) {
return new GenericSoftwareModuleUpdate(id);
}
@Override
public SoftwareModuleCreate create() {
return new JpaSoftwareModuleCreate(softwareManagement);
}
}

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.builder.AbstractSoftwareModuleUpdateCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleCreate;
import org.eclipse.hawkbit.repository.exception.ConstraintViolationException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* Create/build implementation.
*
*/
public class JpaSoftwareModuleCreate extends AbstractSoftwareModuleUpdateCreate<SoftwareModuleCreate>
implements SoftwareModuleCreate {
private final SoftwareManagement softwareManagement;
JpaSoftwareModuleCreate(final SoftwareManagement softwareManagement) {
this.softwareManagement = softwareManagement;
}
@Override
public JpaSoftwareModule build() {
return new JpaSoftwareModule(getSoftwareModuleTypeFromKeyString(type), name, version, description, vendor);
}
private SoftwareModuleType getSoftwareModuleTypeFromKeyString(final String type) {
if (type == null) {
throw new ConstraintViolationException("type cannot be null");
}
final SoftwareModuleType smType = softwareManagement.findSoftwareModuleTypeByKey(type.trim());
if (smType == null) {
throw new EntityNotFoundException(type.trim());
}
return smType;
}
}

View File

@@ -0,0 +1,33 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.GenericSoftwareModuleTypeUpdate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeUpdate;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* Builder implementation for {@link SoftwareModuleType}.
*
*/
public class JpaSoftwareModuleTypeBuilder implements SoftwareModuleTypeBuilder {
@Override
public SoftwareModuleTypeUpdate update(final long id) {
return new GenericSoftwareModuleTypeUpdate(id);
}
@Override
public SoftwareModuleTypeCreate create() {
return new JpaSoftwareModuleTypeCreate();
}
}

View File

@@ -0,0 +1,30 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.AbstractSoftwareModuleTypeUpdateCreate;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
/**
* Create/build implementation.
*
*/
public class JpaSoftwareModuleTypeCreate extends AbstractSoftwareModuleTypeUpdateCreate<SoftwareModuleTypeCreate>
implements SoftwareModuleTypeCreate {
JpaSoftwareModuleTypeCreate() {
}
@Override
public JpaSoftwareModuleType build() {
return new JpaSoftwareModuleType(key, name, description, maxAssignments, colour);
}
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.GenericTagUpdate;
import org.eclipse.hawkbit.repository.builder.TagBuilder;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TagUpdate;
/**
* Builder implementation for {@link Tag}.
*
*/
public class JpaTagBuilder implements TagBuilder {
@Override
public TagUpdate update(final long id) {
return new GenericTagUpdate(id);
}
@Override
public TagCreate create() {
return new JpaTagCreate();
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.AbstractTagUpdateCreate;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* Create/build implementation.
*
*/
public class JpaTagCreate extends AbstractTagUpdateCreate<TagCreate> implements TagCreate {
JpaTagCreate() {
}
public JpaDistributionSetTag buildDistributionSetTag() {
return new JpaDistributionSetTag(name, description, colour);
}
public JpaTargetTag buildTargetTag() {
return new JpaTargetTag(name, description, colour);
}
@Override
public Tag build() {
return new JpaTag(name, description, colour);
}
}

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.TargetBuilder;
import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate;
/**
* Builder implementation for {@link Target}.
*
*/
public class JpaTargetBuilder implements TargetBuilder {
@Override
public TargetUpdate update(final String controllerId) {
return new JpaTargetUpdate(controllerId);
}
@Override
public TargetCreate create() {
return new JpaTargetCreate();
}
}

View File

@@ -0,0 +1,52 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.builder.AbstractTargetUpdateCreate;
import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
/**
* Create/build implementation.
*
*/
public class JpaTargetCreate extends AbstractTargetUpdateCreate<TargetCreate> implements TargetCreate {
JpaTargetCreate() {
super(null);
}
@Override
public JpaTarget build() {
JpaTarget target;
if (StringUtils.isEmpty(securityToken)) {
target = new JpaTarget(controllerId);
} else {
target = new JpaTarget(controllerId, securityToken);
}
if (!StringUtils.isEmpty(name)) {
target.setName(name);
}
target.setDescription(description);
final JpaTargetInfo targetInfo = (JpaTargetInfo) target.getTargetInfo();
targetInfo.setAddress(address);
targetInfo.setUpdateStatus(getStatus().orElse(TargetUpdateStatus.UNKNOWN));
getLastTargetQuery().ifPresent(targetInfo::setLastTargetQuery);
return target;
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.builder.GenericTargetFilterQueryUpdate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryUpdate;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
/**
* Builder implementation for {@link TargetFilterQuery}.
*
*/
public class JpaTargetFilterQueryBuilder implements TargetFilterQueryBuilder {
private final DistributionSetManagement distributionSetManagement;
public JpaTargetFilterQueryBuilder(final DistributionSetManagement distributionSetManagement) {
this.distributionSetManagement = distributionSetManagement;
}
@Override
public TargetFilterQueryUpdate update(final long id) {
return new GenericTargetFilterQueryUpdate(id);
}
@Override
public TargetFilterQueryCreate create() {
return new JpaTargetFilterQueryCreate(distributionSetManagement);
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.builder.AbstractTargetFilterQueryUpdateCreate;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* Create/build implementation.
*
*/
public class JpaTargetFilterQueryCreate extends AbstractTargetFilterQueryUpdateCreate<TargetFilterQueryCreate>
implements TargetFilterQueryCreate {
private final DistributionSetManagement distributionSetManagement;
JpaTargetFilterQueryCreate(final DistributionSetManagement distributionSetManagement) {
this.distributionSetManagement = distributionSetManagement;
}
@Override
public JpaTargetFilterQuery build() {
return new JpaTargetFilterQuery(name, query,
getSet().map(this::findDistributionSetAndThrowExceptionIfNotFound).orElse(null));
}
private DistributionSet findDistributionSetAndThrowExceptionIfNotFound(final Long setId) {
final DistributionSet set = distributionSetManagement.findDistributionSetById(setId);
if (set == null) {
throw new EntityNotFoundException("Distribution set cannot be set as it does not exixt" + setId);
}
return set;
}
}

View File

@@ -0,0 +1,20 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.AbstractTargetUpdateCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate;
public class JpaTargetUpdate extends AbstractTargetUpdateCreate<TargetUpdate> implements TargetUpdate {
JpaTargetUpdate(final String controllerId) {
super(controllerId);
}
}

View File

@@ -120,7 +120,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
@Override
public String toString() {
return "BaseEntity [id=" + id + "]";
return this.getClass().getSimpleName() + " [id=" + id + "]";
}
public void setId(final Long id) {
@@ -172,10 +172,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
} else if (!id.equals(other.id)) {
return false;
}
if (optLockRevision != other.optLockRevision) {
return false;
}
return true;
return optLockRevision == other.optLockRevision;
}
}

View File

@@ -10,11 +10,11 @@ package org.eclipse.hawkbit.repository.jpa.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.hibernate.validator.constraints.NotEmpty;
/**
* {@link TenantAwareBaseEntity} extension for all entities that are named in
@@ -29,7 +29,7 @@ public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseE
@Column(name = "name", nullable = false, length = 64)
@Size(max = 64)
@NotNull
@NotEmpty
private String name;
@Column(name = "description", nullable = true, length = 512)
@@ -66,12 +66,10 @@ public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseE
return name;
}
@Override
public void setDescription(final String description) {
this.description = description;
}
@Override
public void setName(final String name) {
this.name = name;
}

View File

@@ -10,11 +10,11 @@ package org.eclipse.hawkbit.repository.jpa.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.hibernate.validator.constraints.NotEmpty;
/**
* Extension for {@link NamedEntity} that are versioned.
@@ -29,7 +29,7 @@ public abstract class AbstractJpaNamedVersionedEntity extends AbstractJpaNamedEn
@Column(name = "version", nullable = false, length = 64)
@Size(max = 64)
@NotNull
@NotEmpty
private String version;
/**
@@ -55,7 +55,6 @@ public abstract class AbstractJpaNamedVersionedEntity extends AbstractJpaNamedEn
return version;
}
@Override
public void setVersion(final String version) {
this.version = version;
}

View File

@@ -75,6 +75,11 @@ public class DistributionSetTypeElement implements Serializable {
this.mandatory = mandatory;
}
public DistributionSetTypeElement setMandatory(final boolean mandatory) {
this.mandatory = mandatory;
return this;
}
public boolean isMandatory() {
return mandatory;
}
@@ -95,4 +100,35 @@ public class DistributionSetTypeElement implements Serializable {
public String toString() {
return "DistributionSetTypeElement [mandatory=" + mandatory + ", dsType=" + dsType + ", smType=" + smType + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DistributionSetTypeElement other = (DistributionSetTypeElement) obj;
if (key == null) {
if (other.key != null) {
return false;
}
} else if (!key.equals(other.key)) {
return false;
}
return true;
}
}

View File

@@ -41,7 +41,6 @@ public class DistributionSetTypeElementCompositeKey implements Serializable {
* in the key
*/
DistributionSetTypeElementCompositeKey(final JpaDistributionSetType dsType, final JpaSoftwareModuleType smType) {
super();
this.dsType = dsType.getId();
this.smType = smType.getId();
}
@@ -61,4 +60,43 @@ public class DistributionSetTypeElementCompositeKey implements Serializable {
public void setSmType(final Long smType) {
this.smType = smType;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dsType == null) ? 0 : dsType.hashCode());
result = prime * result + ((smType == null) ? 0 : smType.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DistributionSetTypeElementCompositeKey other = (DistributionSetTypeElementCompositeKey) obj;
if (dsType == null) {
if (other.dsType != null) {
return false;
}
} else if (!dsType.equals(other.dsType)) {
return false;
}
if (smType == null) {
if (other.smType != null) {
return false;
}
} else if (!smType.equals(other.smType)) {
return false;
}
return true;
}
}

View File

@@ -10,8 +10,6 @@ package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.model.DistributionSet;
/**
* The DistributionSet Metadata composite key which contains the meta data key
* and the ID of the DistributionSet itself.
@@ -34,8 +32,8 @@ public final class DsMetadataCompositeKey implements Serializable {
* @param key
* the key of the meta data
*/
public DsMetadataCompositeKey(final DistributionSet distributionSet, final String key) {
this.distributionSet = distributionSet.getId();
public DsMetadataCompositeKey(final Long distributionSet, final String key) {
this.distributionSet = distributionSet;
this.key = key;
}

View File

@@ -99,7 +99,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
return distributionSet;
}
@Override
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
@@ -113,7 +112,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
return status;
}
@Override
public void setStatus(final Status status) {
this.status = status;
}
@@ -141,7 +139,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
return Collections.unmodifiableList(actionStatus);
}
@Override
public void setTarget(final Target target) {
this.target = (JpaTarget) target;
}

View File

@@ -104,6 +104,35 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
addMessage(message);
}
/**
* Creates a new {@link ActionStatus} object.
*
* @param status
* the status for this action status
* @param occurredAt
* the occurred timestamp
*/
public JpaActionStatus(final Status status, final long occurredAt) {
this.status = status;
this.occurredAt = occurredAt;
}
/**
* Creates a new {@link ActionStatus} object.
*
* @param status
* the status for this action status
* @param occurredAt
* the occurred timestamp
* @param message
* the message which should be added to this action status
*/
public JpaActionStatus(final Status status, final Long occurredAt, final String message) {
this.status = status;
this.occurredAt = occurredAt;
addMessage(message);
}
/**
* JPA default constructor.
*/
@@ -116,12 +145,10 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
return occurredAt;
}
@Override
public void setOccurredAt(final Long occurredAt) {
this.occurredAt = occurredAt;
}
@Override
public final void addMessage(final String message) {
if (message != null) {
if (messages == null) {
@@ -145,7 +172,6 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
return action;
}
@Override
public void setAction(final Action action) {
this.action = (JpaAction) action;
}
@@ -155,7 +181,6 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
return status;
}
@Override
public void setStatus(final Status status) {
this.status = status;
}

View File

@@ -23,6 +23,7 @@ import javax.validation.constraints.Size;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.hibernate.validator.constraints.NotEmpty;
/**
* JPA implementation of {@link LocalArtifact}.
@@ -37,14 +38,14 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
public class JpaArtifact extends AbstractJpaTenantAwareBaseEntity implements Artifact {
private static final long serialVersionUID = 1L;
@NotNull
@Column(name = "gridfs_file_name", length = 40)
@Size(max = 40)
@NotEmpty
private String gridFsFileName;
@NotNull
@Column(name = "provided_file_name", length = 256)
@Size(max = 256)
@NotEmpty
private String filename;
@ManyToOne(optional = false, cascade = { CascadeType.PERSIST })

View File

@@ -45,7 +45,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetInfo;
@@ -143,11 +142,15 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
* of the {@link DistributionSet}
* @param moduleList
* {@link SoftwareModule}s of the {@link DistributionSet}
* @param requiredMigrationStep
* of the {@link DistributionSet}
*/
public JpaDistributionSet(final String name, final String version, final String description,
final DistributionSetType type, final Collection<SoftwareModule> moduleList) {
final DistributionSetType type, final Collection<SoftwareModule> moduleList,
final boolean requiredMigrationStep) {
super(name, version, description);
this.requiredMigrationStep = requiredMigrationStep;
this.type = type;
if (moduleList != null) {
moduleList.forEach(this::addModule);
@@ -157,6 +160,25 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
}
}
/**
* Parameterized constructor.
*
* @param name
* of the {@link DistributionSet}
* @param version
* of the {@link DistributionSet}
* @param description
* of the {@link DistributionSet}
* @param type
* of the {@link DistributionSet}
* @param moduleList
* {@link SoftwareModule}s of the {@link DistributionSet}
*/
public JpaDistributionSet(final String name, final String version, final String description,
final DistributionSetType type, final Collection<SoftwareModule> moduleList) {
this(name, version, description, type, moduleList, false);
}
@Override
public Set<DistributionSetTag> getTags() {
if (tags == null) {
@@ -166,7 +188,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return Collections.unmodifiableSet(tags);
}
@Override
public boolean addTag(final DistributionSetTag tag) {
if (tags == null) {
tags = new HashSet<>();
@@ -175,7 +196,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return tags.add(tag);
}
@Override
public boolean removeTag(final DistributionSetTag tag) {
if (tags == null) {
return false;
@@ -211,13 +231,11 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return requiredMigrationStep;
}
@Override
public DistributionSet setDeleted(final boolean deleted) {
this.deleted = deleted;
return this;
}
@Override
public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) {
requiredMigrationStep = isRequiredMigrationStep;
return this;
@@ -261,7 +279,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return Collections.unmodifiableSet(modules);
}
@Override
public boolean addModule(final SoftwareModule softwareModule) {
if (modules == null) {
modules = new HashSet<>();
@@ -304,7 +321,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
}
}
@Override
public boolean removeModule(final SoftwareModule softwareModule) {
if (modules == null) {
return false;
@@ -323,21 +339,11 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
}
@Override
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
if (modules == null) {
return null;
}
return modules.stream().filter(module -> module.getType().equals(type)).findFirst().orElse(null);
}
@Override
public DistributionSetType getType() {
return type;
}
@Override
public void setType(final DistributionSetType type) {
this.type = type;
}

View File

@@ -28,7 +28,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
@IdClass(DsMetadataCompositeKey.class)
@Entity
@Table(name = "sp_ds_metadata")
public class JpaDistributionSetMetadata extends AbstractJpaMetaData implements DistributionSetMetadata {
public class JpaDistributionSetMetadata extends JpaMetaData implements DistributionSetMetadata {
private static final long serialVersionUID = 1L;
@Id
@@ -46,7 +46,7 @@ public class JpaDistributionSetMetadata extends AbstractJpaMetaData implements D
}
public DsMetadataCompositeKey getId() {
return new DsMetadataCompositeKey(distributionSet, getKey());
return new DsMetadataCompositeKey(distributionSet.getId(), getKey());
}
public void setDistributionSet(final DistributionSet distributionSet) {

View File

@@ -30,7 +30,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag;
@Table(name = "sp_distributionset_tag", indexes = {
@Index(name = "sp_idx_distribution_set_tag_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"name", "tenant" }, name = "uk_ds_tag"))
public class JpaDistributionSetTag extends AbstractJpaTag implements DistributionSetTag {
public class JpaDistributionSetTag extends JpaTag implements DistributionSetTag {
private static final long serialVersionUID = 1L;
@ManyToMany(mappedBy = "tags", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY)

View File

@@ -28,7 +28,9 @@ import javax.validation.constraints.Size;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.hibernate.validator.constraints.NotEmpty;
/**
* A distribution set type defines which software module types can or have to be
@@ -54,6 +56,7 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
@Column(name = "type_key", nullable = false, length = 64)
@Size(max = 64)
@NotEmpty
private String key;
@Column(name = "colour", nullable = true, length = 16)
@@ -90,13 +93,13 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
* of the type
* @param description
* of the type
* @param color
* @param colour
* of the type. It will be null by default
*/
public JpaDistributionSetType(final String key, final String name, final String description, final String color) {
public JpaDistributionSetType(final String key, final String name, final String description, final String colour) {
super(name, description);
this.key = key;
colour = color;
this.colour = colour;
}
@Override
@@ -114,8 +117,8 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return Collections.emptySet();
}
return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet());
return elements.stream().filter(DistributionSetTypeElement::isMandatory)
.map(DistributionSetTypeElement::getSmType).collect(Collectors.toSet());
}
@Override
@@ -124,7 +127,7 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return Collections.emptySet();
}
return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType())
return elements.stream().filter(element -> !element.isMandatory()).map(DistributionSetTypeElement::getSmType)
.collect(Collectors.toSet());
}
@@ -136,7 +139,7 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return true;
}
return new HashSet<DistributionSetTypeElement>(((JpaDistributionSetType) dsType).elements).equals(elements);
return new HashSet<>(((JpaDistributionSetType) dsType).elements).equals(elements);
}
private boolean isOneModuleListEmpty(final DistributionSetType dsType) {
@@ -150,41 +153,42 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements) && CollectionUtils.isEmpty(elements);
}
@Override
public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) {
public JpaDistributionSetType addOptionalModuleType(final SoftwareModuleType smType) {
return setModuleType(smType, false);
}
public JpaDistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) {
return setModuleType(smType, true);
}
private JpaDistributionSetType setModuleType(final SoftwareModuleType smType, final boolean mandatory) {
if (elements == null) {
elements = new HashSet<>();
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, mandatory));
return this;
}
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, false));
// check if this was in the list before before
final Optional<DistributionSetTypeElement> existing = elements.stream()
.filter(element -> element.getSmType().getKey().equals(smType.getKey())).findFirst();
if (existing.isPresent()) {
existing.get().setMandatory(mandatory);
} else {
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, mandatory));
}
return this;
}
@Override
public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) {
if (elements == null) {
elements = new HashSet<>();
}
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, true));
return this;
}
@Override
public DistributionSetType removeModuleType(final Long smTypeId) {
public JpaDistributionSetType removeModuleType(final Long smTypeId) {
if (elements == null) {
return this;
}
// we search by id (standard equals compares also revison)
final Optional<DistributionSetTypeElement> found = elements.stream()
.filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst();
if (found.isPresent()) {
elements.remove(found.get());
}
elements.stream().filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst()
.ifPresent(elements::remove);
return this;
}
@@ -194,14 +198,13 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return key;
}
@Override
public void setKey(final String key) {
this.key = key;
}
@Override
public boolean checkComplete(final DistributionSet distributionSet) {
return distributionSet.getModules().stream().map(module -> module.getType()).collect(Collectors.toList())
return distributionSet.getModules().stream().map(SoftwareModule::getType).collect(Collectors.toList())
.containsAll(getMandatoryModuleTypes());
}
@@ -210,7 +213,6 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
return colour;
}
@Override
public void setColour(final String colour) {
this.colour = colour;
}

View File

@@ -12,23 +12,23 @@ import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.MetaData;
import org.hibernate.validator.constraints.NotEmpty;
/**
* Meta data for entities.
*
*/
@MappedSuperclass
public abstract class AbstractJpaMetaData implements MetaData {
public class JpaMetaData implements MetaData {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "meta_key", nullable = false, length = 128)
@Size(min = 1, max = 128)
@NotNull
@NotEmpty
private String key;
@Column(name = "meta_value", length = 4000)
@@ -36,12 +36,12 @@ public abstract class AbstractJpaMetaData implements MetaData {
@Basic
private String value;
public AbstractJpaMetaData(final String key, final String value) {
public JpaMetaData(final String key, final String value) {
this.key = key;
this.value = value;
}
public AbstractJpaMetaData() {
public JpaMetaData() {
// Default constructor needed for JPA entities
}
@@ -50,7 +50,6 @@ public abstract class AbstractJpaMetaData implements MetaData {
return key;
}
@Override
public void setKey(final String key) {
this.key = key;
}
@@ -60,7 +59,6 @@ public abstract class AbstractJpaMetaData implements MetaData {
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}
@@ -85,7 +83,7 @@ public abstract class AbstractJpaMetaData implements MetaData {
if (!(this.getClass().isInstance(obj))) {
return false;
}
final AbstractJpaMetaData other = (AbstractJpaMetaData) obj;
final JpaMetaData other = (JpaMetaData) obj;
if (key == null) {
if (other.key != null) {
return false;

View File

@@ -30,12 +30,13 @@ import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.hibernate.validator.constraints.NotEmpty;
/**
* JPA implementation of a {@link Rollout}.
@@ -58,7 +59,7 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
@Column(name = "target_filter", length = 1024, nullable = false)
@Size(max = 1024)
@NotNull
@NotEmpty
private String targetFilterQuery;
@ManyToOne(fetch = FetchType.LAZY)
@@ -94,7 +95,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
return distributionSet;
}
@Override
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
@@ -113,7 +113,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
return targetFilterQuery;
}
@Override
public void setTargetFilterQuery(final String targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
}
@@ -140,7 +139,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
return actionType;
}
@Override
public void setActionType(final ActionType actionType) {
this.actionType = actionType;
}
@@ -150,7 +148,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
return forcedTime;
}
@Override
public void setForcedTime(final long forcedTime) {
this.forcedTime = forcedTime;
}

View File

@@ -24,6 +24,7 @@ import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupUpdatedEvent;
@@ -63,16 +64,19 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
private JpaRolloutGroup parent;
@Column(name = "success_condition", nullable = false)
@NotNull
private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD;
@Column(name = "success_condition_exp", length = 512, nullable = false)
@Size(max = 512)
@NotNull
private String successConditionExp;
@Column(name = "success_action", nullable = false)
@NotNull
private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP;
@Column(name = "success_action_exp", length = 512, nullable = false)
@Column(name = "success_action_exp", length = 512)
@Size(max = 512)
private String successActionExp;
@@ -108,7 +112,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return rollout;
}
@Override
public void setRollout(final Rollout rollout) {
this.rollout = (JpaRollout) rollout;
}
@@ -118,7 +121,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return status;
}
@Override
public void setStatus(final RolloutGroupStatus status) {
this.status = status;
}
@@ -145,7 +147,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return successCondition;
}
@Override
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
successCondition = finishCondition;
}
@@ -155,7 +156,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return successConditionExp;
}
@Override
public void setSuccessConditionExp(final String finishExp) {
successConditionExp = finishExp;
}
@@ -165,7 +165,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return errorCondition;
}
@Override
public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) {
this.errorCondition = errorCondition;
}
@@ -175,7 +174,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return errorConditionExp;
}
@Override
public void setErrorConditionExp(final String errorExp) {
errorConditionExp = errorExp;
}
@@ -185,7 +183,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return errorAction;
}
@Override
public void setErrorAction(final RolloutGroupErrorAction errorAction) {
this.errorAction = errorAction;
}
@@ -195,7 +192,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return errorActionExp;
}
@Override
public void setErrorActionExp(final String errorActionExp) {
this.errorActionExp = errorActionExp;
}
@@ -219,12 +215,10 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
this.totalTargets = totalTargets;
}
@Override
public void setSuccessAction(final RolloutGroupSuccessAction successAction) {
this.successAction = successAction;
}
@Override
public void setSuccessActionExp(final String successActionExp) {
this.successActionExp = successActionExp;
}
@@ -234,8 +228,7 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return targetFilterQuery;
}
@Override
public void setTargetFilterQuery(String targetFilterQuery) {
public void setTargetFilterQuery(final String targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
}
@@ -244,8 +237,7 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
return targetPercentage;
}
@Override
public void setTargetPercentage(float targetPercentage) {
public void setTargetPercentage(final float targetPercentage) {
this.targetPercentage = targetPercentage;
}
@@ -255,7 +247,7 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
@Override
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
totalTargetCountStatus = new TotalTargetCountStatus(new Long(totalTargets));
totalTargetCountStatus = new TotalTargetCountStatus(Long.valueOf(totalTargets));
}
return totalTargetCountStatus;
}
@@ -264,7 +256,6 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
* @param totalTargetCountStatus
* the totalTargetCountStatus to set
*/
@Override
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
this.totalTargetCountStatus = totalTargetCountStatus;
}

View File

@@ -108,7 +108,6 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
this.type = (JpaSoftwareModuleType) type;
}
@Override
public void addArtifact(final Artifact artifact) {
if (null == artifacts) {
artifacts = new ArrayList<>(4);
@@ -148,7 +147,6 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
}
}
@Override
public void setVendor(final String vendor) {
this.vendor = vendor;
}
@@ -174,9 +172,8 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
this.deleted = deleted;
}
@Override
public void setType(final SoftwareModuleType type) {
this.type = (JpaSoftwareModuleType) type;
public void setType(final JpaSoftwareModuleType type) {
this.type = type;
}
public List<SoftwareModuleMetadata> getMetadata() {

View File

@@ -28,7 +28,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
@IdClass(SwMetadataCompositeKey.class)
@Entity
@Table(name = "sp_sw_metadata")
public class JpaSoftwareModuleMetadata extends AbstractJpaMetaData implements SoftwareModuleMetadata {
public class JpaSoftwareModuleMetadata extends JpaMetaData implements SoftwareModuleMetadata {
private static final long serialVersionUID = 1L;
@Id
@@ -54,7 +54,6 @@ public class JpaSoftwareModuleMetadata extends AbstractJpaMetaData implements So
return softwareModule;
}
@Override
public void setSoftwareModule(final SoftwareModule softwareModule) {
this.softwareModule = softwareModule;
}

View File

@@ -14,10 +14,10 @@ import javax.persistence.Index;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.hibernate.validator.constraints.NotEmpty;
/**
* Type of a software modules.
@@ -37,7 +37,7 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
@Column(name = "type_key", nullable = false, length = 64)
@Size(max = 64)
@NotNull
@NotEmpty
private String key;
@Column(name = "max_ds_assignments", nullable = false)
@@ -84,7 +84,6 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
*/
public JpaSoftwareModuleType(final String key, final String name, final String description,
final int maxAssignments, final String colour) {
super();
this.key = key;
this.maxAssignments = maxAssignments;
setDescription(description);
@@ -99,7 +98,6 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
// Default Constructor for JPA.
}
@Override
public void setMaxAssignments(final int maxAssignments) {
this.maxAssignments = maxAssignments;
}
@@ -128,7 +126,6 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
return colour;
}
@Override
public void setColour(final String colour) {
this.colour = colour;
}
@@ -138,7 +135,6 @@ public class JpaSoftwareModuleType extends AbstractJpaNamedEntity implements Sof
return "SoftwareModuleType [key=" + key + ", getName()=" + getName() + ", getId()=" + getId() + "]";
}
@Override
public void setKey(final String key) {
this.key = key;
}

View File

@@ -23,14 +23,14 @@ import org.eclipse.hawkbit.repository.model.Tag;
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
// sub entities
@SuppressWarnings("squid:S2160")
public abstract class AbstractJpaTag extends AbstractJpaNamedEntity implements Tag {
public class JpaTag extends AbstractJpaNamedEntity implements Tag {
private static final long serialVersionUID = 1L;
@Column(name = "colour", nullable = true, length = 16)
@Size(max = 16)
private String colour;
protected AbstractJpaTag() {
protected JpaTag() {
// Default constructor needed for JPA entities
}
@@ -44,7 +44,7 @@ public abstract class AbstractJpaTag extends AbstractJpaNamedEntity implements T
* @param colour
* of tag in UI
*/
public AbstractJpaTag(final String name, final String description, final String colour) {
public JpaTag(final String name, final String description, final String colour) {
super(name, description);
this.colour = colour;
}
@@ -54,7 +54,6 @@ public abstract class AbstractJpaTag extends AbstractJpaNamedEntity implements T
return colour;
}
@Override
public void setColour(final String colour) {
this.colour = colour;
}

View File

@@ -33,7 +33,6 @@ import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.im.authentication.SpPermission;
@@ -51,6 +50,7 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Persistable;
/**
@@ -76,7 +76,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@Column(name = "controller_id", length = 64)
@Size(min = 1, max = 64)
@NotNull
@NotEmpty
private String controllerId;
@Transient
@@ -110,7 +110,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
*/
@Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128)
@Size(max = 64)
@NotNull
@NotEmpty
private String securityToken;
@CascadeOnDelete
@@ -174,7 +174,6 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
return Collections.unmodifiableList(rolloutTargetGroup);
}
@Override
public boolean addTag(final TargetTag tag) {
if (tags == null) {
tags = new HashSet<>();
@@ -183,7 +182,6 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
return tags.add(tag);
}
@Override
public boolean removeTag(final TargetTag tag) {
if (tags == null) {
return false;
@@ -266,7 +264,6 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
* @param securityToken
* the securityToken to set
*/
@Override
public void setSecurityToken(final String securityToken) {
this.securityToken = securityToken;
}
@@ -290,7 +287,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@Override
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new TargetDeletedEvent(getTenant(), getId(), EventPublisherHolder.getInstance().getApplicationId()));
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TargetDeletedEvent(getTenant(), getId(), EventPublisherHolder.getInstance().getApplicationId()));
}
}

View File

@@ -18,11 +18,11 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.hibernate.validator.constraints.NotEmpty;
/**
* Stored target filter.
@@ -40,12 +40,12 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
@Column(name = "name", length = 64, nullable = false)
@Size(max = 64)
@NotNull
@NotEmpty
private String name;
@Column(name = "query", length = 1024, nullable = false)
@Size(max = 1024)
@NotNull
@NotEmpty
private String query;
@ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class)
@@ -79,10 +79,11 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
* @param autoAssignDistributionSet
* of the {@link TargetFilterQuery}.
*/
public JpaTargetFilterQuery(String name, String query, JpaDistributionSet autoAssignDistributionSet) {
public JpaTargetFilterQuery(final String name, final String query,
final DistributionSet autoAssignDistributionSet) {
this.name = name;
this.query = query;
this.autoAssignDistributionSet = autoAssignDistributionSet;
this.autoAssignDistributionSet = (JpaDistributionSet) autoAssignDistributionSet;
}
@Override
@@ -90,7 +91,6 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
return name;
}
@Override
public void setName(final String name) {
this.name = name;
}
@@ -100,7 +100,6 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
return query;
}
@Override
public void setQuery(final String query) {
this.query = query;
}
@@ -110,8 +109,7 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity imple
return autoAssignDistributionSet;
}
@Override
public void setAutoAssignDistributionSet(DistributionSet distributionSet) {
autoAssignDistributionSet = (JpaDistributionSet)distributionSet;
public void setAutoAssignDistributionSet(final JpaDistributionSet distributionSet) {
this.autoAssignDistributionSet = distributionSet;
}
}

View File

@@ -40,20 +40,16 @@ import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.PollStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.eclipse.persistence.descriptors.DescriptorEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Persistable;
@@ -71,7 +67,7 @@ import org.springframework.data.domain.Persistable;
@Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") })
@Entity
@EntityListeners(EntityPropertyChangeListener.class)
public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareEntity {
public class JpaTargetInfo implements Persistable<Long>, TargetInfo {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class);
@@ -176,25 +172,7 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareE
}
}
/**
* @param address
* the target address to set
*
* @throws IllegalArgumentException
* If the given string violates RFC&nbsp;2396
*/
@Override
public void setAddress(final String address) {
// check if this is a real URI
if (address != null) {
try {
URI.create(address);
} catch (final IllegalArgumentException e) {
throw new InvalidTargetAddressException(
"The given address " + address + " violates the RFC-2396 specification", e);
}
}
this.address = address;
}
@@ -330,20 +308,4 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareE
}
return true;
}
@Override
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
// there is no target info created event
}
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TargetUpdatedEvent(this.getTarget(), EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
// there is no target info deleted event
}
}

View File

@@ -30,7 +30,7 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
@Table(name = "sp_target_tag", indexes = {
@Index(name = "sp_idx_target_tag_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"name", "tenant" }, name = "uk_targ_tag"))
public class JpaTargetTag extends AbstractJpaTag implements TargetTag {
public class JpaTargetTag extends JpaTag implements TargetTag {
private static final long serialVersionUID = 1L;
@ManyToMany(mappedBy = "tags", targetEntity = JpaTarget.class, fetch = FetchType.LAZY)

View File

@@ -17,6 +17,7 @@ import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.hibernate.validator.constraints.NotEmpty;
/**
* A JPA entity which stores the tenant specific configuration.
@@ -33,7 +34,7 @@ public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity imp
@Column(name = "conf_key", length = 128, nullable = false)
@Size(max = 128)
@NotNull
@NotEmpty
private String key;
@Column(name = "conf_value", length = 512, nullable = false)
@@ -66,7 +67,6 @@ public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity imp
return key;
}
@Override
public void setKey(final String key) {
this.key = key;
}
@@ -76,7 +76,6 @@ public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity imp
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}

View File

@@ -76,7 +76,6 @@ public class JpaTenantMetaData extends AbstractJpaBaseEntity implements TenantMe
return defaultDsType;
}
@Override
public void setDefaultDsType(final DistributionSetType defaultDsType) {
this.defaultDsType = (JpaDistributionSetType) defaultDsType;
}

View File

@@ -40,10 +40,12 @@ public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator {
}
@Override
public void eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
public void eval(final Rollout rollout, final RolloutGroup rolloutG, final String expression) {
final JpaRolloutGroup rolloutGroup = (JpaRolloutGroup) rolloutG;
systemSecurityContext.runAsSystem(() -> {
rolloutGroup.setStatus(RolloutGroupStatus.ERROR);
rolloutGroupRepository.save((JpaRolloutGroup) rolloutGroup);
rolloutGroupRepository.save(rolloutGroup);
rolloutManagement.pauseRollout(rollout);
return null;
});

View File

@@ -21,12 +21,8 @@ public interface RolloutGroupConditionEvaluator {
// percentage value between 0 and 100
try {
final Integer value = Integer.valueOf(expression);
if (value >= 0 || value <= 100) {
return true;
}
return true;
return value >= 0 && value <= 100;
} catch (final NumberFormatException e) {
return false;
}
}

View File

@@ -50,8 +50,9 @@ import cz.jirutka.rsql.parser.ast.RSQLOperators;
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
/**
* A utility class which is able to parse RSQL strings into an spring data {@link Specification} which then can be
* enhanced sql queries to filter entities. RSQL parser library: https://github.com/jirutka/rsql-parser
* A utility class which is able to parse RSQL strings into an spring data
* {@link Specification} which then can be enhanced sql queries to filter
* entities. RSQL parser library: https://github.com/jirutka/rsql-parser
*
* <ul>
* <li>Equal to : ==</li>
@@ -71,13 +72,15 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor;
* <li>name==targetId1 or description==plugAndPlay or updateStatus==UNKNOWN</li>
* </ul>
* <p>
* There is also a mechanism that allows to refer to known macros that can resolved by an optional {@link StrLookup}
* (cp. {@link VirtualPropertyResolver}).<br>
* An example that queries for all overdue targets using the ${OVERDUE_TS} placeholder introduced by
* {@link VirtualPropertyResolver} looks like this:<br>
* There is also a mechanism that allows to refer to known macros that can
* resolved by an optional {@link StrLookup} (cp.
* {@link VirtualPropertyResolver}).<br>
* An example that queries for all overdue targets using the ${OVERDUE_TS}
* placeholder introduced by {@link VirtualPropertyResolver} looks like
* this:<br>
* <em>lastControllerRequestAt=le=${OVERDUE_TS}</em><br>
* It is possible to escape a macro expression by using a second '$': $${OVERDUE_TS} would prevent the ${OVERDUE_TS}
* token from being expanded.
* It is possible to escape a macro expression by using a second '$':
* $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded.
*
*/
public final class RSQLUtility {
@@ -111,7 +114,7 @@ public final class RSQLUtility {
* if the RSQL syntax is wrong
*/
public static <A extends Enum<A> & FieldNameProvider, T> Specification<T> parse(final String rsql,
final Class<A> fieldNameProvider, VirtualPropertyReplacer virtualPropertyReplacer) {
final Class<A> fieldNameProvider, final VirtualPropertyReplacer virtualPropertyReplacer) {
return new RSQLSpecification<>(rsql.toLowerCase(), fieldNameProvider, virtualPropertyReplacer);
}
@@ -146,7 +149,7 @@ public final class RSQLUtility {
private final VirtualPropertyReplacer virtualPropertyReplacer;
private RSQLSpecification(final String rsql, final Class<A> enumType,
VirtualPropertyReplacer virtualPropertyReplacer) {
final VirtualPropertyReplacer virtualPropertyReplacer) {
this.rsql = rsql;
this.enumType = enumType;
this.virtualPropertyReplacer = virtualPropertyReplacer;
@@ -193,7 +196,7 @@ public final class RSQLUtility {
private final SimpleTypeConverter simpleTypeConverter;
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType,
VirtualPropertyReplacer virtualPropertyReplacer) {
final VirtualPropertyReplacer virtualPropertyReplacer) {
this.root = root;
this.cb = cb;
this.enumType = enumType;
@@ -225,7 +228,7 @@ public final class RSQLUtility {
private String getAndValidatePropertyFieldName(final A propertyEnum, final ComparisonNode node) {
final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
final String[] graph = node.getSelector().split("\\" + SUB_ATTRIBUTE_SEPERATOR);
validateMapParamter(propertyEnum, node, graph);
@@ -281,7 +284,7 @@ public final class RSQLUtility {
private Path<Object> getFieldPath(final A enumField, final String finalProperty) {
Path<Object> fieldPath = null;
final String[] split = finalProperty.split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
final String[] split = finalProperty.split("\\" + SUB_ATTRIBUTE_SEPERATOR);
if (split.length == 0) {
return root.get(split[0]);
}
@@ -336,7 +339,7 @@ public final class RSQLUtility {
final String enumFieldName = enumField.name().toLowerCase();
if (enumField.isMap()) {
return enumFieldName + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + "keyName";
return enumFieldName + SUB_ATTRIBUTE_SEPERATOR + "keyName";
}
return enumFieldName;
@@ -345,8 +348,7 @@ public final class RSQLUtility {
final List<String> expectedSubFieldList = Arrays.stream(enumType.getEnumConstants())
.filter(enumField -> !enumField.getSubEntityAttributes().isEmpty()).flatMap(enumField -> {
final List<String> subEntity = enumField.getSubEntityAttributes().stream()
.map(fieldName -> enumField.name().toLowerCase()
+ FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + fieldName)
.map(fieldName -> enumField.name().toLowerCase() + SUB_ATTRIBUTE_SEPERATOR + fieldName)
.collect(Collectors.toList());
return subEntity.stream();
@@ -357,7 +359,7 @@ public final class RSQLUtility {
private A getFieldEnumByName(final ComparisonNode node) {
String enumName = node.getSelector();
final String[] graph = enumName.split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
final String[] graph = enumName.split("\\" + SUB_ATTRIBUTE_SEPERATOR);
if (graph.length != 0) {
enumName = graph[0];
}
@@ -536,7 +538,7 @@ public final class RSQLUtility {
if (!enumField.isMap()) {
return null;
}
final String[] graph = node.getSelector().split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR);
final String[] graph = node.getSelector().split("\\" + SUB_ATTRIBUTE_SEPERATOR);
final String keyValue = graph[graph.length - 1];
if (fieldPath instanceof MapJoin) {
// Currently we support only string key .So below cast is safe.