Repository API query signatures Entity free (#403)

* Migrated target management queries to IDs inetsead of full entities

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

* Added missing comment.

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

* refactored target,DS,cont,deploy,rg mangement.

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

* Adde versioning documentation.

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

* Rollout, Dist and Software mgmt refactored

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

* Readded line that was remove by incident. 

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

* Fixed broken tests.

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

* Query management refactored

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

* Fix bug of auto assign DS delete

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

* Switch to collection

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

* Fixed compile error

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

* Small glitches

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

* Fixed test after merge

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-01-11 14:32:55 +01:00
committed by GitHub
parent 824ef2982f
commit 889d1492fb
97 changed files with 1126 additions and 1289 deletions

View File

@@ -61,11 +61,11 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
*
* @param pageable
* page parameters
* @param ds
* @param dsId
* the {@link DistributionSet} on which will be filtered
* @return the found {@link Action}s
*/
Page<Action> findByDistributionSet(final Pageable pageable, final JpaDistributionSet ds);
Page<Action> findByDistributionSetId(final Pageable pageable, final Long dsId);
/**
* Retrieves all {@link Action}s which are referring the given
@@ -73,11 +73,11 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
*
* @param pageable
* page parameters
* @param target
* @param controllerId
* the target to find assigned actions
* @return the found {@link Action}s
*/
Slice<Action> findByTarget(Pageable pageable, JpaTarget target);
Slice<Action> findByTargetControllerId(Pageable pageable, String controllerId);
/**
* Retrieves all {@link Action}s which are active and referring to the given
@@ -97,7 +97,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
*
* @param sort
* order
* @param target
* @param controllerId
* the target to find assigned actions
* @param active
* the action active flag
@@ -105,7 +105,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* @return the found {@link Action}
*/
@EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD)
Optional<Action> findFirstByTargetAndActive(final Sort sort, final JpaTarget target, boolean active);
Optional<Action> findFirstByTargetControllerIdAndActive(final Sort sort, final String controllerId, boolean active);
/**
* Retrieves latest {@link Action} for given target and
@@ -162,8 +162,8 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* @return a list of actions ordered by action ID
*/
@EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD)
@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);
@Query("Select a from JpaAction a where a.target.controllerId = :target and a.active= :active order by a.id")
List<Action> findByActiveAndTarget(@Param("target") String target, @Param("active") boolean active);
/**
* Switches the status of actions from one specific status into another,
@@ -203,11 +203,11 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
/**
* Counts all {@link Action}s referring to the given target.
*
* @param target
* @param controllerId
* the target to count the {@link Action}s
* @return the count of actions referring to the given target
*/
Long countByTarget(JpaTarget target);
Long countByTargetControllerId(String controllerId);
/**
* Counts all {@link Action}s referring to the given DistributionSet.
@@ -216,7 +216,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* DistributionSet to count the {@link Action}s from
* @return the count of actions referring to the given distributionSet
*/
Long countByDistributionSet(JpaDistributionSet distributionSet);
Long countByDistributionSetId(Long distributionSet);
/**
* Counts all actions referring to a given rollout and rolloutgroup which
@@ -303,13 +303,13 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
/**
* Retrieves all actions for a specific rollout and in a specific status.
*
* @param rollout
* @param rolloutId
* the rollout the actions beglong to
* @param actionStatus
* the status of the actions
* @return the actions referring a specific rollout an in a specific status
*/
List<Action> findByRolloutAndStatus(JpaRollout rollout, Status actionStatus);
List<Action> findByRolloutIdAndStatus(Long rolloutId, Status actionStatus);
/**
* Get list of objects which has details of status and count of targets in

View File

@@ -44,11 +44,11 @@ public interface ActionStatusRepository
*
* @param pageReq
* parameters
* @param action
* @param actionId
* of the status entries
* @return pages list of {@link ActionStatus} entries
*/
Page<ActionStatus> findByAction(Pageable pageReq, JpaAction action);
Page<ActionStatus> findByActionId(Pageable pageReq, Long actionId);
/**
* Finds all status updates for the defined action and target including
@@ -58,11 +58,11 @@ public interface ActionStatusRepository
* for page configuration
* @param target
* to look for
* @param action
* @param actionId
* to look for
* @return Page with found targets
*/
@EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD)
Page<ActionStatus> getByAction(Pageable pageReq, JpaAction action);
Page<ActionStatus> getByActionId(Pageable pageReq, Long actionId);
}

View File

@@ -11,10 +11,8 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -89,7 +87,7 @@ public interface DistributionSetRepository
* @return list of {@link DistributionSet#getId()}
*/
@Query("select ac.distributionSet.id from JpaAction ac where ac.distributionSet.id in :ids")
List<Long> findAssignedToTargetDistributionSetsById(@Param("ids") Long... ids);
List<Long> findAssignedToTargetDistributionSetsById(@Param("ids") Collection<Long> ids);
/**
* Finds {@link DistributionSet}s based on given ID that are assigned yet to
@@ -100,7 +98,7 @@ public interface DistributionSetRepository
* @return list of {@link DistributionSet#getId()}
*/
@Query("select ra.distributionSet.id from JpaRollout ra where ra.distributionSet.id in :ids")
List<Long> findAssignedToRolloutDistributionSetsById(@Param("ids") Long... ids);
List<Long> findAssignedToRolloutDistributionSetsById(@Param("ids") Collection<Long> ids);
/**
* Finds the distribution set for a specific action.
@@ -109,17 +107,17 @@ public interface DistributionSetRepository
* the action associated with the distribution set to find
* @return the distribution set associated with the given action
*/
@Query("select DISTINCT d from JpaDistributionSet d join fetch d.modules m join d.actions a where a = :action")
JpaDistributionSet findByAction(@Param("action") JpaAction action);
@Query("select DISTINCT d from JpaDistributionSet d join fetch d.modules m join d.actions a where a.id = :action")
JpaDistributionSet findByActionId(@Param("action") Long action);
/**
* Counts {@link DistributionSet} instances of given type in the repository.
*
* @param type
* @param typeId
* to search for
* @return number of found {@link DistributionSet}s
*/
long countByType(JpaDistributionSetType type);
long countByTypeId(Long typeId);
/**
* Counts {@link DistributionSet} with given

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
import org.eclipse.hawkbit.artifact.repository.ArtifactStoreException;
@@ -104,10 +105,14 @@ public class JpaArtifactManagement implements ArtifactManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public boolean clearArtifactBinary(final Artifact existing) {
public boolean clearArtifactBinary(final Long existing) {
return clearArtifactBinary(Optional.ofNullable(localArtifactRepository.findOne(existing))
.orElseThrow(() -> new EntityNotFoundException("Artifact with given ID" + existing + " not found.")));
}
for (final Artifact lArtifact : localArtifactRepository
.findByGridFsFileName(((JpaArtifact) existing).getGridFsFileName())) {
private boolean clearArtifactBinary(final JpaArtifact existing) {
for (final Artifact lArtifact : localArtifactRepository.findByGridFsFileName(existing.getGridFsFileName())) {
if (!lArtifact.getSoftwareModule().isDeleted()
&& Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) {
return false;
@@ -115,8 +120,8 @@ public class JpaArtifactManagement implements ArtifactManagement {
}
try {
LOG.debug("deleting artifact from repository {}", ((JpaArtifact) existing).getGridFsFileName());
artifactRepository.deleteBySha1(((JpaArtifact) existing).getGridFsFileName());
LOG.debug("deleting artifact from repository {}", existing.getGridFsFileName());
artifactRepository.deleteBySha1(existing.getGridFsFileName());
return true;
} catch (final ArtifactStoreException e) {
throw new ArtifactDeleteFailedException(e);
@@ -166,10 +171,13 @@ public class JpaArtifactManagement implements ArtifactManagement {
}
@Override
public DbArtifact loadArtifactBinary(final Artifact artifact) {
final DbArtifact result = artifactRepository.getArtifactBySha1(((JpaArtifact) artifact).getGridFsFileName());
public DbArtifact loadArtifactBinary(final Long artifactId) {
final JpaArtifact artifact = Optional.ofNullable(localArtifactRepository.findOne(artifactId))
.orElseThrow(() -> new EntityNotFoundException("Artifact with given id " + artifactId + " not found."));
final DbArtifact result = artifactRepository.getArtifactBySha1(artifact.getGridFsFileName());
if (result == null) {
throw new GridFSDBFileNotFoundException(((JpaArtifact) artifact).getGridFsFileName());
throw new GridFSDBFileNotFoundException(artifact.getGridFsFileName());
}
return result;

View File

@@ -36,6 +36,7 @@ import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecuto
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus_;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
@@ -45,7 +46,6 @@ import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications;
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.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
@@ -135,12 +135,10 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateLastTargetQuery(final String controllerId, final URI address) {
final Target target = targetRepository.findByControllerId(controllerId);
if (target == null) {
throw new EntityNotFoundException(controllerId);
}
final Target target = Optional.ofNullable(targetRepository.findByControllerId(controllerId))
.orElseThrow(() -> new EntityNotFoundException("Target with given ID " + controllerId + " not found"));
return updateLastTargetQuery(target.getTargetInfo(), address).getTarget();
return updateTargetStatus(target.getTargetInfo(), null, System.currentTimeMillis(), address).getTarget();
}
@Override
@@ -158,7 +156,7 @@ public class JpaControllerManagement implements ControllerManagement {
}
@Override
public boolean hasTargetArtifactAssigned(final String controllerId, final Artifact localArtifact) {
public boolean hasTargetArtifactAssigned(final String controllerId, final Long localArtifact) {
final Target target = targetRepository.findByControllerId(controllerId);
if (target == null) {
return false;
@@ -167,7 +165,7 @@ public class JpaControllerManagement implements ControllerManagement {
}
@Override
public boolean hasTargetArtifactAssigned(final Long targetId, final Artifact localArtifact) {
public boolean hasTargetArtifactAssigned(final Long targetId, final Long localArtifact) {
final Target target = targetRepository.findOne(targetId);
if (target == null) {
return false;
@@ -176,10 +174,11 @@ public class JpaControllerManagement implements ControllerManagement {
}
@Override
public Optional<Action> findOldestActiveActionByTarget(final Target target) {
public Optional<Action> findOldestActiveActionByTarget(final String controllerId) {
// used in favorite to findFirstByTargetAndActiveOrderByIdAsc due to
// DATAJPA-841 issue.
return actionRepository.findFirstByTargetAndActive(new Sort(Direction.ASC, "id"), (JpaTarget) target, true);
return actionRepository.findFirstByTargetControllerIdAndActive(new Sort(Direction.ASC, "id"), controllerId,
true);
}
@Override
@@ -208,13 +207,10 @@ public class JpaControllerManagement implements ControllerManagement {
return result;
}
return updateLastTargetQuery(target.getTargetInfo(), address).getTarget();
return updateTargetStatus(target.getTargetInfo(), null, System.currentTimeMillis(), address).getTarget();
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetInfo updateTargetStatus(final TargetInfo targetInfo, final TargetUpdateStatus status,
private TargetInfo updateTargetStatus(final TargetInfo targetInfo, final TargetUpdateStatus status,
final Long lastTargetQuery, final URI address) {
final JpaTargetInfo mtargetInfo = (JpaTargetInfo) entityManager.merge(targetInfo);
if (status != null) {
@@ -431,22 +427,24 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action registerRetrieved(final Action action, final String message) {
return handleRegisterRetrieved((JpaAction) action, message);
public Action registerRetrieved(final Long actionId, final String message) {
return handleRegisterRetrieved(actionId, message);
}
/**
* Registers retrieved status for given {@link Target} and {@link Action} if
* it does not exist yet.
*
* @param action
* @param actionId
* to the handle status for
* @param message
* for the status
* @return the updated action in case the status has been changed to
* {@link Status#RETRIEVED}
*/
private Action handleRegisterRetrieved(final JpaAction action, final String message) {
private Action handleRegisterRetrieved(final Long actionId, final String message) {
final JpaAction action = Optional.ofNullable(actionRepository.findById(actionId)).orElseThrow(
() -> new EntityNotFoundException("Actionw ith given ID " + actionId + " doesn not exist."));
// do a manual query with CriteriaBuilder to avoid unnecessary field
// queries and an extra
// count query made by spring-data when using pageable requests, we
@@ -458,7 +456,7 @@ public class JpaControllerManagement implements ControllerManagement {
final Root<JpaActionStatus> actionStatusRoot = queryActionStatus.from(JpaActionStatus.class);
final CriteriaQuery<Object[]> query = queryActionStatus
.multiselect(actionStatusRoot.get(JpaActionStatus_.id), actionStatusRoot.get(JpaActionStatus_.status))
.where(cb.equal(actionStatusRoot.get(JpaActionStatus_.action), action))
.where(cb.equal(actionStatusRoot.get(JpaActionStatus_.action).get(JpaAction_.id), actionId))
.orderBy(cb.desc(actionStatusRoot.get(JpaActionStatus_.id)));
final List<Object[]> resultList = entityManager.createQuery(query).setFirstResult(0).setMaxResults(1)
.getResultList();
@@ -480,9 +478,8 @@ public class JpaControllerManagement implements ControllerManagement {
// we modify the action status and the controller won't get the
// cancel job anymore.
if (!action.isCancelingOrCanceled()) {
final JpaAction actionMerge = entityManager.merge(action);
actionMerge.setStatus(Status.RETRIEVED);
return actionRepository.save(actionMerge);
action.setStatus(Status.RETRIEVED);
return actionRepository.save(action);
}
}
return action;
@@ -507,13 +504,6 @@ public class JpaControllerManagement implements ControllerManagement {
.orElseThrow(() -> new EntityNotFoundException("Action with ID " + actionId + " not found!"));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetInfo updateLastTargetQuery(final TargetInfo target, final URI address) {
return updateTargetStatus(target, null, System.currentTimeMillis(), address);
}
@Override
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
final Long shippedBytesOverall) {
@@ -527,7 +517,7 @@ public class JpaControllerManagement implements ControllerManagement {
}
@Override
public Target findByTargetId(final long targetId) {
public Target findByTargetId(final Long targetId) {
return targetRepository.findOne(targetId);
}

View File

@@ -14,6 +14,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -51,6 +52,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Action;
@@ -85,7 +87,6 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
@@ -180,20 +181,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return assignDistributionSetToTargets(set, targets, null, null, actionMessage);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets, final Rollout rollout, final RolloutGroup rolloutGroup) {
final JpaDistributionSet set = distributoinSetRepository.findOne(dsID);
if (set == null) {
throw new EntityNotFoundException(
String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID));
}
return assignDistributionSetToTargets(set, targets, (JpaRollout) rollout, (JpaRolloutGroup) rolloutGroup, null);
}
/**
* method assigns the {@link DistributionSet} to all {@link Target}s by
* their IDs with a specific {@link ActionType} and {@code forcetime}.
@@ -375,22 +362,25 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public Action cancelAction(final Action action, final Target target) {
LOG.debug("cancelAction({}, {})", action, target);
public Action cancelAction(final Long actionId) {
LOG.debug("cancelAction({})", actionId);
final JpaAction action = Optional.ofNullable(actionRepository.findOne(actionId))
.orElseThrow(() -> new EntityNotFoundException("Action with given ID " + actionId + " not found"));
if (action.isCancelingOrCanceled()) {
throw new CancelActionNotAllowedException("Actions in canceling or canceled state cannot be canceled");
}
final JpaAction myAction = (JpaAction) entityManager.merge(action);
if (myAction.isActive()) {
if (action.isActive()) {
LOG.debug("action ({}) was still active. Change to {}.", action, Status.CANCELING);
myAction.setStatus(Status.CANCELING);
action.setStatus(Status.CANCELING);
// document that the status has been retrieved
actionStatusRepository.save(new JpaActionStatus(myAction, Status.CANCELING, System.currentTimeMillis(),
actionStatusRepository.save(new JpaActionStatus(action, Status.CANCELING, System.currentTimeMillis(),
"manual cancelation requested"));
final Action saveAction = actionRepository.save(myAction);
cancelAssignDistributionSetEvent(target, myAction.getId());
final Action saveAction = actionRepository.save(action);
cancelAssignDistributionSetEvent(action.getTarget(), action.getId());
return saveAction;
} else {
@@ -421,15 +411,16 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public Action forceQuitAction(final Action action) {
final JpaAction mergedAction = (JpaAction) entityManager.merge(action);
public Action forceQuitAction(final Long actionId) {
final JpaAction action = Optional.ofNullable(actionRepository.findOne(actionId))
.orElseThrow(() -> new EntityNotFoundException("Action with given ID " + actionId + " not found"));
if (!mergedAction.isCancelingOrCanceled()) {
if (!action.isCancelingOrCanceled()) {
throw new ForceQuitActionNotAllowedException(
"Action [id: " + action.getId() + "] is not canceled yet and cannot be force quit");
}
if (!mergedAction.isActive()) {
if (!action.isActive()) {
throw new ForceQuitActionNotAllowedException(
"Action [id: " + action.getId() + "] is not active and cannot be force quit");
}
@@ -437,39 +428,13 @@ public class JpaDeploymentManagement implements DeploymentManagement {
LOG.warn("action ({}) was still activ and has been force quite.", action);
// document that the status has been retrieved
actionStatusRepository.save(new JpaActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(),
actionStatusRepository.save(new JpaActionStatus(action, Status.CANCELED, System.currentTimeMillis(),
"A force quit has been performed."));
DeploymentHelper.successCancellation(mergedAction, actionRepository, targetRepository, targetInfoRepository,
DeploymentHelper.successCancellation(action, actionRepository, targetRepository, targetInfoRepository,
entityManager);
return actionRepository.save(mergedAction);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public void createScheduledAction(final Collection<Target> targets, final DistributionSet distributionSet,
final ActionType actionType, final Long forcedTime, final Rollout rollout,
final RolloutGroup rolloutGroup) {
// cancel all current scheduled actions for this target. E.g. an action
// is already scheduled and a next action is created then cancel the
// current scheduled action to cancel. E.g. a new scheduled action is
// created.
final List<Long> targetIds = targets.stream().map(t -> t.getId()).collect(Collectors.toList());
actionRepository.switchStatus(Action.Status.CANCELED, targetIds, false, Action.Status.SCHEDULED);
targets.forEach(target -> {
final JpaAction action = new JpaAction();
action.setTarget(target);
action.setActive(false);
action.setDistributionSet(distributionSet);
action.setActionType(actionType);
action.setForcedTime(forcedTime);
action.setStatus(Status.SCHEDULED);
action.setRollout(rollout);
action.setRolloutGroup(rolloutGroup);
actionRepository.save(action);
});
return actionRepository.save(action);
}
@Override
@@ -517,14 +482,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
}
}
@Override
@Modifying
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public Action startScheduledAction(final Long actionId) {
final JpaAction action = actionRepository.findById(actionId);
return startScheduledAction(action);
}
private Action startScheduledAction(final JpaAction action) {
// check if we need to override running update actions
final Set<Long> overrideObsoleteUpdateActions = overrideObsoleteUpdateActions(
@@ -595,17 +552,12 @@ public class JpaDeploymentManagement implements DeploymentManagement {
}
@Override
public Slice<Action> findActionsByTarget(final Pageable pageable, final Target target) {
return actionRepository.findByTarget(pageable, (JpaTarget) target);
public Slice<Action> findActionsByTarget(final String controllerId, final Pageable pageable) {
return actionRepository.findByTargetControllerId(pageable, controllerId);
}
@Override
public List<Action> findActionsByTarget(final Target target) {
return Collections.unmodifiableList(actionRepository.findByTarget(target));
}
@Override
public List<ActionWithStatusCount> findActionsWithStatusCountByTargetOrderByIdDesc(final Target target) {
public List<ActionWithStatusCount> findActionsWithStatusCountByTargetOrderByIdDesc(final String controllerId) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<JpaActionWithStatusCount> query = cb.createQuery(JpaActionWithStatusCount.class);
final Root<JpaAction> actionRoot = query.from(JpaAction.class);
@@ -621,24 +573,25 @@ public class JpaDeploymentManagement implements DeploymentManagement {
actionDsJoin.get(JpaDistributionSet_.id), actionDsJoin.get(JpaDistributionSet_.name),
actionDsJoin.get(JpaDistributionSet_.version), cb.count(actionStatusJoin),
actionRolloutJoin.get(JpaRollout_.name));
multiselect.where(cb.equal(actionRoot.get(JpaAction_.target), target));
multiselect.where(cb.equal(actionRoot.get(JpaAction_.target).get(JpaTarget_.controllerId), controllerId));
multiselect.orderBy(cb.desc(actionRoot.get(JpaAction_.id)));
multiselect.groupBy(actionRoot.get(JpaAction_.id));
return Collections.unmodifiableList(entityManager.createQuery(multiselect).getResultList());
}
@Override
public Page<Action> findActionsByTarget(final String rsqlParam, final Target target, final Pageable pageable) {
public Page<Action> findActionsByTarget(final String rsqlParam, final String controllerId,
final Pageable pageable) {
final Specification<JpaAction> byTargetSpec = createSpecificationFor(target, rsqlParam);
final Specification<JpaAction> byTargetSpec = createSpecificationFor(controllerId, rsqlParam);
final Page<JpaAction> actions = actionRepository.findAll(byTargetSpec, pageable);
return convertAcPage(actions, pageable);
}
private Specification<JpaAction> createSpecificationFor(final Target target, final String rsqlParam) {
private Specification<JpaAction> createSpecificationFor(final String controllerId, final String rsqlParam) {
final Specification<JpaAction> spec = RSQLUtility.parse(rsqlParam, ActionFields.class, virtualPropertyReplacer);
return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb),
cb.equal(root.get(JpaAction_.target), target));
cb.equal(root.get(JpaAction_.target).get(JpaTarget_.controllerId), controllerId));
}
private static Page<Action> convertAcPage(final Page<JpaAction> findAll, final Pageable pageable) {
@@ -646,28 +599,23 @@ public class JpaDeploymentManagement implements DeploymentManagement {
}
@Override
public Slice<Action> findActionsByTarget(final Target foundTarget, final Pageable pageable) {
return actionRepository.findByTarget(pageable, (JpaTarget) foundTarget);
public List<Action> findActiveActionsByTarget(final String controllerId) {
return actionRepository.findByActiveAndTarget(controllerId, true);
}
@Override
public List<Action> findActiveActionsByTarget(final Target target) {
return actionRepository.findByActiveAndTarget((JpaTarget) target, true);
public List<Action> findInActiveActionsByTarget(final String controllerId) {
return actionRepository.findByActiveAndTarget(controllerId, false);
}
@Override
public List<Action> findInActiveActionsByTarget(final Target target) {
return actionRepository.findByActiveAndTarget((JpaTarget) target, false);
public Long countActionsByTarget(final String controllerId) {
return actionRepository.countByTargetControllerId(controllerId);
}
@Override
public Long countActionsByTarget(final Target target) {
return actionRepository.countByTarget((JpaTarget) target);
}
@Override
public Long countActionsByTarget(final String rsqlParam, final Target target) {
return actionRepository.count(createSpecificationFor(target, rsqlParam));
public Long countActionsByTarget(final String rsqlParam, final String controllerId) {
return actionRepository.count(createSpecificationFor(controllerId, rsqlParam));
}
@Override
@@ -683,18 +631,13 @@ public class JpaDeploymentManagement implements DeploymentManagement {
}
@Override
public Page<ActionStatus> findActionStatusByAction(final Pageable pageReq, final Action action) {
return actionStatusRepository.findByAction(pageReq, (JpaAction) action);
public Page<ActionStatus> findActionStatusByAction(final Pageable pageReq, final Long actionId) {
return actionStatusRepository.findByActionId(pageReq, actionId);
}
@Override
public Page<ActionStatus> findActionStatusByActionWithMessages(final Pageable pageReq, final Action action) {
return actionStatusRepository.getByAction(pageReq, (JpaAction) action);
}
@Override
public List<Action> findActionsByRolloutAndStatus(final Rollout rollout, final Action.Status actionStatus) {
return actionRepository.findByRolloutAndStatus((JpaRollout) rollout, actionStatus);
public Page<ActionStatus> findActionStatusByActionWithMessages(final Pageable pageReq, final Long actionId) {
return actionStatusRepository.getByActionId(pageReq, actionId);
}
@Override
@@ -717,8 +660,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
}
@Override
public Slice<Action> findActionsByDistributionSet(final Pageable pageable, final DistributionSet ds) {
return actionRepository.findByDistributionSet(pageable, (JpaDistributionSet) ds);
public Slice<Action> findActionsByDistributionSet(final Pageable pageable, final Long dsId) {
return actionRepository.findByDistributionSetId(pageable, dsId);
}
@Override

View File

@@ -13,6 +13,7 @@ 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;
@@ -36,9 +37,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaDistributionSetTypeCreate;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata_;
@@ -50,7 +49,6 @@ import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
@@ -114,9 +112,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private AfterTransactionCommitExecutor afterCommit;
@Autowired
private TenantAware tenantAware;
@@ -195,14 +190,14 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
if (update.isRequiredMigrationStep() != null
&& !update.isRequiredMigrationStep().equals(set.isRequiredMigrationStep())) {
checkDistributionSetIsAssignedToTargets(set);
checkDistributionSetIsAssignedToTargets(update.getId());
set.setRequiredMigrationStep(update.isRequiredMigrationStep());
}
if (update.getType() != null) {
final DistributionSetType type = findDistributionSetTypeWithExceptionIfNotFound(update.getType());
if (!type.getId().equals(set.getType().getId())) {
checkDistributionSetIsAssignedToTargets(set);
checkDistributionSetIsAssignedToTargets(update.getId());
set.setType(type);
}
@@ -251,7 +246,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSet(final Long... distributionSetIDs) {
public void deleteDistributionSet(final Collection<Long> distributionSetIDs) {
final List<Long> assigned = distributionSetRepository
.findAssignedToTargetDistributionSetsById(distributionSetIDs);
assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs));
@@ -264,7 +259,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
// mark the rest as hard delete
final List<Long> toHardDelete = Arrays.stream(distributionSetIDs).filter(setId -> !assigned.contains(setId))
final List<Long> toHardDelete = distributionSetIDs.stream().filter(setId -> !assigned.contains(setId))
.collect(Collectors.toList());
// hard delete the rest if exists
@@ -274,10 +269,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
distributionSetRepository.deleteByIdIn(toHardDelete);
}
Arrays.stream(distributionSetIDs)
.forEach(dsId -> eventPublisher
.publishEvent(new DistributionSetDeletedEvent(tenantAware.getCurrentTenant(), dsId,
JpaDistributionSet.class.getName(), applicationContext.getId())));
distributionSetIDs.forEach(
dsId -> eventPublisher.publishEvent(new DistributionSetDeletedEvent(tenantAware.getCurrentTenant(),
dsId, JpaDistributionSet.class.getName(), applicationContext.getId())));
}
@Override
@@ -316,7 +310,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
throw new EntityNotFoundException("Not all given software modules where found.");
}
checkDistributionSetIsAssignedToTargets(set);
checkDistributionSetIsAssignedToTargets(setId);
modules.forEach(set::addModule);
@@ -330,7 +324,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId);
final JpaSoftwareModule module = findSoftwareModuleAndThrowExceptionIfNotFound(moduleId);
checkDistributionSetIsAssignedToTargets(set);
checkDistributionSetIsAssignedToTargets(setId);
set.removeModule(module);
@@ -349,7 +343,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
update.getColour().ifPresent(type::setColour);
if (hasModules(update)) {
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(update.getId());
update.getMandatory().ifPresent(
mand -> softwareModuleTypeRepository.findByIdIn(mand).forEach(type::addMandatoryModuleType));
@@ -378,7 +372,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
throw new EntityNotFoundException("Not all given software module types where found.");
}
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(dsTypeId);
modules.forEach(type::addMandatoryModuleType);
@@ -399,18 +393,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
throw new EntityNotFoundException("Not all given software module types where found.");
}
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(dsTypeId);
modules.forEach(type::addOptionalModuleType);
return distributionSetTypeRepository.save(type);
}
private void checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(final JpaDistributionSetType type) {
if (distributionSetRepository.countByType(type) > 0) {
private void checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(final Long type) {
if (distributionSetRepository.countByTypeId(type) > 0) {
throw new EntityReadOnlyException(String.format(
"distribution set type %s is already assigned to distribution sets and cannot be changed",
type.getName()));
"distribution set type %s is already assigned to distribution sets and cannot be changed", type));
}
}
@@ -421,7 +414,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public DistributionSetType unassignSoftwareModuleType(final Long dsTypeId, final Long softwareModuleTypeId) {
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId);
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(type);
checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(dsTypeId);
type.removeModuleType(softwareModuleTypeId);
@@ -604,15 +597,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSetType(final DistributionSetType ty) {
final JpaDistributionSetType type = (JpaDistributionSetType) ty;
public void deleteDistributionSetType(final Long typeId) {
if (distributionSetRepository.countByType(type) > 0) {
final JpaDistributionSetType toDelete = entityManager.merge(type);
final JpaDistributionSetType toDelete = Optional.ofNullable(distributionSetTypeRepository.findOne(typeId))
.orElseThrow(() -> new EntityNotFoundException(
"DistributionSet Type with given ID " + typeId + " does not exist"));
if (distributionSetRepository.countByTypeId(typeId) > 0) {
toDelete.setDeleted(true);
distributionSetTypeRepository.save(toDelete);
} else {
distributionSetTypeRepository.delete(type.getId());
distributionSetTypeRepository.delete(typeId);
}
}
@@ -725,13 +720,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
@Override
public DistributionSet findDistributionSetByAction(final Action action) {
return distributionSetRepository.findByAction((JpaAction) action);
public DistributionSet findDistributionSetByAction(final Long actionId) {
return distributionSetRepository.findByActionId(actionId);
}
@Override
public boolean isDistributionSetInUse(final DistributionSet distributionSet) {
return actionRepository.countByDistributionSet((JpaDistributionSet) distributionSet) > 0;
public boolean isDistributionSetInUse(final Long setId) {
return actionRepository.countByDistributionSetId(setId) > 0;
}
private static List<Specification<JpaDistributionSet>> buildDistributionSetSpecifications(
@@ -776,11 +771,10 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return specList;
}
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 void checkDistributionSetIsAssignedToTargets(final Long distributionSet) {
if (actionRepository.countByDistributionSetId(distributionSet) > 0) {
throw new EntityReadOnlyException(String.format(
"distribution set %s is already assigned to targets and cannot be changed", distributionSet));
}
}
@@ -822,10 +816,15 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> assignTag(final Collection<Long> dsIds, final DistributionSetTag tag) {
public List<DistributionSet> assignTag(final Collection<Long> dsIds, final Long dsTagId) {
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
allDs.forEach(ds -> ds.addTag(tag));
final DistributionSetTag distributionSetTag = Optional
.ofNullable(tagManagement.findDistributionSetTagById(dsTagId))
.orElseThrow(() -> new EntityNotFoundException(
"DistributionSet Tag with given ID " + dsTagId + " not found."));
allDs.forEach(ds -> ds.addTag(distributionSetTag));
return Collections
.unmodifiableList(allDs.stream().map(distributionSetRepository::save).collect(Collectors.toList()));
@@ -834,19 +833,34 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> unAssignAllDistributionSetsByTag(final DistributionSetTag tag) {
public List<DistributionSet> unAssignAllDistributionSetsByTag(final Long dsTagId) {
final DistributionSetTag distributionSetTag = Optional
.ofNullable(tagManagement.findDistributionSetTagById(dsTagId))
.orElseThrow(() -> new EntityNotFoundException(
"DistributionSet Tag with given ID " + dsTagId + " not found."));
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaDistributionSet> distributionSets = (Collection) tag.getAssignedToDistributionSet();
final Collection<JpaDistributionSet> distributionSets = (Collection) distributionSetTag
.getAssignedToDistributionSet();
return Collections.unmodifiableList(unAssignTag(distributionSets, tag));
return Collections.unmodifiableList(unAssignTag(distributionSets, distributionSetTag));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet unAssignTag(final Long dsId, final DistributionSetTag distributionSetTag) {
public DistributionSet unAssignTag(final Long dsId, final Long dsTagId) {
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(Arrays.asList(dsId));
if (allDs.isEmpty()) {
throw new EntityNotFoundException("DistributionSet with given ID " + dsId + " not found.");
}
final DistributionSetTag distributionSetTag = Optional
.ofNullable(tagManagement.findDistributionSetTagById(dsTagId))
.orElseThrow(() -> new EntityNotFoundException(
"DistributionSet Tag with given ID " + dsTagId + " not found."));
final List<JpaDistributionSet> unAssignTag = unAssignTag(allDs, distributionSetTag);
return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
}
@@ -869,22 +883,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSet(final DistributionSet set) {
deleteDistributionSet(set.getId());
public void deleteDistributionSet(final Long setId) {
if (!distributionSetRepository.exists(setId)) {
throw new EntityNotFoundException("DistributionSet with given ID " + setId + " does not exist.");
}
deleteDistributionSet(Lists.newArrayList(setId));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<DistributionSet> sets,
final DistributionSetTag tag) {
return toggleTagAssignment(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()),
tag.getName());
}
@Override
public Long countDistributionSetsByType(final DistributionSetType type) {
return distributionSetRepository.countByType((JpaDistributionSetType) type);
public Long countDistributionSetsByType(final Long typeId) {
return distributionSetRepository.countByTypeId(typeId);
}
}

View File

@@ -11,6 +11,7 @@ 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;
@@ -25,6 +26,7 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.RolloutGroupFields;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
@@ -149,7 +151,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
}
@Override
public Page<Target> findRolloutGroupTargets(final RolloutGroup rolloutGroup, final String rsqlParam,
public Page<Target> findRolloutGroupTargets(final Long rolloutGroupId, final String rsqlParam,
final Pageable pageable) {
final Specification<JpaTarget> rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class,
@@ -158,19 +160,25 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
return convertTPage(targetRepository.findAll((root, query, criteriaBuilder) -> {
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup);
return criteriaBuilder.and(rsqlSpecification.toPredicate(root, query, criteriaBuilder),
criteriaBuilder.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup));
criteriaBuilder.equal(
rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id),
rolloutGroupId));
}, pageable), pageable);
}
@Override
public Page<Target> findRolloutGroupTargets(final RolloutGroup rolloutGroup, final Pageable page) {
public Page<Target> findRolloutGroupTargets(final Long rolloutGroupId, final Pageable page) {
final JpaRolloutGroup rolloutGroup = Optional.ofNullable(rolloutGroupRepository.findOne(rolloutGroupId))
.orElseThrow(() -> new EntityNotFoundException(
"Rollout Group with given ID " + rolloutGroupId + " not found."));
if (isRolloutStatusReady(rolloutGroup)) {
// in case of status ready the action has not been created yet and
// the relation information between target and rollout-group is
// stored in the #TargetRolloutGroup.
return targetRepository.findByRolloutTargetGroupRolloutGroupId(rolloutGroup.getId(), page);
return targetRepository.findByRolloutTargetGroupRolloutGroupId(rolloutGroupId, page);
}
return targetRepository.findByActionsRolloutGroup((JpaRolloutGroup) rolloutGroup, page);
return targetRepository.findByActionsRolloutGroupId(rolloutGroupId, page);
}
private static boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) {
@@ -179,7 +187,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
@Override
public Page<TargetWithActionStatus> findAllTargetsWithActionStatus(final PageRequest pageRequest,
final RolloutGroup rolloutGroup) {
final Long rolloutGroupId) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
@@ -193,12 +201,13 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
final Root<RolloutTargetGroup> countQueryFrom = countQuery.distinct(true).from(RolloutTargetGroup.class);
countQueryFrom.join(RolloutTargetGroup_.target);
countQueryFrom.join(RolloutTargetGroup_.actions, JoinType.LEFT);
countQuery.select(cb.count(countQueryFrom))
.where(cb.equal(countQueryFrom.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup));
countQuery.select(cb.count(countQueryFrom)).where(cb
.equal(countQueryFrom.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id), rolloutGroupId));
final Long totalCount = entityManager.createQuery(countQuery).getSingleResult();
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetJoin, actionJoin.get(JpaAction_.status))
.where(cb.equal(targetRoot.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup));
.where(cb.equal(targetRoot.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id),
rolloutGroupId));
final List<TargetWithActionStatus> targetWithActionStatus = entityManager.createQuery(multiselect)
.setFirstResult(pageRequest.getOffset()).setMaxResults(pageRequest.getPageSize()).getResultList()
.stream().map(o -> new TargetWithActionStatus((Target) o[0], (Action.Status) o[1]))

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -32,6 +33,7 @@ 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.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
@@ -41,6 +43,7 @@ import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditio
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
@@ -336,8 +339,8 @@ public class JpaRolloutManagement implements RolloutManagement {
groupTargetFilter = baseFilter + ";" + group.getTargetFilterQuery();
}
final List<RolloutGroup> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout,
RolloutGroupStatus.READY, group);
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout, RolloutGroupStatus.READY,
group);
final long targetsInGroupFilter = targetManagement
.countAllTargetsByTargetFilterQueryAndNotInRolloutGroups(readyGroups, groupTargetFilter);
@@ -383,7 +386,7 @@ public class JpaRolloutManagement implements RolloutManagement {
return runInNewCountingTransaction("assignTargetsToRolloutGroup", status -> {
final PageRequest pageRequest = new PageRequest(0, Math.toIntExact(limit));
final List<RolloutGroup> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout,
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout,
RolloutGroupStatus.READY, group);
final Page<Target> targets = targetManagement
.findAllTargetsByTargetFilterQueryAndNotInRolloutGroups(pageRequest, readyGroups, targetFilter);
@@ -558,16 +561,57 @@ public class JpaRolloutManagement implements RolloutManagement {
final ActionType actionType = rollout.getActionType();
final long forceTime = rollout.getForcedTime();
final Page<Target> targets = targetManagement.findAllTargetsInRolloutGroupWithoutAction(pageRequest, group);
final Page<Target> targets = targetManagement.findAllTargetsInRolloutGroupWithoutAction(pageRequest,
groupId);
if (targets.getTotalElements() > 0) {
deploymentManagement.createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime,
rollout, group);
createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group);
}
return targets.getNumberOfElements();
});
}
/**
* Creates an action entry into the action repository. In case of existing
* scheduled actions the scheduled actions gets canceled. A scheduled action
* is created in-active.
*
* @param targets
* the targets to create scheduled actions for
* @param distributionSet
* the distribution set for the actions
* @param actionType
* the action type for the action
* @param forcedTime
* the forcedTime of the action
* @param rollout
* the roll out for this action
* @param rolloutGroup
* the roll out group for this action
*/
private void createScheduledAction(final Collection<Target> targets, final DistributionSet distributionSet,
final ActionType actionType, final Long forcedTime, final Rollout rollout,
final RolloutGroup rolloutGroup) {
// cancel all current scheduled actions for this target. E.g. an action
// is already scheduled and a next action is created then cancel the
// current scheduled action to cancel. E.g. a new scheduled action is
// created.
final List<Long> targetIds = targets.stream().map(t -> t.getId()).collect(Collectors.toList());
actionRepository.switchStatus(Action.Status.CANCELED, targetIds, false, Action.Status.SCHEDULED);
targets.forEach(target -> {
final JpaAction action = new JpaAction();
action.setTarget(target);
action.setActive(false);
action.setDistributionSet(distributionSet);
action.setActionType(actionType);
action.setForcedTime(forcedTime);
action.setStatus(Status.SCHEDULED);
action.setRollout(rollout);
action.setRolloutGroup(rolloutGroup);
actionRepository.save(action);
});
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
@@ -903,7 +947,11 @@ public class JpaRolloutManagement implements RolloutManagement {
}
@Override
public float getFinishedPercentForRunningGroup(final Long rolloutId, final RolloutGroup rolloutGroup) {
public float getFinishedPercentForRunningGroup(final Long rolloutId, final Long rolloutGroupId) {
final RolloutGroup rolloutGroup = Optional.ofNullable(rolloutGroupRepository.findOne(rolloutGroupId))
.orElseThrow(() -> new EntityNotFoundException(
"Rollout group with given ID " + rolloutGroupId + " not found."));
final long totalGroup = rolloutGroup.getTotalTargets();
final Long finished = actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rolloutId,
rolloutGroup.getId(), Action.Status.FINISHED);

View File

@@ -55,7 +55,6 @@ import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecifica
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;
@@ -204,9 +203,9 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version,
final SoftwareModuleType type) {
final Long typeId) {
return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type);
return softwareModuleRepository.findOneByNameAndVersionAndTypeId(name, version, typeId);
}
private boolean isUnassigned(final JpaSoftwareModule bsmMerged) {
@@ -225,7 +224,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) {
for (final Artifact localArtifact : swModule.getArtifacts()) {
artifactManagement.clearArtifactBinary(localArtifact);
artifactManagement.clearArtifactBinary(localArtifact.getId());
}
}
@@ -492,22 +491,23 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteSoftwareModuleType(final SoftwareModuleType ty) {
final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty;
public void deleteSoftwareModuleType(final Long typeId) {
final JpaSoftwareModuleType toDelete = Optional.ofNullable(softwareModuleTypeRepository.findOne(typeId))
.orElseThrow(() -> new EntityNotFoundException(
"Software Module Type with giben ID " + typeId + " does not exist."));
if (softwareModuleRepository.countByType(type) > 0
|| distributionSetTypeRepository.countByElementsSmType(type) > 0) {
final JpaSoftwareModuleType toDelete = entityManager.merge(type);
if (softwareModuleRepository.countByType(toDelete) > 0
|| distributionSetTypeRepository.countByElementsSmType(toDelete) > 0) {
toDelete.setDeleted(true);
softwareModuleTypeRepository.save(toDelete);
} else {
softwareModuleTypeRepository.delete(type.getId());
softwareModuleTypeRepository.delete(toDelete);
}
}
@Override
public Page<SoftwareModule> findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) {
return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set);
public Page<SoftwareModule> findSoftwareModuleByAssignedTo(final Pageable pageable, final Long setId) {
return softwareModuleRepository.findByAssignedToId(pageable, setId);
}
@Override

View File

@@ -97,7 +97,7 @@ public class JpaTagManagement implements TagManagement {
public void deleteTargetTag(final String targetTagName) {
final JpaTargetTag tag = targetTagRepository.findByNameEquals(targetTagName);
targetRepository.findByTag(tag).forEach(set -> {
targetRepository.findByTag(tag.getId()).forEach(set -> {
set.removeTag(tag);
targetRepository.save(set);
});

View File

@@ -13,8 +13,6 @@ 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;
@@ -45,6 +43,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
/**
* JPA implementation of {@link TargetFilterQueryManagement}.
@@ -54,18 +53,24 @@ import com.google.common.base.Strings;
@Validated
public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement {
@Autowired
private TargetFilterQueryRepository targetFilterQueryRepository;
private final TargetFilterQueryRepository targetFilterQueryRepository;
private final VirtualPropertyReplacer virtualPropertyReplacer;
private final DistributionSetManagement distributionSetManagement;
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
JpaTargetFilterQueryManagement(final TargetFilterQueryRepository targetFilterQueryRepository,
final VirtualPropertyReplacer virtualPropertyReplacer,
final DistributionSetManagement distributionSetManagement) {
this.targetFilterQueryRepository = targetFilterQueryRepository;
this.virtualPropertyReplacer = virtualPropertyReplacer;
this.distributionSetManagement = distributionSetManagement;
}
@Autowired
private DistributionSetManagement distributionSetManagement;
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Override
public TargetFilterQuery createTargetFilterQuery(final TargetFilterQueryCreate c) {
final JpaTargetFilterQueryCreate create = (JpaTargetFilterQueryCreate) c;
@@ -109,8 +114,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull final Pageable pageable,
final String rsqlFilter) {
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(final Pageable pageable, final String rsqlFilter) {
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
if (!Strings.isNullOrEmpty(rsqlFilter)) {
specList = Collections.singletonList(
@@ -120,18 +124,14 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(@NotNull final Pageable pageable,
final DistributionSet distributionSet) {
return findTargetFilterQueryByAutoAssignDS(pageable, distributionSet, null);
}
public Page<TargetFilterQuery> findTargetFilterQueryByAutoAssignDS(final Pageable pageable, final Long setId,
final String rsqlFilter) {
final List<Specification<JpaTargetFilterQuery>> specList = Lists.newArrayListWithExpectedSize(2);
final DistributionSet distributionSet = findDistributionSetAndThrowExceptionIfNotFound(setId);
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
@Override
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));
}
if (!Strings.isNullOrEmpty(rsqlFilter)) {
specList.add(RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class, virtualPropertyReplacer));
}
@@ -139,7 +139,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryWithAutoAssignDS(@NotNull final Pageable pageable) {
public Page<TargetFilterQuery> findTargetFilterQueryWithAutoAssignDS(final Pageable pageable) {
final List<Specification<JpaTargetFilterQuery>> specList = Collections
.singletonList(TargetFilterQuerySpecification.withAutoAssignDS());
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);

View File

@@ -49,7 +49,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
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;
@@ -90,6 +89,9 @@ public class JpaTargetManagement implements TargetManagement {
@Autowired
private TargetRepository targetRepository;
@Autowired
private TargetFilterQueryRepository targetFilterQueryRepository;
@Autowired
private TargetTagRepository targetTagRepository;
@@ -160,7 +162,12 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Slice<Target> findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) {
public Slice<Target> findTargetsByTargetFilterQuery(final Long targetFilterQueryId, final Pageable pageable) {
final TargetFilterQuery targetFilterQuery = Optional
.ofNullable(targetFilterQueryRepository.findOne(targetFilterQueryId))
.orElseThrow(() -> new EntityNotFoundException(
"TargetFilterQuery with given ID" + targetFilterQueryId + " not found"));
return findTargetsBySpec(
RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyReplacer), pageable);
}
@@ -203,13 +210,6 @@ public class JpaTargetManagement implements TargetManagement {
return targetRepository.save(target);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargets(final Long... targetIDs) {
deleteTargets(Lists.newArrayList(targetIDs));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@@ -220,6 +220,18 @@ public class JpaTargetManagement implements TargetManagement {
targetId, JpaTarget.class.getName(), applicationContext.getId())));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTarget(final String controllerID) {
final Long targetId = Optional.ofNullable(targetRepository.findByControllerId(controllerID))
.orElseThrow(
() -> new EntityNotFoundException("Target with given ID " + controllerID + " does not exist."))
.getId();
targetRepository.delete(targetId);
}
@Override
public Page<Target> findTargetByAssignedDistributionSet(final Long distributionSetID, final Pageable pageReq) {
return targetRepository.findByAssignedDistributionSetId(pageReq, distributionSetID);
@@ -340,14 +352,6 @@ public class JpaTargetManagement implements TargetManagement {
return targetRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetTagAssignmentResult toggleTagAssignment(final Collection<Target> targets, final TargetTag tag) {
return toggleTagAssignment(
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()), tag.getName());
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@@ -384,10 +388,13 @@ public class JpaTargetManagement implements TargetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> assignTag(final Collection<String> controllerIds, final TargetTag tag) {
public List<Target> assignTag(final Collection<String> controllerIds, final Long tagId) {
final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds));
final JpaTargetTag tag = Optional.ofNullable(targetTagRepository.findOne(tagId))
.orElseThrow(() -> new EntityNotFoundException("Tag with given ID " + tagId + "does not exist"));
allTargets.forEach(target -> target.addTag(tag));
return Collections
.unmodifiableList(allTargets.stream().map(targetRepository::save).collect(Collectors.toList()));
@@ -406,17 +413,29 @@ public class JpaTargetManagement implements TargetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> unAssignAllTargetsByTag(final TargetTag tag) {
public List<Target> unAssignAllTargetsByTag(final Long targetTagId) {
final TargetTag tag = Optional.ofNullable(targetTagRepository.findOne(targetTagId)).orElseThrow(
() -> new EntityNotFoundException("TargetTag with given ID " + targetTagId + " does not exist."));
if (tag.getAssignedToTargets().isEmpty()) {
return Collections.emptyList();
}
return unAssignTag(tag.getAssignedToTargets(), tag);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target unAssignTag(final String controllerID, final TargetTag targetTag) {
public Target unAssignTag(final String controllerID, final Long targetTagId) {
final List<Target> allTargets = Collections.unmodifiableList(targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID))));
final List<Target> unAssignTag = unAssignTag(allTargets, targetTag);
final TargetTag tag = Optional.ofNullable(targetTagRepository.findOne(targetTagId)).orElseThrow(
() -> new EntityNotFoundException("TargetTag with given ID " + targetTagId + " does not exist."));
final List<Target> unAssignTag = unAssignTag(allTargets, tag);
return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
}
@@ -489,16 +508,6 @@ public class JpaTargetManagement implements TargetManagement {
return targetRepository.countByTargetInfoInstalledDistributionSetId(distId);
}
@Override
public List<TargetIdName> findAllTargetIds() {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<TargetIdName> query = cb.createQuery(TargetIdName.class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
return entityManager.createQuery(query.multiselect(targetRoot.get(JpaTarget_.id),
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name))).getResultList();
}
@Override
public List<TargetIdName> findAllTargetIdsByFilters(final Pageable pageRequest,
final Collection<TargetUpdateStatus> filterByStatus, final Boolean overdueState,
@@ -535,7 +544,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public List<TargetIdName> findAllTargetIdsByTargetFilterQuery(final Pageable pageRequest,
final TargetFilterQuery targetFilterQuery) {
final String targetFilterQuery) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
@@ -548,7 +557,7 @@ public class JpaTargetManagement implements TargetManagement {
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id),
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(Lists.newArrayList(spec), targetRoot,
multiselect, cb);
@@ -565,9 +574,9 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull final Pageable pageRequest,
final Long distributionSetId, @NotNull final TargetFilterQuery targetFilterQuery) {
final Long distributionSetId, @NotNull final String targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
return findTargetsBySpec(
@@ -579,8 +588,8 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Page<Target> findAllTargetsByTargetFilterQueryAndNotInRolloutGroups(@NotNull final Pageable pageRequest,
final List<RolloutGroup> groups, @NotNull final String targetFilterQuery) {
public Page<Target> findAllTargetsByTargetFilterQueryAndNotInRolloutGroups(final Pageable pageRequest,
final Collection<Long> groups, final String targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
@@ -592,28 +601,26 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findAllTargetsInRolloutGroupWithoutAction(@NotNull final Pageable pageRequest,
@NotNull final RolloutGroup group) {
@NotNull final Long group) {
return findTargetsBySpec(
(root, cq, cb) -> TargetSpecifications.hasNoActionInRolloutGroup(group).toPredicate(root, cq, cb),
pageRequest);
}
@Override
public Long countAllTargetsByTargetFilterQueryAndNotInRolloutGroups(final List<RolloutGroup> groups,
@NotNull final String targetFilterQuery) {
public Long countAllTargetsByTargetFilterQueryAndNotInRolloutGroups(final Collection<Long> groups,
final String targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
specList.add(spec);
specList.add(TargetSpecifications.isNotInRolloutGroups(groups));
final List<Specification<JpaTarget>> specList = Lists.newArrayList(spec,
TargetSpecifications.isNotInRolloutGroups(groups));
return countByCriteriaAPI(specList);
}
@Override
public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId,
@NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId, final String targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer);
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
specList.add(spec);
@@ -654,11 +661,16 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public List<Target> findTargetsByTag(final String tagName) {
final JpaTargetTag tag = targetTagRepository.findByNameEquals(tagName);
return Collections.unmodifiableList(targetRepository.findByTag(tag));
return Collections.unmodifiableList(targetRepository.findByTag(tag.getId()));
}
@Override
public Long countTargetByTargetFilterQuery(final TargetFilterQuery targetFilterQuery) {
public Long countTargetByTargetFilterQuery(final Long targetFilterQueryId) {
final TargetFilterQuery targetFilterQuery = Optional
.ofNullable(targetFilterQueryRepository.findOne(targetFilterQueryId))
.orElseThrow(() -> new EntityNotFoundException(
"TargetFilterQuery with given ID" + targetFilterQueryId + " not found"));
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
virtualPropertyReplacer);
return targetRepository.count(specs);

View File

@@ -61,6 +61,7 @@ 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;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -354,13 +355,24 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
/**
* {@link JpaTargetFilterQueryManagement} bean.
*
* @param targetFilterQueryRepository
* to query entity access
* @param virtualPropertyReplacer
* for RSQL handling
* @param distributionSetManagement
* for auto assign DS access
*
* @return a new {@link TargetFilterQueryManagement}
*/
@Bean
@ConditionalOnMissingBean
public TargetFilterQueryManagement targetFilterQueryManagement() {
return new JpaTargetFilterQueryManagement();
public TargetFilterQueryManagement targetFilterQueryManagement(
final TargetFilterQueryRepository targetFilterQueryRepository,
final VirtualPropertyReplacer virtualPropertyReplacer,
final DistributionSetManagement distributionSetManagement) {
return new JpaTargetFilterQueryManagement(targetFilterQueryRepository, virtualPropertyReplacer,
distributionSetManagement);
}
/**

View File

@@ -176,11 +176,11 @@ final class RolloutHelper {
* the group to add
* @return list of groups
*/
static List<RolloutGroup> getGroupsByStatusIncludingGroup(final Rollout rollout,
static List<Long> getGroupsByStatusIncludingGroup(final Rollout rollout,
final RolloutGroup.RolloutGroupStatus status, final RolloutGroup group) {
return rollout.getRolloutGroups().stream()
.filter(innerGroup -> innerGroup.getStatus().equals(status) || innerGroup.equals(group))
.collect(Collectors.toList());
.map(RolloutGroup::getId).collect(Collectors.toList());
}
/**

View File

@@ -50,12 +50,12 @@ public interface SoftwareModuleRepository
* to be filtered on
* @param version
* to be filtered on
* @param type
* @param typeId
* to be filtered on
* @return the found {@link SoftwareModule} with the given name AND version
* AND type
*/
JpaSoftwareModule findOneByNameAndVersionAndType(String name, String version, JpaSoftwareModuleType type);
JpaSoftwareModule findOneByNameAndVersionAndTypeId(String name, String version, Long typeId);
/**
* deletes the {@link SoftwareModule}s with the given IDs.
@@ -77,12 +77,12 @@ public interface SoftwareModuleRepository
/**
* @param pageable
* the page request to page the result set
* @param set
* @param setId
* to search for
* @return all {@link SoftwareModule}s that are assigned to given
* {@link DistributionSet}.
*/
Page<SoftwareModule> findByAssignedTo(Pageable pageable, JpaDistributionSet set);
Page<SoftwareModule> findByAssignedToId(Pageable pageable, Long setId);
/**
* @param pageable

View File

@@ -12,9 +12,7 @@ import java.util.Collection;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
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;
@@ -63,12 +61,12 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
/**
* Finds {@link Target}s by assigned {@link Tag}.
*
* @param tag
* @param tagId
* to be found
* @return list of found targets
*/
@Query(value = "SELECT DISTINCT t FROM JpaTarget t JOIN t.tags tt WHERE tt = :tag")
List<JpaTarget> findByTag(@Param("tag") final JpaTargetTag tag);
@Query(value = "SELECT DISTINCT t FROM JpaTarget t JOIN t.tags tt WHERE tt.id = :tag")
List<JpaTarget> findByTag(@Param("tag") final Long tagId);
/**
* Finds all {@link Target}s based on given {@link Target#getControllerId()}
@@ -190,11 +188,11 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
* Finds all targets related to a target rollout group stored for a specific
* rollout.
*
* @param rolloutGroup
* @param rolloutGroupId
* the rollout group the targets should belong to
* @param page
* the page request parameter
* @return a page of all targets related to a rollout group
*/
Page<Target> findByActionsRolloutGroup(JpaRolloutGroup rolloutGroup, Pageable page);
Page<Target> findByActionsRolloutGroupId(Long rolloutGroupId, Pageable page);
}

View File

@@ -77,8 +77,9 @@ public class AutoAssignChecker {
* @param transactionManager
* to run transactions
*/
public AutoAssignChecker(TargetFilterQueryManagement targetFilterQueryManagement, TargetManagement targetManagement,
DeploymentManagement deploymentManagement, PlatformTransactionManager transactionManager) {
public AutoAssignChecker(final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetManagement targetManagement, final DeploymentManagement deploymentManagement,
final PlatformTransactionManager transactionManager) {
this.targetFilterQueryManagement = targetFilterQueryManagement;
this.targetManagement = targetManagement;
this.deploymentManagement = deploymentManagement;
@@ -97,12 +98,12 @@ public class AutoAssignChecker {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void check() {
PageRequest pageRequest = new PageRequest(0, PAGE_SIZE);
final PageRequest pageRequest = new PageRequest(0, PAGE_SIZE);
Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement
final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement
.findTargetFilterQueryWithAutoAssignDS(pageRequest);
for (TargetFilterQuery filterQuery : filterQueries) {
for (final TargetFilterQuery filterQuery : filterQueries) {
checkByTargetFilterQueryAndAssignDS(filterQuery);
}
@@ -116,9 +117,9 @@ public class AutoAssignChecker {
* @param targetFilterQuery
* the target filter query
*/
private void checkByTargetFilterQueryAndAssignDS(TargetFilterQuery targetFilterQuery) {
private void checkByTargetFilterQueryAndAssignDS(final TargetFilterQuery targetFilterQuery) {
try {
DistributionSet distributionSet = targetFilterQuery.getAutoAssignDistributionSet();
final DistributionSet distributionSet = targetFilterQuery.getAutoAssignDistributionSet();
int count;
do {
@@ -142,11 +143,12 @@ public class AutoAssignChecker {
* distribution set id to assign
* @return count of targets
*/
private int runTransactionalAssignment(TargetFilterQuery targetFilterQuery, Long dsId) {
private int runTransactionalAssignment(final TargetFilterQuery targetFilterQuery, final Long dsId) {
final String actionMessage = String.format(ACTION_MESSAGE, targetFilterQuery.getName());
return transactionTemplate.execute(status -> {
List<TargetWithActionType> targets = getTargetsWithActionType(targetFilterQuery, dsId, PAGE_SIZE);
int count = targets.size();
final List<TargetWithActionType> targets = getTargetsWithActionType(targetFilterQuery.getQuery(), dsId,
PAGE_SIZE);
final int count = targets.size();
if (count > 0) {
deploymentManagement.assignDistributionSet(dsId, targets, actionMessage);
}
@@ -167,10 +169,10 @@ public class AutoAssignChecker {
* maximum amount of targets to retrieve
* @return list of targets with action type
*/
private List<TargetWithActionType> getTargetsWithActionType(TargetFilterQuery targetFilterQuery, Long dsId,
int count) {
Page<Target> targets = targetManagement.findAllTargetsByTargetFilterQueryAndNonDS(new PageRequest(0, count),
dsId, targetFilterQuery);
private List<TargetWithActionType> getTargetsWithActionType(final String targetFilterQuery, final Long dsId,
final int count) {
final Page<Target> targets = targetManagement
.findAllTargetsByTargetFilterQueryAndNonDS(new PageRequest(0, count), dsId, targetFilterQuery);
return targets.getContent().stream().map(t -> new TargetWithActionType(t.getControllerId(),
Action.ActionType.FORCED, RepositoryModelConstants.NO_FORCE_TIME)).collect(Collectors.toList());

View File

@@ -21,7 +21,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.data.jpa.domain.Specification;
@@ -49,15 +48,13 @@ public final class ActionSpecifications {
* assigned
* @return a specification to use with spring JPA
*/
public static Specification<JpaAction> hasTargetAssignedArtifact(final Target target,
final Artifact localArtifact) {
public static Specification<JpaAction> hasTargetAssignedArtifact(final Target target, final Long localArtifact) {
return (actionRoot, query, criteriaBuilder) -> {
final Join<JpaAction, JpaDistributionSet> dsJoin = actionRoot.join(JpaAction_.distributionSet);
final SetJoin<JpaDistributionSet, JpaSoftwareModule> modulesJoin = dsJoin.join(JpaDistributionSet_.modules);
final ListJoin<JpaSoftwareModule, JpaArtifact> artifactsJoin = modulesJoin
.join(JpaSoftwareModule_.artifacts);
return criteriaBuilder.and(
criteriaBuilder.equal(artifactsJoin.get(JpaArtifact_.filename), localArtifact.getFilename()),
return criteriaBuilder.and(criteriaBuilder.equal(artifactsJoin.get(JpaArtifact_.id), localArtifact),
criteriaBuilder.equal(actionRoot.get(JpaAction_.target), target));
};
}

View File

@@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_;
@@ -135,14 +136,13 @@ public final class TargetSpecifications {
public static Specification<JpaTarget> isOverdue(final long overdueTimestamp) {
return (targetRoot, query, cb) -> {
final Join<JpaTarget, JpaTargetInfo> targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo);
return cb.lessThanOrEqualTo(
targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), overdueTimestamp);
return cb.lessThanOrEqualTo(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), overdueTimestamp);
};
}
/**
* {@link Specification} for retrieving {@link Target}s by
* "like controllerId or like name or like description".
* {@link Specification} for retrieving {@link Target}s by "like
* controllerId or like name or like description".
*
* @param searchText
* to be filtered on
@@ -158,8 +158,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by
* "like controllerId".
* {@link Specification} for retrieving {@link Target}s by "like
* controllerId".
*
* @param distributionId
* to be filtered on
@@ -195,8 +195,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by
* "has no tag names"or "has at least on of the given tag names".
* {@link Specification} for retrieving {@link Target}s by "has no tag
* names"or "has at least on of the given tag names".
*
* @param tagNames
* to be filtered on
@@ -242,8 +242,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s that don't have the given
* distribution set in their action history
* {@link Specification} for retrieving {@link Target}s that don't have the
* given distribution set in their action history
*
* @param distributionSetId
* the ID of the distribution set which must not be assigned
@@ -267,11 +267,12 @@ public final class TargetSpecifications {
* the {@link RolloutGroup}s
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> isNotInRolloutGroups(final List<RolloutGroup> groups) {
public static Specification<JpaTarget> isNotInRolloutGroups(final Collection<Long> groups) {
return (targetRoot, query, cb) -> {
ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = targetRoot.join(JpaTarget_.rolloutTargetGroup,
JoinType.LEFT);
Predicate inRolloutGroups = rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).in(groups);
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = targetRoot
.join(JpaTarget_.rolloutTargetGroup, JoinType.LEFT);
final Predicate inRolloutGroups = rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup)
.get(JpaRolloutGroup_.id).in(groups);
rolloutTargetJoin.on(inRolloutGroups);
return cb.isNull(rolloutTargetJoin.get(RolloutTargetGroup_.target));
};
@@ -285,14 +286,15 @@ public final class TargetSpecifications {
* the {@link RolloutGroup}
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasNoActionInRolloutGroup(final RolloutGroup group) {
public static Specification<JpaTarget> hasNoActionInRolloutGroup(final Long group) {
return (targetRoot, query, cb) -> {
ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = targetRoot.join(JpaTarget_.rolloutTargetGroup,
JoinType.INNER);
rolloutTargetJoin.on(cb.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup), group));
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = targetRoot
.join(JpaTarget_.rolloutTargetGroup, JoinType.INNER);
rolloutTargetJoin.on(
cb.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id), group));
final ListJoin<JpaTarget, JpaAction> actionsJoin = targetRoot.join(JpaTarget_.actions, JoinType.LEFT);
actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.rolloutGroup), group));
actionsJoin.on(cb.equal(actionsJoin.get(JpaAction_.rolloutGroup).get(JpaRolloutGroup_.id), group));
return cb.isNull(actionsJoin.get(JpaAction_.id));
};