Started to split the actual model.

Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-05-20 17:25:38 +02:00
parent 3e5330a5e6
commit e3041aa9ae
154 changed files with 6730 additions and 4950 deletions

View File

@@ -20,6 +20,7 @@ import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.TargetRepository;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
@@ -147,7 +148,7 @@ public class EntityChangeEventListener {
}
private static boolean isTargetInfoNew(final Object targetInfo) {
return ((TargetInfo) targetInfo).isNew();
return ((JpaTargetInfo) targetInfo).isNew();
}
}

View File

@@ -31,8 +31,6 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
/**
* Service layer for all operations of the DDI API (with access permissions only
@@ -248,7 +246,6 @@ public interface ControllerManagement {
*
*/
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
TargetInfo updateLastTargetQuery(@NotNull TargetInfo target, @NotNull URI address);
/**
@@ -271,4 +268,11 @@ public interface ControllerManagement {
TargetInfo updateTargetStatus(@NotNull TargetInfo targetInfo, TargetUpdateStatus status, Long lastTargetQuery,
URI address);
/**
* Generates an empty {@link ActionStatus} without persisting it.
*
* @return {@link ActionStatus} object
*/
ActionStatus generateActionStatus();
}

View File

@@ -31,7 +31,6 @@ import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -179,7 +178,7 @@ public interface DeploymentManagement {
* @return the count value of found actions associated to the target
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Long countActionsByTarget(@NotNull Specification<Action> spec, @NotNull Target target);
Long countActionsByTarget(@NotNull String rsqlParam, @NotNull Target target);
/**
* counts all actions associated to a specific target.
@@ -281,9 +280,9 @@ public interface DeploymentManagement {
* @return a slice of actions assigned to the specific target and the
* specification
*/
// TODO fix this
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Slice<Action> findActionsByTarget(@NotNull Specification<Action> specifiction, @NotNull Target target,
@NotNull Pageable pageable);
Slice<Action> findActionsByTarget(@NotNull String rsqlParam, @NotNull Target target, @NotNull Pageable pageable);
/**
* Retrieves all {@link Action}s of a specific target ordered by action ID.
@@ -440,4 +439,10 @@ public interface DeploymentManagement {
+ SpringEvalExpressions.IS_SYSTEM_CODE)
Action startScheduledAction(@NotNull Action action);
/**
* Generates an empty {@link Action} without persisting it.
*
* @return {@link Action} object
*/
Action generateAction();
}

View File

@@ -51,7 +51,7 @@ public class DistributionSetAssignmentResult extends AssignmentResult<Target> {
this.actions = actions;
this.targetManagement = targetManagement;
}
/**
* @return the actionIds
*/
@@ -59,9 +59,10 @@ public class DistributionSetAssignmentResult extends AssignmentResult<Target> {
return actions;
}
@SuppressWarnings("unchecked")
@Override
public List<Target> getAssignedEntity() {
return targetManagement.findTargetByControllerID(assignedTargets);
return (List<Target>) targetManagement.findTargetByControllerID(assignedTargets);
}
}

View File

@@ -21,14 +21,14 @@ import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMis
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.jpa.model.DistributionSetTypeElement;
import org.eclipse.hawkbit.repository.jpa.model.DsMetadataCompositeKey;
import org.eclipse.hawkbit.repository.model.Action;
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.DistributionSetTagAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.DistributionSetTypeElement;
import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Tag;
@@ -36,7 +36,6 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
@@ -274,18 +273,7 @@ public interface DistributionSetManagement {
* @return the found {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Iterable<DistributionSet> findDistributionSetList(Collection<Long> dist);
/**
* Retrieves {@link DistributionSet} List including details information,
* i.e. @link BaseSoftwareModule}s and {@link DistributionSetTag}s.
*
* @param distributionIdSet
* List of {@link DistributionSet} IDs to be found
* @return the found {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
List<DistributionSet> findDistributionSetListWithDetails(Collection<Long> distributionIdSet);
List<DistributionSet> findDistributionSetsAll(Collection<Long> dist);
/**
* finds all meta data by the given distribution set id.
@@ -315,7 +303,7 @@ public interface DistributionSetManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId,
@NotNull Specification<DistributionSetMetadata> spec, @NotNull Pageable pageable);
@NotNull String rsqlParam, @NotNull Pageable pageable);
// TODO discuss: use enum instead of the true,false,null switch ?
/**
@@ -357,8 +345,8 @@ public interface DistributionSetManagement {
* @return all found {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSet> findDistributionSetsAll(@NotNull Specification<DistributionSet> spec,
@NotNull Pageable pageReq, Boolean deleted);
Page<DistributionSet> findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq,
Boolean deleted);
/**
* method retrieves all {@link DistributionSet}s from the repository in the
@@ -442,8 +430,7 @@ public interface DistributionSetManagement {
* @return the found {@link SoftwareModuleType}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSetType> findDistributionSetTypesAll(@NotNull Specification<DistributionSetType> spec,
@NotNull Pageable pageable);
Page<DistributionSetType> findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable);
/**
* finds a single distribution set meta data by its id.
@@ -580,4 +567,17 @@ public interface DistributionSetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType);
/**
* Generates an empty {@link DistributionSetType} without persisting it.
*
* @return {@link DistributionSetType} object
*/
DistributionSetType generateDistributionSetType();
/**
* Generates an empty {@link DistributionSet} without persisting it.
*
* @return {@link DistributionSet} object
*/
DistributionSet generateDistributionSet();
}

View File

@@ -84,8 +84,8 @@ public interface RolloutGroupManagement {
* @return a page of found {@link RolloutGroup}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
Page<RolloutGroup> findRolloutGroupsAll(@NotNull Rollout rollout,
@NotNull Specification<RolloutGroup> specification, @NotNull Pageable page);
Page<RolloutGroup> findRolloutGroupsAll(@NotNull Rollout rollout, @NotNull String rsqlParam,
@NotNull Pageable page);
/**
* Retrieves a page of {@link RolloutGroup}s filtered by a given
@@ -128,8 +128,8 @@ public interface RolloutGroupManagement {
* @return Page<Target> list of targets of a rollout group
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
Page<Target> findRolloutGroupTargets(@NotNull RolloutGroup rolloutGroup,
@NotNull Specification<Target> specification, @NotNull Pageable page);
Page<Target> findRolloutGroupTargets(@NotNull RolloutGroup rolloutGroup, @NotNull String rsqlParam,
@NotNull Pageable page);
/**
* Get count of targets in different status in rollout group.
@@ -141,4 +141,10 @@ public interface RolloutGroupManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
RolloutGroup findRolloutGroupWithDetailedStatus(@NotNull Long rolloutGroupId);
/**
* Generates an empty {@link RolloutGroup} without persisting it.
*
* @return {@link RolloutGroup} object
*/
RolloutGroup generateRolloutGroup();
}

View File

@@ -13,16 +13,15 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.eventbus.event.RolloutGroupCreatedEvent;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -179,8 +178,7 @@ public interface RolloutManagement {
* @return a page of found rollouts
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
Page<Rollout> findAllWithDetailedStatusByPredicate(@NotNull Specification<Rollout> specification,
@NotNull Pageable page);
Page<Rollout> findAllWithDetailedStatusByPredicate(@NotNull String rsqlParam, @NotNull Pageable page);
/**
* Finds rollouts by given text in name or description.
@@ -335,4 +333,11 @@ public interface RolloutManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
Rollout updateRollout(@NotNull Rollout rollout);
/**
* Generates an empty {@link Rollout} without persisting it.
*
* @return {@link Rollout} object
*/
Rollout generateRollout();
}

View File

@@ -17,17 +17,16 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.model.CustomSoftwareModule;
import org.eclipse.hawkbit.repository.model.DistributionSet;
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.SwMetadataCompositeKey;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -290,7 +289,7 @@ public interface SoftwareManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId,
@NotNull Specification<SoftwareModuleMetadata> spec, @NotNull Pageable pageable);
@NotNull String rsqlParam, @NotNull Pageable pageable);
/**
* Filter {@link SoftwareModule}s with given
@@ -347,8 +346,7 @@ public interface SoftwareManagement {
* @return the found {@link SoftwareModule}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<SoftwareModule> findSoftwareModulesByPredicate(@NotNull Specification<SoftwareModule> spec,
@NotNull Pageable pageable);
Page<SoftwareModule> findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable);
/**
* retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType}
@@ -411,8 +409,7 @@ public interface SoftwareManagement {
* @return the found {@link SoftwareModuleType}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<SoftwareModuleType> findSoftwareModuleTypesByPredicate(@NotNull Specification<SoftwareModuleType> spec,
@NotNull Pageable pageable);
Page<SoftwareModuleType> findSoftwareModuleTypesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable);
/**
* Retrieves software module including details (
@@ -468,4 +465,17 @@ public interface SoftwareManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm);
/**
* Generates an empty {@link SoftwareModuleType} without persisting it.
*
* @return {@link SoftwareModuleType} object
*/
SoftwareModuleType generateSoftwareModuleType();
/**
* Generates an empty {@link SoftwareModule} without persisting it.
*
* @return {@link SoftwareModule} object
*/
SoftwareModule generateSoftwareModule();
}

View File

@@ -23,7 +23,6 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -90,7 +89,7 @@ public interface TagManagement {
* if given object has already an ID.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
List<TargetTag> createTargetTags(@NotNull Iterable<TargetTag> targetTags);
List<TargetTag> createTargetTags(@NotNull Collection<TargetTag> targetTags);
/**
* Deletes {@link DistributionSetTag} by given
@@ -138,8 +137,7 @@ public interface TagManagement {
* @return the found {@link DistributionSetTag}s, never {@code null}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSetTag> findAllDistributionSetTags(@NotNull Specification<DistributionSetTag> spec,
@NotNull Pageable pageable);
Page<DistributionSetTag> findAllDistributionSetTags(@NotNull String rsqlParam, @NotNull Pageable pageable);
/**
* @return all {@link TargetTag}s
@@ -168,7 +166,7 @@ public interface TagManagement {
* @return the found {@link Target}s, never {@code null}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetTag> findAllTargetTags(@NotNull Specification<TargetTag> spec, @NotNull Pageable pageable);
Page<TargetTag> findAllTargetTags(@NotNull String rsqlParam, @NotNull Pageable pageable);
/**
* Find {@link DistributionSet} based on given name.
@@ -233,4 +231,18 @@ public interface TagManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
TargetTag updateTargetTag(@NotNull TargetTag targetTag);
/**
* Generates an empty {@link TargetTag} without persisting it.
*
* @return {@link TargetTag} object
*/
TargetTag generateTargetTag();
/**
* Generates an empty {@link DistributionSetTag} without persisting it.
*
* @return {@link DistributionSetTag} object
*/
DistributionSetTag generateDistributionSetTag();
}

View File

@@ -30,7 +30,6 @@ import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -290,8 +289,8 @@ public interface TargetManagement {
* @return the found {@link Target}s, never {@code null}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
Page<Target> findTargetByAssignedDistributionSet(@NotNull Long distributionSetID,
@NotNull Specification<Target> spec, @NotNull Pageable pageReq);
Page<Target> findTargetByAssignedDistributionSet(@NotNull Long distributionSetID, @NotNull String rsqlParam,
@NotNull Pageable pageReq);
/**
* Find {@link Target} based on given ID returns found Target without
@@ -390,8 +389,8 @@ public interface TargetManagement {
* @return the found {@link Target}s, never {@code null}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
Page<Target> findTargetByInstalledDistributionSet(@NotNull Long distributionSetId,
@NotNull Specification<Target> spec, @NotNull Pageable pageable);
Page<Target> findTargetByInstalledDistributionSet(@NotNull Long distributionSetId, @NotNull String rsqlParam,
@NotNull Pageable pageable);
/**
* Retrieves the {@link Target} which have a certain
@@ -418,18 +417,6 @@ public interface TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Slice<Target> findTargetsAll(@NotNull Pageable pageable);
/**
* Retrieves all targets based on the given specification.
*
* @param spec
* the specification for the query
* @param pageable
* pagination parameter
* @return the found {@link Target}s, never {@code null}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<Target> findTargetsAll(@NotNull Specification<Target> spec, @NotNull Pageable pageable);
/**
* Retrieves all targets without details, i.e. NO {@link Target#getTags()}
* and {@link Target#getActions()} possible based on
@@ -442,7 +429,7 @@ public interface TargetManagement {
* @return the found {@link Target}s, never {@code null}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Slice<Target> findTargetsAll(@NotNull String targetFilterQuery, @NotNull Pageable pageable);
Page<Target> findTargetsAll(@NotNull String targetFilterQuery, @NotNull Pageable pageable);
/**
* Retrieves all targets without details, i.e. NO {@link Target#getTags()}
@@ -599,6 +586,16 @@ public interface TargetManagement {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_CONTROLLER)
List<Target> updateTargets(@NotNull Iterable<Target> targets);
List<Target> updateTargets(@NotNull Collection<Target> targets);
/**
* Generates an empty {@link Target} without persisting it.
*
* @param controllerID
* of the {@link Target}
*
* @return {@link Target} object
*/
Target generateTarget(@NotEmpty String controllerID);
}

View File

@@ -142,5 +142,4 @@ public interface TenantConfigurationManagement {
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
+ SpringEvalExpressions.IS_SYSTEM_CODE)
<T> T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class<T> propertyType);
}

View File

@@ -11,6 +11,12 @@ 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.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -37,7 +43,7 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface ActionRepository extends BaseEntityRepository<Action, Long>, JpaSpecificationExecutor<Action> {
public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>, JpaSpecificationExecutor<JpaAction> {
/**
* Retrieves an Action with all lazy attributes.
*
@@ -46,7 +52,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* @return the found {@link Action}
*/
@EntityGraph(value = "Action.all", type = EntityGraphType.LOAD)
Action findById(Long actionId);
JpaAction findById(Long actionId);
/**
* Retrieves all {@link Action}s which are referring the given
@@ -58,7 +64,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the {@link DistributionSet} on which will be filtered
* @return the found {@link Action}s
*/
Page<Action> findByDistributionSet(final Pageable pageable, final DistributionSet ds);
Page<Action> findByDistributionSet(final Pageable pageable, final JpaDistributionSet ds);
/**
* Retrieves all {@link Action}s which are referring the given
@@ -70,7 +76,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the target to find assigned actions
* @return the found {@link Action}s
*/
Slice<Action> findByTarget(Pageable pageable, Target target);
Slice<Action> findByTarget(Pageable pageable, JpaTarget target);
/**
* Retrieves all {@link Action}s which are active and referring the given
@@ -86,7 +92,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* @return the found {@link Action}s
*/
@EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD)
List<Action> findByTargetAndActiveOrderByIdAsc(final Target target, boolean active);
List<Action> findByTargetAndActiveOrderByIdAsc(final JpaTarget target, boolean active);
/**
* Retrieves latest {@link UpdateAction} for given target and
@@ -99,9 +105,9 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* @return action if there is one with assigned target and module is part of
* assigned {@link DistributionSet}.
*/
@Query("Select a from Action a join a.distributionSet ds join ds.modules modul where a.target.controllerId = :target and modul = :module order by a.id desc")
@Query("Select a from JpaAction a join a.distributionSet ds join ds.modules modul where a.target.controllerId = :target and modul = :module order by a.id desc")
List<Action> findActionByTargetAndSoftwareModule(@Param("target") final String targetId,
@Param("module") SoftwareModule module);
@Param("module") JpaSoftwareModule module);
/**
* Retrieves all {@link UpdateAction}s which are referring the given
@@ -115,9 +121,9 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the {@link DistributionSet} on which will be filtered
* @return the found {@link UpdateAction}s
*/
@Query("Select a from Action a where a.target = :target and a.distributionSet = :ds order by a.id")
Page<Action> findByTargetAndDistributionSet(final Pageable pageable, @Param("target") final Target target,
@Param("ds") DistributionSet ds);
@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,
@Param("ds") JpaDistributionSet ds);
/**
* Retrieves all {@link Action}s of a specific target, without pagination
@@ -127,8 +133,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* to search for
* @return a list of actions according to the searched target
*/
@Query("Select a from Action a where a.target = :target order by a.id")
List<Action> findByTarget(@Param("target") final Target target);
@Query("Select a from JpaAction a where a.target = :target order by a.id")
List<Action> findByTarget(@Param("target") final JpaTarget target);
/**
* Retrieves all {@link Action}s of a specific target and given active flag
@@ -143,8 +149,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* {@code false} for inactive
* @return a paged list of actions ordered by action ID
*/
@Query("Select a from Action a where a.target = :target and a.active= :active order by a.id")
Page<Action> findByActiveAndTarget(Pageable pageable, @Param("target") Target target,
@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);
/**
@@ -160,8 +166,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* @return a list of actions ordered by action ID
*/
@EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD)
@Query("Select a from Action a where a.target = :target and a.active= :active order by a.id")
List<Action> findByActiveAndTarget(@Param("target") Target target, @Param("active") boolean active);
@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.
@@ -174,8 +180,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE Action a SET a.active = false WHERE a IN :keySet AND a.target IN :targetsIds")
void setToInactive(@Param("keySet") List<Action> keySet, @Param("targetsIds") List<Long> targetsIds);
@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,
@@ -193,7 +199,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE Action a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false")
@Query("UPDATE JpaAction a SET a.status = :statusToSet WHERE a.target IN :targetsIds AND a.active = :active AND a.status = :currentStatus AND a.distributionSet.requiredMigrationStep = false")
void switchStatus(@Param("statusToSet") Action.Status statusToSet, @Param("targetsIds") List<Long> targetIds,
@Param("active") boolean active, @Param("currentStatus") Action.Status currentStatus);
@@ -213,8 +219,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE Action 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") Rollout rollout,
@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);
/**
@@ -228,8 +234,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the status which the actions should not have
* @return the found list of {@link Action}s
*/
@Query("SELECT a FROM Action a WHERE a.active = true AND a.distributionSet.requiredMigrationStep = false AND a.target IN ?1 AND a.status != ?2")
List<Action> findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep(
@Query("SELECT a FROM JpaAction a WHERE a.active = true AND a.distributionSet.requiredMigrationStep = false AND a.target IN ?1 AND a.status != ?2")
List<JpaAction> findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep(
Collection<Long> targetIds, Action.Status notStatus);
/**
@@ -239,15 +245,15 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the target to count the {@link Action}s
* @return the count of actions referring to the given target
*/
Long countByTarget(Target target);
Long countByTarget(JpaTarget target);
@Override
@CacheEvict(value = "feedbackReceivedOverTime", allEntries = true)
<S extends Action> List<S> save(Iterable<S> entities);
<S extends JpaAction> List<S> save(Iterable<S> entities);
@Override
@CacheEvict(value = "feedbackReceivedOverTime", allEntries = true)
<S extends Action> S save(S entity);
<S extends JpaAction> S save(S entity);
/**
* Counts all {@link Action}s referring to the given DistributionSet.
@@ -256,7 +262,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* DistributionSet to count the {@link Action}s from
* @return the count of actions referring to the given distributionSet
*/
Long countByDistributionSet(DistributionSet distributionSet);
Long countByDistributionSet(JpaDistributionSet distributionSet);
/**
* Counts all {@link Action}s referring to the given rollout.
@@ -265,7 +271,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the rollout to count the {@link Action}s from
* @return the count of actions referring to the given rollout
*/
Long countByRollout(Rollout rollout);
Long countByRollout(JpaRollout rollout);
/**
* Counts all actions referring to a given rollout and rolloutgroup which
@@ -286,8 +292,8 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* @return the count of actions referring the rollout and rolloutgroup and
* are not in given states
*/
Long countByRolloutAndRolloutGroupAndStatusNotAndStatusNotAndStatusNot(Rollout rollout, RolloutGroup rolloutGroup,
Status notStatus1, Status notStatus2, Status notStatus3);
Long countByRolloutAndRolloutGroupAndStatusNotAndStatusNotAndStatusNot(JpaRollout rollout,
JpaRolloutGroup rolloutGroup, Status notStatus1, Status notStatus2, Status notStatus3);
/**
* Counts all actions referring to a given rollout and rolloutgroup.
@@ -298,7 +304,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the rolloutgroup the actions belong to
* @return the count of actions referring to a rollout and rolloutgroup
*/
Long countByRolloutAndRolloutGroup(Rollout rollout, RolloutGroup rolloutGroup);
Long countByRolloutAndRolloutGroup(JpaRollout rollout, JpaRolloutGroup rolloutGroup);
/**
* Counts all actions referring to a given rollout, rolloutgroup and status.
@@ -329,7 +335,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* @return the actions referring a specific rollout and a specific parent
* rolloutgroup in a specific status
*/
List<Action> findByRolloutAndRolloutGroupParentAndStatus(Rollout rollout, RolloutGroup rolloutGroupParent,
List<Action> findByRolloutAndRolloutGroupParentAndStatus(JpaRollout rollout, JpaRolloutGroup rolloutGroupParent,
Status actionStatus);
/**
@@ -341,7 +347,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* the status of the actions
* @return the actions referring a specific rollout an in a specific status
*/
List<Action> findByRolloutAndStatus(Rollout rollout, Status actionStatus);
List<Action> findByRolloutAndStatus(JpaRollout rollout, Status actionStatus);
/**
* Get list of objects which has details of status and count of targets in
@@ -351,7 +357,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* id of {@link Rollout}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rollout.id IN ?1 GROUP BY a.rollout.id,a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rollout.id IN ?1 GROUP BY a.rollout.id,a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutId(List<Long> rolloutId);
/**
@@ -362,7 +368,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* id of {@link Rollout}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rollout.id = ?1 GROUP BY a.rollout.id,a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rollout.id = ?1 GROUP BY a.rollout.id,a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutId(Long rolloutId);
/**
@@ -373,7 +379,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* id of {@link RolloutGroup}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rolloutGroup.id = ?1 GROUP BY a.rolloutGroup.id, a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rolloutGroup.id = ?1 GROUP BY a.rolloutGroup.id, a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutGroupId(Long rolloutGroupId);
/**
@@ -384,7 +390,7 @@ public interface ActionRepository extends BaseEntityRepository<Action, Long>, Jp
* list of id of {@link RolloutGroup}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM Action a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutGroupId(List<Long> rolloutGroupId);
}

View File

@@ -8,6 +8,8 @@
*/
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;
@@ -25,7 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface ActionStatusRepository
extends BaseEntityRepository<ActionStatus, Long>, JpaSpecificationExecutor<ActionStatus> {
extends BaseEntityRepository<JpaActionStatus, Long>, JpaSpecificationExecutor<JpaActionStatus> {
/**
* Counts {@link ActionStatus} entries of given {@link Action} in
@@ -35,7 +37,7 @@ public interface ActionStatusRepository
* to count status entries
* @return number of actions in repository
*/
Long countByAction(Action action);
Long countByAction(JpaAction action);
/**
* Counts {@link ActionStatus} entries of given {@link Action} with given
@@ -47,7 +49,7 @@ public interface ActionStatusRepository
* to filter for
* @return number of actions in repository
*/
Long countByActionAndStatus(Action action, Status status);
Long countByActionAndStatus(JpaAction action, Status status);
/**
* Retrieves all {@link ActionStatus} entries from repository of given
@@ -59,7 +61,7 @@ public interface ActionStatusRepository
* of the status entries
* @return pages list of {@link ActionStatus} entries
*/
Page<ActionStatus> findByAction(Pageable pageReq, Action action);
Page<ActionStatus> findByAction(Pageable pageReq, JpaAction action);
/**
* Finds all status updates for the defined action and target including
@@ -74,6 +76,6 @@ public interface ActionStatusRepository
* @return Page with found targets
*/
@EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD)
Page<ActionStatus> getByAction(Pageable pageReq, Action action);
Page<ActionStatus> getByAction(Pageable pageReq, JpaAction action);
}

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.repository.NoRepositoryBean;
@@ -27,7 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@NoRepositoryBean
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface BaseEntityRepository<T extends TenantAwareBaseEntity, I extends Serializable>
public interface BaseEntityRepository<T extends JpaTenantAwareBaseEntity, I extends Serializable>
extends PagingAndSortingRepository<T, I> {
/**

View File

@@ -15,10 +15,11 @@ 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;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
/**
@@ -48,10 +49,10 @@ public final class DeploymentHelper {
*
* @return updated target
*/
static Target updateTargetInfo(@NotNull final Target target, @NotNull final TargetUpdateStatus status,
static JpaTarget updateTargetInfo(@NotNull final JpaTarget target, @NotNull final TargetUpdateStatus status,
final boolean setInstalledDate, final TargetInfoRepository targetInfoRepository,
final EntityManager entityManager) {
final TargetInfo ts = target.getTargetInfo();
final JpaTargetInfo ts = (JpaTargetInfo) target.getTargetInfo();
ts.setUpdateStatus(status);
if (setInstalledDate) {
@@ -77,7 +78,7 @@ public final class DeploymentHelper {
* @param targetInfoRepository
* for the operation
*/
static void successCancellation(final Action action, final ActionRepository actionRepository,
static void successCancellation(final JpaAction action, final ActionRepository actionRepository,
final TargetManagement targetManagement, final TargetInfoRepository targetInfoRepository,
final EntityManager entityManager) {
@@ -85,7 +86,7 @@ public final class DeploymentHelper {
action.setActive(false);
action.setStatus(Status.CANCELED);
final Target target = action.getTarget();
final JpaTarget target = (JpaTarget) action.getTarget();
final List<Action> nextActiveActions = actionRepository.findByTargetAndActiveOrderByIdAsc(target, true).stream()
.filter(a -> !a.getId().equals(action.getId())).collect(Collectors.toList());

View File

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

View File

@@ -11,10 +11,12 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List;
import org.eclipse.hawkbit.repository.model.Action;
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.DistributionSet;
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.Tag;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -30,7 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface DistributionSetRepository
extends BaseEntityRepository<DistributionSet, Long>, JpaSpecificationExecutor<DistributionSet> {
extends BaseEntityRepository<JpaDistributionSet, Long>, JpaSpecificationExecutor<JpaDistributionSet> {
/**
* Finds {@link DistributionSet}s by assigned {@link Tag}.
@@ -39,8 +41,8 @@ public interface DistributionSetRepository
* to be found
* @return list of found {@link DistributionSet}s
*/
@Query(value = "Select Distinct ds from DistributionSet ds join ds.tags dst where dst = :tag")
List<DistributionSet> findByTag(@Param("tag") final DistributionSetTag tag);
@Query(value = "Select Distinct ds from JpaDistributionSet ds join ds.tags dst where dst = :tag")
List<JpaDistributionSet> findByTag(@Param("tag") final JpaDistributionSetTag tag);
/**
* deletes the {@link DistributionSet}s with the given IDs.
@@ -50,9 +52,12 @@ public interface DistributionSetRepository
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("update DistributionSet d set d.deleted = 1 where d.id in :ids")
@Query("update JpaDistributionSet d set d.deleted = 1 where d.id in :ids")
void deleteDistributionSet(@Param("ids") Long... ids);
@Override
List<JpaDistributionSet> findAll(Iterable<Long> ids);
/**
* deletes {@link DistributionSet}s by the given IDs.
*
@@ -63,7 +68,7 @@ public interface DistributionSetRepository
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM DistributionSet d WHERE d.id IN ?1")
@Query("DELETE FROM JpaDistributionSet d WHERE d.id IN ?1")
int deleteByIdIn(Collection<Long> ids);
/**
@@ -74,7 +79,7 @@ public interface DistributionSetRepository
* to search for
* @return {@link List} of found {@link DistributionSet}s
*/
List<DistributionSet> findByModules(SoftwareModule module);
List<DistributionSet> findByModules(JpaSoftwareModule module);
/**
* Finds {@link DistributionSet}s based on given ID if they are not assigned
@@ -84,7 +89,7 @@ public interface DistributionSetRepository
* to search for
* @return
*/
@Query("select ac.distributionSet.id from Action ac where ac.distributionSet.id in :ids")
@Query("select ac.distributionSet.id from JpaAction ac where ac.distributionSet.id in :ids")
List<Long> findAssignedDistributionSetsById(@Param("ids") Long... ids);
/**
@@ -98,7 +103,7 @@ public interface DistributionSetRepository
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
*/
@Override
<S extends DistributionSet> List<S> save(Iterable<S> entities);
<S extends JpaDistributionSet> List<S> save(Iterable<S> entities);
/**
* Finds the distribution set for a specific action.
@@ -107,8 +112,8 @@ 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 DistributionSet d join fetch d.modules m join d.actions a where a = :action")
DistributionSet findByAction(@Param("action") Action 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);
/**
* Counts {@link DistributionSet} instances of given type in the repository.
@@ -117,7 +122,7 @@ public interface DistributionSetRepository
* to search for
* @return number of found {@link DistributionSet}s
*/
long countByType(DistributionSetType type);
long countByType(JpaDistributionSetType type);
/**
* Counts {@link DistributionSet} with given

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.TargetTag;
@@ -24,7 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface DistributionSetTagRepository
extends BaseEntityRepository<DistributionSetTag, Long>, JpaSpecificationExecutor<DistributionSetTag> {
extends BaseEntityRepository<JpaDistributionSetTag, Long>, JpaSpecificationExecutor<JpaDistributionSetTag> {
/**
* deletes the {@link DistributionSet} with the given name.
*
@@ -43,7 +44,7 @@ public interface DistributionSetTagRepository
* to filter on
* @return the {@link DistributionSetTag} if found, otherwise null
*/
DistributionSetTag findByNameEquals(final String tagName);
JpaDistributionSetTag findByNameEquals(final String tagName);
/**
* Returns all instances of the type.
@@ -51,8 +52,8 @@ public interface DistributionSetTagRepository
* @return all entities
*/
@Override
List<DistributionSetTag> findAll();
List<JpaDistributionSetTag> findAll();
@Override
<S extends DistributionSetTag> List<S> save(Iterable<S> entities);
<S extends JpaDistributionSetTag> List<S> save(Iterable<S> entities);
}

View File

@@ -8,8 +8,9 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
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;
@@ -23,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface DistributionSetTypeRepository
extends BaseEntityRepository<DistributionSetType, Long>, JpaSpecificationExecutor<DistributionSetType> {
extends BaseEntityRepository<JpaDistributionSetType, Long>, JpaSpecificationExecutor<JpaDistributionSetType> {
/**
*
@@ -34,7 +35,7 @@ public interface DistributionSetTypeRepository
* <code>false</code> if undeleted ones
* @return list of found {@link DistributionSetType}s
*/
Page<DistributionSetType> findByDeleted(Pageable pageable, boolean isDeleted);
Page<JpaDistributionSetType> findByDeleted(Pageable pageable, boolean isDeleted);
/**
* @param isDeleted
@@ -54,5 +55,5 @@ public interface DistributionSetTypeRepository
* @return the number of {@link DistributionSetType}s in the repository
* assigned to the given software module type
*/
Long countByElementsSmType(SoftwareModuleType softwareModuleType);
Long countByElementsSmType(JpaSoftwareModuleType softwareModuleType);
}

View File

@@ -14,7 +14,7 @@ import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.eclipse.hawkbit.repository.model.TargetInfo;
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;
@@ -40,7 +40,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void setTargetUpdateStatus(final TargetUpdateStatus status, final List<Long> targets) {
final Query query = entityManager.createQuery(
"update TargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status");
"update JpaTargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status");
query.setParameter("targets", targets);
query.setParameter("status", status);
@@ -50,7 +50,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
public <S extends TargetInfo> S save(final S entity) {
public <S extends JpaTargetInfo> S save(final S entity) {
if (entity.isNew()) {
entityManager.persist(entity);
@@ -66,7 +66,7 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository {
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
public void deleteByTargetIdIn(final Collection<Long> targetIDs) {
final javax.persistence.Query query = entityManager
.createQuery("DELETE FROM TargetInfo ti where ti.targetId IN :target");
.createQuery("DELETE FROM JpaTargetInfo ti where ti.targetId IN :target");
query.setParameter("target", targetIDs);
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifactProvider;
import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
@@ -17,6 +18,6 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface ExternalArtifactProviderRepository extends BaseEntityRepository<ExternalArtifactProvider, Long> {
public interface ExternalArtifactProviderRepository extends BaseEntityRepository<JpaExternalArtifactProvider, Long> {
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifact;
import org.eclipse.hawkbit.repository.model.ExternalArtifact;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -19,7 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface ExternalArtifactRepository extends BaseEntityRepository<ExternalArtifact, Long> {
public interface ExternalArtifactRepository extends BaseEntityRepository<JpaExternalArtifact, Long> {
/**
* Searches for external artifact for a base software module.
@@ -31,6 +32,6 @@ public interface ExternalArtifactRepository extends BaseEntityRepository<Externa
*
* @return Page<ExternalArtifact>
*/
Page<ExternalArtifact> findBySoftwareModuleId(Pageable pageReq, final Long swId);
Page<JpaExternalArtifact> findBySoftwareModuleId(Pageable pageReq, final Long swId);
}

View File

@@ -24,12 +24,16 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.GridFSDBFileNotFoundException;
import org.eclipse.hawkbit.repository.exception.InvalidMD5HashException;
import org.eclipse.hawkbit.repository.exception.InvalidSHA1HashException;
import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaExternalArtifactProvider;
import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.ExternalArtifact;
import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.specifications.SoftwareModuleSpecification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -88,7 +92,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
final String urlSuffix, final Long moduleId) {
final SoftwareModule module = getModuleAndThrowExceptionIfThatFails(moduleId);
return externalArtifactRepository.save(new ExternalArtifact(externalRepository, urlSuffix, module));
return externalArtifactRepository.save(new JpaExternalArtifact(externalRepository, urlSuffix, module));
}
@Override
@@ -97,7 +101,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
public ExternalArtifactProvider createExternalArtifactProvider(final String name, final String description,
final String basePath, final String defaultUrlSuffix) {
return externalArtifactProviderRepository
.save(new ExternalArtifactProvider(name, description, basePath, defaultUrlSuffix));
.save(new JpaExternalArtifactProvider(name, description, basePath, defaultUrlSuffix));
}
@Override
@@ -142,7 +146,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
}
existing.getSoftwareModule().removeArtifact(existing);
softwareModuleRepository.save(existing.getSoftwareModule());
softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule());
externalArtifactRepository.delete(id);
}
@@ -156,7 +160,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
boolean artifactIsOnlyUsedByOneSoftwareModule = true;
for (final LocalArtifact lArtifact : localArtifactRepository
.findByGridFsFileName(existing.getGridFsFileName())) {
.findByGridFsFileName(((JpaLocalArtifact) existing).getGridFsFileName())) {
if (!lArtifact.getSoftwareModule().isDeleted()
&& Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) {
artifactIsOnlyUsedByOneSoftwareModule = false;
@@ -166,8 +170,8 @@ public class JpaArtifactManagement implements ArtifactManagement {
if (artifactIsOnlyUsedByOneSoftwareModule) {
try {
LOG.debug("deleting artifact from repository {}", existing.getGridFsFileName());
artifactRepository.deleteBySha1(existing.getGridFsFileName());
LOG.debug("deleting artifact from repository {}", ((JpaLocalArtifact) existing).getGridFsFileName());
artifactRepository.deleteBySha1(((JpaLocalArtifact) existing).getGridFsFileName());
} catch (final ArtifactStoreException e) {
throw new ArtifactDeleteFailedException(e);
}
@@ -178,7 +182,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteLocalArtifact(final Long id) {
final LocalArtifact existing = localArtifactRepository.findOne(id);
final JpaLocalArtifact existing = localArtifactRepository.findOne(id);
if (null == existing) {
return;
@@ -187,7 +191,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
deleteLocalArtifact(existing);
existing.getSoftwareModule().removeArtifact(existing);
softwareModuleRepository.save(existing.getSoftwareModule());
softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule());
localArtifactRepository.delete(id);
}
@@ -219,7 +223,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
@Override
public SoftwareModule findSoftwareModuleById(final Long id) {
final Specification<SoftwareModule> spec = SoftwareModuleSpecification.byId(id);
final Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.byId(id);
return softwareModuleRepository.findOne(spec);
}
@@ -246,9 +250,10 @@ public class JpaArtifactManagement implements ArtifactManagement {
@Override
public DbArtifact loadLocalArtifactBinary(final LocalArtifact artifact) {
final DbArtifact result = artifactRepository.getArtifactBySha1(artifact.getGridFsFileName());
final DbArtifact result = artifactRepository
.getArtifactBySha1(((JpaLocalArtifact) artifact).getGridFsFileName());
if (result == null) {
throw new GridFSDBFileNotFoundException(artifact.getGridFsFileName());
throw new GridFSDBFileNotFoundException(((JpaLocalArtifact) artifact).getGridFsFileName());
}
return result;
@@ -256,9 +261,9 @@ public class JpaArtifactManagement implements ArtifactManagement {
private LocalArtifact storeArtifactMetadata(final SoftwareModule softwareModule, final String providedFilename,
final DbArtifact result, final LocalArtifact existing) {
LocalArtifact artifact = existing;
JpaLocalArtifact artifact = (JpaLocalArtifact) existing;
if (existing == null) {
artifact = new LocalArtifact(result.getHashes().getSha1(), providedFilename, softwareModule);
artifact = new JpaLocalArtifact(result.getHashes().getSha1(), providedFilename, softwareModule);
}
artifact.setMd5Hash(result.getHashes().getMd5());
artifact.setSha1Hash(result.getHashes().getSha1());

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository.jpa;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -24,19 +25,25 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
import org.eclipse.hawkbit.repository.exception.ToManyStatusEntriesException;
import org.eclipse.hawkbit.repository.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.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
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.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.ActionStatus_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.Target_;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.repository.specifications.ActionSpecifications;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.slf4j.Logger;
@@ -46,6 +53,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -116,7 +124,8 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
public Action getActionForDownloadByTargetAndSoftwareModule(final String controllerId,
final SoftwareModule module) {
final List<Action> action = actionRepository.findActionByTargetAndSoftwareModule(controllerId, module);
final List<Action> action = actionRepository.findActionByTargetAndSoftwareModule(controllerId,
(JpaSoftwareModule) module);
if (action.isEmpty() || action.get(0).isCancelingOrCanceled()) {
throw new EntityNotFoundException(
@@ -137,12 +146,12 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
public List<Action> findActionByTargetAndActive(final Target target) {
return actionRepository.findByTargetAndActiveOrderByIdAsc(target, true);
return actionRepository.findByTargetAndActiveOrderByIdAsc((JpaTarget) target, true);
}
@Override
public List<SoftwareModule> findSoftwareModulesByDistributionSet(final DistributionSet distributionSet) {
return softwareModuleRepository.findByAssignedTo(distributionSet);
return new ArrayList<>(softwareModuleRepository.findByAssignedTo((JpaDistributionSet) distributionSet));
}
@Override
@@ -154,13 +163,13 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target findOrRegisterTargetIfItDoesNotexist(final String controllerId, final URI address) {
final Specification<Target> spec = (targetRoot, query, cb) -> cb.equal(targetRoot.get(Target_.controllerId),
controllerId);
final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb
.equal(targetRoot.get(JpaTarget_.controllerId), controllerId);
Target target = targetRepository.findOne(spec);
JpaTarget target = targetRepository.findOne(spec);
if (target == null) {
target = new Target(controllerId);
target = new JpaTarget(controllerId);
target.setDescription("Plug and Play target: " + controllerId);
target.setName(controllerId);
return targetManagement.createTarget(target, TargetUpdateStatus.REGISTERED, System.currentTimeMillis(),
@@ -175,7 +184,7 @@ public class JpaControllerManagement implements ControllerManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetInfo updateTargetStatus(final TargetInfo targetInfo, final TargetUpdateStatus status,
final Long lastTargetQuery, final URI address) {
final TargetInfo mtargetInfo = entityManager.merge(targetInfo);
final JpaTargetInfo mtargetInfo = (JpaTargetInfo) entityManager.merge(targetInfo);
if (status != null) {
mtargetInfo.setUpdateStatus(status);
}
@@ -192,7 +201,7 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action addCancelActionStatus(final ActionStatus actionStatus) {
final Action action = actionStatus.getAction();
final JpaAction action = (JpaAction) actionStatus.getAction();
checkForToManyStatusEntries(action);
action.setStatus(actionStatus.getStatus());
@@ -217,7 +226,7 @@ public class JpaControllerManagement implements ControllerManagement {
default:
}
actionRepository.save(action);
actionStatusRepository.save(actionStatus);
actionStatusRepository.save((JpaActionStatus) actionStatus);
return action;
}
@@ -226,14 +235,14 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action addUpdateActionStatus(@NotNull final ActionStatus actionStatus) {
final Action action = actionStatus.getAction();
final JpaAction action = (JpaAction) actionStatus.getAction();
if (!action.isActive()) {
LOG.debug("Update of actionStatus {} for action {} not possible since action not active anymore.",
actionStatus.getId(), action.getId());
return action;
}
return handleAddUpdateActionStatus(actionStatus, action);
return handleAddUpdateActionStatus((JpaActionStatus) actionStatus, action);
}
/**
@@ -243,11 +252,11 @@ public class JpaControllerManagement implements ControllerManagement {
* @param action
* @return
*/
private Action handleAddUpdateActionStatus(final ActionStatus actionStatus, final Action action) {
private Action handleAddUpdateActionStatus(final JpaActionStatus actionStatus, final JpaAction action) {
LOG.debug("addUpdateActionStatus for action {}", action.getId());
final Action mergedAction = entityManager.merge(action);
Target mergedTarget = mergedAction.getTarget();
final JpaAction mergedAction = entityManager.merge(action);
JpaTarget mergedTarget = (JpaTarget) mergedAction.getTarget();
// check for a potential DOS attack
checkForToManyStatusEntries(action);
@@ -284,7 +293,7 @@ public class JpaControllerManagement implements ControllerManagement {
targetManagement.updateTarget(mergedTarget);
}
private void checkForToManyStatusEntries(final Action action) {
private void checkForToManyStatusEntries(final JpaAction action) {
if (securityProperties.getDos().getMaxStatusEntriesPerAction() > 0) {
final Long statusCount = actionStatusRepository.countByAction(action);
@@ -299,11 +308,11 @@ public class JpaControllerManagement implements ControllerManagement {
}
}
private void handleFinishedAndStoreInTargetStatus(final Target target, final Action action) {
private void handleFinishedAndStoreInTargetStatus(final JpaTarget target, final JpaAction action) {
action.setActive(false);
action.setStatus(Status.FINISHED);
final TargetInfo targetInfo = target.getTargetInfo();
final DistributionSet ds = entityManager.merge(action.getDistributionSet());
final JpaTargetInfo targetInfo = (JpaTargetInfo) target.getTargetInfo();
final JpaDistributionSet ds = (JpaDistributionSet) entityManager.merge(action.getDistributionSet());
targetInfo.setInstalledDistributionSet(ds);
if (target.getAssignedDistributionSet() != null && targetInfo.getInstalledDistributionSet() != null && target
.getAssignedDistributionSet().getId().equals(targetInfo.getInstalledDistributionSet().getId())) {
@@ -321,15 +330,16 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateControllerAttributes(final String controllerId, final Map<String, String> data) {
final Target target = targetRepository.findByControllerId(controllerId);
final JpaTarget target = targetRepository.findByControllerId(controllerId);
if (target == null) {
throw new EntityNotFoundException(controllerId);
}
target.getTargetInfo().getControllerAttributes().putAll(data);
final JpaTargetInfo targetInfo = (JpaTargetInfo) target.getTargetInfo();
targetInfo.getControllerAttributes().putAll(data);
if (target.getTargetInfo().getControllerAttributes().size() > securityProperties.getDos()
if (targetInfo.getControllerAttributes().size() > securityProperties.getDos()
.getMaxAttributeEntriesPerTarget()) {
LOG_DOS.info("Target tries to insert more than the allowed number of entries ({}). DOS attack anticipated!",
securityProperties.getDos().getMaxAttributeEntriesPerTarget());
@@ -337,8 +347,8 @@ public class JpaControllerManagement implements ControllerManagement {
String.valueOf(securityProperties.getDos().getMaxAttributeEntriesPerTarget()));
}
target.getTargetInfo().setLastTargetQuery(System.currentTimeMillis());
target.getTargetInfo().setRequestControllerAttributes(false);
targetInfo.setLastTargetQuery(System.currentTimeMillis());
targetInfo.setRequestControllerAttributes(false);
return targetRepository.save(target);
}
@@ -346,7 +356,7 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action registerRetrieved(final Action action, final String message) {
return handleRegisterRetrieved(action, message);
return handleRegisterRetrieved((JpaAction) action, message);
}
/**
@@ -360,7 +370,7 @@ public class JpaControllerManagement implements ControllerManagement {
* @return the updated action in case the status has been changed to
* {@link Status#RETRIEVED}
*/
private Action handleRegisterRetrieved(final Action action, final String message) {
private Action handleRegisterRetrieved(final JpaAction action, final String message) {
// 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
@@ -369,11 +379,11 @@ public class JpaControllerManagement implements ControllerManagement {
// or not.
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> queryActionStatus = cb.createQuery(Object[].class);
final Root<ActionStatus> actionStatusRoot = queryActionStatus.from(ActionStatus.class);
final Root<JpaActionStatus> actionStatusRoot = queryActionStatus.from(JpaActionStatus.class);
final CriteriaQuery<Object[]> query = queryActionStatus
.multiselect(actionStatusRoot.get(ActionStatus_.id), actionStatusRoot.get(ActionStatus_.status))
.where(cb.equal(actionStatusRoot.get(ActionStatus_.action), action))
.orderBy(cb.desc(actionStatusRoot.get(ActionStatus_.id)));
.multiselect(actionStatusRoot.get(JpaActionStatus_.id), actionStatusRoot.get(JpaActionStatus_.status))
.where(cb.equal(actionStatusRoot.get(JpaActionStatus_.action), action))
.orderBy(cb.desc(actionStatusRoot.get(JpaActionStatus_.id)));
final List<Object[]> resultList = entityManager.createQuery(query).setFirstResult(0).setMaxResults(1)
.getResultList();
@@ -387,14 +397,14 @@ public class JpaControllerManagement implements ControllerManagement {
if (resultList.isEmpty() || resultList.get(0)[1] != Status.RETRIEVED) {
// document that the status has been retrieved
actionStatusRepository
.save(new ActionStatus(action, Status.RETRIEVED, System.currentTimeMillis(), message));
.save(new JpaActionStatus(action, Status.RETRIEVED, System.currentTimeMillis(), message));
// don't change the action status itself in case the action is in
// canceling state otherwise
// we modify the action status and the controller won't get the
// cancel job anymore.
if (!action.isCancelingOrCanceled()) {
final Action actionMerge = entityManager.merge(action);
final JpaAction actionMerge = entityManager.merge(action);
actionMerge.setStatus(Status.RETRIEVED);
return actionRepository.save(actionMerge);
}
@@ -406,7 +416,7 @@ public class JpaControllerManagement implements ControllerManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void addInformationalActionStatus(final ActionStatus statusMessage) {
actionStatusRepository.save(statusMessage);
actionStatusRepository.save((JpaActionStatus) statusMessage);
}
@Override
@@ -421,4 +431,10 @@ public class JpaControllerManagement implements ControllerManagement {
public TargetInfo updateLastTargetQuery(final TargetInfo target, final URI address) {
return updateTargetStatus(target, null, System.currentTimeMillis(), address);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public ActionStatus generateActionStatus() {
return new JpaActionStatus();
}
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -32,6 +33,7 @@ import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.TargetManagement;
@@ -39,24 +41,32 @@ import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
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.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
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.ActionStatus;
import org.eclipse.hawkbit.repository.model.ActionWithStatusCount;
import org.eclipse.hawkbit.repository.model.Action_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
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.Rollout_;
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.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,12 +74,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -126,7 +138,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
public DistributionSetAssignmentResult assignDistributionSet(final DistributionSet pset,
final List<Target> targets) {
return assignDistributionSetByTargetId(pset,
return assignDistributionSetByTargetId((JpaDistributionSet) pset,
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList()),
ActionType.FORCED, Action.NO_FORCE_TIME);
@@ -159,7 +171,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets) {
final DistributionSet set = distributoinSetRepository.findOne(dsID);
final JpaDistributionSet set = distributoinSetRepository.findOne(dsID);
if (set == null) {
throw new EntityNotFoundException(
String.format("no %s with id %d found", DistributionSet.class.getSimpleName(), dsID));
@@ -174,13 +186,13 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@CacheEvict(value = { "distributionUsageAssigned" }, allEntries = true)
public DistributionSetAssignmentResult assignDistributionSet(final Long dsID,
final Collection<TargetWithActionType> targets, final Rollout rollout, final RolloutGroup rolloutGroup) {
final DistributionSet set = distributoinSetRepository.findOne(dsID);
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, rollout, rolloutGroup);
return assignDistributionSetToTargets(set, targets, (JpaRollout) rollout, (JpaRolloutGroup) rolloutGroup);
}
/**
@@ -201,9 +213,9 @@ public class JpaDeploymentManagement implements DeploymentManagement {
* {@link SoftwareModuleType} are not assigned as define by the
* {@link DistributionSetType}.
*/
private DistributionSetAssignmentResult assignDistributionSetToTargets(@NotNull final DistributionSet set,
final Collection<TargetWithActionType> targetsWithActionType, final Rollout rollout,
final RolloutGroup rolloutGroup) {
private DistributionSetAssignmentResult assignDistributionSetToTargets(@NotNull final JpaDistributionSet set,
final Collection<TargetWithActionType> targetsWithActionType, final JpaRollout rollout,
final JpaRolloutGroup rolloutGroup) {
if (!set.isComplete()) {
throw new IncompleteDistributionSetException(
@@ -223,7 +235,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// maximum 1000 elements, so we need to split the entries here and
// execute multiple statements we take the target only into account if
// the requested operation is no duplicate of a previous one
final List<Target> targets = Lists.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream()
final List<JpaTarget> targets = Lists.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream()
.map(ids -> targetRepository
.findAll(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, set.getId())))
.flatMap(t -> t.stream()).collect(Collectors.toList());
@@ -262,7 +274,7 @@ 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, Action> targetIdsToActions = actionRepository
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()));
@@ -272,7 +284,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// of the action itself and with this action status we have a nicer
// action history.
targetIdsToActions.values().forEach(action -> {
final ActionStatus actionStatus = new ActionStatus();
final JpaActionStatus actionStatus = new JpaActionStatus();
actionStatus.setAction(action);
actionStatus.setOccurredAt(action.getCreatedAt());
actionStatus.setStatus(Status.RUNNING);
@@ -289,7 +301,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
LOG.debug("assignDistribution({}) finished {}", set, result);
final List<SoftwareModule> softwareModules = softwareModuleRepository.findByAssignedTo(set);
final List<JpaSoftwareModule> softwareModules = softwareModuleRepository.findByAssignedTo(set);
// detaching as it is not necessary to persist the set itself
entityManager.detach(set);
@@ -299,16 +311,17 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return result;
}
private void sendDistributionSetAssignmentEvent(final List<Target> targets, final Set<Long> targetIdsCancellList,
final Map<String, Action> targetIdsToActions, final List<SoftwareModule> softwareModules) {
private void sendDistributionSetAssignmentEvent(final List<JpaTarget> targets, final Set<Long> targetIdsCancellList,
final Map<String, JpaAction> targetIdsToActions, final List<JpaSoftwareModule> softwareModules) {
targets.stream().filter(t -> !!!targetIdsCancellList.contains(t.getId()))
.forEach(t -> assignDistributionSetEvent(t, targetIdsToActions.get(t.getControllerId()).getId(),
softwareModules));
}
private static Action createTargetAction(final Map<String, TargetWithActionType> targetsWithActionMap,
final Target target, final DistributionSet set, final Rollout rollout, final RolloutGroup rolloutGroup) {
final Action actionForTarget = new Action();
private static JpaAction createTargetAction(final Map<String, TargetWithActionType> targetsWithActionMap,
final JpaTarget target, final JpaDistributionSet set, final JpaRollout rollout,
final JpaRolloutGroup rolloutGroup) {
final JpaAction actionForTarget = new JpaAction();
final TargetWithActionType targetWithActionType = targetsWithActionMap.get(target.getControllerId());
actionForTarget.setActionType(targetWithActionType.getActionType());
actionForTarget.setForcedTime(targetWithActionType.getForceTime());
@@ -332,9 +345,12 @@ public class JpaDeploymentManagement implements DeploymentManagement {
* @param softwareModules
* the software modules which have been assigned
*/
private void assignDistributionSetEvent(final Target target, final Long actionId,
final List<SoftwareModule> softwareModules) {
target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING);
private void assignDistributionSetEvent(final JpaTarget target, final Long actionId,
final List<JpaSoftwareModule> modules) {
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<SoftwareModule> softwareModules = (Collection) modules;
afterCommit.afterCommit(() -> {
eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo()));
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(),
@@ -357,14 +373,14 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// Figure out if there are potential target/action combinations that
// need to be considered
// for cancelation
final List<Action> activeActions = actionRepository
final List<JpaAction> activeActions = actionRepository
.findByActiveAndTargetIdInAndActionStatusNotEqualToAndDistributionSetRequiredMigrationStep(targetsIds,
Action.Status.CANCELING);
activeActions.forEach(action -> {
action.setStatus(Status.CANCELING);
// document that the status has been retrieved
actionStatusRepository.save(new ActionStatus(action, Status.CANCELING, System.currentTimeMillis(),
actionStatusRepository.save(new JpaActionStatus(action, Status.CANCELING, System.currentTimeMillis(),
"manual cancelation requested"));
cancelAssignDistributionSetEvent(action.getTarget(), action.getId());
@@ -378,7 +394,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
}
private DistributionSetAssignmentResult assignDistributionSetByTargetId(@NotNull final DistributionSet set,
private DistributionSetAssignmentResult assignDistributionSetByTargetId(@NotNull final JpaDistributionSet set,
@NotEmpty final List<String> tIDs, final ActionType actionType, final long forcedTime) {
return assignDistributionSetToTargets(set, tIDs.stream()
@@ -394,14 +410,14 @@ public class JpaDeploymentManagement implements DeploymentManagement {
if (action.isCancelingOrCanceled()) {
throw new CancelActionNotAllowedException("Actions in canceling or canceled state cannot be canceled");
}
final Action myAction = entityManager.merge(action);
final JpaAction myAction = (JpaAction) entityManager.merge(action);
if (myAction.isActive()) {
LOG.debug("action ({}) was still active. Change to {}.", action, Status.CANCELING);
myAction.setStatus(Status.CANCELING);
// document that the status has been retrieved
actionStatusRepository.save(new ActionStatus(myAction, Status.CANCELING, System.currentTimeMillis(),
actionStatusRepository.save(new JpaActionStatus(myAction, Status.CANCELING, System.currentTimeMillis(),
"manual cancelation requested"));
final Action saveAction = actionRepository.save(myAction);
cancelAssignDistributionSetEvent(target, myAction.getId());
@@ -431,7 +447,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
public Action forceQuitAction(final Action action) {
final Action mergedAction = entityManager.merge(action);
final JpaAction mergedAction = (JpaAction) entityManager.merge(action);
if (!mergedAction.isCancelingOrCanceled()) {
throw new ForceQuitActionNotAllowedException(
@@ -446,7 +462,7 @@ 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 ActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(),
actionStatusRepository.save(new JpaActionStatus(mergedAction, Status.CANCELED, System.currentTimeMillis(),
"A force quit has been performed."));
DeploymentHelper.successCancellation(mergedAction, actionRepository, targetManagement, targetInfoRepository,
@@ -468,7 +484,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
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 Action action = new Action();
final JpaAction action = new JpaAction();
action.setTarget(target);
action.setActive(false);
action.setDistributionSet(distributionSet);
@@ -486,8 +502,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Transactional(isolation = Isolation.READ_COMMITTED)
public Action startScheduledAction(final Action action) {
final Action mergedAction = entityManager.merge(action);
final Target mergedTarget = entityManager.merge(action.getTarget());
final JpaAction mergedAction = (JpaAction) entityManager.merge(action);
final JpaTarget mergedTarget = (JpaTarget) entityManager.merge(action.getTarget());
// check if we need to override running update actions
final Set<Long> overrideObsoleteUpdateActions = overrideObsoleteUpdateActions(
@@ -509,14 +525,14 @@ public class JpaDeploymentManagement implements DeploymentManagement {
mergedAction.setStatus(Status.RUNNING);
final Action savedAction = actionRepository.save(mergedAction);
final ActionStatus actionStatus = new ActionStatus();
final JpaActionStatus actionStatus = new JpaActionStatus();
actionStatus.setAction(action);
actionStatus.setOccurredAt(action.getCreatedAt());
actionStatus.setStatus(Status.RUNNING);
actionStatusRepository.save(actionStatus);
mergedTarget.setAssignedDistributionSet(action.getDistributionSet());
final TargetInfo targetInfo = mergedTarget.getTargetInfo();
final JpaTargetInfo targetInfo = (JpaTargetInfo) mergedTarget.getTargetInfo();
targetInfo.setUpdateStatus(TargetUpdateStatus.PENDING);
targetRepository.save(mergedTarget);
targetInfoRepository.save(targetInfo);
@@ -524,11 +540,11 @@ public class JpaDeploymentManagement implements DeploymentManagement {
// in case we canceled an action before for this target, then don't fire
// assignment event
if (!overrideObsoleteUpdateActions.contains(savedAction.getId())) {
final List<SoftwareModule> softwareModules = softwareModuleRepository
.findByAssignedTo(action.getDistributionSet());
final List<JpaSoftwareModule> softwareModules = softwareModuleRepository
.findByAssignedTo((JpaDistributionSet) action.getDistributionSet());
// send distribution set assignment event
assignDistributionSetEvent(mergedAction.getTarget(), mergedAction.getId(), softwareModules);
assignDistributionSetEvent((JpaTarget) mergedAction.getTarget(), mergedAction.getId(), softwareModules);
}
return savedAction;
}
@@ -545,84 +561,93 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
public Slice<Action> findActionsByTarget(final Pageable pageable, final Target target) {
return actionRepository.findByTarget(pageable, target);
return actionRepository.findByTarget(pageable, (JpaTarget) target);
}
@Override
public List<Action> findActionsByTarget(final Target target) {
return actionRepository.findByTarget(target);
return actionRepository.findByTarget((JpaTarget) target);
}
@Override
public List<ActionWithStatusCount> findActionsWithStatusCountByTargetOrderByIdDesc(final Target target) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<ActionWithStatusCount> query = cb.createQuery(ActionWithStatusCount.class);
final Root<Action> actionRoot = query.from(Action.class);
final ListJoin<Action, ActionStatus> actionStatusJoin = actionRoot.join(Action_.actionStatus, JoinType.LEFT);
final Join<Action, DistributionSet> actionDsJoin = actionRoot.join(Action_.distributionSet);
final Join<Action, Rollout> actionRolloutJoin = actionRoot.join(Action_.rollout, JoinType.LEFT);
final Root<JpaAction> actionRoot = query.from(JpaAction.class);
final ListJoin<JpaAction, JpaActionStatus> actionStatusJoin = actionRoot.join(JpaAction_.actionStatus,
JoinType.LEFT);
final Join<JpaAction, JpaDistributionSet> actionDsJoin = actionRoot.join(JpaAction_.distributionSet);
final Join<JpaAction, JpaRollout> actionRolloutJoin = actionRoot.join(JpaAction_.rollout, JoinType.LEFT);
final CriteriaQuery<ActionWithStatusCount> multiselect = query.distinct(true).multiselect(
actionRoot.get(Action_.id), actionRoot.get(Action_.actionType), actionRoot.get(Action_.active),
actionRoot.get(Action_.forcedTime), actionRoot.get(Action_.status), actionRoot.get(Action_.createdAt),
actionRoot.get(Action_.lastModifiedAt), actionDsJoin.get(DistributionSet_.id),
actionDsJoin.get(DistributionSet_.name), actionDsJoin.get(DistributionSet_.version),
cb.count(actionStatusJoin), actionRolloutJoin.get(Rollout_.name));
multiselect.where(cb.equal(actionRoot.get(Action_.target), target));
multiselect.orderBy(cb.desc(actionRoot.get(Action_.id)));
multiselect.groupBy(actionRoot.get(Action_.id));
actionRoot.get(JpaAction_.id), actionRoot.get(JpaAction_.actionType), actionRoot.get(JpaAction_.active),
actionRoot.get(JpaAction_.forcedTime), actionRoot.get(JpaAction_.status),
actionRoot.get(JpaAction_.createdAt), actionRoot.get(JpaAction_.lastModifiedAt),
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.orderBy(cb.desc(actionRoot.get(JpaAction_.id)));
multiselect.groupBy(actionRoot.get(JpaAction_.id));
return entityManager.createQuery(multiselect).getResultList();
}
@Override
public Slice<Action> findActionsByTarget(final Specification<Action> specifiction, final Target target,
final Pageable pageable) {
public Page<Action> findActionsByTarget(final String rsqlParam, final Target target, final Pageable pageable) {
final Specification<JpaAction> specification = RSQLUtility.parse(rsqlParam, ActionFields.class);
return actionRepository.findAll((Specification<Action>) (root, query, cb) -> cb
.and(specifiction.toPredicate(root, query, cb), cb.equal(root.get(Action_.target), target)), pageable);
return convertAcPage(actionRepository.findAll((Specification<JpaAction>) (root, query, cb) -> cb
.and(specification.toPredicate(root, query, cb), cb.equal(root.get(JpaAction_.target), target)),
pageable));
}
private static Page<Action> convertAcPage(final Page<JpaAction> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
public Slice<Action> findActionsByTarget(final Target foundTarget, final Pageable pageable) {
return actionRepository.findByTarget(pageable, foundTarget);
return actionRepository.findByTarget(pageable, (JpaTarget) foundTarget);
}
@Override
public Page<Action> findActiveActionsByTarget(final Pageable pageable, final Target target) {
return actionRepository.findByActiveAndTarget(pageable, target, true);
return actionRepository.findByActiveAndTarget(pageable, (JpaTarget) target, true);
}
@Override
public List<Action> findActiveActionsByTarget(final Target target) {
return actionRepository.findByActiveAndTarget(target, true);
return actionRepository.findByActiveAndTarget((JpaTarget) target, true);
}
@Override
public List<Action> findInActiveActionsByTarget(final Target target) {
return actionRepository.findByActiveAndTarget(target, false);
return actionRepository.findByActiveAndTarget((JpaTarget) target, false);
}
@Override
public Page<Action> findInActiveActionsByTarget(final Pageable pageable, final Target target) {
return actionRepository.findByActiveAndTarget(pageable, target, false);
return actionRepository.findByActiveAndTarget(pageable, (JpaTarget) target, false);
}
@Override
public Long countActionsByTarget(final Target target) {
return actionRepository.countByTarget(target);
return actionRepository.countByTarget((JpaTarget) target);
}
@Override
public Long countActionsByTarget(final Specification<Action> spec, final Target target) {
public Long countActionsByTarget(final String rsqlParam, final Target target) {
final Specification<JpaAction> spec = RSQLUtility.parse(rsqlParam, ActionFields.class);
return actionRepository.count((root, query, cb) -> cb.and(spec.toPredicate(root, query, cb),
cb.equal(root.get(Action_.target), target)));
cb.equal(root.get(JpaAction_.target), target)));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Action forceTargetAction(final Long actionId) {
final Action action = actionRepository.findOne(actionId);
final JpaAction action = actionRepository.findOne(actionId);
if (action != null && !action.isForced()) {
action.setActionType(ActionType.FORCED);
return actionRepository.save(action);
@@ -634,20 +659,27 @@ public class JpaDeploymentManagement implements DeploymentManagement {
public Page<ActionStatus> findActionStatusByAction(final Pageable pageReq, final Action action,
final boolean withMessages) {
if (withMessages) {
return actionStatusRepository.getByAction(pageReq, action);
return actionStatusRepository.getByAction(pageReq, (JpaAction) action);
} else {
return actionStatusRepository.findByAction(pageReq, action);
return actionStatusRepository.findByAction(pageReq, (JpaAction) action);
}
}
@Override
public List<Action> findActionsByRolloutGroupParentAndStatus(final Rollout rollout,
final RolloutGroup rolloutGroupParent, final Action.Status actionStatus) {
return actionRepository.findByRolloutAndRolloutGroupParentAndStatus(rollout, rolloutGroupParent, actionStatus);
return actionRepository.findByRolloutAndRolloutGroupParentAndStatus((JpaRollout) rollout,
(JpaRolloutGroup) rolloutGroupParent, actionStatus);
}
@Override
public List<Action> findActionsByRolloutAndStatus(final Rollout rollout, final Action.Status actionStatus) {
return actionRepository.findByRolloutAndStatus(rollout, actionStatus);
return actionRepository.findByRolloutAndStatus((JpaRollout) rollout, actionStatus);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public Action generateAction() {
return new JpaAction();
}
}

View File

@@ -24,28 +24,36 @@ import javax.persistence.EntityManager;
import org.eclipse.hawkbit.eventbus.event.DistributionSetTagAssigmentResultEvent;
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.DistributionSetFields;
import org.eclipse.hawkbit.repository.DistributionSetFilter;
import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder;
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.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.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_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
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.DistributionSetMetadata;
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.DistributionSet_;
import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.specifications.DistributionSetSpecification;
import org.eclipse.hawkbit.repository.specifications.DistributionSetTypeSpecification;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
@@ -54,6 +62,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -111,12 +120,12 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<Long> dsIds, final String tagName) {
final Iterable<DistributionSet> sets = findDistributionSetListWithDetails(dsIds);
final List<JpaDistributionSet> sets = findDistributionSetListWithDetails(dsIds);
final DistributionSetTag myTag = tagManagement.findDistributionSetTag(tagName);
DistributionSetTagAssignmentResult result;
final List<DistributionSet> toBeChangedDSs = new ArrayList<>();
for (final DistributionSet set : sets) {
final List<JpaDistributionSet> toBeChangedDSs = new ArrayList<>();
for (final JpaDistributionSet set : sets) {
if (set.getTags().add(myTag)) {
toBeChangedDSs.add(set);
}
@@ -124,17 +133,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
// un-assignment case
if (toBeChangedDSs.isEmpty()) {
for (final DistributionSet set : sets) {
for (final JpaDistributionSet set : sets) {
if (set.getTags().remove(myTag)) {
toBeChangedDSs.add(set);
}
}
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0,
toBeChangedDSs.size(), Collections.emptyList(), distributionSetRepository.save(toBeChangedDSs),
myTag);
toBeChangedDSs.size(), Collections.emptyList(),
new ArrayList<>(distributionSetRepository.save(toBeChangedDSs)), myTag);
} else {
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(),
0, distributionSetRepository.save(toBeChangedDSs), Collections.emptyList(), myTag);
0, new ArrayList<>(distributionSetRepository.save(toBeChangedDSs)), Collections.emptyList(), myTag);
}
final DistributionSetTagAssignmentResult resultAssignment = result;
@@ -145,8 +154,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return result;
}
@Override
public List<DistributionSet> findDistributionSetListWithDetails(final Collection<Long> distributionIdSet) {
private List<JpaDistributionSet> findDistributionSetListWithDetails(final Collection<Long> distributionIdSet) {
return distributionSetRepository.findAll(DistributionSetSpecification.byIds(distributionIdSet));
}
@@ -156,8 +164,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public DistributionSet updateDistributionSet(final DistributionSet ds) {
checkNotNull(ds.getId());
final DistributionSet persisted = findDistributionSetByIdWithDetails(ds.getId());
checkDistributionSetSoftwareModulesIsAllowedToModify(ds, persisted.getModules());
return distributionSetRepository.save(ds);
checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, persisted.getModules());
return distributionSetRepository.save((JpaDistributionSet) ds);
}
@Override
@@ -196,7 +204,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
if (dSet.getType() == null) {
dSet.setType(systemManagement.getTenantMetadata().getDefaultDsType());
}
return distributionSetRepository.save(dSet);
return distributionSetRepository.save((JpaDistributionSet) dSet);
}
private void prepareDsSave(final DistributionSet dSet) {
@@ -220,18 +228,22 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
ds.setType(systemManagement.getTenantMetadata().getDefaultDsType());
}
}
return distributionSetRepository.save(distributionSets);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaDistributionSet> toSave = (Collection) distributionSets;
return new ArrayList<>(distributionSetRepository.save(toSave));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet assignSoftwareModules(final DistributionSet ds, final Set<SoftwareModule> softwareModules) {
checkDistributionSetSoftwareModulesIsAllowedToModify(ds, softwareModules);
checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, softwareModules);
for (final SoftwareModule softwareModule : softwareModules) {
ds.addModule(softwareModule);
}
return distributionSetRepository.save(ds);
return distributionSetRepository.save((JpaDistributionSet) ds);
}
@Override
@@ -241,8 +253,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
final Set<SoftwareModule> softwareModules = new HashSet<>();
softwareModules.add(softwareModule);
ds.removeModule(softwareModule);
checkDistributionSetSoftwareModulesIsAllowedToModify(ds, softwareModules);
return distributionSetRepository.save(ds);
checkDistributionSetSoftwareModulesIsAllowedToModify((JpaDistributionSet) ds, softwareModules);
return distributionSetRepository.save((JpaDistributionSet) ds);
}
@Override
@@ -251,7 +263,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public DistributionSetType updateDistributionSetType(final DistributionSetType dsType) {
checkNotNull(dsType.getId());
final DistributionSetType persisted = distributionSetTypeRepository.findOne(dsType.getId());
final JpaDistributionSetType persisted = distributionSetTypeRepository.findOne(dsType.getId());
// throw exception if user tries to update a DS type that is already in
// use
@@ -261,25 +273,36 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
dsType.getName()));
}
return distributionSetTypeRepository.save(dsType);
return distributionSetTypeRepository.save((JpaDistributionSetType) dsType);
}
@Override
public Page<DistributionSetType> findDistributionSetTypesAll(final Specification<DistributionSetType> spec,
final Pageable pageable) {
return distributionSetTypeRepository.findAll(spec, pageable);
public Page<DistributionSetType> findDistributionSetTypesAll(final String rsqlParam, final Pageable pageable) {
final Specification<JpaDistributionSetType> spec = RSQLUtility.parse(rsqlParam,
DistributionSetTypeFields.class);
return convertDsTPage(distributionSetTypeRepository.findAll(spec, pageable));
}
private static Page<DistributionSetType> convertDsTPage(final Page<JpaDistributionSetType> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
public Page<DistributionSetType> findDistributionSetTypesAll(final Pageable pageable) {
return distributionSetTypeRepository.findByDeleted(pageable, false);
return convertDsTPage(distributionSetTypeRepository.findByDeleted(pageable, false));
}
@Override
public Page<DistributionSet> findDistributionSetsByFilters(final Pageable pageable,
final DistributionSetFilter distributionSetFilter) {
final List<Specification<DistributionSet>> specList = buildDistributionSetSpecifications(distributionSetFilter);
return findByCriteriaAPI(pageable, specList);
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
distributionSetFilter);
return convertDsPage(findByCriteriaAPI(pageable, specList));
}
private static Page<DistributionSet> convertDsPage(final Page<JpaDistributionSet> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
/**
@@ -291,7 +314,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
*/
private DistributionSet findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
final DistributionSetFilter distributionSetFilter) {
final List<Specification<DistributionSet>> specList = buildDistributionSetSpecifications(distributionSetFilter);
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
distributionSetFilter);
if (specList == null || specList.isEmpty()) {
return null;
}
@@ -301,30 +325,33 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
public Page<DistributionSet> findDistributionSetsAll(final Pageable pageReq, final Boolean deleted,
final Boolean complete) {
final List<Specification<DistributionSet>> specList = new ArrayList<>();
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>();
if (deleted != null) {
final Specification<DistributionSet> spec = DistributionSetSpecification.isDeleted(deleted);
final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isDeleted(deleted);
specList.add(spec);
}
if (complete != null) {
final Specification<DistributionSet> spec = DistributionSetSpecification.isCompleted(complete);
final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isCompleted(complete);
specList.add(spec);
}
return findByCriteriaAPI(pageReq, specList);
return convertDsPage(findByCriteriaAPI(pageReq, specList));
}
@Override
public Page<DistributionSet> findDistributionSetsAll(final Specification<DistributionSet> spec,
final Pageable pageReq, final Boolean deleted) {
final List<Specification<DistributionSet>> specList = new ArrayList<>();
public Page<DistributionSet> findDistributionSetsAll(final String rsqlParam, final Pageable pageReq,
final Boolean deleted) {
final Specification<JpaDistributionSet> spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class);
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>();
if (deleted != null) {
specList.add(DistributionSetSpecification.isDeleted(deleted));
}
specList.add(spec);
return findByCriteriaAPI(pageReq, specList);
return convertDsPage(findByCriteriaAPI(pageReq, specList));
}
@Override
@@ -371,23 +398,23 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
public DistributionSet findDistributionSetByNameAndVersion(final String distributionName, final String version) {
final Specification<DistributionSet> spec = DistributionSetSpecification
final Specification<JpaDistributionSet> spec = DistributionSetSpecification
.equalsNameAndVersionIgnoreCase(distributionName, version);
return distributionSetRepository.findOne(spec);
}
@Override
public Iterable<DistributionSet> findDistributionSetList(final Collection<Long> dist) {
return distributionSetRepository.findAll(dist);
public List<DistributionSet> findDistributionSetsAll(final Collection<Long> dist) {
return new ArrayList<>(distributionSetRepository.findAll(DistributionSetSpecification.byIds(dist)));
}
@Override
public Long countDistributionSetsAll() {
final List<Specification<DistributionSet>> specList = new ArrayList<>();
final List<Specification<JpaDistributionSet>> specList = new LinkedList<>();
final Specification<DistributionSet> spec = DistributionSetSpecification.isDeleted(Boolean.FALSE);
final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isDeleted(Boolean.FALSE);
specList.add(spec);
return distributionSetRepository.count(SpecificationsBuilder.combineWithAnd(specList));
@@ -421,16 +448,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
throw new EntityAlreadyExistsException("Given type contains an Id!");
}
return distributionSetTypeRepository.save(type);
return distributionSetTypeRepository.save((JpaDistributionSetType) type);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSetType(final DistributionSetType type) {
public void deleteDistributionSetType(final DistributionSetType ty) {
final JpaDistributionSetType type = (JpaDistributionSetType) ty;
if (distributionSetRepository.countByType(type) > 0) {
final DistributionSetType toDelete = entityManager.merge(type);
final JpaDistributionSetType toDelete = entityManager.merge(type);
toDelete.setDeleted(true);
distributionSetTypeRepository.save(toDelete);
} else {
@@ -441,7 +469,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public DistributionSetMetadata createDistributionSetMetadata(final DistributionSetMetadata metadata) {
public DistributionSetMetadata createDistributionSetMetadata(final DistributionSetMetadata md) {
final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) md;
if (distributionSetMetadataRepository.exists(metadata.getId())) {
throwMetadataKeyAlreadyExists(metadata.getId().getKey());
}
@@ -449,31 +479,38 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
// log written because
// modifying metadata is modifying the base distribution set itself for
// auditing purposes.
entityManager.merge(metadata.getDistributionSet()).setLastModifiedAt(0L);
entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L);
return distributionSetMetadataRepository.save(metadata);
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public List<DistributionSetMetadata> createDistributionSetMetadata(
final Collection<DistributionSetMetadata> metadata) {
for (final DistributionSetMetadata distributionSetMetadata : metadata) {
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 -> entityManager.merge(m.getDistributionSet()).setLastModifiedAt(-1L));
return (List<DistributionSetMetadata>) distributionSetMetadataRepository.save(metadata);
metadata.forEach(m -> entityManager.merge((JpaDistributionSet) m.getDistributionSet()).setLastModifiedAt(0L));
return new ArrayList<DistributionSetMetadata>(
(Collection<? extends DistributionSetMetadata>) distributionSetMetadataRepository.save(metadata));
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public DistributionSetMetadata updateDistributionSetMetadata(final DistributionSetMetadata metadata) {
public DistributionSetMetadata updateDistributionSetMetadata(final DistributionSetMetadata md) {
final JpaDistributionSetMetadata metadata = (JpaDistributionSetMetadata) md;
// check if exists otherwise throw entity not found exception
findOne(metadata.getId());
// touch it to update the lock revision because we are modifying the
// DS indirectly
entityManager.merge(metadata.getDistributionSet()).setLastModifiedAt(0L);
entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L);
return distributionSetMetadataRepository.save(metadata);
}
@@ -488,23 +525,29 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(final Long distributionSetId,
final Pageable pageable) {
return distributionSetMetadataRepository.findAll(
(Specification<DistributionSetMetadata>) (root, query, cb) -> cb.equal(
root.get(DistributionSetMetadata_.distributionSet).get(DistributionSet_.id), distributionSetId),
pageable);
return convertMdPage(distributionSetMetadataRepository
.findAll((Specification<JpaDistributionSetMetadata>) (root, query, cb) -> cb.equal(
root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id),
distributionSetId), pageable));
}
@Override
public Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(final Long distributionSetId,
final Specification<DistributionSetMetadata> spec, final Pageable pageable) {
return distributionSetMetadataRepository
.findAll(
(Specification<DistributionSetMetadata>) (root, query,
cb) -> cb.and(
cb.equal(root.get(DistributionSetMetadata_.distributionSet)
.get(DistributionSet_.id), distributionSetId),
spec.toPredicate(root, query, cb)),
pageable);
final String rsqlParam, final Pageable pageable) {
final Specification<JpaDistributionSetMetadata> spec = RSQLUtility.parse(rsqlParam,
DistributionSetMetadataFields.class);
return convertMdPage(
distributionSetMetadataRepository
.findAll((Specification<JpaDistributionSetMetadata>) (root, query, cb) -> cb.and(
cb.equal(root.get(JpaDistributionSetMetadata_.distributionSet)
.get(JpaDistributionSet_.id), distributionSetId),
spec.toPredicate(root, query, cb)), pageable));
}
private static Page<DistributionSetMetadata> convertMdPage(final Page<JpaDistributionSetMetadata> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
@@ -518,19 +561,19 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
public DistributionSet findDistributionSetByAction(final Action action) {
return distributionSetRepository.findByAction(action);
return distributionSetRepository.findByAction((JpaAction) action);
}
@Override
public boolean isDistributionSetInUse(final DistributionSet distributionSet) {
return actionRepository.countByDistributionSet(distributionSet) > 0;
return actionRepository.countByDistributionSet((JpaDistributionSet) distributionSet) > 0;
}
private static List<Specification<DistributionSet>> buildDistributionSetSpecifications(
private static List<Specification<JpaDistributionSet>> buildDistributionSetSpecifications(
final DistributionSetFilter distributionSetFilter) {
final List<Specification<DistributionSet>> specList = new ArrayList<>();
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>();
Specification<DistributionSet> spec;
Specification<JpaDistributionSet> spec;
if (null != distributionSetFilter.getIsComplete()) {
spec = DistributionSetSpecification.isCompleted(distributionSetFilter.getIsComplete());
@@ -568,7 +611,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return specList;
}
private void checkDistributionSetSoftwareModulesIsAllowedToModify(final DistributionSet distributionSet,
private void checkDistributionSetSoftwareModulesIsAllowedToModify(final JpaDistributionSet distributionSet,
final Set<SoftwareModule> softwareModules) {
if (!new HashSet<SoftwareModule>(distributionSet.getModules()).equals(softwareModules)
&& actionRepository.countByDistributionSet(distributionSet) > 0) {
@@ -602,8 +645,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
* list of @link {@link Specification}
* @return the page with the found {@link DistributionSet}
*/
private Page<DistributionSet> findByCriteriaAPI(final Pageable pageable,
final List<Specification<DistributionSet>> specList) {
private Page<JpaDistributionSet> findByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaDistributionSet>> specList) {
if (specList == null || specList.isEmpty()) {
return distributionSetRepository.findAll(pageable);
@@ -627,10 +670,11 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> assignTag(final Collection<Long> dsIds, final DistributionSetTag tag) {
final List<DistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
allDs.forEach(ds -> ds.getTags().add(tag));
final List<DistributionSet> save = distributionSetRepository.save(allDs);
final List<DistributionSet> save = new ArrayList<>(distributionSetRepository.save(allDs));
afterCommit.afterCommit(() -> {
@@ -646,19 +690,23 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSet> unAssignAllDistributionSetsByTag(final DistributionSetTag tag) {
return unAssignTag(tag.getAssignedToDistributionSet(), tag);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaDistributionSet> distributionSets = (Collection) tag.getAssignedToDistributionSet();
return new ArrayList<>(unAssignTag(distributionSets, tag));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public DistributionSet unAssignTag(final Long dsId, final DistributionSetTag distributionSetTag) {
final List<DistributionSet> allDs = findDistributionSetListWithDetails(Arrays.asList(dsId));
final List<DistributionSet> unAssignTag = unAssignTag(allDs, distributionSetTag);
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(Arrays.asList(dsId));
final List<JpaDistributionSet> unAssignTag = unAssignTag(allDs, distributionSetTag);
return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
}
private List<DistributionSet> unAssignTag(final Collection<DistributionSet> distributionSets,
private List<JpaDistributionSet> unAssignTag(final Collection<JpaDistributionSet> distributionSets,
final DistributionSetTag tag) {
distributionSets.forEach(ds -> ds.getTags().remove(tag));
return distributionSetRepository.save(distributionSets);
@@ -685,4 +733,16 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
final DistributionSetTag tag) {
return toggleTagAssignment(sets.stream().map(ds -> ds.getId()).collect(Collectors.toList()), tag.getName());
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public DistributionSetType generateDistributionSetType() {
return new JpaDistributionSetType();
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public DistributionSet generateDistributionSet() {
return new JpaDistributionSet();
}
}

View File

@@ -34,13 +34,13 @@ import org.eclipse.hawkbit.report.model.DataReportSeriesItem;
import org.eclipse.hawkbit.report.model.InnerOuterDataReportSeries;
import org.eclipse.hawkbit.report.model.SeriesTime;
import org.eclipse.hawkbit.repository.ReportManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSet_;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetInfo_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.Target_;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -88,13 +88,13 @@ public class JpaReportManagement implements ReportManagement {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<Target> targetRoot = query.from(Target.class);
final Join<Target, TargetInfo> targetInfo = targetRoot.join(Target_.targetInfo);
final Expression<Long> countColumn = cb.count(targetInfo.get(TargetInfo_.targetId));
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
final Join<JpaTarget, JpaTargetInfo> targetInfo = targetRoot.join(JpaTarget_.targetInfo);
final Expression<Long> countColumn = cb.count(targetInfo.get(JpaTargetInfo_.targetId));
final CriteriaQuery<Object[]> multiselect = query
.multiselect(targetInfo.get(TargetInfo_.updateStatus), countColumn)
.groupBy(targetInfo.get(TargetInfo_.updateStatus))
.orderBy(cb.desc(targetInfo.get(TargetInfo_.updateStatus)));
.multiselect(targetInfo.get(JpaTargetInfo_.updateStatus), countColumn)
.groupBy(targetInfo.get(JpaTargetInfo_.updateStatus))
.orderBy(cb.desc(targetInfo.get(JpaTargetInfo_.updateStatus)));
// | col1 | col2 |
// | U_STATUS | COUNT |
@@ -114,16 +114,17 @@ public class JpaReportManagement implements ReportManagement {
// top X entries distribution usage
final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> queryTopX = cbTopX.createQuery(Object[].class);
final Root<DistributionSet> rootTopX = queryTopX.from(DistributionSet.class);
final ListJoin<DistributionSet, Target> joinTopX = rootTopX.join(DistributionSet_.assignedToTargets,
final Root<JpaDistributionSet> rootTopX = queryTopX.from(JpaDistributionSet.class);
final ListJoin<JpaDistributionSet, JpaTarget> joinTopX = rootTopX.join(JpaDistributionSet_.assignedToTargets,
JoinType.LEFT);
final Expression<Long> countColumn = cbTopX.count(joinTopX);
// top x usage query
final CriteriaQuery<Object[]> groupBy = queryTopX
.multiselect(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version), countColumn)
.where(cbTopX.equal(rootTopX.get(DistributionSet_.deleted), false))
.groupBy(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version))
.orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(DistributionSet_.name)));
.multiselect(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version),
countColumn)
.where(cbTopX.equal(rootTopX.get(JpaDistributionSet_.deleted), false))
.groupBy(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version))
.orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(JpaDistributionSet_.name)));
// | col1 | col2 | col3 |
// | NAME | VER | COUNT |
final List<Object[]> resultListTop = entityManager.createQuery(groupBy).getResultList();
@@ -138,16 +139,17 @@ public class JpaReportManagement implements ReportManagement {
// top X entries distribution usage
final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> queryTopX = cbTopX.createQuery(Object[].class);
final Root<DistributionSet> rootTopX = queryTopX.from(DistributionSet.class);
final ListJoin<DistributionSet, TargetInfo> joinTopX = rootTopX.join(DistributionSet_.installedAtTargets,
JoinType.LEFT);
final Root<JpaDistributionSet> rootTopX = queryTopX.from(JpaDistributionSet.class);
final ListJoin<JpaDistributionSet, JpaTargetInfo> joinTopX = rootTopX
.join(JpaDistributionSet_.installedAtTargets, JoinType.LEFT);
final Expression<Long> countColumn = cbTopX.count(joinTopX);
// top x usage query
final CriteriaQuery<Object[]> groupBy = queryTopX
.multiselect(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version), countColumn)
.where(cbTopX.equal(rootTopX.get(DistributionSet_.deleted), false))
.groupBy(rootTopX.get(DistributionSet_.name), rootTopX.get(DistributionSet_.version))
.orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(DistributionSet_.name)));
.multiselect(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version),
countColumn)
.where(cbTopX.equal(rootTopX.get(JpaDistributionSet_.deleted), false))
.groupBy(rootTopX.get(JpaDistributionSet_.name), rootTopX.get(JpaDistributionSet_.version))
.orderBy(cbTopX.desc(countColumn), cbTopX.asc(rootTopX.get(JpaDistributionSet_.name)));
// | col1 | col2 | col3 |
// | NAME | VER | COUNT |
final List<Object[]> resultListTop = entityManager.createQuery(groupBy).getResultList();
@@ -213,6 +215,7 @@ public class JpaReportManagement implements ReportManagement {
final LocalDateTime from, final LocalDateTime to) {
final Query createNativeQuery = entityManager
.createNativeQuery(getFeedbackReceivedQueryTemplate(dateType, from, to));
@SuppressWarnings("unchecked")
final List<Object[]> resultList = createNativeQuery.getResultList();
final List<DataReportSeriesItem<T>> reportItems = resultList.stream()
@@ -275,15 +278,15 @@ public class JpaReportManagement implements ReportManagement {
// count select statement
final CriteriaQuery<Long> countSelect = cb.createQuery(Long.class);
final Root<Target> countSelectRoot = countSelect.from(Target.class);
final Join<Target, TargetInfo> targetInfoJoin = countSelectRoot.join(Target_.targetInfo);
final Root<JpaTarget> countSelectRoot = countSelect.from(JpaTarget.class);
final Join<JpaTarget, JpaTargetInfo> targetInfoJoin = countSelectRoot.join(JpaTarget_.targetInfo);
countSelect.select(cb.count(countSelectRoot));
if (start != null && end != null) {
countSelect.where(cb.between(targetInfoJoin.get(TargetInfo_.lastTargetQuery), start, end));
countSelect.where(cb.between(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), start, end));
} else if (from == null && to != null) {
countSelect.where(cb.lessThanOrEqualTo(targetInfoJoin.get(TargetInfo_.lastTargetQuery), end));
countSelect.where(cb.lessThanOrEqualTo(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), end));
} else {
countSelect.where(cb.isNull(targetInfoJoin.get(TargetInfo_.lastTargetQuery)));
countSelect.where(cb.isNull(targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery)));
}
return countSelect;
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -20,28 +21,36 @@ import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Root;
import org.eclipse.hawkbit.repository.RolloutGroupFields;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup_;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action_;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup_;
import org.eclipse.hawkbit.repository.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.model.RolloutTargetGroup_;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetWithActionStatus;
import org.eclipse.hawkbit.repository.model.Target_;
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -72,20 +81,34 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
@Override
public Page<RolloutGroup> findRolloutGroupsByRolloutId(final Long rolloutId, final Pageable page) {
return rolloutGroupRepository.findByRolloutId(rolloutId, page);
return convertPage(rolloutGroupRepository.findByRolloutId(rolloutId, page));
}
private static Page<RolloutGroup> convertPage(final Slice<JpaRolloutGroup> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
private static Page<Target> convertTPage(final Page<JpaTarget> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
public Page<RolloutGroup> findRolloutGroupsAll(final Rollout rollout,
final Specification<RolloutGroup> specification, final Pageable page) {
return rolloutGroupRepository.findAll((root, query, criteriaBuilder) -> criteriaBuilder.and(
criteriaBuilder.equal(root.get(RolloutGroup_.rollout), rollout),
specification.toPredicate(root, query, criteriaBuilder)), page);
public Page<RolloutGroup> findRolloutGroupsAll(final Rollout rollout, final String rsqlParam, final Pageable page) {
final Specification<JpaRolloutGroup> specification = RSQLUtility.parse(rsqlParam, RolloutGroupFields.class);
return convertPage(
rolloutGroupRepository
.findAll(
(root, query, criteriaBuilder) -> criteriaBuilder.and(
criteriaBuilder.equal(root.get(JpaRolloutGroup_.rollout), rollout),
specification.toPredicate(root, query, criteriaBuilder)),
page));
}
@Override
public Page<RolloutGroup> findAllRolloutGroupsWithDetailedStatus(final Long rolloutId, final Pageable page) {
final Page<RolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutId(rolloutId, page);
final Page<JpaRolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutId(rolloutId, page);
final List<Long> rolloutGroupIds = rolloutGroups.getContent().stream().map(rollout -> rollout.getId())
.collect(Collectors.toList());
final Map<Long, List<TotalTargetCountActionStatus>> allStatesForRollout = getStatusCountItemForRolloutGroup(
@@ -97,7 +120,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus);
}
return rolloutGroups;
return convertPage(rolloutGroups);
}
@Override
@@ -121,13 +144,16 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
}
@Override
public Page<Target> findRolloutGroupTargets(final RolloutGroup rolloutGroup,
final Specification<Target> specification, final Pageable page) {
return targetRepository.findAll((root, query, criteriaBuilder) -> {
final ListJoin<Target, RolloutTargetGroup> rolloutTargetJoin = root.join(Target_.rolloutTargetGroup);
return criteriaBuilder.and(specification.toPredicate(root, query, criteriaBuilder),
public Page<Target> findRolloutGroupTargets(final RolloutGroup rolloutGroup, final String rsqlParam,
final Pageable page) {
final Specification<JpaTarget> rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class);
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));
}, page);
}, page));
}
@Override
@@ -138,7 +164,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
// stored in the #TargetRolloutGroup.
return targetRepository.findByRolloutTargetGroupRolloutGroupId(rolloutGroup.getId(), page);
}
return targetRepository.findByActionsRolloutGroup(rolloutGroup, page);
return targetRepository.findByActionsRolloutGroup((JpaRolloutGroup) rolloutGroup, page);
}
private static boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) {
@@ -154,8 +180,8 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
final CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
final Root<RolloutTargetGroup> targetRoot = query.distinct(true).from(RolloutTargetGroup.class);
final Join<RolloutTargetGroup, Target> targetJoin = targetRoot.join(RolloutTargetGroup_.target);
final ListJoin<RolloutTargetGroup, Action> actionJoin = targetRoot.join(RolloutTargetGroup_.actions,
final Join<RolloutTargetGroup, JpaTarget> targetJoin = targetRoot.join(RolloutTargetGroup_.target);
final ListJoin<RolloutTargetGroup, JpaAction> actionJoin = targetRoot.join(RolloutTargetGroup_.actions,
JoinType.LEFT);
final Root<RolloutTargetGroup> countQueryFrom = countQuery.distinct(true).from(RolloutTargetGroup.class);
@@ -165,7 +191,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
.where(cb.equal(countQueryFrom.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup));
final Long totalCount = entityManager.createQuery(countQuery).getSingleResult();
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetJoin, actionJoin.get(Action_.status))
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetJoin, actionJoin.get(JpaAction_.status))
.where(cb.equal(targetRoot.get(RolloutTargetGroup_.rolloutGroup), rolloutGroup));
final List<TargetWithActionStatus> targetWithActionStatus = entityManager.createQuery(multiselect)
.setFirstResult(pageRequest.getOffset()).setMaxResults(pageRequest.getPageSize()).getResultList()
@@ -173,4 +199,10 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
.collect(Collectors.toList());
return new PageImpl<>(targetWithActionStatus, pageRequest, totalCount);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public RolloutGroup generateRolloutGroup() {
return new JpaRolloutGroup();
}
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -19,24 +20,28 @@ import javax.persistence.EntityManager;
import org.eclipse.hawkbit.cache.CacheWriteNotify;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.RolloutFields;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupErrorCondition;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.model.Rollout_;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.rollout.condition.RolloutGroupActionEvaluator;
import org.eclipse.hawkbit.rollout.condition.RolloutGroupConditionEvaluator;
import org.slf4j.Logger;
@@ -46,6 +51,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
@@ -132,15 +138,21 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
public Page<Rollout> findAll(final Pageable page) {
return rolloutRepository.findAll(page);
return convertPage(rolloutRepository.findAll(page));
}
private static Page<Rollout> convertPage(final Slice<JpaRollout> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
public Page<Rollout> findAllWithDetailedStatusByPredicate(final Specification<Rollout> specification,
final Pageable page) {
final Page<Rollout> findAll = rolloutRepository.findAll(specification, page);
public Page<Rollout> findAllWithDetailedStatusByPredicate(final String rsqlParam, final Pageable page) {
final Specification<JpaRollout> specification = RSQLUtility.parse(rsqlParam, RolloutFields.class);
final Page<JpaRollout> findAll = rolloutRepository.findAll(specification, page);
setRolloutStatusDetails(findAll);
return findAll;
return convertPage(findAll);
}
@Override
@@ -153,7 +165,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Modifying
public Rollout createRollout(final Rollout rollout, final int amountGroup,
final RolloutGroupConditions conditions) {
final Rollout savedRollout = createRollout(rollout, amountGroup);
final JpaRollout savedRollout = createRollout((JpaRollout) rollout, amountGroup);
return createRolloutGroups(amountGroup, conditions, savedRollout);
}
@@ -162,7 +174,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Modifying
public Rollout createRolloutAsync(final Rollout rollout, final int amountGroup,
final RolloutGroupConditions conditions) {
final Rollout savedRollout = createRollout(rollout, amountGroup);
final JpaRollout savedRollout = createRollout((JpaRollout) rollout, amountGroup);
creatingRollouts.add(savedRollout.getName());
// need to flush the entity manager here to get the ID of the rollout,
// because entity manager is set to FlushMode#Auto, entitymanager will
@@ -182,7 +194,7 @@ public class JpaRolloutManagement implements RolloutManagement {
return savedRollout;
}
private Rollout createRollout(final Rollout rollout, final int amountGroup) {
private JpaRollout createRollout(final JpaRollout rollout, final int amountGroup) {
verifyRolloutGroupParameter(amountGroup);
final Long totalTargets = targetManagement.countTargetByTargetFilterQuery(rollout.getTargetFilterQuery());
rollout.setTotalTargets(totalTargets.longValue());
@@ -198,7 +210,7 @@ public class JpaRolloutManagement implements RolloutManagement {
}
private Rollout createRolloutGroupsInNewTransaction(final int amountOfGroups,
final RolloutGroupConditions conditions, final Rollout savedRollout) {
final RolloutGroupConditions conditions, final JpaRollout savedRollout) {
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setName("creatingRollout");
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
@@ -221,7 +233,7 @@ public class JpaRolloutManagement implements RolloutManagement {
* @return the rollout with created groups
*/
private Rollout createRolloutGroups(final int amountOfGroups, final RolloutGroupConditions conditions,
final Rollout savedRollout) {
final JpaRollout savedRollout) {
int pageIndex = 0;
int groupIndex = 0;
final Long totalCount = savedRollout.getTotalTargets();
@@ -237,7 +249,7 @@ public class JpaRolloutManagement implements RolloutManagement {
while (pageIndex < totalCount) {
groupIndex++;
final String nameAndDesc = "group-" + groupIndex;
final RolloutGroup group = new RolloutGroup();
final JpaRolloutGroup group = new JpaRolloutGroup();
group.setName(nameAndDesc);
group.setDescription(nameAndDesc);
group.setRollout(savedRollout);
@@ -272,7 +284,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public Rollout startRollout(final Rollout rollout) {
final Rollout mergedRollout = entityManager.merge(rollout);
final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout);
checkIfRolloutCanStarted(rollout, mergedRollout);
return doStartRollout(mergedRollout);
}
@@ -281,10 +293,10 @@ public class JpaRolloutManagement implements RolloutManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public Rollout startRolloutAsync(final Rollout rollout) {
final Rollout mergedRollout = entityManager.merge(rollout);
final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout);
checkIfRolloutCanStarted(rollout, mergedRollout);
mergedRollout.setStatus(RolloutStatus.STARTING);
final Rollout updatedRollout = rolloutRepository.save(mergedRollout);
final JpaRollout updatedRollout = rolloutRepository.save(mergedRollout);
startingRollouts.add(updatedRollout.getName());
executor.execute(() -> {
try {
@@ -303,13 +315,13 @@ public class JpaRolloutManagement implements RolloutManagement {
}
private Rollout doStartRollout(final Rollout rollout) {
private Rollout doStartRollout(final JpaRollout rollout) {
final DistributionSet distributionSet = rollout.getDistributionSet();
final ActionType actionType = rollout.getActionType();
final long forceTime = rollout.getForcedTime();
final List<RolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutOrderByIdAsc(rollout);
final List<JpaRolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutOrderByIdAsc(rollout);
for (int iGroup = 0; iGroup < rolloutGroups.size(); iGroup++) {
final RolloutGroup rolloutGroup = rolloutGroups.get(iGroup);
final JpaRolloutGroup rolloutGroup = rolloutGroups.get(iGroup);
final List<Target> targetGroup = targetRepository.findByRolloutTargetGroupRolloutGroup(rolloutGroup);
// firstgroup can already be started
if (iGroup == 0) {
@@ -336,7 +348,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void pauseRollout(final Rollout rollout) {
final Rollout mergedRollout = entityManager.merge(rollout);
final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout);
if (mergedRollout.getStatus() != RolloutStatus.RUNNING) {
throw new RolloutIllegalStateException("Rollout can only be paused in state running but current state is "
+ rollout.getStatus().name().toLowerCase());
@@ -354,7 +366,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void resumeRollout(final Rollout rollout) {
final Rollout mergedRollout = entityManager.merge(rollout);
final JpaRollout mergedRollout = entityManager.merge((JpaRollout) rollout);
if (!(RolloutStatus.PAUSED.equals(mergedRollout.getStatus()))) {
throw new RolloutIllegalStateException("Rollout can only be resumed in state paused but current state is "
+ rollout.getStatus().name().toLowerCase());
@@ -379,13 +391,13 @@ public class JpaRolloutManagement implements RolloutManagement {
return;
}
final List<Rollout> rolloutsToCheck = rolloutRepository.findByLastCheckAndStatus(lastCheck,
final List<JpaRollout> rolloutsToCheck = rolloutRepository.findByLastCheckAndStatus(lastCheck,
RolloutStatus.RUNNING);
LOGGER.info("Found {} running rollouts to check", rolloutsToCheck.size());
for (final Rollout rollout : rolloutsToCheck) {
for (final JpaRollout rollout : rolloutsToCheck) {
LOGGER.debug("Checking rollout {}", rollout);
final List<RolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutAndStatus(rollout,
final List<JpaRolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutAndStatus(rollout,
RolloutGroupStatus.RUNNING);
if (rolloutGroups.isEmpty()) {
@@ -415,7 +427,7 @@ public class JpaRolloutManagement implements RolloutManagement {
* In case this happens, set the rollout to error state.
*/
private void verifyStuckedRollouts() {
final List<Rollout> rolloutsInCreatingState = rolloutRepository.findByStatus(RolloutStatus.CREATING);
final List<JpaRollout> rolloutsInCreatingState = rolloutRepository.findByStatus(RolloutStatus.CREATING);
rolloutsInCreatingState.stream().filter(rollout -> !creatingRollouts.contains(rollout.getName()))
.forEach(rollout -> {
LOGGER.warn(
@@ -425,7 +437,7 @@ public class JpaRolloutManagement implements RolloutManagement {
rolloutRepository.save(rollout);
});
final List<Rollout> rolloutsInStartingState = rolloutRepository.findByStatus(RolloutStatus.STARTING);
final List<JpaRollout> rolloutsInStartingState = rolloutRepository.findByStatus(RolloutStatus.STARTING);
rolloutsInStartingState.stream().filter(rollout -> !startingRollouts.contains(rollout.getName()))
.forEach(rollout -> {
LOGGER.warn(
@@ -437,8 +449,8 @@ public class JpaRolloutManagement implements RolloutManagement {
}
private void executeRolloutGroups(final Rollout rollout, final List<RolloutGroup> rolloutGroups) {
for (final RolloutGroup rolloutGroup : rolloutGroups) {
private void executeRolloutGroups(final JpaRollout rollout, final List<JpaRolloutGroup> rolloutGroups) {
for (final JpaRolloutGroup rolloutGroup : rolloutGroups) {
// error state check, do we need to stop the whole
// rollout because of error?
final RolloutGroupErrorCondition errorCondition = rolloutGroup.getErrorCondition();
@@ -459,8 +471,8 @@ public class JpaRolloutManagement implements RolloutManagement {
}
}
private void executeLatestRolloutGroup(final Rollout rollout) {
final List<RolloutGroup> latestRolloutGroup = rolloutGroupRepository
private void executeLatestRolloutGroup(final JpaRollout rollout) {
final List<JpaRolloutGroup> latestRolloutGroup = rolloutGroupRepository
.findByRolloutAndStatusNotOrderByIdDesc(rollout, RolloutGroupStatus.SCHEDULED);
if (latestRolloutGroup.isEmpty()) {
return;
@@ -478,13 +490,13 @@ public class JpaRolloutManagement implements RolloutManagement {
}
}
private boolean isRolloutComplete(final Rollout rollout) {
private boolean isRolloutComplete(final JpaRollout rollout) {
final Long groupsActiveLeft = rolloutGroupRepository.countByRolloutAndStatusOrStatus(rollout,
RolloutGroupStatus.RUNNING, RolloutGroupStatus.SCHEDULED);
return groupsActiveLeft == 0;
}
private boolean isRolloutGroupComplete(final Rollout rollout, final RolloutGroup rolloutGroup) {
private boolean isRolloutGroupComplete(final JpaRollout rollout, final JpaRolloutGroup rolloutGroup) {
final Long actionsLeftForRollout = actionRepository
.countByRolloutAndRolloutGroupAndStatusNotAndStatusNotAndStatusNot(rollout, rolloutGroup,
Action.Status.ERROR, Action.Status.FINISHED, Action.Status.CANCELED);
@@ -543,22 +555,22 @@ public class JpaRolloutManagement implements RolloutManagement {
return rolloutRepository.count(likeNameOrDescription(searchText));
}
private static Specification<Rollout> likeNameOrDescription(final String searchText) {
private static Specification<JpaRollout> likeNameOrDescription(final String searchText) {
return (rolloutRoot, query, criteriaBuilder) -> {
final String searchTextToLower = searchText.toLowerCase();
return criteriaBuilder.or(
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(Rollout_.name)), searchTextToLower),
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(Rollout_.description)),
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.name)), searchTextToLower),
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.description)),
searchTextToLower));
};
}
@Override
public Slice<Rollout> findRolloutByFilters(final Pageable pageable, final String searchText) {
final Specification<Rollout> specs = likeNameOrDescription(searchText);
final Slice<Rollout> findAll = criteriaNoCountDao.findAll(specs, pageable, Rollout.class);
final Specification<JpaRollout> specs = likeNameOrDescription(searchText);
final Slice<JpaRollout> findAll = criteriaNoCountDao.findAll(specs, pageable, JpaRollout.class);
setRolloutStatusDetails(findAll);
return findAll;
return convertPage(findAll);
}
@Override
@@ -579,7 +591,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Modifying
public Rollout updateRollout(final Rollout rollout) {
Assert.notNull(rollout.getId());
return rolloutRepository.save(rollout);
return rolloutRepository.save((JpaRollout) rollout);
}
/**
@@ -593,9 +605,9 @@ public class JpaRolloutManagement implements RolloutManagement {
*/
@Override
public Page<Rollout> findAllRolloutsWithDetailedStatus(final Pageable page) {
final Page<Rollout> rollouts = findAll(page);
final Page<JpaRollout> rollouts = rolloutRepository.findAll(page);
setRolloutStatusDetails(rollouts);
return rollouts;
return convertPage(rollouts);
}
@@ -615,7 +627,7 @@ public class JpaRolloutManagement implements RolloutManagement {
return resultList.stream().collect(Collectors.groupingBy(TotalTargetCountActionStatus::getId));
}
private void setRolloutStatusDetails(final Slice<Rollout> rollouts) {
private void setRolloutStatusDetails(final Slice<JpaRollout> rollouts) {
final List<Long> rolloutIds = rollouts.getContent().stream().map(rollout -> rollout.getId())
.collect(Collectors.toList());
final Map<Long, List<TotalTargetCountActionStatus>> allStatesForRollout = getStatusCountItemForRollout(
@@ -648,4 +660,10 @@ public class JpaRolloutManagement implements RolloutManagement {
// calculate threshold
return ((float) finished / (float) totalGroup) * 100;
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public Rollout generateRollout() {
return new JpaRollout();
}
}

View File

@@ -13,6 +13,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -27,23 +28,32 @@ import javax.persistence.criteria.Root;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.ArtifactManagement;
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.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_;
import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.model.CustomSoftwareModule;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSet_;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata_;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.SoftwareModule_;
import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.specifications.SoftwareModuleSpecification;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
@@ -52,6 +62,7 @@ import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -100,7 +111,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
public SoftwareModule updateSoftwareModule(final SoftwareModule sm) {
checkNotNull(sm.getId());
final SoftwareModule module = softwareModuleRepository.findOne(sm.getId());
final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId());
boolean updated = false;
if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) {
@@ -121,7 +132,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) {
checkNotNull(sm.getId());
final SoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId());
final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId());
boolean updated = false;
if (sm.getDescription() != null && !sm.getDescription().equals(type.getDescription())) {
@@ -142,7 +153,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
if (null != swModule.getId()) {
throw new EntityAlreadyExistsException();
}
return softwareModuleRepository.save(swModule);
return softwareModuleRepository.save((JpaSoftwareModule) swModule);
}
@Override
@@ -155,30 +166,40 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
});
return softwareModuleRepository.save(swModules);
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaSoftwareModule> jpaCast = (Collection) swModules;
return new ArrayList<>(softwareModuleRepository.save(jpaCast));
}
@Override
public Slice<SoftwareModule> findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final List<Specification<JpaSoftwareModule>> specList = new LinkedList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.equalType(type);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type);
specList.add(spec);
spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
return findSwModuleByCriteriaAPI(pageable, specList);
return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList));
}
private static Page<SoftwareModule> convertSmPage(final Slice<JpaSoftwareModule> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
private static Page<SoftwareModuleMetadata> convertSmMdPage(final Slice<JpaSoftwareModuleMetadata> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
public Long countSoftwareModulesByType(final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.equalType(type);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type);
specList.add(spec);
spec = SoftwareModuleSpecification.isDeletedFalse();
@@ -196,24 +217,24 @@ public class JpaSoftwareManagement implements SoftwareManagement {
public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version,
final SoftwareModuleType type) {
return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, type);
return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type);
}
private boolean isUnassigned(final SoftwareModule bsmMerged) {
private boolean isUnassigned(final JpaSoftwareModule bsmMerged) {
return distributionSetRepository.findByModules(bsmMerged).isEmpty();
}
private Slice<SoftwareModule> findSwModuleByCriteriaAPI(final Pageable pageable,
final List<Specification<SoftwareModule>> specList) {
private Slice<JpaSoftwareModule> findSwModuleByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaSoftwareModule>> specList) {
return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable,
SoftwareModule.class);
JpaSoftwareModule.class);
}
private Long countSwModuleByCriteriaAPI(final List<Specification<SoftwareModule>> specList) {
private Long countSwModuleByCriteriaAPI(final List<Specification<JpaSoftwareModule>> specList) {
return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
private void deleteGridFsArtifacts(final SoftwareModule swModule) {
private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) {
for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) {
artifactManagement.deleteLocalArtifact(localArtifact);
}
@@ -223,7 +244,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteSoftwareModules(final Collection<Long> ids) {
final List<SoftwareModule> swModulesToDelete = softwareModuleRepository.findByIdIn(ids);
final List<JpaSoftwareModule> swModulesToDelete = softwareModuleRepository.findByIdIn(ids);
final Set<Long> assignedModuleIds = new HashSet<>();
swModulesToDelete.forEach(swModule -> {
@@ -253,29 +274,29 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
public Slice<SoftwareModule> findSoftwareModulesAll(final Pageable pageable) {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(SoftwareModule_.type);
root.fetch(JpaSoftwareModule_.type);
}
return cb.conjunction();
};
specList.add(spec);
return findSwModuleByCriteriaAPI(pageable, specList);
return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList));
}
@Override
public Long countSoftwareModulesAll() {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
final Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
final Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
return countSwModuleByCriteriaAPI(specList);
@@ -287,30 +308,38 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
@Override
public Page<SoftwareModule> findSoftwareModulesByPredicate(final Specification<SoftwareModule> spec,
final Pageable pageable) {
return softwareModuleRepository.findAll(spec, pageable);
public Page<SoftwareModule> findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) {
final Specification<JpaSoftwareModule> spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class);
return convertSmPage(softwareModuleRepository.findAll(spec, pageable));
}
@Override
public Page<SoftwareModuleType> findSoftwareModuleTypesByPredicate(final Specification<SoftwareModuleType> spec,
public Page<SoftwareModuleType> findSoftwareModuleTypesByPredicate(final String rsqlParam,
final Pageable pageable) {
return softwareModuleTypeRepository.findAll(spec, pageable);
final Specification<JpaSoftwareModuleType> spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class);
return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable));
}
private static Page<SoftwareModuleType> convertSmTPage(final Slice<JpaSoftwareModuleType> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public List<SoftwareModule> findSoftwareModulesById(final Collection<Long> ids) {
return softwareModuleRepository.findByIdIn(ids);
return new ArrayList<>(softwareModuleRepository.findByIdIn(ids));
}
@Override
public Slice<SoftwareModule> findSoftwareModuleByFilters(final Pageable pageable, final String searchText,
final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
if (!Strings.isNullOrEmpty(searchText)) {
@@ -319,50 +348,53 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
if (null != type) {
spec = SoftwareModuleSpecification.equalType(type);
spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type);
specList.add(spec);
}
spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(SoftwareModule_.type);
root.fetch(JpaSoftwareModule_.type);
}
return cb.conjunction();
};
specList.add(spec);
return findSwModuleByCriteriaAPI(pageable, specList);
return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList));
}
@Override
public Slice<CustomSoftwareModule> findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc(
final Pageable pageable, final Long orderByDistributionId, final String searchText,
final SoftwareModuleType type) {
final SoftwareModuleType ty) {
final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty;
final List<CustomSoftwareModule> resultList = new ArrayList<>();
final int pageSize = pageable.getPageSize();
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
// get the assigned software modules
final CriteriaQuery<SoftwareModule> assignedQuery = cb.createQuery(SoftwareModule.class);
final Root<SoftwareModule> assignedRoot = assignedQuery.from(SoftwareModule.class);
final CriteriaQuery<JpaSoftwareModule> assignedQuery = cb.createQuery(JpaSoftwareModule.class);
final Root<JpaSoftwareModule> assignedRoot = assignedQuery.from(JpaSoftwareModule.class);
assignedQuery.distinct(true);
final ListJoin<SoftwareModule, DistributionSet> assignedDsJoin = assignedRoot.join(SoftwareModule_.assignedTo);
final ListJoin<JpaSoftwareModule, JpaDistributionSet> assignedDsJoin = assignedRoot
.join(JpaSoftwareModule_.assignedTo);
// build the specifications and then to predicates necessary by the
// given filters
final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type),
assignedRoot, assignedQuery, cb,
cb.equal(assignedDsJoin.get(DistributionSet_.id), orderByDistributionId));
cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId));
// if we have some predicates then add it to the where clause of the
// multi select
assignedQuery.where(specPredicate);
assignedQuery.orderBy(cb.asc(assignedRoot.get(SoftwareModule_.name)),
cb.asc(assignedRoot.get(SoftwareModule_.version)));
assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)),
cb.asc(assignedRoot.get(JpaSoftwareModule_.version)));
// don't page the assigned query on database, we need all assigned
// software modules to filter
// them out in the unassigned query
final List<SoftwareModule> assignedSoftwareModules = entityManager.createQuery(assignedQuery).getResultList();
final List<JpaSoftwareModule> assignedSoftwareModules = entityManager.createQuery(assignedQuery)
.getResultList();
// map result
if (pageable.getOffset() < assignedSoftwareModules.size()) {
assignedSoftwareModules
@@ -375,14 +407,14 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
// get the unassigned software modules
final CriteriaQuery<SoftwareModule> unassignedQuery = cb.createQuery(SoftwareModule.class);
final CriteriaQuery<JpaSoftwareModule> unassignedQuery = cb.createQuery(JpaSoftwareModule.class);
unassignedQuery.distinct(true);
final Root<SoftwareModule> unassignedRoot = unassignedQuery.from(SoftwareModule.class);
final Root<JpaSoftwareModule> unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class);
Predicate[] unassignedSpec;
if (!assignedSoftwareModules.isEmpty()) {
unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot,
unassignedQuery, cb, cb.not(unassignedRoot.get(SoftwareModule_.id)
unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id)
.in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList()))));
} else {
unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot,
@@ -390,9 +422,9 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
unassignedQuery.where(unassignedSpec);
unassignedQuery.orderBy(cb.asc(unassignedRoot.get(SoftwareModule_.name)),
cb.asc(unassignedRoot.get(SoftwareModule_.version)));
final List<SoftwareModule> unassignedSoftwareModules = entityManager.createQuery(unassignedQuery)
unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)),
cb.asc(unassignedRoot.get(JpaSoftwareModule_.version)));
final List<JpaSoftwareModule> unassignedSoftwareModules = entityManager.createQuery(unassignedQuery)
.setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size()))
.setMaxResults(pageSize).getResultList();
// map result
@@ -401,9 +433,9 @@ public class JpaSoftwareManagement implements SoftwareManagement {
return new SliceImpl<>(resultList);
}
private static List<Specification<SoftwareModule>> buildSpecificationList(final String searchText,
final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
private static List<Specification<JpaSoftwareModule>> buildSpecificationList(final String searchText,
final JpaSoftwareModuleType type) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
if (!Strings.isNullOrEmpty(searchText)) {
specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText));
}
@@ -414,8 +446,8 @@ public class JpaSoftwareManagement implements SoftwareManagement {
return specList;
}
private Predicate[] specificationsToPredicate(final List<Specification<SoftwareModule>> specifications,
final Root<SoftwareModule> root, final CriteriaQuery<?> query, final CriteriaBuilder cb,
private Predicate[] specificationsToPredicate(final List<Specification<JpaSoftwareModule>> specifications,
final Root<JpaSoftwareModule> root, final CriteriaQuery<?> query, final CriteriaBuilder cb,
final Predicate... additionalPredicates) {
final List<Predicate> predicates = new ArrayList<>();
specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb)));
@@ -428,9 +460,9 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) {
final List<Specification<SoftwareModule>> specList = new ArrayList<>();
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
Specification<SoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
if (!Strings.isNullOrEmpty(searchText)) {
@@ -439,7 +471,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
}
if (null != type) {
spec = SoftwareModuleSpecification.equalType(type);
spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type);
specList.add(spec);
}
@@ -479,17 +511,18 @@ public class JpaSoftwareManagement implements SoftwareManagement {
throw new EntityAlreadyExistsException("Given type contains an Id!");
}
return softwareModuleTypeRepository.save(type);
return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteSoftwareModuleType(final SoftwareModuleType type) {
public void deleteSoftwareModuleType(final SoftwareModuleType ty) {
final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty;
if (softwareModuleRepository.countByType(type) > 0
|| distributionSetTypeRepository.countByElementsSmType(type) > 0) {
final SoftwareModuleType toDelete = entityManager.merge(type);
final JpaSoftwareModuleType toDelete = entityManager.merge(type);
toDelete.setDeleted(true);
softwareModuleTypeRepository.save(toDelete);
} else {
@@ -499,19 +532,22 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
public Page<SoftwareModule> findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) {
return softwareModuleRepository.findByAssignedTo(pageable, set);
return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set);
}
@Override
public Page<SoftwareModule> findSoftwareModuleByAssignedToAndType(final Pageable pageable,
final DistributionSet set, final SoftwareModuleType type) {
return softwareModuleRepository.findByAssignedToAndType(pageable, set, type);
return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set,
(JpaSoftwareModuleType) type);
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata metadata) {
public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md;
if (softwareModuleMetadataRepository.exists(metadata.getId())) {
throwMetadataKeyAlreadyExists(metadata.getId().getKey());
}
@@ -519,32 +555,36 @@ public class JpaSoftwareManagement implements SoftwareManagement {
// log written because
// modifying metadata is modifying the base software module itself for
// auditing purposes.
entityManager.merge(metadata.getSoftwareModule()).setLastModifiedAt(-1L);
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> metadata) {
for (final SoftwareModuleMetadata softwareModuleMetadata : metadata) {
public List<SoftwareModuleMetadata> createSoftwareModuleMetadata(final Collection<SoftwareModuleMetadata> md) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaSoftwareModuleMetadata> metadata = (Collection) md;
for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) {
checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId());
}
metadata.forEach(m -> entityManager.merge(m.getSoftwareModule()).setLastModifiedAt(-1L));
return softwareModuleMetadataRepository.save(metadata);
metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L));
return new ArrayList<>(softwareModuleMetadataRepository.save(metadata));
}
@Override
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata metadata) {
public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) 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(metadata.getSoftwareModule()).setLastModifiedAt(-1L);
entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L);
return softwareModuleMetadataRepository.save(metadata);
}
@@ -563,15 +603,18 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override
public Page<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId,
final Specification<SoftwareModuleMetadata> spec, final Pageable pageable) {
return softwareModuleMetadataRepository
.findAll(
(Specification<SoftwareModuleMetadata>) (root, query,
cb) -> cb.and(
cb.equal(root.get(SoftwareModuleMetadata_.softwareModule)
.get(SoftwareModule_.id), softwareModuleId),
final String rsqlParam, final Pageable pageable) {
final Specification<JpaSoftwareModuleMetadata> spec = RSQLUtility.parse(rsqlParam,
SoftwareModuleMetadataFields.class);
return convertSmMdPage(
softwareModuleMetadataRepository
.findAll(
(Specification<JpaSoftwareModuleMetadata>) (root, query, cb) -> cb.and(
cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule)
.get(JpaSoftwareModule_.id), softwareModuleId),
spec.toPredicate(root, query, cb)),
pageable);
pageable));
}
@Override
@@ -609,4 +652,16 @@ public class JpaSoftwareManagement implements SoftwareManagement {
return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList());
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public SoftwareModuleType generateSoftwareModuleType() {
return new JpaSoftwareModuleType();
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public SoftwareModule generateSoftwareModule() {
return new JpaSoftwareModule();
}
}

View File

@@ -20,6 +20,9 @@ import org.eclipse.hawkbit.report.model.SystemUsageReport;
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.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.TenantMetaData;
@@ -167,7 +170,7 @@ public class JpaSystemManagement implements SystemManagement {
try {
createInitialTenant.set(tenant);
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
return tenantMetaDataRepository.save(new TenantMetaData(createStandardSoftwareDataSetup(), tenant));
return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant));
} finally {
createInitialTenant.remove();
}
@@ -253,27 +256,26 @@ public class JpaSystemManagement implements SystemManagement {
throw new EntityNotFoundException("Metadata does not exist: " + metaData.getId());
}
return tenantMetaDataRepository.save(metaData);
return tenantMetaDataRepository.save((JpaTenantMetaData) metaData);
}
private DistributionSetType createStandardSoftwareDataSetup() {
final SoftwareModuleType eclApp = softwareModuleTypeRepository.save(new SoftwareModuleType("application",
final SoftwareModuleType eclApp = softwareModuleTypeRepository.save(new JpaSoftwareModuleType("application",
"ECL Application", "Edge Controller Linux base application type", 1));
final SoftwareModuleType eclOs = softwareModuleTypeRepository
.save(new SoftwareModuleType("os", "ECL OS", "Edge Controller Linux operation system image type", 1));
final SoftwareModuleType eclOs = softwareModuleTypeRepository.save(
new JpaSoftwareModuleType("os", "ECL OS", "Edge Controller Linux operation system image type", 1));
final SoftwareModuleType eclJvm = softwareModuleTypeRepository.save(
new SoftwareModuleType("runtime", "ECL JVM", "Edge Controller Linux java virtual machine type.", 1));
new JpaSoftwareModuleType("runtime", "ECL JVM", "Edge Controller Linux java virtual machine type.", 1));
distributionSetTypeRepository.save(
new DistributionSetType("ecl_os", "OS only", "Standard Edge Controller Linux distribution set type.")
.addMandatoryModuleType(eclOs));
distributionSetTypeRepository.save((JpaDistributionSetType) new JpaDistributionSetType("ecl_os", "OS only",
"Standard Edge Controller Linux distribution set type.").addMandatoryModuleType(eclOs));
distributionSetTypeRepository.save(new DistributionSetType("ecl_os_app", "OS with optional app",
"Standard Edge Controller Linux distribution set type. OS only.").addMandatoryModuleType(eclOs)
.addOptionalModuleType(eclApp));
distributionSetTypeRepository.save((JpaDistributionSetType) new JpaDistributionSetType("ecl_os_app",
"OS with optional app", "Standard Edge Controller Linux distribution set type. OS only.")
.addMandatoryModuleType(eclOs).addOptionalModuleType(eclApp));
return distributionSetTypeRepository
.save(new DistributionSetType("ecl_os_app_jvm", "OS with optional app and jvm",
return distributionSetTypeRepository.save(
(JpaDistributionSetType) new JpaDistributionSetType("ecl_os_app_jvm", "OS with optional app and jvm",
"Standard Edge Controller Linux distribution set type. OS with optional application.")
.addMandatoryModuleType(eclOs).addOptionalModuleType(eclApp)
.addOptionalModuleType(eclJvm));

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -21,20 +22,26 @@ import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent;
import org.eclipse.hawkbit.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
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.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -86,7 +93,7 @@ public class JpaTagManagement implements TagManagement {
throw new EntityAlreadyExistsException();
}
final TargetTag save = targetTagRepository.save(targetTag);
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
afterCommit
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
@@ -97,13 +104,17 @@ public class JpaTagManagement implements TagManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<TargetTag> createTargetTags(final Iterable<TargetTag> targetTags) {
public List<TargetTag> createTargetTags(final Collection<TargetTag> tt) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaTargetTag> targetTags = (Collection) tt;
targetTags.forEach(tag -> {
if (tag.getId() != null) {
throw new EntityAlreadyExistsException();
}
});
final List<TargetTag> save = targetTagRepository.save(targetTags);
final List<TargetTag> save = new ArrayList<>(targetTagRepository.save(targetTags));
afterCommit
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
return save;
@@ -113,10 +124,10 @@ public class JpaTagManagement implements TagManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargetTag(final String targetTagName) {
final TargetTag tag = targetTagRepository.findByNameEquals(targetTagName);
final JpaTargetTag tag = targetTagRepository.findByNameEquals(targetTagName);
final List<Target> changed = new LinkedList<>();
for (final Target target : targetRepository.findByTag(tag)) {
final List<JpaTarget> changed = new LinkedList<>();
for (final JpaTarget target : targetRepository.findByTag(tag)) {
target.getTags().remove(tag);
changed.add(target);
}
@@ -133,12 +144,22 @@ public class JpaTagManagement implements TagManagement {
@Override
public List<TargetTag> findAllTargetTags() {
return targetTagRepository.findAll();
return new ArrayList<>(targetTagRepository.findAll());
}
@Override
public Page<TargetTag> findAllTargetTags(final Specification<TargetTag> spec, final Pageable pageable) {
return targetTagRepository.findAll(spec, pageable);
public Page<TargetTag> findAllTargetTags(final String rsqlParam, final Pageable pageable) {
final Specification<JpaTargetTag> spec = RSQLUtility.parse(rsqlParam, TagFields.class);
return convertTPage(targetTagRepository.findAll(spec, pageable));
}
private static Page<TargetTag> convertTPage(final Page<JpaTargetTag> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
private static Page<DistributionSetTag> convertDsPage(final Page<JpaDistributionSetTag> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
@@ -152,7 +173,7 @@ public class JpaTagManagement implements TagManagement {
public TargetTag updateTargetTag(final TargetTag targetTag) {
checkNotNull(targetTag.getName());
checkNotNull(targetTag.getId());
final TargetTag save = targetTagRepository.save(targetTag);
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagUpdateEvent(save)));
return save;
}
@@ -174,7 +195,7 @@ public class JpaTagManagement implements TagManagement {
throw new EntityAlreadyExistsException();
}
final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag);
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit(
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
@@ -184,14 +205,17 @@ public class JpaTagManagement implements TagManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<DistributionSetTag> createDistributionSetTags(
final Collection<DistributionSetTag> distributionSetTags) {
public List<DistributionSetTag> createDistributionSetTags(final Collection<DistributionSetTag> dst) {
@SuppressWarnings({ "rawtypes", "unchecked" })
final Collection<JpaDistributionSetTag> distributionSetTags = (Collection) dst;
for (final DistributionSetTag dsTag : distributionSetTags) {
if (dsTag.getId() != null) {
throw new EntityAlreadyExistsException();
}
}
final List<DistributionSetTag> save = distributionSetTagRepository.save(distributionSetTags);
final List<DistributionSetTag> save = new ArrayList<>(distributionSetTagRepository.save(distributionSetTags));
afterCommit.afterCommit(
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
@@ -202,10 +226,10 @@ public class JpaTagManagement implements TagManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSetTag(final String tagName) {
final DistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName);
final JpaDistributionSetTag tag = distributionSetTagRepository.findByNameEquals(tagName);
final List<DistributionSet> changed = new LinkedList<>();
for (final DistributionSet set : distributionSetRepository.findByTag(tag)) {
final List<JpaDistributionSet> changed = new LinkedList<>();
for (final JpaDistributionSet set : distributionSetRepository.findByTag(tag)) {
set.getTags().remove(tag);
changed.add(set);
}
@@ -224,7 +248,7 @@ public class JpaTagManagement implements TagManagement {
public DistributionSetTag updateDistributionSetTag(final DistributionSetTag distributionSetTag) {
checkNotNull(distributionSetTag.getName());
checkNotNull(distributionSetTag.getId());
final DistributionSetTag save = distributionSetTagRepository.save(distributionSetTag);
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagUpdateEvent(save)));
return save;
@@ -232,7 +256,7 @@ public class JpaTagManagement implements TagManagement {
@Override
public List<DistributionSetTag> findAllDistributionSetTags() {
return distributionSetTagRepository.findAll();
return new ArrayList<>(distributionSetTagRepository.findAll());
}
@Override
@@ -247,18 +271,31 @@ public class JpaTagManagement implements TagManagement {
@Override
public Page<TargetTag> findAllTargetTags(final Pageable pageReq) {
return targetTagRepository.findAll(pageReq);
return convertTPage(targetTagRepository.findAll(pageReq));
}
@Override
public Page<DistributionSetTag> findAllDistributionSetTags(final Pageable pageReq) {
return distributionSetTagRepository.findAll(pageReq);
return convertDsPage(distributionSetTagRepository.findAll(pageReq));
}
@Override
public Page<DistributionSetTag> findAllDistributionSetTags(final Specification<DistributionSetTag> spec,
final Pageable pageable) {
return distributionSetTagRepository.findAll(spec, pageable);
public Page<DistributionSetTag> findAllDistributionSetTags(final String rsqlParam, final Pageable pageable) {
final Specification<JpaDistributionSetTag> spec = RSQLUtility.parse(rsqlParam, TagFields.class);
return convertDsPage(distributionSetTagRepository.findAll(spec, pageable));
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public TargetTag generateTargetTag() {
return new JpaTargetTag();
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public DistributionSetTag generateDistributionSetTag() {
return new JpaDistributionSetTag();
}
}

View File

@@ -13,11 +13,13 @@ import java.util.List;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.specifications.TargetFilterQuerySpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
@@ -50,7 +52,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
if (targetFilterQueryRepository.findByName(customTargetFilter.getName()) != null) {
throw new EntityAlreadyExistsException(customTargetFilter.getName());
}
return targetFilterQueryRepository.save(customTargetFilter);
return targetFilterQueryRepository.save((JpaTargetFilterQuery) customTargetFilter);
}
@Override
@@ -62,25 +64,29 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
@Override
public Page<TargetFilterQuery> findAllTargetFilterQuery(final Pageable pageable) {
return targetFilterQueryRepository.findAll(pageable);
return convertPage(targetFilterQueryRepository.findAll(pageable));
}
private static Page<TargetFilterQuery> convertPage(final Page<JpaTargetFilterQuery> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
public Page<TargetFilterQuery> findTargetFilterQueryByFilters(final Pageable pageable, final String name) {
final List<Specification<TargetFilterQuery>> specList = new ArrayList<>();
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>();
if (!Strings.isNullOrEmpty(name)) {
specList.add(TargetFilterQuerySpecification.likeName(name));
}
return findTargetFilterQueryByCriteriaAPI(pageable, specList);
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList));
}
private Page<TargetFilterQuery> findTargetFilterQueryByCriteriaAPI(final Pageable pageable,
final List<Specification<TargetFilterQuery>> specList) {
private Page<JpaTargetFilterQuery> findTargetFilterQueryByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaTargetFilterQuery>> specList) {
if (specList == null || specList.isEmpty()) {
return targetFilterQueryRepository.findAll(pageable);
}
final Specifications<TargetFilterQuery> specs = SpecificationsBuilder.combineWithAnd(specList);
final Specifications<JpaTargetFilterQuery> specs = SpecificationsBuilder.combineWithAnd(specList);
return targetFilterQueryRepository.findAll(specs, pageable);
}
@@ -99,7 +105,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public TargetFilterQuery updateTargetFilterQuery(final TargetFilterQuery targetFilterQuery) {
Assert.notNull(targetFilterQuery.getId());
return targetFilterQueryRepository.save(targetFilterQuery);
return targetFilterQueryRepository.save((JpaTargetFilterQuery) targetFilterQuery);
}
}

View File

@@ -33,22 +33,25 @@ import org.eclipse.hawkbit.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.model.DistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
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.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
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.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetInfo_;
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.model.Target_;
import org.eclipse.hawkbit.repository.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.specifications.TargetSpecifications;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
@@ -58,6 +61,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
@@ -121,7 +125,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public List<Target> findTargetByControllerID(final Collection<String> controllerIDs) {
return targetRepository.findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs));
return new ArrayList<>(targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs)));
}
@Override
@@ -134,28 +139,27 @@ public class JpaTargetManagement implements TargetManagement {
// workarround - no join fetch allowed that is why we need specification
// instead of query for
// count() of Pageable
final Specification<Target> spec = (root, query, cb) -> {
final Specification<JpaTarget> spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(Target_.targetInfo);
root.fetch(JpaTarget_.targetInfo);
}
return cb.conjunction();
};
return criteriaNoCountDao.findAll(spec, pageable, Target.class);
return convertPage(criteriaNoCountDao.findAll(spec, pageable, JpaTarget.class));
}
@Override
public Slice<Target> findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) {
return findTargetsAll(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class), pageable);
return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class), pageable);
}
@Override
public Slice<Target> findTargetsAll(final String targetFilterQuery, final Pageable pageable) {
return findTargetsAll(RSQLUtility.parse(targetFilterQuery, TargetFields.class), pageable);
public Page<Target> findTargetsAll(final String targetFilterQuery, final Pageable pageable) {
return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery, TargetFields.class), pageable);
}
@Override
public Page<Target> findTargetsAll(final Specification<Target> spec, final Pageable pageable) {
return targetRepository.findAll(spec, pageable);
private Page<Target> findTargetsBySpec(final Specification<JpaTarget> spec, final Pageable pageable) {
return convertPage(targetRepository.findAll(spec, pageable));
}
@Override
@@ -171,16 +175,23 @@ public class JpaTargetManagement implements TargetManagement {
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target updateTarget(final Target target) {
Assert.notNull(target.getId());
target.setNew(false);
return targetRepository.save(target);
final JpaTarget toUpdate = (JpaTarget) target;
toUpdate.setNew(false);
return targetRepository.save(toUpdate);
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> updateTargets(final Iterable<Target> targets) {
targets.forEach(target -> target.setNew(false));
return targetRepository.save(targets);
public List<Target> updateTargets(final Collection<Target> targets) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaTarget> toUpdate = (Collection) targets;
toUpdate.forEach(target -> target.setNew(false));
return new ArrayList<>(targetRepository.save(toUpdate));
}
@Override
@@ -206,11 +217,22 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Page<Target> findTargetByAssignedDistributionSet(final Long distributionSetID,
final Specification<Target> spec, final Pageable pageReq) {
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(
public Page<Target> findTargetByAssignedDistributionSet(final Long distributionSetID, final String rsqlParam,
final Pageable pageReq) {
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class);
return convertPage(targetRepository.findAll((Specification<JpaTarget>) (root, query, cb) -> cb.and(
TargetSpecifications.hasAssignedDistributionSet(distributionSetID).toPredicate(root, query, cb),
spec.toPredicate(root, query, cb)), pageReq);
spec.toPredicate(root, query, cb)), pageReq));
}
private static Page<Target> convertPage(final Page<JpaTarget> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
private static Slice<Target> convertPage(final Slice<JpaTarget> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()));
}
@Override
@@ -219,11 +241,14 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId,
final Specification<Target> spec, final Pageable pageable) {
return targetRepository.findAll((Specification<Target>) (root, query, cb) -> cb.and(
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId, final String rsqlParam,
final Pageable pageable) {
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class);
return convertPage(targetRepository.findAll((Specification<JpaTarget>) (root, query, cb) -> cb.and(
TargetSpecifications.hasInstalledDistributionSet(distributionSetId).toPredicate(root, query, cb),
spec.toPredicate(root, query, cb)), pageable);
spec.toPredicate(root, query, cb)), pageable));
}
@Override
@@ -235,7 +260,7 @@ public class JpaTargetManagement implements TargetManagement {
public Slice<Target> findTargetByFilters(final Pageable pageable, final Collection<TargetUpdateStatus> status,
final String searchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final String... tagNames) {
final List<Specification<Target>> specList = buildSpecificationList(status, searchText,
final List<Specification<JpaTarget>> specList = buildSpecificationList(status, searchText,
installedOrAssignedDistributionSetId, selectTargetWithNoTag, true, tagNames);
return findByCriteriaAPI(pageable, specList);
}
@@ -244,15 +269,15 @@ public class JpaTargetManagement implements TargetManagement {
public Long countTargetByFilters(final Collection<TargetUpdateStatus> status, final String searchText,
final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag,
final String... tagNames) {
final List<Specification<Target>> specList = buildSpecificationList(status, searchText,
final List<Specification<JpaTarget>> specList = buildSpecificationList(status, searchText,
installedOrAssignedDistributionSetId, selectTargetWithNoTag, true, tagNames);
return countByCriteriaAPI(specList);
}
private static List<Specification<Target>> buildSpecificationList(final Collection<TargetUpdateStatus> status,
private static List<Specification<JpaTarget>> buildSpecificationList(final Collection<TargetUpdateStatus> status,
final String searchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final boolean fetch, final String... tagNames) {
final List<Specification<Target>> specList = new ArrayList<>();
final List<Specification<JpaTarget>> specList = new ArrayList<>();
if (status != null && !status.isEmpty()) {
specList.add(TargetSpecifications.hasTargetUpdateStatus(status, fetch));
}
@@ -269,14 +294,15 @@ public class JpaTargetManagement implements TargetManagement {
return specList;
}
private Slice<Target> findByCriteriaAPI(final Pageable pageable, final List<Specification<Target>> specList) {
private Slice<Target> findByCriteriaAPI(final Pageable pageable, final List<Specification<JpaTarget>> specList) {
if (specList == null || specList.isEmpty()) {
return criteriaNoCountDao.findAll(pageable, Target.class);
return convertPage(criteriaNoCountDao.findAll(pageable, JpaTarget.class));
}
return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, Target.class);
return convertPage(
criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, JpaTarget.class));
}
private Long countByCriteriaAPI(final List<Specification<Target>> specList) {
private Long countByCriteriaAPI(final List<Specification<JpaTarget>> specList) {
if (specList == null || specList.isEmpty()) {
return targetRepository.count();
}
@@ -298,7 +324,7 @@ public class JpaTargetManagement implements TargetManagement {
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<Target> allTargets = targetRepository
final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
// all are already assigned -> unassign
@@ -315,7 +341,7 @@ public class JpaTargetManagement implements TargetManagement {
// some or none are assigned -> assign
allTargets.forEach(target -> target.getTags().add(tag));
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(),
allTargets.size(), 0, targetRepository.save(allTargets), Collections.emptyList(), tag);
allTargets.size(), 0, new ArrayList<>(targetRepository.save(allTargets)), Collections.emptyList(), tag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result)));
@@ -328,11 +354,11 @@ public class JpaTargetManagement implements TargetManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> assignTag(final Collection<String> targetIds, final TargetTag tag) {
final List<Target> allTargets = targetRepository
final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
allTargets.forEach(target -> target.getTags().add(tag));
final List<Target> save = targetRepository.save(allTargets);
final List<Target> save = new ArrayList<>(targetRepository.save(allTargets));
afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save,
@@ -344,9 +370,11 @@ public class JpaTargetManagement implements TargetManagement {
}
private List<Target> unAssignTag(final Collection<Target> targets, final TargetTag tag) {
targets.forEach(target -> target.getTags().remove(tag));
final Collection<JpaTarget> toUnassign = (Collection) targets;
final List<Target> save = targetRepository.save(targets);
toUnassign.forEach(target -> target.getTags().remove(tag));
final List<Target> save = new ArrayList<>(targetRepository.save(toUnassign));
afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(),
Collections.emptyList(), save, tag);
@@ -366,8 +394,9 @@ public class JpaTargetManagement implements TargetManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target unAssignTag(final String controllerID, final TargetTag targetTag) {
final List<Target> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID)));
// TODO : optimize this, findone?
final List<Target> allTargets = new ArrayList<>(targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID))));
final List<Target> unAssignTag = unAssignTag(allTargets, targetTag);
return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
}
@@ -378,20 +407,20 @@ public class JpaTargetManagement implements TargetManagement {
final Collection<TargetUpdateStatus> filterByStatus, final String filterBySearchText,
final Boolean selectTargetWithNoTag, final String... filterByTagNames) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Target> query = cb.createQuery(Target.class);
final Root<Target> targetRoot = query.from(Target.class);
final CriteriaQuery<JpaTarget> query = cb.createQuery(JpaTarget.class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
// necessary joins for the select
final Join<Target, TargetInfo> targetInfo = (Join<Target, TargetInfo>) targetRoot.fetch(Target_.targetInfo,
JoinType.LEFT);
final Join<JpaTarget, JpaTargetInfo> targetInfo = (Join<JpaTarget, JpaTargetInfo>) targetRoot
.fetch(JpaTarget_.targetInfo, JoinType.LEFT);
// select case expression to retrieve the case value as a column to be
// able to order based on
// this column, installed first,...
final Expression<Object> selectCase = cb.selectCase()
.when(cb.equal(targetInfo.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id),
.when(cb.equal(targetInfo.get(JpaTargetInfo_.installedDistributionSet).get(JpaDistributionSet_.id),
orderByDistributionId), 1)
.when(cb.equal(targetRoot.get(Target_.assignedDistributionSet).get(DistributionSet_.id),
.when(cb.equal(targetRoot.get(JpaTarget_.assignedDistributionSet).get(JpaDistributionSet_.id),
orderByDistributionId), 2)
.otherwise(100);
// multiselect statement order by the select case and controllerId
@@ -409,7 +438,7 @@ public class JpaTargetManagement implements TargetManagement {
query.where(specificationsForMultiSelect);
}
// add the order to the multi select first based on the selectCase
query.orderBy(cb.asc(selectCase), cb.desc(targetRoot.get(Target_.id)));
query.orderBy(cb.asc(selectCase), cb.desc(targetRoot.get(JpaTarget_.id)));
// the result is a Object[] due the fact that the selectCase is an extra
// column, so it cannot
// be mapped directly to a Target entity because the selectCase is not a
@@ -419,14 +448,14 @@ public class JpaTargetManagement implements TargetManagement {
// multiselect order) of the array and
// the 2nd contains the selectCase int value.
final int pageSize = pageable.getPageSize();
final List<Target> resultList = entityManager.createQuery(query).setFirstResult(pageable.getOffset())
final List<JpaTarget> resultList = entityManager.createQuery(query).setFirstResult(pageable.getOffset())
.setMaxResults(pageSize + 1).getResultList();
final boolean hasNext = resultList.size() > pageSize;
return new SliceImpl<>(resultList, pageable, hasNext);
return new SliceImpl<>(new ArrayList<>(resultList), pageable, hasNext);
}
private static Predicate[] specificationsToPredicate(final List<Specification<Target>> specifications,
final Root<Target> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
private static Predicate[] specificationsToPredicate(final List<Specification<JpaTarget>> specifications,
final Root<JpaTarget> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
final Predicate[] predicates = new Predicate[specifications.size()];
for (int index = 0; index < predicates.length; index++) {
predicates[index] = specifications.get(index).toPredicate(root, query, cb);
@@ -448,9 +477,9 @@ public class JpaTargetManagement implements TargetManagement {
public List<TargetIdName> findAllTargetIds() {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<TargetIdName> query = cb.createQuery(TargetIdName.class);
final Root<Target> targetRoot = query.from(Target.class);
return entityManager.createQuery(query.multiselect(targetRoot.get(Target_.id),
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name))).getResultList();
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();
}
@@ -461,16 +490,16 @@ public class JpaTargetManagement implements TargetManagement {
final String... filterByTagNames) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<Target> targetRoot = query.from(Target.class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
List<Object[]> resultList;
String sortProperty = Target_.id.getName();
String sortProperty = JpaTarget_.id.getName();
if (pageRequest.getSort() != null && pageRequest.getSort().iterator().hasNext()) {
sortProperty = pageRequest.getSort().iterator().next().getProperty();
}
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(Target_.id),
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name), targetRoot.get(sortProperty));
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id),
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
buildSpecificationList(filterByStatus, filterBySearchText, installedOrAssignedDistributionSetId,
@@ -493,18 +522,18 @@ public class JpaTargetManagement implements TargetManagement {
final TargetFilterQuery targetFilterQuery) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
final Root<Target> targetRoot = query.from(Target.class);
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
String sortProperty = Target_.id.getName();
String sortProperty = JpaTarget_.id.getName();
if (pageRequest.getSort() != null && pageRequest.getSort().iterator().hasNext()) {
sortProperty = pageRequest.getSort().iterator().next().getProperty();
}
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(Target_.id),
targetRoot.get(Target_.controllerId), targetRoot.get(Target_.name), targetRoot.get(sortProperty));
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id),
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
final Specification<Target> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
final List<Specification<Target>> specList = new ArrayList<>();
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
final List<Specification<JpaTarget>> specList = new ArrayList<>();
specList.add(spec);
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(specList, targetRoot, multiselect,
@@ -529,16 +558,17 @@ public class JpaTargetManagement implements TargetManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetsCreatedOverPeriod" }, allEntries = true)
public Target createTarget(final Target target, final TargetUpdateStatus status, final Long lastTargetQuery,
public Target createTarget(final Target t, final TargetUpdateStatus status, final Long lastTargetQuery,
final URI address) {
final JpaTarget target = (JpaTarget) t;
if (targetRepository.findByControllerId(target.getControllerId()) != null) {
throw new EntityAlreadyExistsException(target.getControllerId());
}
target.setNew(true);
final Target savedTarget = targetRepository.save(target);
final TargetInfo targetInfo = savedTarget.getTargetInfo();
final JpaTarget savedTarget = targetRepository.save(target);
final JpaTargetInfo targetInfo = (JpaTargetInfo) savedTarget.getTargetInfo();
targetInfo.setUpdateStatus(status);
if (lastTargetQuery != null) {
targetInfo.setLastTargetQuery(lastTargetQuery);
@@ -596,24 +626,24 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public List<Target> findTargetsByTag(final String tagName) {
final TargetTag tag = targetTagRepository.findByNameEquals(tagName);
return targetRepository.findByTag(tag);
final JpaTargetTag tag = targetTagRepository.findByNameEquals(tagName);
return new ArrayList<>(targetRepository.findByTag(tag));
}
@Override
public Long countTargetByTargetFilterQuery(final TargetFilterQuery targetFilterQuery) {
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
return targetRepository.count(specs);
}
@Override
public Long countTargetByTargetFilterQuery(final String targetFilterQuery) {
final Specification<Target> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class);
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class);
return targetRepository.count(specs);
}
private List<Object[]> getTargetIdNameResultSet(final Pageable pageRequest, final CriteriaBuilder cb,
final Root<Target> targetRoot, final CriteriaQuery<Object[]> multiselect) {
final Root<JpaTarget> targetRoot, final CriteriaQuery<Object[]> multiselect) {
List<Object[]> resultList;
if (pageRequest.getSort() != null) {
final List<Order> orders = new ArrayList<>();
@@ -633,4 +663,10 @@ public class JpaTargetManagement implements TargetManagement {
}
return resultList;
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public Target generateTarget(final String controllerId) {
return new JpaTarget(controllerId);
}
}

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
@@ -134,16 +135,17 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
configurationKey.validate(applicationContext, value);
TenantConfiguration tenantConfiguration = tenantConfigurationRepository
JpaTenantConfiguration tenantConfiguration = tenantConfigurationRepository
.findByKey(configurationKey.getKeyName());
if (tenantConfiguration == null) {
tenantConfiguration = new TenantConfiguration(configurationKey.getKeyName(), value.toString());
tenantConfiguration = new JpaTenantConfiguration(configurationKey.getKeyName(), value.toString());
} else {
tenantConfiguration.setValue(value.toString());
}
final TenantConfiguration updatedTenantConfiguration = tenantConfigurationRepository.save(tenantConfiguration);
final JpaTenantConfiguration updatedTenantConfiguration = tenantConfigurationRepository
.save(tenantConfiguration);
final Class<T> clazzT = (Class<T>) value.getClass();

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import java.util.Optional;
import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -23,7 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface LocalArtifactRepository extends BaseEntityRepository<LocalArtifact, Long> {
public interface LocalArtifactRepository extends BaseEntityRepository<JpaLocalArtifact, Long> {
/**
* Counts artifacts size where the related software module is not
@@ -31,7 +32,7 @@ public interface LocalArtifactRepository extends BaseEntityRepository<LocalArtif
*
* @return sum of artifacts size in bytes
*/
@Query("SELECT SUM(la.size) FROM LocalArtifact la WHERE la.softwareModule.deleted = 0")
@Query("SELECT SUM(la.size) FROM JpaLocalArtifact la WHERE la.softwareModule.deleted = 0")
Optional<Long> getSumOfUndeletedArtifactSize();
/**
@@ -60,7 +61,7 @@ public interface LocalArtifactRepository extends BaseEntityRepository<LocalArtif
* to search
* @return {@link LocalArtifact} the first in the result list
*/
LocalArtifact findFirstByGridFsFileName(String gridFsFileName);
JpaLocalArtifact findFirstByGridFsFileName(String gridFsFileName);
/**
* Searches for a {@link LocalArtifact} based user provided filename at

View File

@@ -10,9 +10,11 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -26,7 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface RolloutGroupRepository
extends BaseEntityRepository<RolloutGroup, Long>, JpaSpecificationExecutor<RolloutGroup> {
extends BaseEntityRepository<JpaRolloutGroup, Long>, JpaSpecificationExecutor<JpaRolloutGroup> {
/**
* Retrieves all {@link RolloutGroup} referring a specific rollout in the
@@ -36,7 +38,7 @@ public interface RolloutGroupRepository
* the rollout the rolloutgroups belong to
* @return the rollout groups belonging to a rollout ordered by ID ASC.
*/
List<RolloutGroup> findByRolloutOrderByIdAsc(final Rollout rollout);
List<JpaRolloutGroup> findByRolloutOrderByIdAsc(final JpaRollout rollout);
/**
* Retrieves all {@link RolloutGroup} referring a specific rollout in a
@@ -48,7 +50,7 @@ public interface RolloutGroupRepository
* the status of the rollout groups
* @return the rollout groups belonging to a rollout in a specific status
*/
List<RolloutGroup> findByRolloutAndStatus(final Rollout rollout, final RolloutGroupStatus status);
List<JpaRolloutGroup> findByRolloutAndStatus(final Rollout rollout, final RolloutGroupStatus status);
/**
* Counts all {@link RolloutGroup} referring a specific rollout.
@@ -57,7 +59,7 @@ public interface RolloutGroupRepository
* the rollout the rolloutgroup belong to
* @return the count of the rollout groups for a specific rollout
*/
Long countByRollout(final Rollout rollout);
Long countByRollout(final JpaRollout rollout);
/**
* Counts all {@link RolloutGroup} referring a specific rollout in a
@@ -70,7 +72,7 @@ public interface RolloutGroupRepository
* @return the count of rollout groups belonging to a rollout in a specific
* status
*/
Long countByRolloutAndStatus(Rollout rollout, RolloutGroupStatus rolloutGroupStatus);
Long countByRolloutAndStatus(JpaRollout rollout, RolloutGroupStatus rolloutGroupStatus);
/**
* Counts all {@link RolloutGroup} referring a specific rollout in specific
@@ -88,8 +90,8 @@ public interface RolloutGroupRepository
* @return the count of rollout groups belonging to a rollout in specific
* status
*/
@Query("SELECT COUNT(r.id) FROM RolloutGroup r WHERE r.rollout = :rollout and (r.status = :status1 or r.status = :status2)")
Long countByRolloutAndStatusOrStatus(@Param("rollout") Rollout rollout,
@Query("SELECT COUNT(r.id) FROM JpaRolloutGroup r WHERE r.rollout = :rollout and (r.status = :status1 or r.status = :status2)")
Long countByRolloutAndStatusOrStatus(@Param("rollout") JpaRollout rollout,
@Param("status1") RolloutGroupStatus rolloutGroupStatus1,
@Param("status2") RolloutGroupStatus rolloutGroupStatus2);
@@ -103,7 +105,7 @@ public interface RolloutGroupRepository
* the status of the rolloutgroups
* @return The child {@link RolloutGroup}s in a specific status
*/
List<RolloutGroup> findByParentAndStatus(RolloutGroup rolloutGroup, RolloutGroupStatus status);
List<JpaRolloutGroup> findByParentAndStatus(JpaRolloutGroup rolloutGroup, RolloutGroupStatus status);
/**
* Retrieves all {@link RolloutGroup} for a specific rollout and status not
@@ -116,7 +118,7 @@ public interface RolloutGroupRepository
* @return rolloutgroup referring to a rollout and not having a specific
* status ordered by ID DESC.
*/
List<RolloutGroup> findByRolloutAndStatusNotOrderByIdDesc(Rollout rollout, RolloutGroupStatus notStatus);
List<JpaRolloutGroup> findByRolloutAndStatusNotOrderByIdDesc(JpaRollout rollout, RolloutGroupStatus notStatus);
/**
* Retrieves all {@link RolloutGroup} for a specific rollout.
@@ -127,6 +129,6 @@ public interface RolloutGroupRepository
* the page request to sort, limit the result
* @return a page of found {@link RolloutGroup} or {@code empty}.
*/
Page<RolloutGroup> findByRolloutId(final Long rolloutId, Pageable page);
Page<JpaRolloutGroup> findByRolloutId(final Long rolloutId, Pageable page);
}

View File

@@ -10,8 +10,9 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout.RolloutStatus;
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;
@@ -25,7 +26,8 @@ import org.springframework.transaction.annotation.Transactional;
* The repository interface for the {@link Rollout} model.
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface RolloutRepository extends BaseEntityRepository<Rollout, Long>, JpaSpecificationExecutor<Rollout> {
public interface RolloutRepository
extends BaseEntityRepository<JpaRollout, Long>, JpaSpecificationExecutor<JpaRollout> {
/**
* Updates the {@code lastCheck} field of the {@link Rollout} for rollouts
@@ -42,7 +44,7 @@ public interface RolloutRepository extends BaseEntityRepository<Rollout, Long>,
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE Rollout r SET r.lastCheck = :lastCheck WHERE r.lastCheck < (:lastCheck - :delay) AND r.status=:status")
@Query("UPDATE JpaRollout r SET r.lastCheck = :lastCheck WHERE r.lastCheck < (:lastCheck - :delay) AND r.status=:status")
int updateLastCheck(@Param("lastCheck") final long lastCheck, @Param("delay") final long delay,
@Param("status") final RolloutStatus status);
@@ -57,7 +59,7 @@ public interface RolloutRepository extends BaseEntityRepository<Rollout, Long>,
* @return the list of {@link Rollout} for specific lastCheck time and
* status
*/
List<Rollout> findByLastCheckAndStatus(long lastCheck, RolloutStatus status);
List<JpaRollout> findByLastCheckAndStatus(long lastCheck, RolloutStatus status);
/**
* Retrieves all {@link Rollout} for a specific {@code name}
@@ -66,7 +68,7 @@ public interface RolloutRepository extends BaseEntityRepository<Rollout, Long>,
* the rollout name
* @return {@link Rollout} for specific name
*/
Page<Rollout> findByName(final Pageable pageable, String name);
Page<JpaRollout> findByName(final Pageable pageable, String name);
/**
* Retrieves all {@link Rollout} for a specific {@code name}
@@ -75,7 +77,7 @@ public interface RolloutRepository extends BaseEntityRepository<Rollout, Long>,
* the rollout name
* @return {@link Rollout} for specific name
*/
Rollout findByName(String name);
JpaRollout findByName(String name);
/**
* Retrieves all {@link Rollout} for a specific status.
@@ -84,5 +86,5 @@ public interface RolloutRepository extends BaseEntityRepository<Rollout, Long>,
* the status of the rollouts to retrieve
* @return a list of {@link Rollout} having the given status
*/
List<Rollout> findByStatus(final RolloutStatus status);
List<JpaRollout> findByStatus(final RolloutStatus status);
}

View File

@@ -8,8 +8,8 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.model.RolloutTargetGroupId;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroupId;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Isolation;

View File

@@ -10,8 +10,9 @@ 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;
import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -25,8 +26,8 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface SoftwareModuleMetadataRepository
extends PagingAndSortingRepository<SoftwareModuleMetadata, SwMetadataCompositeKey>,
JpaSpecificationExecutor<SoftwareModuleMetadata> {
extends PagingAndSortingRepository<JpaSoftwareModuleMetadata, SwMetadataCompositeKey>,
JpaSpecificationExecutor<JpaSoftwareModuleMetadata> {
/**
* Saves all given entities.
@@ -37,7 +38,7 @@ public interface SoftwareModuleMetadataRepository
* in case the given entity is (@literal null}.
*/
@Override
<S extends SoftwareModuleMetadata> List<S> save(Iterable<S> entities);
<S extends JpaSoftwareModuleMetadata> List<S> save(Iterable<S> entities);
/**
* finds all software module meta data of the given software module id.

View File

@@ -10,6 +10,9 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
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.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -30,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface SoftwareModuleRepository
extends BaseEntityRepository<SoftwareModule, Long>, JpaSpecificationExecutor<SoftwareModule> {
extends BaseEntityRepository<JpaSoftwareModule, Long>, JpaSpecificationExecutor<JpaSoftwareModule> {
/**
* Counts all {@link SoftwareModule}s based on the given {@link Type}.
@@ -39,7 +42,7 @@ public interface SoftwareModuleRepository
* to count for
* @return number of {@link SoftwareModule}s
*/
Long countByType(SoftwareModuleType type);
Long countByType(JpaSoftwareModuleType type);
/**
* Retrieves {@link SoftwareModule} by filtering on name AND version AND
@@ -54,7 +57,7 @@ public interface SoftwareModuleRepository
* @return the found {@link SoftwareModule} with the given name AND version
* AND type
*/
SoftwareModule findOneByNameAndVersionAndType(String name, String version, SoftwareModuleType type);
JpaSoftwareModule findOneByNameAndVersionAndType(String name, String version, JpaSoftwareModuleType type);
/**
* deletes the {@link SoftwareModule}s with the given IDs.
@@ -69,7 +72,7 @@ public interface SoftwareModuleRepository
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE SoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids")
@Query("UPDATE JpaSoftwareModule b SET b.deleted = 1, b.lastModifiedAt = :lastModifiedAt, b.lastModifiedBy = :lastModifiedBy WHERE b.id IN :ids")
void deleteSoftwareModule(@Param("lastModifiedAt") Long modifiedAt, @Param("lastModifiedBy") String modifiedBy,
@Param("ids") final Long... ids);
@@ -81,7 +84,7 @@ public interface SoftwareModuleRepository
* @return all {@link SoftwareModule}s that are assigned to given
* {@link DistributionSet}.
*/
Page<SoftwareModule> findByAssignedTo(Pageable pageable, DistributionSet set);
Page<SoftwareModule> findByAssignedTo(Pageable pageable, JpaDistributionSet set);
/**
*
@@ -92,7 +95,7 @@ public interface SoftwareModuleRepository
* {@link DistributionSet}
*/
@EntityGraph(value = "SoftwareModule.artifacts", type = EntityGraphType.LOAD)
List<SoftwareModule> findByAssignedTo(DistributionSet set);
List<JpaSoftwareModule> findByAssignedTo(JpaDistributionSet set);
/**
* @param pageable
@@ -104,7 +107,7 @@ public interface SoftwareModuleRepository
* @return all {@link SoftwareModule}s that are assigned to given
* {@link DistributionSet} filtered by {@link SoftwareModuleType}.
*/
Page<SoftwareModule> findByAssignedToAndType(Pageable pageable, DistributionSet set, SoftwareModuleType type);
Page<SoftwareModule> findByAssignedToAndType(Pageable pageable, JpaDistributionSet set, JpaSoftwareModuleType type);
/**
* retrieves all software modules with a given {@link SoftwareModuleType}
@@ -117,11 +120,11 @@ public interface SoftwareModuleRepository
* @return {@link List} of found {@link SoftwareModule}s
*/
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("SELECT sm FROM SoftwareModule sm WHERE sm.id IN ?1 and sm.type = ?2")
List<SoftwareModule> findByIdInAndType(Iterable<Long> ids, SoftwareModuleType type);
@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 SoftwareModule> List<S> save(Iterable<S> entities);
<S extends JpaSoftwareModule> List<S> save(Iterable<S> entities);
/**
* retrieves all software modules with a given
@@ -132,6 +135,6 @@ public interface SoftwareModuleRepository
* @return {@link List} of found {@link SoftwareModule}s
*/
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("SELECT sm FROM SoftwareModule sm WHERE sm.id IN ?1")
List<SoftwareModule> findByIdIn(Iterable<Long> ids);
@Query("SELECT sm FROM JpaSoftwareModule sm WHERE sm.id IN ?1")
List<JpaSoftwareModule> findByIdIn(Iterable<Long> ids);
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -21,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface SoftwareModuleTypeRepository
extends BaseEntityRepository<SoftwareModuleType, Long>, JpaSpecificationExecutor<SoftwareModuleType> {
extends BaseEntityRepository<JpaSoftwareModuleType, Long>, JpaSpecificationExecutor<JpaSoftwareModuleType> {
/**
* @param pageable
@@ -47,7 +48,7 @@ public interface SoftwareModuleTypeRepository
* @return all {@link SoftwareModuleType}s in the repository with given
* {@link SoftwareModuleType#getKey()}
*/
SoftwareModuleType findByKey(String key);
JpaSoftwareModuleType findByKey(String key);
/**
*
@@ -56,5 +57,5 @@ public interface SoftwareModuleTypeRepository
* @return all {@link SoftwareModuleType}s in the repository with given
* {@link SoftwareModuleType#getName()}
*/
SoftwareModuleType findByName(String name);
JpaSoftwareModuleType findByName(String name);
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -21,7 +22,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface TargetFilterQueryRepository
extends BaseEntityRepository<TargetFilterQuery, Long>, JpaSpecificationExecutor<TargetFilterQuery> {
extends BaseEntityRepository<JpaTargetFilterQuery, Long>, JpaSpecificationExecutor<JpaTargetFilterQuery> {
/**
* Find customer target filter by name
@@ -35,11 +36,11 @@ public interface TargetFilterQueryRepository
* Find list of all custom target filters.
*/
@Override
Page<TargetFilterQuery> findAll();
Page<JpaTargetFilterQuery> findAll();
@Override
@Modifying
@Transactional
<S extends TargetFilterQuery> S save(S entity);
<S extends JpaTargetFilterQuery> S save(S entity);
}

View File

@@ -13,6 +13,7 @@ import java.util.List;
import javax.persistence.Entity;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.springframework.cache.annotation.CacheEvict;
@@ -42,7 +43,7 @@ public interface TargetInfoRepository {
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("update TargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status")
@Query("update JpaTargetInfo ti set ti.updateStatus = :status where ti.targetId in :targets and ti.updateStatus != :status")
void setTargetUpdateStatus(@Param("status") TargetUpdateStatus status, @Param("targets") List<Long> targets);
/**
@@ -54,7 +55,7 @@ public interface TargetInfoRepository {
* @return persisted or updated {@link Entity}
*/
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends TargetInfo> S save(S entity);
<S extends JpaTargetInfo> S save(S entity);
/**
* Deletes info entries by ID.

View File

@@ -11,11 +11,13 @@ package org.eclipse.hawkbit.repository.jpa;
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.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TargetWithActionStatus;
import org.springframework.cache.annotation.CacheEvict;
@@ -35,7 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface TargetRepository extends BaseEntityRepository<Target, Long>, JpaSpecificationExecutor<Target> {
public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>, JpaSpecificationExecutor<JpaTarget> {
/**
* Loads {@link Target} including details {@link EntityGraph} by given ID.
@@ -45,7 +47,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* @return found {@link Target} or <code>null</code> if not found.
*/
@EntityGraph(value = "Target.detail", type = EntityGraphType.LOAD)
Target findByControllerId(String controllerID);
JpaTarget findByControllerId(String controllerID);
/**
* Finds targets by given list of {@link Target#getControllerId()}s.
@@ -65,7 +67,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM Target t WHERE t.id IN ?1")
@Query("DELETE FROM JpaTarget t WHERE t.id IN ?1")
void deleteByIdIn(final Collection<Long> targetIDs);
/**
@@ -75,8 +77,8 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* to be found
* @return list of found targets
*/
@Query(value = "SELECT DISTINCT t FROM Target t JOIN t.tags tt WHERE tt = :tag")
List<Target> findByTag(@Param("tag") final TargetTag tag);
@Query(value = "SELECT DISTINCT t FROM JpaTarget t JOIN t.tags tt WHERE tt = :tag")
List<JpaTarget> findByTag(@Param("tag") final JpaTargetTag tag);
/**
* Finds all {@link Target}s based on given {@link Target#getControllerId()}
@@ -88,7 +90,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* to search for
* @return {@link List} of found {@link Target}s.
*/
@Query(value = "SELECT DISTINCT t from Target t JOIN t.tags tt WHERE tt.name = :tagname AND t.controllerId IN :targets")
@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,
@Param("targets") final Collection<String> controllerIds);
@@ -114,7 +116,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
*
* @return found targets
*/
Page<Target> findByTargetInfoInstalledDistributionSet(final Pageable pageable, final DistributionSet set);
Page<Target> findByTargetInfoInstalledDistributionSet(final Pageable pageable, final JpaDistributionSet set);
/**
* retrieves the {@link Target}s which has the {@link DistributionSet}
@@ -138,7 +140,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
*
* @return found targets
*/
Page<Target> findByAssignedDistributionSet(final Pageable pageable, final DistributionSet set);
Page<Target> findByAssignedDistributionSet(final Pageable pageable, final JpaDistributionSet set);
/**
* Saves all given {@link Target}s.
@@ -154,7 +156,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends Target> List<S> save(Iterable<S> entities);
<S extends JpaTarget> List<S> save(Iterable<S> entities);
/**
* Saves a given entity. Use the returned instance for further operations as
@@ -168,7 +170,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends Target> S save(S entity);
<S extends JpaTarget> S save(S entity);
/**
* Finds all targets that have defined {@link DistributionSet} assigned.
@@ -199,7 +201,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* @return number of found {@link Target}s with given
* {@link Target#getControllerId()}s
*/
@Query("SELECT COUNT(t) FROM Target t WHERE t.controllerId IN ?1")
@Query("SELECT COUNT(t) FROM JpaTarget t WHERE t.controllerId IN ?1")
Long countByControllerIdIn(final Collection<String> ids);
/**
@@ -228,7 +230,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* @return found targets
*/
Page<Target> findByAssignedDistributionSetOrTargetInfoInstalledDistributionSet(final Pageable pageable,
final DistributionSet assigned, final DistributionSet installed);
final JpaDistributionSet assigned, final JpaDistributionSet installed);
/**
* Finds all targets that have defined {@link DistributionSet} assigned or
@@ -255,12 +257,12 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* @see org.springframework.data.repository.CrudRepository#findAll()
*/
@Override
List<Target> findAll();
List<JpaTarget> findAll();
@Override
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("SELECT t FROM Target t WHERE t.id IN ?1")
List<Target> findAll(Iterable<Long> ids);
@Query("SELECT t FROM JpaTarget t WHERE t.id IN ?1")
List<JpaTarget> findAll(Iterable<Long> ids);
/**
* Sets {@link Target#getAssignedDistributionSet()}.
@@ -276,11 +278,11 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE Target t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy WHERE t.id IN :targets")
void setAssignedDistributionSet(@Param("set") DistributionSet set, @Param("lastModifiedAt") Long modifiedAt,
@Query("UPDATE JpaTarget t SET t.assignedDistributionSet = :set, t.lastModifiedAt = :lastModifiedAt, t.lastModifiedBy = :lastModifiedBy WHERE t.id IN :targets")
void setAssignedDistributionSet(@Param("set") JpaDistributionSet set, @Param("lastModifiedAt") Long modifiedAt,
@Param("lastModifiedBy") String modifiedBy, @Param("targets") Collection<Long> targets);
List<Target> findByRolloutTargetGroupRolloutGroup(final RolloutGroup rolloutGroup);
List<Target> findByRolloutTargetGroupRolloutGroup(final JpaRolloutGroup rolloutGroup);
/**
*
@@ -304,7 +306,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* the page request parameter
* @return a page of all targets related to a rollout group
*/
Page<Target> findByActionsRolloutGroup(RolloutGroup rolloutGroup, Pageable page);
Page<Target> findByActionsRolloutGroup(JpaRolloutGroup rolloutGroup, Pageable page);
/**
* Find all targets with action status for a specific group.
@@ -315,7 +317,7 @@ public interface TargetRepository extends BaseEntityRepository<Target, Long>, Jp
* 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 Action a inner join fetch a.target t where a.rolloutGroup.id = :rolloutGroupId")
@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

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
@@ -22,7 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface TargetTagRepository
extends BaseEntityRepository<TargetTag, Long>, JpaSpecificationExecutor<TargetTag> {
extends BaseEntityRepository<JpaTargetTag, Long>, JpaSpecificationExecutor<JpaTargetTag> {
/**
* deletes the {@link TargetTag}s with the given tag names.
@@ -42,7 +43,7 @@ public interface TargetTagRepository
* to filter on
* @return the {@link TargetTag} if found, otherwise null
*/
TargetTag findByNameEquals(final String tagName);
JpaTargetTag findByNameEquals(final String tagName);
/**
* Returns all instances of the type.
@@ -50,8 +51,8 @@ public interface TargetTagRepository
* @return all entities
*/
@Override
List<TargetTag> findAll();
List<JpaTargetTag> findAll();
@Override
<S extends TargetTag> List<S> save(Iterable<S> entities);
<S extends JpaTargetTag> List<S> save(Iterable<S> entities);
}

View File

@@ -10,6 +10,7 @@ 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;
import org.springframework.transaction.annotation.Transactional;
@@ -19,7 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface TenantConfigurationRepository extends BaseEntityRepository<TenantConfiguration, Long> {
public interface TenantConfigurationRepository extends BaseEntityRepository<JpaTenantConfiguration, Long> {
/**
* Finds a specific {@link TenantConfiguration} by the configuration key.
@@ -28,10 +29,10 @@ public interface TenantConfigurationRepository extends BaseEntityRepository<Tena
* the configuration key to find the configuration for
* @return the found tenant configuration object otherwise {@code null}
*/
TenantConfiguration findByKey(String configurationKey);
JpaTenantConfiguration findByKey(String configurationKey);
@Override
List<TenantConfiguration> findAll();
List<JpaTenantConfiguration> findAll();
/**
* Deletes a tenant configuration by tenant and key.

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
import org.eclipse.hawkbit.repository.model.TenantMetaData;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Isolation;
@@ -20,7 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
*
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
public interface TenantMetaDataRepository extends PagingAndSortingRepository<TenantMetaData, Long> {
public interface TenantMetaDataRepository extends PagingAndSortingRepository<JpaTenantMetaData, Long> {
/**
* Search {@link TenantMetaData} by tenant name.
@@ -42,7 +43,7 @@ public interface TenantMetaDataRepository extends PagingAndSortingRepository<Ten
Long countByTenantIgnoreCase(String tenant);
@Override
List<TenantMetaData> findAll();
List<JpaTenantMetaData> findAll();
/**
* @param tenant

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serializable;
@@ -21,6 +21,10 @@ import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* Relation element between a {@link DistributionSetType} and its
* {@link SoftwareModuleType} elements.
@@ -40,12 +44,12 @@ public class DistributionSetTypeElement implements Serializable {
@MapsId("dsType")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "distribution_set_type", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_dstype"))
private DistributionSetType dsType;
private JpaDistributionSetType dsType;
@MapsId("smType")
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "software_module_type", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_type_element_smtype"))
private SoftwareModuleType smType;
private JpaSoftwareModuleType smType;
public DistributionSetTypeElement() {
// Default constructor for JPA
@@ -62,7 +66,7 @@ public class DistributionSetTypeElement implements Serializable {
* to <code>true</code> if the {@link SoftwareModuleType} if
* mandatory element in the {@link DistributionSet}.
*/
public DistributionSetTypeElement(final DistributionSetType dsType, final SoftwareModuleType smType,
public DistributionSetTypeElement(final JpaDistributionSetType dsType, final JpaSoftwareModuleType smType,
final boolean mandatory) {
super();
key = new DistributionSetTypeElementCompositeKey(dsType, smType);

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serializable;
@@ -40,7 +40,7 @@ public class DistributionSetTypeElementCompositeKey implements Serializable {
* @param smType
* in the key
*/
DistributionSetTypeElementCompositeKey(final DistributionSetType dsType, final SoftwareModuleType smType) {
DistributionSetTypeElementCompositeKey(final JpaDistributionSetType dsType, final JpaSoftwareModuleType smType) {
super();
this.dsType = dsType.getId();
this.smType = smType.getId();

View File

@@ -6,10 +6,12 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
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.

View File

@@ -0,0 +1,274 @@
/**
* 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.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedEntityGraphs;
import javax.persistence.NamedSubgraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.eclipse.hawkbit.cache.CacheField;
import org.eclipse.hawkbit.cache.CacheKeys;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.ActionStatus;
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.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.persistence.annotations.CascadeOnDelete;
/**
* <p>
* Applicable transition changes of the {@link SoftwareModule}s state of a
* {@link Target}, e.g. install, uninstall, update and preparations for the
* transition change, i.e. download.
* </p>
*
* <p>
* Actions are managed by the SP server and applied to the targets by the
* client.
* <p>
*/
@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"),
@Index(name = "sp_idx_action_02", columnList = "tenant,target,active"),
@Index(name = "sp_idx_action_prim", columnList = "tenant,id") })
@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }),
@NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"),
@NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) })
@Entity
public class JpaAction extends JpaTenantAwareBaseEntity implements Action {
private static final long serialVersionUID = 1L;
/**
* the {@link DistributionSet} which should be installed by this action.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds"))
private JpaDistributionSet distributionSet;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target"))
private JpaTarget target;
@Column(name = "active")
private boolean active;
@Column(name = "action_type", nullable = false)
@Enumerated(EnumType.STRING)
private ActionType actionType;
@Column(name = "forced_time")
private long forcedTime;
@Column(name = "status")
private Status status;
@CascadeOnDelete
@OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = {
CascadeType.REMOVE })
private List<ActionStatus> actionStatus;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup"))
private JpaRolloutGroup rolloutGroup;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
private JpaRollout rollout;
/**
* Note: filled only in {@link Status#DOWNLOAD}.
*/
@Transient
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
private int downloadProgressPercent;
/**
* @return the distributionSet
*/
@Override
public DistributionSet getDistributionSet() {
return distributionSet;
}
/**
* @param distributionSet
* the distributionSet to set
*/
@Override
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
/**
* @return true when action is in state {@link Status#CANCELING} or
* {@link Status#CANCELED}, false otherwise
*/
@Override
public boolean isCancelingOrCanceled() {
return status == Status.CANCELING || status == Status.CANCELED;
}
@Override
public void setActive(final boolean active) {
this.active = active;
}
@Override
public Status getStatus() {
return status;
}
@Override
public void setStatus(final Status status) {
this.status = status;
}
@Override
public int getDownloadProgressPercent() {
return downloadProgressPercent;
}
@Override
public void setDownloadProgressPercent(final int downloadProgressPercent) {
this.downloadProgressPercent = downloadProgressPercent;
}
@Override
public boolean isActive() {
return active;
}
@Override
public void setActionType(final ActionType actionType) {
this.actionType = actionType;
}
/**
* @return the actionType
*/
@Override
public ActionType getActionType() {
return actionType;
}
@Override
public List<ActionStatus> getActionStatus() {
return actionStatus;
}
@Override
public void setTarget(final Target target) {
this.target = (JpaTarget) target;
}
@Override
public Target getTarget() {
return target;
}
@Override
public long getForcedTime() {
return forcedTime;
}
@Override
public void setForcedTime(final long forcedTime) {
this.forcedTime = forcedTime;
}
@Override
public RolloutGroup getRolloutGroup() {
return rolloutGroup;
}
@Override
public void setRolloutGroup(final RolloutGroup rolloutGroup) {
this.rolloutGroup = (JpaRolloutGroup) rolloutGroup;
}
@Override
public Rollout getRollout() {
return rollout;
}
@Override
public void setRollout(final Rollout rollout) {
this.rollout = (JpaRollout) rollout;
}
/**
* checks if the {@link #forcedTime} is hit by the given
* {@code hitTimeMillis}, by means if the given milliseconds are greater
* than the forcedTime.
*
* @param hitTimeMillis
* the milliseconds, mostly the
* {@link System#currentTimeMillis()}
* @return {@code true} if this {@link #type} is in
* {@link ActionType#TIMEFORCED} and the given {@code hitTimeMillis}
* is greater than the {@link #forcedTime} otherwise {@code false}
*/
@Override
public boolean isHitAutoForceTime(final long hitTimeMillis) {
if (actionType == ActionType.TIMEFORCED) {
return hitTimeMillis >= forcedTime;
}
return false;
}
/**
* @return {@code true} if either the {@link #type} is
* {@link ActionType#FORCED} or {@link ActionType#TIMEFORCED} but
* then if the {@link #forcedTime} has been exceeded otherwise
* always {@code false}
*/
@Override
public boolean isForce() {
switch (actionType) {
case FORCED:
return true;
case TIMEFORCED:
return isHitAutoForceTime(System.currentTimeMillis());
default:
return false;
}
}
/**
* @return true when action is forced, false otherwise
*/
@Override
public boolean isForced() {
return actionType == ActionType.FORCED;
}
@Override
public String toString() {
return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]";
}
}

View File

@@ -0,0 +1,154 @@
/**
* 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.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.Table;
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.persistence.annotations.CascadeOnDelete;
import com.google.common.base.Splitter;
/**
* Entity to store the status for a specific action.
*/
@Table(name = "sp_action_status", indexes = { @Index(name = "sp_idx_action_status_01", columnList = "tenant,action"),
@Index(name = "sp_idx_action_status_02", columnList = "tenant,action,status"),
@Index(name = "sp_idx_action_status_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "ActionStatus.withMessages", attributeNodes = { @NamedAttributeNode("messages") })
@Entity
public class JpaActionStatus extends JpaTenantAwareBaseEntity implements ActionStatus {
private static final long serialVersionUID = 1L;
@Column(name = "target_occurred_at")
private Long occurredAt;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "action", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_act_stat_action"))
private JpaAction action;
@Column(name = "status")
private Status status;
@CascadeOnDelete
@ElementCollection(fetch = FetchType.LAZY, targetClass = String.class)
@CollectionTable(name = "sp_action_status_messages", joinColumns = @JoinColumn(name = "action_status_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_stat_msg_act_stat")), indexes = {
@Index(name = "sp_idx_action_status_msgs_01", columnList = "action_status_id") })
@Column(name = "detail_message", length = 512)
private final List<String> messages = new ArrayList<>();
/**
* Creates a new {@link ActionStatus} object.
*
* @param action
* the action for this action status
* @param status
* the status for this action status
* @param occurredAt
* the occurred timestamp
*/
public JpaActionStatus(final Action action, final Status status, final Long occurredAt) {
this.action = (JpaAction) action;
this.status = status;
this.occurredAt = occurredAt;
}
/**
* Creates a new {@link ActionStatus} object.
*
* @param action
* the action for this action status
* @param status
* the status for this action status
* @param occurredAt
* the occurred timestamp
* @param messages
* the messages which should be added to this action status
*/
public JpaActionStatus(final JpaAction action, final Status status, final Long occurredAt,
final String... messages) {
this.action = action;
this.status = status;
this.occurredAt = occurredAt;
for (final String msg : messages) {
addMessage(msg);
}
}
/**
* JPA default constructor.
*/
public JpaActionStatus() {
// JPA default constructor.
}
@Override
public Long getOccurredAt() {
return occurredAt;
}
@Override
public void setOccurredAt(final Long occurredAt) {
this.occurredAt = occurredAt;
}
/**
* Adds message including splitting in case it exceeds 512 length.
*
* @param message
* to add
*/
@Override
public final void addMessage(final String message) {
Splitter.fixedLength(512).split(message).forEach(messages::add);
}
@Override
public List<String> getMessages() {
return messages;
}
@Override
public Action getAction() {
return action;
}
@Override
public void setAction(final Action action) {
this.action = (JpaAction) action;
}
@Override
public Status getStatus() {
return status;
}
@Override
public void setStatus(final Status status) {
this.status = status;
}
}

View File

@@ -0,0 +1,63 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* Tenant specific locally stored artifact representation that is used by
* {@link SoftwareModule}.
*/
@MappedSuperclass
public abstract class JpaArtifact extends JpaTenantAwareBaseEntity implements Artifact {
private static final long serialVersionUID = 1L;
@Column(name = "sha1_hash", length = 40, nullable = true)
private String sha1Hash;
@Column(name = "md5_hash", length = 32, nullable = true)
private String md5Hash;
@Column(name = "file_size")
private Long size;
@Override
public abstract SoftwareModule getSoftwareModule();
@Override
public String getMd5Hash() {
return md5Hash;
}
@Override
public String getSha1Hash() {
return sha1Hash;
}
public void setMd5Hash(final String md5Hash) {
this.md5Hash = md5Hash;
}
public void setSha1Hash(final String sha1Hash) {
this.sha1Hash = sha1Hash;
}
@Override
public Long getSize() {
return size;
}
public void setSize(final Long size) {
this.size = size;
}
}

View File

@@ -0,0 +1,184 @@
/**
* 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.model;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener;
import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* Holder of the base attributes common to all entities.
*
*/
@MappedSuperclass
@Access(AccessType.FIELD)
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class })
public abstract class JpaBaseEntity implements BaseEntity {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
private String createdBy;
private String lastModifiedBy;
private Long createdAt;
private Long lastModifiedAt;
@Version
@Column(name = "optlock_revision")
private long optLockRevision;
/**
* Default constructor needed for JPA entities.
*/
public JpaBaseEntity() {
// Default constructor needed for JPA entities.
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "created_at", insertable = true, updatable = false)
public Long getCreatedAt() {
return createdAt;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "created_by", insertable = true, updatable = false, length = 40)
public String getCreatedBy() {
return createdBy;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_at", insertable = false, updatable = true)
public Long getLastModifiedAt() {
return lastModifiedAt;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_by", insertable = false, updatable = true, length = 40)
public String getLastModifiedBy() {
return lastModifiedBy;
}
@CreatedBy
public void setCreatedBy(final String createdBy) {
this.createdBy = createdBy;
}
@LastModifiedBy
public void setLastModifiedBy(final String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
@CreatedDate
public void setCreatedAt(final Long createdAt) {
this.createdAt = createdAt;
}
@LastModifiedDate
public void setLastModifiedAt(final Long lastModifiedAt) {
this.lastModifiedAt = lastModifiedAt;
}
@Override
public long getOptLockRevision() {
return optLockRevision;
}
public void setOptLockRevision(final long optLockRevision) {
this.optLockRevision = optLockRevision;
}
@Override
public Long getId() {
return id;
}
@Override
public String toString() {
return "BaseEntity [id=" + id + "]";
}
public void setId(final Long id) {
this.id = id;
}
/**
* Defined equals/hashcode strategy for the repository in general is that an
* entity is equal if it has the same {@link #getId()} and
* {@link #getOptLockRevision()} and class.
*
* @see java.lang.Object#hashCode()
*/
@Override
// Exception squid:S864 - generated code
@SuppressWarnings({ "squid:S864" })
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (id == null ? 0 : id.hashCode());
result = prime * result + (int) (optLockRevision ^ optLockRevision >>> 32);
result = prime * result + this.getClass().getName().hashCode();
return result;
}
/**
* Defined equals/hashcode strategy for the repository in general is that an
* entity is equal if it has the same {@link #getId()} and
* {@link #getOptLockRevision()} and class.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
// code
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(this.getClass().isInstance(obj))) {
return false;
}
final JpaBaseEntity other = (JpaBaseEntity) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
if (optLockRevision != other.optLockRevision) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,326 @@
/**
* 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.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetIdName;
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.TargetInfo;
import org.eclipse.persistence.annotations.CascadeOnDelete;
/**
* <p>
* The {@link DistributionSet} is defined in the SP repository and contains at
* least an OS and an Agent Hub.
* </p>
*
* <p>
* A {@link Target} has exactly one target {@link DistributionSet} assigned.
* </p>
*
*/
@Entity
@Table(name = "sp_distribution_set", uniqueConstraints = {
@UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = {
@Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"),
@Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"),
@Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"),
@NamedAttributeNode("tags"), @NamedAttributeNode("type") })
public class JpaDistributionSet extends JpaNamedVersionedEntity implements DistributionSet {
private static final long serialVersionUID = 1L;
@Column(name = "required_migration_step")
private boolean requiredMigrationStep = false;
@ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY)
@JoinTable(name = "sp_ds_module", joinColumns = {
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = {
@JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) })
private final Set<SoftwareModule> modules = new HashSet<>();
@ManyToMany(targetEntity = JpaDistributionSetTag.class)
@JoinTable(name = "sp_ds_dstag", joinColumns = {
@JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = {
@JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) })
private Set<DistributionSetTag> tags = new HashSet<>();
@Column(name = "deleted")
private boolean deleted = false;
@OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY)
private List<Target> assignedToTargets;
@OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY)
private List<TargetInfo> installedAtTargets;
@OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY)
private List<Action> actions;
@CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = {
CascadeType.REMOVE })
@JoinColumn(name = "ds_id", insertable = false, updatable = false)
private final List<DistributionSetMetadata> metadata = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class)
@JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
private DistributionSetType type;
@Column(name = "complete")
private boolean complete = false;
/**
* Default constructor.
*/
public JpaDistributionSet() {
super();
}
/**
* 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 Iterable<SoftwareModule> moduleList) {
super(name, version, description);
this.type = type;
if (moduleList != null) {
moduleList.forEach(this::addModule);
}
if (this.type != null) {
complete = this.type.checkComplete(this);
}
}
@Override
public Set<DistributionSetTag> getTags() {
return tags;
}
@Override
public boolean isDeleted() {
return deleted;
}
/**
* @return immutable list of meta data elements.
*/
@Override
public List<DistributionSetMetadata> getMetadata() {
return Collections.unmodifiableList(metadata);
}
@Override
public List<Action> getActions() {
return actions;
}
@Override
public boolean isRequiredMigrationStep() {
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;
}
@Override
public DistributionSet setTags(final Set<DistributionSetTag> tags) {
this.tags = tags;
return this;
}
/**
* @return the assignedTargets
*/
@Override
public List<Target> getAssignedTargets() {
return assignedToTargets;
}
/**
* @return the installedTargets
*/
@Override
public List<TargetInfo> getInstalledTargets() {
return installedAtTargets;
}
@Override
public String toString() {
return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision()
+ ", getId()=" + getId() + "]";
}
/**
*
* @return unmodifiableSet of {@link SoftwareModule}.
*/
@Override
public Set<SoftwareModule> getModules() {
return Collections.unmodifiableSet(modules);
}
@Override
public DistributionSetIdName getDistributionSetIdName() {
return new DistributionSetIdName(getId(), getName(), getVersion());
}
/**
* @param softwareModule
* @return <code>true</code> if the module was added and <code>false</code>
* if it already existed in the set
*
*/
@Override
public boolean addModule(final SoftwareModule softwareModule) {
// we cannot allow that modules are added without a type defined
if (type == null) {
throw new DistributionSetTypeUndefinedException();
}
// check if it is allowed to such a module to this DS type
if (!type.containsModuleType(softwareModule.getType())) {
throw new UnsupportedSoftwareModuleForThisDistributionSetException();
}
final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
if (found.isPresent()) {
return false;
}
final long allready = modules.stream()
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
if (allready >= softwareModule.getType().getMaxAssignments()) {
final Optional<SoftwareModule> sameKey = modules.stream()
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst();
modules.remove(sameKey.get());
}
if (modules.add(softwareModule)) {
complete = type.checkComplete(this);
return true;
}
return false;
}
/**
* Removed given {@link SoftwareModule} from this DS instance.
*
* @param softwareModule
* to remove
* @return <code>true</code> if element was found and removed
*/
@Override
public boolean removeModule(final SoftwareModule softwareModule) {
final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
if (found.isPresent()) {
modules.remove(found.get());
complete = type.checkComplete(this);
return true;
}
return false;
}
/**
* Searches through modules for the given type.
*
* @param type
* to search for
* @return SoftwareModule of given type or <code>null</code> if not in the
* list.
*/
@Override
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type))
.findFirst();
if (result.isPresent()) {
return result.get();
}
return null;
}
@Override
public DistributionSetType getType() {
return type;
}
@Override
public void setType(final DistributionSetType type) {
this.type = type;
}
@Override
public boolean isComplete() {
return complete;
}
}

View File

@@ -0,0 +1,85 @@
/**
* 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.model;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
/**
* Meta data for {@link DistributionSet}.
*
*/
@IdClass(DsMetadataCompositeKey.class)
@Entity
@Table(name = "sp_ds_metadata")
public class JpaDistributionSetMetadata extends JpaMetaData implements DistributionSetMetadata {
private static final long serialVersionUID = 1L;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds"))
private JpaDistributionSet distributionSet;
public JpaDistributionSetMetadata() {
// default public constructor for JPA
}
public JpaDistributionSetMetadata(final String key, final DistributionSet distributionSet, final String value) {
super(key, value);
this.distributionSet = (JpaDistributionSet) distributionSet;
}
public DsMetadataCompositeKey getId() {
return new DsMetadataCompositeKey(distributionSet, getKey());
}
@Override
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
@Override
public DistributionSet getDistributionSet() {
return distributionSet;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((distributionSet == null) ? 0 : distributionSet.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
final JpaDistributionSetMetadata other = (JpaDistributionSetMetadata) obj;
if (distributionSet == null) {
if (other.distributionSet != null) {
return false;
}
} else if (!distributionSet.equals(other.distributionSet)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,90 @@
/**
* 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.model;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Index;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* A {@link DistributionSetTag} is used to describe DistributionSet attributes
* and use them also for filtering the DistributionSet list.
*
*/
@Entity
@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 JpaTag implements DistributionSetTag {
private static final long serialVersionUID = 1L;
@ManyToMany(mappedBy = "tags", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY)
private List<DistributionSet> assignedToDistributionSet;
/**
* Public constructor.
*
* @param name
* of the {@link DistributionSetTag}
**/
public JpaDistributionSetTag(final String name) {
super(name, null, null);
}
/**
* Public constructor.
*
* @param name
* of the {@link DistributionSetTag}
* @param description
* of the {@link DistributionSetTag}
* @param colour
* of tag in UI
*/
public JpaDistributionSetTag(final String name, final String description, final String colour) {
super(name, description, colour);
}
public JpaDistributionSetTag() {
super();
}
@Override
public List<DistributionSet> getAssignedToDistributionSet() {
return assignedToDistributionSet;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof DistributionSetTag)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,310 @@
/**
* 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.model;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* A distribution set type defines which software module types can or have to be
* {@link DistributionSet}.
*
*/
@Entity
@Table(name = "sp_distribution_set_type", indexes = {
@Index(name = "sp_idx_distribution_set_type_01", columnList = "tenant,deleted"),
@Index(name = "sp_idx_distribution_set_type_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_dst_name"),
@UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_dst_key") })
public class JpaDistributionSetType extends JpaNamedEntity implements DistributionSetType {
private static final long serialVersionUID = 1L;
@OneToMany(targetEntity = DistributionSetTypeElement.class, cascade = {
CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "distribution_set_type", insertable = false, updatable = false)
private final Set<DistributionSetTypeElement> elements = new HashSet<>();
@Column(name = "type_key", nullable = false, length = 64)
private String key;
@Column(name = "colour", nullable = true, length = 16)
private String colour;
@Column(name = "deleted")
private boolean deleted = false;
public JpaDistributionSetType() {
// default public constructor for JPA
}
/**
* Standard constructor.
*
* @param key
* of the type (unique)
* @param name
* of the type (unique)
* @param description
* of the type
*/
public JpaDistributionSetType(final String key, final String name, final String description) {
this(key, name, description, null);
}
/**
* Constructor.
*
* @param key
* of the type
* @param name
* of the type
* @param description
* of the type
* @param color
* of the type. It will be null by default
*/
public JpaDistributionSetType(final String key, final String name, final String description, final String color) {
super(name, description);
this.key = key;
colour = color;
}
/**
* @return the deleted
*/
@Override
public boolean isDeleted() {
return deleted;
}
/**
* @param deleted
* the deleted to set
*/
@Override
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
@Override
public Set<SoftwareModuleType> getMandatoryModuleTypes() {
return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet());
}
@Override
public Set<SoftwareModuleType> getOptionalModuleTypes() {
return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet());
}
/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType}.
*
* @param softwareModuleType
* search for
* @return <code>true</code> if found
*/
@Override
public boolean containsModuleType(final SoftwareModuleType softwareModuleType) {
for (final DistributionSetTypeElement distributionSetTypeElement : elements) {
if (distributionSetTypeElement.getSmType().equals(softwareModuleType)) {
return true;
}
}
return false;
}
/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType} and defined as
* {@link DistributionSetTypeElement#isMandatory()}.
*
* @param softwareModuleType
* search for
* @return <code>true</code> if found
*/
@Override
public boolean containsMandatoryModuleType(final SoftwareModuleType softwareModuleType) {
return elements.stream().filter(element -> element.isMandatory())
.filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent();
}
/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType} and defined as
* {@link DistributionSetTypeElement#isMandatory()}.
*
* @param softwareModuleType
* search for by {@link SoftwareModuleType#getId()}
* @return <code>true</code> if found
*/
@Override
public boolean containsMandatoryModuleType(final Long softwareModuleTypeId) {
return elements.stream().filter(element -> element.isMandatory())
.filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent();
}
/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType} and NOT defined as
* {@link DistributionSetTypeElement#isMandatory()}.
*
* @param softwareModuleType
* search for
* @return <code>true</code> if found
*/
@Override
public boolean containsOptionalModuleType(final SoftwareModuleType softwareModuleType) {
return elements.stream().filter(element -> !element.isMandatory())
.filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent();
}
/**
* Checks if the given {@link SoftwareModuleType} is in this
* {@link DistributionSetType} and NOT defined as
* {@link DistributionSetTypeElement#isMandatory()}.
*
* @param softwareModuleTypeId
* search by {@link SoftwareModuleType#getId()}
* @return <code>true</code> if found
*/
@Override
public boolean containsOptionalModuleType(final Long softwareModuleTypeId) {
return elements.stream().filter(element -> !element.isMandatory())
.filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent();
}
/**
* Compares the modules of this {@link DistributionSetType} and the given
* one.
*
* @param dsType
* to compare with
* @return <code>true</code> if the lists are identical.
*/
@Override
public boolean areModuleEntriesIdentical(final DistributionSetType dsType) {
return new HashSet<DistributionSetTypeElement>(((JpaDistributionSetType) dsType).elements).equals(elements);
}
/**
* Adds {@link SoftwareModuleType} that is optional for the
* {@link DistributionSet}.
*
* @param smType
* to add
* @return updated instance
*/
@Override
public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) {
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, false));
return this;
}
/**
* Adds {@link SoftwareModuleType} that is mandatory for the
* {@link DistributionSet}.
*
* @param smType
* to add
* @return updated instance
*/
@Override
public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) {
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, true));
return this;
}
/**
* Removes {@link SoftwareModuleType} from the list.
*
* @param smTypeId
* to remove
* @return updated instance
*/
@Override
public DistributionSetType removeModuleType(final Long smTypeId) {
// 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());
}
return this;
}
@Override
public String getKey() {
return key;
}
@Override
public void setKey(final String key) {
this.key = key;
}
/**
* @param distributionSet
* to check for completeness
* @return <code>true</code> if the all mandatory software module types are
* in the system.
*/
@Override
public boolean checkComplete(final DistributionSet distributionSet) {
return distributionSet.getModules().stream().map(module -> module.getType()).collect(Collectors.toList())
.containsAll(getMandatoryModuleTypes());
}
@Override
public String getColour() {
return colour;
}
@Override
public void setColour(final String colour) {
this.colour = colour;
}
public Set<DistributionSetTypeElement> getElements() {
return elements;
}
@Override
public String toString() {
return "DistributionSetType [key=" + key + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]";
}
}

View File

@@ -0,0 +1,142 @@
/**
* 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.model;
import java.net.URL;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.model.ExternalArtifact;
import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* External artifact representation with all the necessary information to
* generate an artifact {@link URL} at runtime.
*
*/
@Table(name = "sp_external_artifact", indexes = {
@Index(name = "sp_idx_external_artifact_prim", columnList = "id,tenant") })
@Entity
public class JpaExternalArtifact extends JpaArtifact implements ExternalArtifact {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "provider", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_art_to_ext_provider"))
private JpaExternalArtifactProvider externalArtifactProvider;
@Column(name = "url_suffix", length = 512)
private String urlSuffix;
// CascadeType.PERSIST as we register ourself at the BSM
@ManyToOne(optional = false, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_external_assigned_sm"))
private JpaSoftwareModule softwareModule;
/**
* Default constructor.
*/
public JpaExternalArtifact() {
super();
}
/**
* Constructs {@link ExternalArtifact}.
*
* @param externalArtifactProvider
* of the artifact
* @param urlSuffix
* of the artifact
* @param softwareModule
* of the artifact
*/
public JpaExternalArtifact(@NotNull final ExternalArtifactProvider externalArtifactProvider, final String urlSuffix,
final SoftwareModule softwareModule) {
setSoftwareModule(softwareModule);
this.externalArtifactProvider = (JpaExternalArtifactProvider) externalArtifactProvider;
if (urlSuffix != null) {
this.urlSuffix = urlSuffix;
} else {
this.urlSuffix = externalArtifactProvider.getDefaultSuffix();
}
}
/**
* @return the softwareModule
*/
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
@Override
public final void setSoftwareModule(final SoftwareModule softwareModule) {
this.softwareModule = (JpaSoftwareModule) softwareModule;
this.softwareModule.addArtifact(this);
}
@Override
public ExternalArtifactProvider getExternalArtifactProvider() {
return externalArtifactProvider;
}
@Override
public String getUrl() {
return new StringBuilder().append(externalArtifactProvider.getBasePath()).append(urlSuffix).toString();
}
@Override
public String getUrlSuffix() {
return urlSuffix;
}
@Override
public void setExternalArtifactProvider(final ExternalArtifactProvider externalArtifactProvider) {
this.externalArtifactProvider = (JpaExternalArtifactProvider) externalArtifactProvider;
}
/**
* @param urlSuffix
* the urlSuffix to set
*/
@Override
public void setUrlSuffix(final String urlSuffix) {
this.urlSuffix = urlSuffix;
}
@Override
public int hashCode() { // NOSONAR - as this is generated
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof JpaExternalArtifact)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,83 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
import org.eclipse.hawkbit.repository.model.ExternalArtifact;
import org.eclipse.hawkbit.repository.model.ExternalArtifactProvider;
/**
* External repositories for artifact storage. The SP server provides URLs for
* the targets to download from these external resources but does not access
* them itself.
*
*/
@Table(name = "sp_external_provider", indexes = {
@Index(name = "sp_idx_external_provider_prim", columnList = "tenant,id") })
@Entity
public class JpaExternalArtifactProvider extends JpaNamedEntity implements ExternalArtifactProvider {
private static final long serialVersionUID = 1L;
@Column(name = "base_url", length = 512, nullable = false)
private String basePath;
@Column(name = "default_url_suffix", length = 512, nullable = true)
private String defaultSuffix;
/**
* Constructs {@link ExternalArtifactProvider} based on given properties.
*
* @param name
* of the provided
* @param description
* which is optional
* @param baseURL
* of all {@link ExternalArtifact}s of the provider
* @param defaultUrlSuffix
* that is used if {@link ExternalArtifact#getUrlSuffix()} is
* empty.
*/
public JpaExternalArtifactProvider(final String name, final String description, final String baseURL,
final String defaultUrlSuffix) {
super(name, description);
basePath = baseURL;
defaultSuffix = defaultUrlSuffix;
}
JpaExternalArtifactProvider() {
super();
defaultSuffix = "";
basePath = "";
}
@Override
public String getBasePath() {
return basePath;
}
@Override
public String getDefaultSuffix() {
return defaultSuffix;
}
@Override
public void setBasePath(final String basePath) {
this.basePath = basePath;
}
@Override
public void setDefaultSuffix(final String defaultSuffix) {
this.defaultSuffix = defaultSuffix;
}
}

View File

@@ -0,0 +1,118 @@
/**
* 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.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSFile;
/**
* Tenant specific locally stored artifact representation that is used by
* {@link SoftwareModule} . It contains all information that is provided by the
* user while all SP server generated information related to the artifact (hash,
* length) is stored directly with the binary itself.
*
*
*
*/
@Table(name = "sp_artifact", indexes = { @Index(name = "sp_idx_artifact_01", columnList = "tenant,software_module"),
@Index(name = "sp_idx_artifact_prim", columnList = "tenant,id") })
@Entity
public class JpaLocalArtifact extends JpaArtifact implements LocalArtifact {
private static final long serialVersionUID = 1L;
@NotNull
@Column(name = "gridfs_file_name", length = 40)
private String gridFsFileName;
@NotNull
@Column(name = "provided_file_name", length = 256)
private String filename;
@ManyToOne(optional = false, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_assigned_sm"))
private JpaSoftwareModule softwareModule;
/**
* Default constructor.
*/
public JpaLocalArtifact() {
super();
}
/**
* Constructs artifact.
*
* @param gridFsFileName
* that is the link to the {@link GridFS} entity.
* @param filename
* that is used by {@link GridFSFile} store.
* @param softwareModule
* of this artifact
*/
public JpaLocalArtifact(@NotNull final String gridFsFileName, @NotNull final String filename,
final SoftwareModule softwareModule) {
setSoftwareModule(softwareModule);
this.gridFsFileName = gridFsFileName;
this.filename = filename;
}
@Override
public int hashCode() { // NOSONAR - as this is generated
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof LocalArtifact)) {
return false;
}
return true;
}
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
@Override
public final void setSoftwareModule(final SoftwareModule softwareModule) {
this.softwareModule = (JpaSoftwareModule) softwareModule;
this.softwareModule.addArtifact(this);
}
public String getGridFsFileName() {
return gridFsFileName;
}
@Override
public String getFilename() {
return filename;
}
}

View File

@@ -0,0 +1,102 @@
/**
* 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.model;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import org.eclipse.hawkbit.repository.model.MetaData;
/**
* Meta data for entities.
*
*/
@MappedSuperclass
public abstract class JpaMetaData implements MetaData {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "meta_key", length = 128)
private String key;
@Column(name = "meta_value", length = 4000)
@Basic
private String value;
public JpaMetaData(final String key, final String value) {
super();
this.key = key;
this.value = value;
}
public JpaMetaData() {
// Default constructor needed for JPA entities
}
@Override
public String getKey() {
return key;
}
@Override
public void setKey(final String key) {
this.key = key;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(this.getClass().isInstance(obj))) {
return false;
}
final JpaMetaData other = (JpaMetaData) obj;
if (key == null) {
if (other.key != null) {
return false;
}
} else if (!key.equals(other.key)) {
return false;
}
if (value == null) {
if (other.value != null) {
return false;
}
} else if (!value.equals(other.value)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,70 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/**
* {@link TenantAwareBaseEntity} extension for all entities that are named in
* addition to their technical ID.
*/
@MappedSuperclass
public abstract class JpaNamedEntity extends JpaTenantAwareBaseEntity implements NamedEntity {
private static final long serialVersionUID = 1L;
@Column(name = "name", nullable = false, length = 64)
private String name;
@Column(name = "description", nullable = true, length = 512)
private String description;
/**
* Default constructor.
*/
public JpaNamedEntity() {
super();
}
/**
* Parameterized constructor.
*
* @param name
* of the {@link NamedEntity}
* @param description
* of the {@link NamedEntity}
*/
public JpaNamedEntity(final String name, final String description) {
this.name = name;
this.description = description;
}
@Override
public String getDescription() {
return description;
}
@Override
public String getName() {
return name;
}
@Override
public void setDescription(final String description) {
this.description = description;
}
@Override
public void setName(final String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,55 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
/**
* Extension for {@link NamedEntity} that are versioned.
*
*/
@MappedSuperclass
public abstract class JpaNamedVersionedEntity extends JpaNamedEntity implements NamedVersionedEntity {
private static final long serialVersionUID = 1L;
@Column(name = "version", nullable = false, length = 64)
private String version;
/**
* parameterized constructor.
*
* @param name
* of the entity
* @param version
* of the entity
* @param description
*/
public JpaNamedVersionedEntity(final String name, final String version, final String description) {
super(name, description);
this.version = version;
}
JpaNamedVersionedEntity() {
super();
}
@Override
public String getVersion() {
return version;
}
@Override
public void setVersion(final String version) {
this.version = version;
}
}

View File

@@ -0,0 +1,260 @@
/**
* 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.model;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.cache.CacheField;
import org.eclipse.hawkbit.cache.CacheKeys;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
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;
/**
* @author Michael Hirsch
*
*/
@Entity
@Table(name = "sp_rollout", indexes = {
@Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"name", "tenant" }, name = "uk_rollout"))
public class JpaRollout extends JpaNamedEntity implements Rollout {
private static final long serialVersionUID = 1L;
@OneToMany(targetEntity = JpaRolloutGroup.class)
@JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup"))
private List<RolloutGroup> rolloutGroups;
@Column(name = "target_filter", length = 1024, nullable = false)
private String targetFilterQuery;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds"))
private JpaDistributionSet distributionSet;
@Column(name = "status")
private RolloutStatus status = RolloutStatus.CREATING;
@Column(name = "last_check")
private long lastCheck = 0L;
@Column(name = "action_type", nullable = false)
@Enumerated(EnumType.STRING)
private ActionType actionType = ActionType.FORCED;
@Column(name = "forced_time")
private long forcedTime;
@Column(name = "total_targets")
private long totalTargets;
@Transient
@CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL)
private int rolloutGroupsTotal = 0;
@Transient
@CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED)
private int rolloutGroupsCreated = 0;
@Transient
private transient TotalTargetCountStatus totalTargetCountStatus;
@Override
public DistributionSet getDistributionSet() {
return distributionSet;
}
@Override
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = (JpaDistributionSet) distributionSet;
}
@Override
public List<RolloutGroup> getRolloutGroups() {
return rolloutGroups;
}
@Override
public void setRolloutGroups(final List<RolloutGroup> rolloutGroups) {
this.rolloutGroups = rolloutGroups;
}
@Override
public String getTargetFilterQuery() {
return targetFilterQuery;
}
@Override
public void setTargetFilterQuery(final String targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
}
@Override
public RolloutStatus getStatus() {
return status;
}
@Override
public void setStatus(final RolloutStatus status) {
this.status = status;
}
@Override
public long getLastCheck() {
return lastCheck;
}
@Override
public void setLastCheck(final long lastCheck) {
this.lastCheck = lastCheck;
}
@Override
public ActionType getActionType() {
return actionType;
}
@Override
public void setActionType(final ActionType actionType) {
this.actionType = actionType;
}
@Override
public long getForcedTime() {
return forcedTime;
}
@Override
public void setForcedTime(final long forcedTime) {
this.forcedTime = forcedTime;
}
@Override
public long getTotalTargets() {
return totalTargets;
}
@Override
public void setTotalTargets(final long totalTargets) {
this.totalTargets = totalTargets;
}
@Override
public int getRolloutGroupsTotal() {
return rolloutGroupsTotal;
}
@Override
public void setRolloutGroupsTotal(final int rolloutGroupsTotal) {
this.rolloutGroupsTotal = rolloutGroupsTotal;
}
@Override
public int getRolloutGroupsCreated() {
return rolloutGroupsCreated;
}
@Override
public void setRolloutGroupsCreated(final int rolloutGroupsCreated) {
this.rolloutGroupsCreated = rolloutGroupsCreated;
}
@Override
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
}
return totalTargetCountStatus;
}
@Override
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
this.totalTargetCountStatus = totalTargetCountStatus;
}
@Override
public String toString() {
return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery
+ ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck
+ ", getName()=" + getName() + ", getId()=" + getId() + "]";
}
/**
*
* State machine for rollout.
*
*/
public enum RolloutStatus {
/**
* Rollouts is beeing created.
*/
CREATING,
/**
* Rollout is ready to start.
*/
READY,
/**
* Rollout is paused.
*/
PAUSED,
/**
* Rollout is starting.
*/
STARTING,
/**
* Rollout is stopped.
*/
STOPPED,
/**
* Rollout is running.
*/
RUNNING,
/**
* Rollout is finished.
*/
FINISHED,
/**
* Rollout could not created due errors, might be database problem due
* asynchronous creating.
*/
ERROR_CREATING,
/**
* Rollout could not started due errors, might be database problem due
* asynchronous starting.
*/
ERROR_STARTING;
}
}

View File

@@ -0,0 +1,509 @@
/**
* 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.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
/**
* JPA entity definition of persisting a group of an rollout.
*
* @author Michael Hirsch
*
*/
@Entity
@Table(name = "sp_rolloutgroup", indexes = {
@Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"name", "rollout", "tenant" }, name = "uk_rolloutgroup"))
public class JpaRolloutGroup extends JpaNamedEntity implements RolloutGroup {
private static final long serialVersionUID = 1L;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout"))
private JpaRollout rollout;
@Column(name = "status")
private RolloutGroupStatus status = RolloutGroupStatus.READY;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class)
@JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false)
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
private JpaRolloutGroup parent;
@Column(name = "success_condition", nullable = false)
private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD;
@Column(name = "success_condition_exp", length = 512, nullable = false)
private String successConditionExp = null;
@Column(name = "success_action", nullable = false)
private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP;
@Column(name = "success_action_exp", length = 512, nullable = false)
private String successActionExp = null;
@Column(name = "error_condition")
private RolloutGroupErrorCondition errorCondition = null;
@Column(name = "error_condition_exp", length = 512)
private String errorConditionExp = null;
@Column(name = "error_action")
private RolloutGroupErrorAction errorAction = null;
@Column(name = "error_action_exp", length = 512)
private String errorActionExp = null;
@Column(name = "total_targets")
private long totalTargets;
@Transient
private transient TotalTargetCountStatus totalTargetCountStatus;
@Override
public Rollout getRollout() {
return rollout;
}
@Override
public void setRollout(final Rollout rollout) {
this.rollout = (JpaRollout) rollout;
}
@Override
public RolloutGroupStatus getStatus() {
return status;
}
@Override
public void setStatus(final RolloutGroupStatus status) {
this.status = status;
}
public List<RolloutTargetGroup> getRolloutTargetGroup() {
return rolloutTargetGroup;
}
@Override
public RolloutGroup getParent() {
return parent;
}
@Override
public void setParent(final RolloutGroup parent) {
this.parent = (JpaRolloutGroup) parent;
}
@Override
public RolloutGroupSuccessCondition getSuccessCondition() {
return successCondition;
}
@Override
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
successCondition = finishCondition;
}
@Override
public String getSuccessConditionExp() {
return successConditionExp;
}
@Override
public void setSuccessConditionExp(final String finishExp) {
successConditionExp = finishExp;
}
@Override
public RolloutGroupErrorCondition getErrorCondition() {
return errorCondition;
}
@Override
public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) {
this.errorCondition = errorCondition;
}
@Override
public String getErrorConditionExp() {
return errorConditionExp;
}
@Override
public void setErrorConditionExp(final String errorExp) {
errorConditionExp = errorExp;
}
@Override
public RolloutGroupErrorAction getErrorAction() {
return errorAction;
}
@Override
public void setErrorAction(final RolloutGroupErrorAction errorAction) {
this.errorAction = errorAction;
}
@Override
public String getErrorActionExp() {
return errorActionExp;
}
@Override
public void setErrorActionExp(final String errorActionExp) {
this.errorActionExp = errorActionExp;
}
@Override
public RolloutGroupSuccessAction getSuccessAction() {
return successAction;
}
@Override
public String getSuccessActionExp() {
return successActionExp;
}
@Override
public long getTotalTargets() {
return totalTargets;
}
@Override
public void setTotalTargets(final long totalTargets) {
this.totalTargets = totalTargets;
}
@Override
public void setSuccessAction(final RolloutGroupSuccessAction successAction) {
this.successAction = successAction;
}
@Override
public void setSuccessActionExp(final String successActionExp) {
this.successActionExp = successActionExp;
}
/**
* @return the totalTargetCountStatus
*/
@Override
public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) {
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets);
}
return totalTargetCountStatus;
}
/**
* @param totalTargetCountStatus
* the totalTargetCountStatus to set
*/
@Override
public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) {
this.totalTargetCountStatus = totalTargetCountStatus;
}
@Override
public String toString() {
return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup
+ ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp
+ ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName()
+ ", getId()=" + getId() + "]";
}
/**
* Rollout goup state machine.
*
*/
public enum RolloutGroupStatus {
/**
* Ready to start the group.
*/
READY,
/**
* Group is scheduled and started sometime, e.g. trigger of group
* before.
*/
SCHEDULED,
/**
* Group is finished.
*/
FINISHED,
/**
* Group is finished and has errors.
*/
ERROR,
/**
* Group is running.
*/
RUNNING;
}
/**
* The condition to evaluate if an group is success state.
*/
public enum RolloutGroupSuccessCondition {
THRESHOLD("thresholdRolloutGroupSuccessCondition");
private final String beanName;
private RolloutGroupSuccessCondition(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
}
/**
* The condition to evaluate if an group is in error state.
*/
public enum RolloutGroupErrorCondition {
THRESHOLD("thresholdRolloutGroupErrorCondition");
private final String beanName;
private RolloutGroupErrorCondition(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
}
/**
* The actions executed when the {@link RolloutGroup#errorCondition} is hit.
*/
public enum RolloutGroupErrorAction {
PAUSE("pauseRolloutGroupAction");
private final String beanName;
private RolloutGroupErrorAction(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
}
/**
* The actions executed when the {@link RolloutGroup#successCondition} is
* hit.
*/
public enum RolloutGroupSuccessAction {
NEXTGROUP("startNextRolloutGroupAction");
private final String beanName;
private RolloutGroupSuccessAction(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
}
/**
* Object which holds all {@link RolloutGroup} conditions together which can
* easily built.
*/
public static class RolloutGroupConditions {
private RolloutGroupSuccessCondition successCondition = null;
private String successConditionExp = null;
private RolloutGroupSuccessAction successAction = null;
private String successActionExp = null;
private RolloutGroupErrorCondition errorCondition = null;
private String errorConditionExp = null;
private RolloutGroupErrorAction errorAction = null;
private String errorActionExp = null;
public RolloutGroupSuccessCondition getSuccessCondition() {
return successCondition;
}
public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) {
successCondition = finishCondition;
}
public String getSuccessConditionExp() {
return successConditionExp;
}
public void setSuccessConditionExp(final String finishConditionExp) {
successConditionExp = finishConditionExp;
}
public RolloutGroupSuccessAction getSuccessAction() {
return successAction;
}
public void setSuccessAction(final RolloutGroupSuccessAction successAction) {
this.successAction = successAction;
}
public String getSuccessActionExp() {
return successActionExp;
}
public void setSuccessActionExp(final String successActionExp) {
this.successActionExp = successActionExp;
}
public RolloutGroupErrorCondition getErrorCondition() {
return errorCondition;
}
public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) {
this.errorCondition = errorCondition;
}
public String getErrorConditionExp() {
return errorConditionExp;
}
public void setErrorConditionExp(final String errorConditionExp) {
this.errorConditionExp = errorConditionExp;
}
public RolloutGroupErrorAction getErrorAction() {
return errorAction;
}
public void setErrorAction(final RolloutGroupErrorAction errorAction) {
this.errorAction = errorAction;
}
public String getErrorActionExp() {
return errorActionExp;
}
public void setErrorActionExp(final String errorActionExp) {
this.errorActionExp = errorActionExp;
}
}
/**
* Builder to build easily the {@link RolloutGroupConditions}.
*
*/
public static class RolloutGroupConditionBuilder {
private final RolloutGroupConditions conditions = new RolloutGroupConditions();
public RolloutGroupConditions build() {
return conditions;
}
/**
* Sets the finish condition and expression on the builder.
*
* @param condition
* the finish condition
* @param expression
* the finish expression
* @return the builder itself
*/
public RolloutGroupConditionBuilder successCondition(final RolloutGroupSuccessCondition condition,
final String expression) {
conditions.setSuccessCondition(condition);
conditions.setSuccessConditionExp(expression);
return this;
}
/**
* Sets the success action and expression on the builder.
*
* @param action
* the success action
* @param expression
* the error expression
* @return the builder itself
*/
public RolloutGroupConditionBuilder successAction(final RolloutGroupSuccessAction action,
final String expression) {
conditions.setSuccessAction(action);
conditions.setSuccessActionExp(expression);
return this;
}
/**
* Sets the error condition and expression on the builder.
*
* @param condition
* the error condition
* @param expression
* the error expression
* @return the builder itself
*/
public RolloutGroupConditionBuilder errorCondition(final RolloutGroupErrorCondition condition,
final String expression) {
conditions.setErrorCondition(condition);
conditions.setErrorConditionExp(expression);
return this;
}
/**
* Sets the error action and expression on the builder.
*
* @param action
* the error action
* @param expression
* the error expression
* @return the builder itself
*/
public RolloutGroupConditionBuilder errorAction(final RolloutGroupErrorAction action, final String expression) {
conditions.setErrorAction(action);
conditions.setErrorActionExp(expression);
return this;
}
}
}

View File

@@ -0,0 +1,266 @@
/**
* 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.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.ExternalArtifact;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.persistence.annotations.CascadeOnDelete;
/**
* Base Software Module that is supported by OS level provisioning mechanism on
* the edge controller, e.g. OS, JVM, AgentHub.
*
*/
@Entity
@Table(name = "sp_base_software_module", uniqueConstraints = @UniqueConstraint(columnNames = { "module_type", "name",
"version", "tenant" }, name = "uk_base_sw_mod"), indexes = {
@Index(name = "sp_idx_base_sw_module_01", columnList = "tenant,deleted,name,version"),
@Index(name = "sp_idx_base_sw_module_02", columnList = "tenant,deleted,module_type"),
@Index(name = "sp_idx_base_sw_module_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "SoftwareModule.artifacts", attributeNodes = { @NamedAttributeNode("artifacts") })
public class JpaSoftwareModule extends JpaNamedVersionedEntity implements SoftwareModule {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "module_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_module_type"))
private JpaSoftwareModuleType type;
@ManyToMany(mappedBy = "modules", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY)
private final List<DistributionSet> assignedTo = new ArrayList<>();
@Column(name = "deleted")
private boolean deleted = false;
@Column(name = "vendor", nullable = true, length = 256)
private String vendor;
@OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = JpaLocalArtifact.class)
private List<LocalArtifact> artifacts;
@OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = JpaExternalArtifact.class)
private List<ExternalArtifact> externalArtifacts;
@CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, targetEntity = JpaSoftwareModuleMetadata.class)
@JoinColumn(name = "sw_id", insertable = false, updatable = false)
private final List<SoftwareModuleMetadata> metadata = new ArrayList<>();
/**
* Default constructor.
*/
public JpaSoftwareModule() {
super();
}
/**
* parameterized constructor.
*
* @param type
* of the {@link SoftwareModule}
* @param name
* abstract name of the {@link SoftwareModule}
* @param version
* of the {@link SoftwareModule}
* @param description
* of the {@link SoftwareModule}
* @param vendor
* of the {@link SoftwareModule}
*/
public JpaSoftwareModule(final SoftwareModuleType type, final String name, final String version,
final String description, final String vendor) {
super(name, version, description);
this.vendor = vendor;
this.type = (JpaSoftwareModuleType) type;
}
/**
* @param artifact
* is added to the assigned {@link Artifact}s.
*/
@Override
public void addArtifact(final LocalArtifact artifact) {
if (null == artifacts) {
artifacts = new ArrayList<>(4);
}
if (!artifacts.contains(artifact)) {
artifacts.add(artifact);
}
}
/**
* @param artifact
* is added to the assigned {@link Artifact}s.
*/
@Override
public void addArtifact(final ExternalArtifact artifact) {
if (null == externalArtifacts) {
externalArtifacts = new ArrayList<>(4);
}
if (!externalArtifacts.contains(artifact)) {
externalArtifacts.add(artifact);
}
}
/**
* @param artifactId
* to look for
* @return found {@link Artifact}
*/
@Override
public Optional<LocalArtifact> getLocalArtifact(final Long artifactId) {
if (null == artifacts) {
return Optional.empty();
}
return artifacts.stream().filter(artifact -> artifact.getId().equals(artifactId)).findFirst();
}
/**
* @param fileName
* to look for
* @return found {@link Artifact}
*/
@Override
public Optional<LocalArtifact> getLocalArtifactByFilename(final String fileName) {
if (null == artifacts) {
return Optional.empty();
}
return artifacts.stream().filter(artifact -> artifact.getFilename().equalsIgnoreCase(fileName.trim()))
.findFirst();
}
/**
* @return the artifacts
*/
@Override
public List<Artifact> getArtifacts() {
final List<Artifact> result = new ArrayList<>();
result.addAll(artifacts);
result.addAll(externalArtifacts);
return result;
}
/**
* @return local artifacts only
*/
@Override
public List<LocalArtifact> getLocalArtifacts() {
if (artifacts == null) {
return Collections.emptyList();
}
return artifacts;
}
@Override
public String getVendor() {
return vendor;
}
/**
* @param artifact
* is removed from the assigned {@link LocalArtifact}s.
*/
@Override
public void removeArtifact(final LocalArtifact artifact) {
if (null != artifacts) {
artifacts.remove(artifact);
}
}
/**
* @param artifact
* is removed from the assigned {@link ExternalArtifact}s.
*/
@Override
public void removeArtifact(final ExternalArtifact artifact) {
if (null != externalArtifacts) {
externalArtifacts.remove(artifact);
}
}
@Override
public void setVendor(final String vendor) {
this.vendor = vendor;
}
@Override
public SoftwareModuleType getType() {
return type;
}
@Override
public boolean isDeleted() {
return deleted;
}
@Override
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
@Override
public void setType(final SoftwareModuleType type) {
this.type = (JpaSoftwareModuleType) type;
}
/**
* @return immutable list of meta data elements.
*/
@Override
public List<SoftwareModuleMetadata> getMetadata() {
return Collections.unmodifiableList(metadata);
}
@Override
public String toString() {
return "SoftwareModule [deleted=" + deleted + ", name=" + getName() + ", version=" + getVersion()
+ ", revision=" + getOptLockRevision() + ", Id=" + getId() + ", type=" + getType().getName() + "]";
}
/**
* @return the assignedTo
*/
@Override
public List<DistributionSet> getAssignedTo() {
return assignedTo;
}
}

View File

@@ -0,0 +1,85 @@
/**
* 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.model;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
/**
* Metadata for {@link SoftwareModule}.
*
*/
@IdClass(SwMetadataCompositeKey.class)
@Entity
@Table(name = "sp_sw_metadata")
public class JpaSoftwareModuleMetadata extends JpaMetaData implements SoftwareModuleMetadata {
private static final long serialVersionUID = 1L;
@Id
@ManyToOne(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY)
@JoinColumn(name = "sw_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_sw"))
private SoftwareModule softwareModule;
public JpaSoftwareModuleMetadata() {
// default public constructor for JPA
}
public JpaSoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) {
super(key, value);
this.softwareModule = softwareModule;
}
public SwMetadataCompositeKey getId() {
return new SwMetadataCompositeKey(softwareModule, getKey());
}
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
@Override
public void setSoftwareModule(final SoftwareModule softwareModule) {
this.softwareModule = softwareModule;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((softwareModule == null) ? 0 : softwareModule.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
final JpaSoftwareModuleMetadata other = (JpaSoftwareModuleMetadata) obj;
if (softwareModule == null) {
if (other.softwareModule != null) {
return false;
}
} else if (!softwareModule.equals(other.softwareModule)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,125 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
/**
* Type of a software modules.
*
*/
@Entity
@Table(name = "sp_software_module_type", indexes = {
@Index(name = "sp_idx_software_module_type_01", columnList = "tenant,deleted"),
@Index(name = "sp_idx_software_module_type_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_smt_type_key"),
@UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_smt_name") })
public class JpaSoftwareModuleType extends JpaNamedEntity implements SoftwareModuleType {
private static final long serialVersionUID = 1L;
@Column(name = "type_key", nullable = false, length = 64)
private String key;
@Column(name = "max_ds_assignments", nullable = false)
private int maxAssignments;
@Column(name = "colour", nullable = true, length = 16)
private String colour;
@Column(name = "deleted")
private boolean deleted = false;
/**
* Constructor.
*
* @param key
* of the type
* @param name
* of the type
* @param description
* of the type
* @param maxAssignments
* assignments to a DS
*/
public JpaSoftwareModuleType(final String key, final String name, final String description, final int maxAssignments) {
this(key, name, description, maxAssignments, null);
}
/**
* Constructor.
*
* @param key
* of the type
* @param name
* of the type
* @param description
* of the type
* @param maxAssignments
* assignments to a DS
* @param colour
* of the type. It will be null by default
*/
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);
setName(name);
this.colour = colour;
}
/**
* Default Constructor.
*/
public JpaSoftwareModuleType() {
super();
}
@Override
public String getKey() {
return key;
}
@Override
public int getMaxAssignments() {
return maxAssignments;
}
@Override
public boolean isDeleted() {
return deleted;
}
@Override
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
@Override
public String getColour() {
return colour;
}
@Override
public void setColour(final String colour) {
this.colour = colour;
}
@Override
public String toString() {
return "SoftwareModuleType [key=" + key + ", getName()=" + getName() + ", getId()=" + getId() + "]";
}
}

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.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* A Tag can be used as describing and organizational meta information for any
* kind of entity.
*
*/
@MappedSuperclass
public abstract class JpaTag extends JpaNamedEntity implements Tag {
private static final long serialVersionUID = 1L;
@Column(name = "colour", nullable = true, length = 16)
private String colour;
protected JpaTag() {
super();
}
/**
* Public constructor.
*
* @param name
* of the {@link Tag}
* @param description
* of the {@link Tag}
* @param colour
* of tag in UI
*/
public JpaTag(final String name, final String description, final String colour) {
super(name, description);
this.colour = colour;
}
@Override
public String getColour() {
return colour;
}
@Override
public void setColour(final String colour) {
this.colour = colour;
}
@Override
public String toString() {
return "Tag [getOptLockRevision()=" + getOptLockRevision() + ", getId()=" + getId() + "]";
}
}

View File

@@ -0,0 +1,237 @@
/**
* 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.model;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
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;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetIdName;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.helper.SecurityChecker;
import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.springframework.data.domain.Persistable;
/**
* <p>
* The {@link Target} is the target of all provisioning operations. It contains
* the currently installed {@link DistributionSet} (i.e. current state). In
* addition it holds the target {@link DistributionSet} that has to be
* provisioned next (i.e. target state).
* </p>
*
* <p>
* {@link #getStatus()}s() shows if the {@link Target} is
* {@link TargetStatus#IN_SYNC} or a provisioning is
* {@link TargetStatus#PENDING} or the target is only
* {@link TargetStatus#REGISTERED}, i.e. a target {@link DistributionSet} .
* </p>
*
*/
@Entity
@Table(name = "sp_target", indexes = {
@Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"),
@Index(name = "sp_idx_target_02", columnList = "tenant,name"),
@Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"),
@Index(name = "sp_idx_target_04", columnList = "tenant,created_at"),
@Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"controller_id", "tenant" }, name = "uk_tenant_controller_id"))
@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"),
@NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") })
public class JpaTarget extends JpaNamedEntity implements Persistable<Long>, Target {
private static final long serialVersionUID = 1L;
@Column(name = "controller_id", length = 64)
@Size(min = 1)
@NotNull
private String controllerId;
@Transient
private boolean entityNew = false;
@ManyToMany(targetEntity = JpaTargetTag.class)
@JoinTable(name = "sp_target_target_tag", joinColumns = {
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = {
@JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) })
private Set<TargetTag> tags = new HashSet<>();
@CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = {
CascadeType.REMOVE }, targetEntity = JpaAction.class)
@JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ"))
private final List<Action> actions = new ArrayList<>();
@ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class)
@JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds"))
private JpaDistributionSet assignedDistributionSet;
@CascadeOnDelete
@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class)
@PrimaryKeyJoinColumn
private JpaTargetInfo targetInfo = null;
/**
* the security token of the target which allows if enabled to authenticate
* with this security token.
*/
@Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128)
private String securityToken = null;
@CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
@JoinColumn(name = "target_Id", insertable = false, updatable = false)
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>();
/**
* Constructor.
*
* @param controllerId
* controller ID of the {@link Target}
*/
public JpaTarget(final String controllerId) {
this.controllerId = controllerId;
setName(controllerId);
securityToken = SecurityTokenGeneratorHolder.getInstance().generateToken();
targetInfo = new JpaTargetInfo(this);
}
/**
* empty constructor for JPA.
*/
JpaTarget() {
controllerId = null;
securityToken = null;
}
@Override
public DistributionSet getAssignedDistributionSet() {
return assignedDistributionSet;
}
@Override
public String getControllerId() {
return controllerId;
}
@Override
public Set<TargetTag> getTags() {
return tags;
}
@Override
public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) {
this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet;
}
@Override
public void setControllerId(final String controllerId) {
this.controllerId = controllerId;
}
@Override
public void setTags(final Set<TargetTag> tags) {
this.tags = tags;
}
@Override
public List<Action> getActions() {
return actions;
}
@Override
public TargetIdName getTargetIdName() {
return new TargetIdName(getId(), getControllerId(), getName());
}
@Override
@Transient
public boolean isNew() {
return entityNew;
}
/**
* @param isNew
* the isNew to set
*/
public void setNew(final boolean entityNew) {
this.entityNew = entityNew;
}
/**
* @return the targetInfo
*/
@Override
public TargetInfo getTargetInfo() {
return targetInfo;
}
/**
* @param targetInfo
* the targetInfo to set
*/
@Override
public void setTargetInfo(final TargetInfo targetInfo) {
this.targetInfo = (JpaTargetInfo) targetInfo;
}
/**
* @return the securityToken
*/
@Override
public String getSecurityToken() {
if (SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) {
return securityToken;
}
return null;
}
/**
* @param securityToken
* the securityToken to set
*/
@Override
public void setSecurityToken(final String securityToken) {
this.securityToken = securityToken;
}
@Override
public String toString() {
return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]";
}
}

View File

@@ -0,0 +1,64 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
/**
* Stored target filter.
*
*/
@Entity
@Table(name = "sp_target_filter_query", indexes = {
@Index(name = "sp_idx_target_filter_query_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = {
"name", "tenant" }, name = "uk_tenant_custom_filter_name"))
public class JpaTargetFilterQuery extends JpaTenantAwareBaseEntity implements TargetFilterQuery {
private static final long serialVersionUID = 7493966984413479089L;
@Column(name = "name", length = 64)
private String name;
@Column(name = "query", length = 1024)
private String query;
public JpaTargetFilterQuery() {
// Default constructor for JPA.
}
public JpaTargetFilterQuery(final String name, final String query) {
this.name = name;
this.query = query;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(final String name) {
this.name = name;
}
@Override
public String getQuery() {
return query;
}
@Override
public void setQuery(final String query) {
this.query = query;
}
}

View File

@@ -0,0 +1,372 @@
/**
* 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.model;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MapKeyColumn;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.eclipse.hawkbit.repository.model.DistributionSet;
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.SystemSecurityContextHolder;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Persistable;
/**
* A table which contains all the information inserted, updated by the
* controller itself. So this entity does not provide audit information because
* changes on this entity are mostly only done by controller requests. That's
* the reason that we store these information in a separated table so we don't
* modifying the {@link Target} itself when a controller reports it's
* {@link #lastTargetQuery} for example.
*
*/
@Table(name = "sp_target_info", indexes = {
@Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") })
@Entity
public class JpaTargetInfo implements Persistable<Long>, TargetInfo {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class);
@Id
private Long targetId;
@Transient
private boolean entityNew = false;
@CascadeOnDelete
@OneToOne(cascade = { CascadeType.MERGE,
CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class)
@JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ"))
@MapsId
private JpaTarget target;
@Column(name = "address", length = 512)
private String address = null;
@Column(name = "last_target_query")
private Long lastTargetQuery = null;
@Column(name = "install_date")
private Long installationDate;
@Column(name = "update_status", nullable = false, length = 255)
@Enumerated(EnumType.STRING)
private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN;
@ManyToOne(optional = true, fetch = FetchType.LAZY)
@JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds"))
private JpaDistributionSet installedDistributionSet;
/**
* Read only on management API. Are commited by controller.
*/
@ElementCollection
@Column(name = "attribute_value", length = 128)
@MapKeyColumn(name = "attribute_key", nullable = false, length = 32)
@CollectionTable(name = "sp_target_attributes", joinColumns = {
@JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target"))
private final Map<String, String> controllerAttributes = Collections.synchronizedMap(new HashMap<String, String>());
// set default request controller attributes to true, because we want to
// request them the first
// time
@Column(name = "request_controller_attributes", nullable = false)
private boolean requestControllerAttributes = true;
/**
* Constructor for {@link TargetStatus}.
*
* @param target
* related to this status.
*/
public JpaTargetInfo(final JpaTarget target) {
this.target = target;
targetId = target.getId();
}
JpaTargetInfo() {
target = null;
targetId = null;
}
@Override
public Long getId() {
return targetId;
}
@Override
@Transient
public boolean isNew() {
return entityNew;
}
/**
* @param isNew
* the isNew to set
*/
public void setNew(final boolean entityNew) {
this.entityNew = entityNew;
}
/**
* @return the ipAddress
*/
@Override
public URI getAddress() {
if (address == null) {
return null;
}
try {
return URI.create(address);
} catch (final IllegalArgumentException e) {
LOG.warn("Invalid address provided. Cloud not be configured to URI", e);
return null;
}
}
/**
* @param address
* the ipAddress to set
*
* @throws IllegalArgumentException
* If the given string violates RFC&nbsp;2396
*/
public void setAddress(final String address) {
// check if this is a real URI
if (address != null) {
URI.create(address);
}
this.address = address;
}
public Long getTargetId() {
return targetId;
}
public void setTargetId(final Long targetId) {
this.targetId = targetId;
}
@Override
public Target getTarget() {
return target;
}
public void setTarget(final JpaTarget target) {
this.target = target;
}
@Override
public Long getLastTargetQuery() {
return lastTargetQuery;
}
public void setLastTargetQuery(final Long lastTargetQuery) {
this.lastTargetQuery = lastTargetQuery;
}
public void setRequestControllerAttributes(final boolean requestControllerAttributes) {
this.requestControllerAttributes = requestControllerAttributes;
}
@Override
public Map<String, String> getControllerAttributes() {
return controllerAttributes;
}
public boolean isRequestControllerAttributes() {
return requestControllerAttributes;
}
@Override
public Long getInstallationDate() {
return installationDate;
}
public void setInstallationDate(final Long installationDate) {
this.installationDate = installationDate;
}
@Override
public TargetUpdateStatus getUpdateStatus() {
return updateStatus;
}
public void setUpdateStatus(final TargetUpdateStatus updateStatus) {
this.updateStatus = updateStatus;
}
@Override
public DistributionSet getInstalledDistributionSet() {
return installedDistributionSet;
}
public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) {
this.installedDistributionSet = installedDistributionSet;
}
/**
* @return the poll time which holds the last poll time of the target, the
* next poll time and the overdue time. In case the
* {@link #lastTargetQuery} is not set e.g. the target never polled
* before this method returns {@code null}
*/
@Override
public PollStatus getPollStatus() {
if (lastTargetQuery == null) {
return null;
}
return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> {
final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder
.getInstance().getTenantConfigurationManagement()
.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
final Duration overdueTime = DurationHelper.formattedStringToDuration(
TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement()
.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)
.getValue());
final LocalDateTime currentDate = LocalDateTime.now();
final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery),
ZoneId.systemDefault());
final LocalDateTime nextPollDate = lastPollDate.plus(pollTime);
final LocalDateTime overdueDate = nextPollDate.plus(overdueTime);
return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate);
});
}
/**
* The poll time object which holds all the necessary information around the
* target poll time, e.g. the last poll time, the next poll time and the
* overdue poll time.
*
*/
public static final class PollStatus {
private final LocalDateTime lastPollDate;
private final LocalDateTime nextPollDate;
private final LocalDateTime overdueDate;
private final LocalDateTime currentDate;
private PollStatus(final LocalDateTime lastPollDate, final LocalDateTime nextPollDate,
final LocalDateTime overdueDate, final LocalDateTime currentDate) {
this.lastPollDate = lastPollDate;
this.nextPollDate = nextPollDate;
this.overdueDate = overdueDate;
this.currentDate = currentDate;
}
/**
* calculates if the target poll time is overdue and the target has not
* been polled in the configured poll time interval.
*
* @return {@code true} if the current time is after the poll time
* overdue date otherwise {@code false}.
*/
public boolean isOverdue() {
return currentDate.isAfter(overdueDate);
}
/**
* @return the lastPollDate
*/
public LocalDateTime getLastPollDate() {
return lastPollDate;
}
public LocalDateTime getNextPollDate() {
return nextPollDate;
}
public LocalDateTime getOverdueDate() {
return overdueDate;
}
public LocalDateTime getCurrentDate() {
return currentDate;
}
@Override
public String toString() {
return "PollTime [lastPollDate=" + lastPollDate + ", nextPollDate=" + nextPollDate + ", overdueDate="
+ overdueDate + ", currentDate=" + currentDate + "]";
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((target == null) ? 0 : target.hashCode());
result = prime * result + ((targetId == null) ? 0 : targetId.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof TargetInfo)) {
return false;
}
final JpaTargetInfo other = (JpaTargetInfo) obj;
if (target == null) {
if (other.target != null) {
return false;
}
} else if (!target.equals(other.target)) {
return false;
}
if (targetId == null) {
if (other.targetId != null) {
return false;
}
} else if (!targetId.equals(other.targetId)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,91 @@
/**
* 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.model;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Index;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* A {@link TargetTag} is used to describe Target attributes and use them also
* for filtering the target list.
*
*/
@Entity
@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 JpaTag implements TargetTag {
private static final long serialVersionUID = 1L;
@ManyToMany(mappedBy = "tags", targetEntity = JpaTarget.class, fetch = FetchType.LAZY)
private List<Target> assignedToTargets;
/**
* Constructor.
*
* @param name
* of {@link TargetTag}
* @param description
* of {@link TargetTag}
* @param colour
* of {@link TargetTag}
*/
public JpaTargetTag(final String name, final String description, final String colour) {
super(name, description, colour);
}
/**
* Public constructor.
*
* @param name
* of the {@link TargetTag}
**/
public JpaTargetTag(final String name) {
super(name, null, null);
}
public JpaTargetTag() {
super();
}
@Override
public List<Target> getAssignedToTargets() {
return assignedToTargets;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof TargetTag)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,115 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder;
import org.eclipse.persistence.annotations.Multitenant;
import org.eclipse.persistence.annotations.MultitenantType;
import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;
/**
* Holder of the base attributes common to all tenant aware entities.
*
*/
@MappedSuperclass
@TenantDiscriminatorColumn(name = "tenant", length = 40)
@Multitenant(MultitenantType.SINGLE_TABLE)
public abstract class JpaTenantAwareBaseEntity extends JpaBaseEntity implements TenantAwareBaseEntity {
private static final long serialVersionUID = 1L;
@Column(name = "tenant", nullable = false, insertable = false, updatable = false, length = 40)
private String tenant;
/**
* Default constructor needed for JPA entities.
*/
public JpaTenantAwareBaseEntity() {
// Default constructor needed for JPA entities.
}
/**
* PrePersist listener method for all {@link TenantAwareBaseEntity}
* entities.
*/
@PrePersist
public void prePersist() {
// before persisting the entity check the current ID of the tenant by
// using the TenantAware
// service
final String currentTenant = SystemManagementHolder.getInstance().currentTenant();
if (currentTenant == null) {
throw new TenantNotExistException("Tenant "
+ TenantAwareHolder.getInstance().getTenantAware().getCurrentTenant()
+ " does not exists, cannot create entity " + this.getClass() + " with id " + super.getId());
}
setTenant(currentTenant.toUpperCase());
}
@Override
public String getTenant() {
return tenant;
}
public void setTenant(final String tenant) {
this.tenant = tenant;
}
@Override
public String toString() {
return "BaseEntity [id=" + super.getId() + "]";
}
/**
* Tenant aware entities extend the equals/hashcode strategy with the tenant
* name. That would allow for instance in a multi-schema based data
* separation setup to have the same primary key for different entities of
* different tenants.
*
* @see org.eclipse.hawkbit.repository.model.BaseEntity#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + (tenant == null ? 0 : tenant.hashCode());
return result;
}
/**
* Tenant aware entities extend the equals/hashcode strategy with the tenant
* name. That would allow for instance in a multi-schema based data
* separation setup to have the same primary key for different entities of
* different tenants.
*
* @see org.eclipse.hawkbit.repository.model.BaseEntity#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
final JpaTenantAwareBaseEntity other = (JpaTenantAwareBaseEntity) obj;
if (tenant == null) {
if (other.tenant != null) {
return false;
}
} else if (!tenant.equals(other.tenant)) {
return false;
}
return true;
}
}

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.model;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
/**
* A JPA entity which stores the tenant specific configuration.
*
*/
@Entity
@Table(name = "sp_tenant_configuration", uniqueConstraints = @UniqueConstraint(columnNames = { "conf_key",
"tenant" }, name = "uk_tenant_key"))
public class JpaTenantConfiguration extends JpaTenantAwareBaseEntity implements TenantConfiguration {
private static final long serialVersionUID = 1L;
@Column(name = "conf_key", length = 128)
private String key;
@Column(name = "conf_value", length = 512)
@Basic
private String value;
/**
* JPA default constructor.
*/
public JpaTenantConfiguration() {
// JPA default constructor.
}
/**
* @param key
* the key of this configuration
* @param value
* the value of this configuration
*/
public JpaTenantConfiguration(final String key, final String value) {
this.key = key;
this.value = value;
}
@Override
public String getKey() {
return key;
}
@Override
public void setKey(final String key) {
this.key = key;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(final String value) {
this.value = value;
}
}

View File

@@ -0,0 +1,107 @@
/**
* 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.model;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.eclipse.hawkbit.repository.model.TenantMetaData;
/**
* Tenant entity with meta data that is configured globally for the entire
* tenant. This entity is not tenant aware to allow the system to access it
* through the {@link EntityManager} even before the actual tenant exists.
*
* Entities owned by the tenant are based on {@link TenantAwareBaseEntity}.
*
*/
@Table(name = "sp_tenant", indexes = {
@Index(name = "sp_idx_tenant_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "tenant" }, name = "uk_tenantmd_tenant") })
@Entity
public class JpaTenantMetaData extends JpaBaseEntity implements TenantMetaData {
private static final long serialVersionUID = 1L;
@Column(name = "tenant", nullable = false, length = 40)
private String tenant;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "default_ds_type", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_tenant_md_default_ds_type"))
private JpaDistributionSetType defaultDsType;
/**
* Default constructor needed for JPA entities.
*/
public JpaTenantMetaData() {
// Default constructor needed for JPA entities.
}
/**
* Standard constructor.
*
* @param defaultDsType
* of this tenant
* @param tenant
*/
public JpaTenantMetaData(final DistributionSetType defaultDsType, final String tenant) {
super();
this.defaultDsType = (JpaDistributionSetType) defaultDsType;
this.tenant = tenant;
}
@Override
public DistributionSetType getDefaultDsType() {
return defaultDsType;
}
@Override
public void setDefaultDsType(final DistributionSetType defaultDsType) {
this.defaultDsType = (JpaDistributionSetType) defaultDsType;
}
@Override
public String getTenant() {
return tenant;
}
public void setTenant(final String tenant) {
this.tenant = tenant;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof TenantMetaData)) {
return false;
}
return true;
}
}

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serializable;
import java.util.List;
@@ -24,6 +24,9 @@ import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.persistence.annotations.ExistenceChecking;
import org.eclipse.persistence.annotations.ExistenceType;
@@ -41,16 +44,16 @@ public class RolloutTargetGroup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@ManyToOne(targetEntity = RolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "rolloutGroup_Id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_group") )
@ManyToOne(targetEntity = JpaRolloutGroup.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "rolloutGroup_Id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_group"))
private RolloutGroup rolloutGroup;
@Id
@ManyToOne(targetEntity = Target.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "target_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_target") )
private Target target;
@ManyToOne(targetEntity = JpaTarget.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "target_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollouttargetgroup_target"))
private JpaTarget target;
@OneToMany(targetEntity = Action.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@OneToMany(targetEntity = JpaAction.class, fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST })
@JoinColumns(value = { @JoinColumn(name = "rolloutgroup", referencedColumnName = "rolloutGroup_Id"),
@JoinColumn(name = "target", referencedColumnName = "target_id") })
private List<Action> actions;
@@ -64,7 +67,7 @@ public class RolloutTargetGroup implements Serializable {
public RolloutTargetGroup(final RolloutGroup rolloutGroup, final Target target) {
this.rolloutGroup = rolloutGroup;
this.target = target;
this.target = (JpaTarget) target;
}
public RolloutTargetGroupId getId() {

View File

@@ -6,10 +6,13 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Combined unique key of the table {@link RolloutTargetGroup}.
*

View File

@@ -6,10 +6,12 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
package org.eclipse.hawkbit.repository.jpa.model;
import java.io.Serializable;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
/**
* The Software Module meta data composite key which contains the meta data key
* and the ID of the software module itself.

View File

@@ -6,20 +6,22 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.SetJoin;
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.JpaLocalArtifact;
import org.eclipse.hawkbit.repository.jpa.model.JpaLocalArtifact_;
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.Action_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSet_;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.LocalArtifact_;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModule_;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.data.jpa.domain.Specification;
@@ -28,7 +30,7 @@ import org.springframework.data.jpa.domain.Specification;
* Spring Data JPQL Specifications.
*
*/
public class ActionSpecifications {
public final class ActionSpecifications {
private ActionSpecifications() {
// utility class
@@ -47,15 +49,16 @@ public class ActionSpecifications {
* assigned
* @return a specification to use with spring JPA
*/
public static Specification<Action> hasTargetAssignedArtifact(final Target target,
public static Specification<JpaAction> hasTargetAssignedArtifact(final Target target,
final LocalArtifact localArtifact) {
return (actionRoot, query, criteriaBuilder) -> {
final Join<Action, DistributionSet> dsJoin = actionRoot.join(Action_.distributionSet);
final SetJoin<DistributionSet, SoftwareModule> modulesJoin = dsJoin.join(DistributionSet_.modules);
final ListJoin<SoftwareModule, LocalArtifact> artifactsJoin = modulesJoin.join(SoftwareModule_.artifacts);
final Join<JpaAction, JpaDistributionSet> dsJoin = actionRoot.join(JpaAction_.distributionSet);
final SetJoin<JpaDistributionSet, JpaSoftwareModule> modulesJoin = dsJoin.join(JpaDistributionSet_.modules);
final ListJoin<JpaSoftwareModule, JpaLocalArtifact> artifactsJoin = modulesJoin
.join(JpaSoftwareModule_.artifacts);
return criteriaBuilder.and(
criteriaBuilder.equal(artifactsJoin.get(LocalArtifact_.filename), localArtifact.getFilename()),
criteriaBuilder.equal(actionRoot.get(Action_.target), target));
criteriaBuilder.equal(artifactsJoin.get(JpaLocalArtifact_.filename), localArtifact.getFilename()),
criteriaBuilder.equal(actionRoot.get(JpaAction_.target), target));
};
}
}

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import java.util.Collection;
@@ -18,15 +18,17 @@ import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.SetJoin;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag_;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTag_;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.DistributionSet_;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetInfo_;
import org.eclipse.hawkbit.repository.model.Target_;
import org.springframework.data.jpa.domain.Specification;
/**
@@ -48,8 +50,8 @@ public final class DistributionSetSpecification {
* attribute is ignored
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> isDeleted(final Boolean isDeleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(DistributionSet_.deleted), isDeleted);
public static Specification<JpaDistributionSet> isDeleted(final Boolean isDeleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSet_.deleted), isDeleted);
}
@@ -62,8 +64,8 @@ public final class DistributionSetSpecification {
* the attribute is ignored
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> isCompleted(final Boolean isCompleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(DistributionSet_.complete), isCompleted);
public static Specification<JpaDistributionSet> isCompleted(final Boolean isCompleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSet_.complete), isCompleted);
}
@@ -75,12 +77,12 @@ public final class DistributionSetSpecification {
* to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> byId(final Long distid) {
public static Specification<JpaDistributionSet> byId(final Long distid) {
return (targetRoot, query, cb) -> {
final Predicate predicate = cb.equal(targetRoot.<Long> get(DistributionSet_.id), distid);
targetRoot.fetch(DistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(DistributionSet_.tags, JoinType.LEFT);
targetRoot.fetch(DistributionSet_.type, JoinType.LEFT);
final Predicate predicate = cb.equal(targetRoot.<Long> get(JpaDistributionSet_.id), distid);
targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
query.distinct(true);
return predicate;
@@ -95,12 +97,12 @@ public final class DistributionSetSpecification {
* to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> byIds(final Collection<Long> distids) {
public static Specification<JpaDistributionSet> byIds(final Collection<Long> distids) {
return (targetRoot, query, cb) -> {
final Predicate predicate = targetRoot.<Long> get(DistributionSet_.id).in(distids);
targetRoot.fetch(DistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(DistributionSet_.tags, JoinType.LEFT);
targetRoot.fetch(DistributionSet_.type, JoinType.LEFT);
final Predicate predicate = targetRoot.<Long> get(JpaDistributionSet_.id).in(distids);
targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
query.distinct(true);
return predicate;
};
@@ -114,11 +116,11 @@ public final class DistributionSetSpecification {
* to be filtered on
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> likeNameOrDescriptionOrVersion(final String subString) {
public static Specification<JpaDistributionSet> likeNameOrDescriptionOrVersion(final String subString) {
return (targetRoot, query, cb) -> cb.or(
cb.like(cb.lower(targetRoot.<String> get(DistributionSet_.name)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(DistributionSet_.version)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(DistributionSet_.description)), subString.toLowerCase()));
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.name)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.version)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.description)), subString.toLowerCase()));
}
/**
@@ -131,10 +133,10 @@ public final class DistributionSetSpecification {
* flag to select distribution sets with no tag
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> hasTags(final Collection<String> tagNames,
public static Specification<JpaDistributionSet> hasTags(final Collection<String> tagNames,
final Boolean selectDSWithNoTag) {
return (targetRoot, query, cb) -> {
final SetJoin<DistributionSet, DistributionSetTag> tags = targetRoot.join(DistributionSet_.tags,
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = targetRoot.join(JpaDistributionSet_.tags,
JoinType.LEFT);
final Predicate predicate = getPredicate(tags, tagNames, selectDSWithNoTag, cb);
query.distinct(true);
@@ -142,10 +144,10 @@ public final class DistributionSetSpecification {
};
}
private static Predicate getPredicate(final SetJoin<DistributionSet, DistributionSetTag> tags,
private static Predicate getPredicate(final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags,
final Collection<String> tagNames, final Boolean selectDSWithNoTag, final CriteriaBuilder cb) {
tags.get(DistributionSetTag_.name);
final Path<String> exp = tags.get(DistributionSetTag_.name);
tags.get(JpaDistributionSetTag_.name);
final Path<String> exp = tags.get(JpaDistributionSetTag_.name);
if (selectDSWithNoTag != null && selectDSWithNoTag) {
if (tagNames != null) {
return cb.or(exp.isNull(), exp.in(tagNames));
@@ -167,11 +169,11 @@ public final class DistributionSetSpecification {
* to be filtered on
* @return the {@link Specification}
*/
public static Specification<DistributionSet> equalsNameAndVersionIgnoreCase(final String name,
public static Specification<JpaDistributionSet> equalsNameAndVersionIgnoreCase(final String name,
final String version) {
return (targetRoot, query, cb) -> cb.and(
cb.equal(cb.lower(targetRoot.<String> get(DistributionSet_.name)), name.toLowerCase()),
cb.equal(cb.lower(targetRoot.<String> get(DistributionSet_.version)), version.toLowerCase()));
cb.equal(cb.lower(targetRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
cb.equal(cb.lower(targetRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
}
@@ -183,8 +185,9 @@ public final class DistributionSetSpecification {
* to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSet> byType(final DistributionSetType type) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<DistributionSetType> get(DistributionSet_.type), type);
public static Specification<JpaDistributionSet> byType(final DistributionSetType type) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<JpaDistributionSetType> get(JpaDistributionSet_.type),
type);
}
@@ -195,12 +198,12 @@ public final class DistributionSetSpecification {
* @return the specification to search for a distribution set which is
* installed to the given targetId
*/
public static Specification<DistributionSet> installedTarget(final String installedTargetId) {
public static Specification<JpaDistributionSet> installedTarget(final String installedTargetId) {
return (dsRoot, query, cb) -> {
final ListJoin<DistributionSet, TargetInfo> installedTargetJoin = dsRoot
.join(DistributionSet_.installedAtTargets, JoinType.INNER);
final Join<TargetInfo, Target> targetJoin = installedTargetJoin.join(TargetInfo_.target);
return cb.equal(targetJoin.get(Target_.controllerId), installedTargetId);
final ListJoin<JpaDistributionSet, JpaTargetInfo> installedTargetJoin = dsRoot
.join(JpaDistributionSet_.installedAtTargets, JoinType.INNER);
final Join<JpaTargetInfo, JpaTarget> targetJoin = installedTargetJoin.join(JpaTargetInfo_.target);
return cb.equal(targetJoin.get(JpaTarget_.controllerId), installedTargetId);
};
}
@@ -211,11 +214,11 @@ public final class DistributionSetSpecification {
* @return the specification to search for a distribution set which is
* assigned to the given targetId
*/
public static Specification<DistributionSet> assignedTarget(final String assignedTargetId) {
public static Specification<JpaDistributionSet> assignedTarget(final String assignedTargetId) {
return (dsRoot, query, cb) -> {
final ListJoin<DistributionSet, Target> assignedTargetJoin = dsRoot.join(DistributionSet_.assignedToTargets,
JoinType.INNER);
return cb.equal(assignedTargetJoin.get(Target_.controllerId), assignedTargetId);
final ListJoin<JpaDistributionSet, JpaTarget> assignedTargetJoin = dsRoot
.join(JpaDistributionSet_.assignedToTargets, JoinType.INNER);
return cb.equal(assignedTargetJoin.get(JpaTarget_.controllerId), assignedTargetId);
};
}

View File

@@ -6,11 +6,12 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.DistributionSetType_;
import org.springframework.data.jpa.domain.Specification;
/**
@@ -31,8 +32,9 @@ public final class DistributionSetTypeSpecification {
* attribute is ignored
* @return the {@link DistributionSetType} {@link Specification}
*/
public static Specification<DistributionSetType> isDeleted(final Boolean isDeleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(DistributionSetType_.deleted), isDeleted);
public static Specification<JpaDistributionSetType> isDeleted(final Boolean isDeleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSetType_.deleted),
isDeleted);
}
/**
@@ -44,8 +46,8 @@ public final class DistributionSetTypeSpecification {
* to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSetType> byId(final Long distid) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Long> get(DistributionSetType_.id), distid);
public static Specification<JpaDistributionSetType> byId(final Long distid) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Long> get(JpaDistributionSetType_.id), distid);
}
/**
@@ -57,8 +59,8 @@ public final class DistributionSetTypeSpecification {
* to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSetType> byName(final String name) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<String> get(DistributionSetType_.name), name);
public static Specification<JpaDistributionSetType> byName(final String name) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<String> get(JpaDistributionSetType_.name), name);
}
/**
@@ -70,8 +72,8 @@ public final class DistributionSetTypeSpecification {
* to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<DistributionSetType> byKey(final String key) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<String> get(DistributionSetType_.key), key);
public static Specification<JpaDistributionSetType> byKey(final String key) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<String> get(JpaDistributionSetType_.key), key);
}
}

View File

@@ -6,13 +6,14 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import javax.persistence.criteria.Predicate;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.SoftwareModule_;
import org.springframework.data.jpa.domain.Specification;
/**
@@ -33,10 +34,10 @@ public final class SoftwareModuleSpecification {
* to search for
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<SoftwareModule> byId(final Long moduleId) {
public static Specification<JpaSoftwareModule> byId(final Long moduleId) {
return (targetRoot, query, cb) -> {
final Predicate predicate = cb.equal(targetRoot.<Long> get(SoftwareModule_.id), moduleId);
targetRoot.fetch(SoftwareModule_.type);
final Predicate predicate = cb.equal(targetRoot.<Long> get(JpaSoftwareModule_.id), moduleId);
targetRoot.fetch(JpaSoftwareModule_.type);
return predicate;
};
}
@@ -47,8 +48,8 @@ public final class SoftwareModuleSpecification {
*
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<SoftwareModule> isDeletedFalse() {
return (swRoot, query, cb) -> cb.equal(swRoot.<Boolean> get(SoftwareModule_.deleted), Boolean.FALSE);
public static Specification<JpaSoftwareModule> isDeletedFalse() {
return (swRoot, query, cb) -> cb.equal(swRoot.<Boolean> get(JpaSoftwareModule_.deleted), Boolean.FALSE);
}
/**
@@ -59,10 +60,10 @@ public final class SoftwareModuleSpecification {
* to be filtered on
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<SoftwareModule> likeNameOrVersion(final String subString) {
public static Specification<JpaSoftwareModule> likeNameOrVersion(final String subString) {
return (targetRoot, query, cb) -> cb.or(
cb.like(cb.lower(targetRoot.<String> get(SoftwareModule_.name)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(SoftwareModule_.version)), subString.toLowerCase()));
cb.like(cb.lower(targetRoot.<String> get(JpaSoftwareModule_.name)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaSoftwareModule_.version)), subString.toLowerCase()));
}
/**
@@ -73,8 +74,9 @@ public final class SoftwareModuleSpecification {
* to be filtered on
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<SoftwareModule> equalType(final SoftwareModuleType type) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<SoftwareModuleType> get(SoftwareModule_.type), type);
public static Specification<JpaSoftwareModule> equalType(final JpaSoftwareModuleType type) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<JpaSoftwareModuleType> get(JpaSoftwareModule_.type),
type);
}
}

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import java.util.List;

View File

@@ -6,10 +6,11 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery_;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery_;
import org.springframework.data.jpa.domain.Specification;
/**
@@ -22,10 +23,10 @@ public class TargetFilterQuerySpecification {
// utility class
}
public static Specification<TargetFilterQuery> likeName(final String searchText) {
public static Specification<JpaTargetFilterQuery> likeName(final String searchText) {
return (targetFilterQueryRoot, query, cb) -> {
final String searchTextToLower = searchText.toLowerCase();
return cb.like(cb.lower(targetFilterQueryRoot.get(TargetFilterQuery_.name)), searchTextToLower);
return cb.like(cb.lower(targetFilterQueryRoot.get(JpaTargetFilterQuery_.name)), searchTextToLower);
};
}
}

View File

@@ -6,7 +6,7 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.specifications;
package org.eclipse.hawkbit.repository.jpa.specifications;
import java.util.Collection;
import java.util.List;
@@ -20,15 +20,19 @@ import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSet_;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetInfo_;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTag_;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.Target_;
import org.springframework.data.jpa.domain.Specification;
/**
@@ -50,10 +54,11 @@ public final class TargetSpecifications {
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> byControllerIdWithStatusAndTagsInJoin(final Collection<String> controllerIDs) {
public static Specification<JpaTarget> byControllerIdWithStatusAndTagsInJoin(
final Collection<String> controllerIDs) {
return (targetRoot, query, cb) -> {
final Predicate predicate = targetRoot.get(Target_.controllerId).in(controllerIDs);
targetRoot.fetch(Target_.tags, JoinType.LEFT);
final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs);
targetRoot.fetch(JpaTarget_.tags, JoinType.LEFT);
query.distinct(true);
return predicate;
};
@@ -68,12 +73,12 @@ public final class TargetSpecifications {
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> byControllerIdWithStatusAndAssignedInJoin(
public static Specification<JpaTarget> byControllerIdWithStatusAndAssignedInJoin(
final Collection<String> controllerIDs) {
return (targetRoot, query, cb) -> {
final Predicate predicate = targetRoot.get(Target_.controllerId).in(controllerIDs);
targetRoot.fetch(Target_.assignedDistributionSet);
final Predicate predicate = targetRoot.get(JpaTarget_.controllerId).in(controllerIDs);
targetRoot.fetch(JpaTarget_.assignedDistributionSet);
return predicate;
};
}
@@ -89,19 +94,19 @@ public final class TargetSpecifications {
* join it.
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> hasTargetUpdateStatus(final Collection<TargetUpdateStatus> updateStatus,
public static Specification<JpaTarget> hasTargetUpdateStatus(final Collection<TargetUpdateStatus> updateStatus,
final boolean fetch) {
return (targetRoot, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
if (fetch) {
targetRoot.fetch(Target_.targetInfo);
targetRoot.fetch(JpaTarget_.targetInfo);
} else {
targetRoot.join(Target_.targetInfo);
targetRoot.join(JpaTarget_.targetInfo);
}
return targetRoot.get(Target_.targetInfo).get(TargetInfo_.updateStatus).in(updateStatus);
return targetRoot.get(JpaTarget_.targetInfo).get(JpaTargetInfo_.updateStatus).in(updateStatus);
}
final Join<Target, TargetInfo> targetInfoJoin = targetRoot.join(Target_.targetInfo);
return targetInfoJoin.get(TargetInfo_.updateStatus).in(updateStatus);
final Join<JpaTarget, JpaTargetInfo> targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo);
return targetInfoJoin.get(JpaTargetInfo_.updateStatus).in(updateStatus);
};
}
@@ -113,11 +118,11 @@ public final class TargetSpecifications {
* to be filtered on
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> likeNameOrDescriptionOrIp(final String searchText) {
public static Specification<JpaTarget> likeNameOrDescriptionOrIp(final String searchText) {
return (targetRoot, query, cb) -> {
final String searchTextToLower = searchText.toLowerCase();
return cb.or(cb.like(cb.lower(targetRoot.get(Target_.name)), searchTextToLower),
cb.like(cb.lower(targetRoot.get(Target_.description)), searchTextToLower));
return cb.or(cb.like(cb.lower(targetRoot.get(JpaTarget_.name)), searchTextToLower),
cb.like(cb.lower(targetRoot.get(JpaTarget_.description)), searchTextToLower));
};
}
@@ -129,14 +134,14 @@ public final class TargetSpecifications {
* to be filtered on
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> hasInstalledOrAssignedDistributionSet(@NotNull final Long distributionId) {
public static Specification<JpaTarget> hasInstalledOrAssignedDistributionSet(@NotNull final Long distributionId) {
return (targetRoot, query, cb) -> {
final Join<Target, TargetInfo> targetInfoJoin = targetRoot.join(Target_.targetInfo);
final Join<JpaTarget, JpaTargetInfo> targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo);
return cb.or(
cb.equal(targetInfoJoin.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id),
cb.equal(targetInfoJoin.get(JpaTargetInfo_.installedDistributionSet).get(JpaDistributionSet_.id),
distributionId),
cb.equal(targetRoot.<DistributionSet> get(Target_.assignedDistributionSet).get(DistributionSet_.id),
distributionId));
cb.equal(targetRoot.<JpaDistributionSet> get(JpaTarget_.assignedDistributionSet)
.get(JpaDistributionSet_.id), distributionId));
};
}
@@ -150,13 +155,12 @@ public final class TargetSpecifications {
* set that is not yet assigned
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> hasControllerIdAndAssignedDistributionSetIdNot(final List<String> tIDs,
public static Specification<JpaTarget> hasControllerIdAndAssignedDistributionSetIdNot(final List<String> tIDs,
@NotNull final Long distributionId) {
return (targetRoot, query, cb) -> cb
.and(targetRoot.get(Target_.controllerId).in(tIDs),
cb.or(cb.notEqual(targetRoot.<DistributionSet> get(Target_.assignedDistributionSet)
.get(DistributionSet_.id), distributionId),
cb.isNull(targetRoot.<DistributionSet> get(Target_.assignedDistributionSet))));
return (targetRoot, query, cb) -> cb.and(targetRoot.get(JpaTarget_.controllerId).in(tIDs),
cb.or(cb.notEqual(targetRoot.<JpaDistributionSet> get(JpaTarget_.assignedDistributionSet)
.get(JpaDistributionSet_.id), distributionId),
cb.isNull(targetRoot.<JpaDistributionSet> get(JpaTarget_.assignedDistributionSet))));
}
/**
@@ -169,7 +173,7 @@ public final class TargetSpecifications {
* flag to get targets with no tag assigned
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> hasTags(final String[] tagNames, final Boolean selectTargetWithNoTag) {
public static Specification<JpaTarget> hasTags(final String[] tagNames, final Boolean selectTargetWithNoTag) {
return (targetRoot, query, cb) -> {
final Predicate predicate = getPredicate(targetRoot, cb, selectTargetWithNoTag, tagNames);
query.distinct(true);
@@ -177,10 +181,10 @@ public final class TargetSpecifications {
};
}
private static Predicate getPredicate(final Root<Target> targetRoot, final CriteriaBuilder cb,
private static Predicate getPredicate(final Root<JpaTarget> targetRoot, final CriteriaBuilder cb,
final Boolean selectTargetWithNoTag, final String[] tagNames) {
final SetJoin<Target, TargetTag> tags = targetRoot.join(Target_.tags, JoinType.LEFT);
final Path<String> exp = tags.get(TargetTag_.name);
final SetJoin<JpaTarget, JpaTargetTag> tags = targetRoot.join(JpaTarget_.tags, JoinType.LEFT);
final Path<String> exp = tags.get(JpaTargetTag_.name);
if (selectTargetWithNoTag) {
if (tagNames != null) {
return cb.or(exp.isNull(), exp.in(tagNames));
@@ -200,9 +204,9 @@ public final class TargetSpecifications {
* the ID of the distribution set which must be assigned
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> hasAssignedDistributionSet(final Long distributionSetId) {
public static Specification<JpaTarget> hasAssignedDistributionSet(final Long distributionSetId) {
return (targetRoot, query, cb) -> cb.equal(
targetRoot.<DistributionSet> get(Target_.assignedDistributionSet).get(DistributionSet_.id),
targetRoot.<JpaDistributionSet> get(JpaTarget_.assignedDistributionSet).get(JpaDistributionSet_.id),
distributionSetId);
}
@@ -214,10 +218,10 @@ public final class TargetSpecifications {
* the ID of the distribution set which must be assigned
* @return the {@link Target} {@link Specification}
*/
public static Specification<Target> hasInstalledDistributionSet(final Long distributionSetId) {
public static Specification<JpaTarget> hasInstalledDistributionSet(final Long distributionSetId) {
return (targetRoot, query, cb) -> {
final Join<Target, TargetInfo> targetInfoJoin = targetRoot.join(Target_.targetInfo);
return cb.equal(targetInfoJoin.get(TargetInfo_.installedDistributionSet).get(DistributionSet_.id),
final Join<JpaTarget, JpaTargetInfo> targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo);
return cb.equal(targetInfoJoin.get(JpaTargetInfo_.installedDistributionSet).get(JpaDistributionSet_.id),
distributionSetId);
};
}

View File

@@ -10,193 +10,66 @@ package org.eclipse.hawkbit.repository.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedEntityGraphs;
import javax.persistence.NamedSubgraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.eclipse.hawkbit.cache.CacheField;
import org.eclipse.hawkbit.cache.CacheKeys;
import org.eclipse.persistence.annotations.CascadeOnDelete;
/**
* <p>
* Applicable transition changes of the {@link SoftwareModule}s state of a
* {@link Target}, e.g. install, uninstall, update and preparations for the
* transition change, i.e. download.
* </p>
*
* <p>
* Actions are managed by the SP server and applied to the targets by the
* client.
* <p>
*/
@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"),
@Index(name = "sp_idx_action_02", columnList = "tenant,target,active"),
@Index(name = "sp_idx_action_prim", columnList = "tenant,id") })
@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }),
@NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"),
@NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) })
@Entity
public class Action extends TenantAwareBaseEntity {
private static final long serialVersionUID = 1L;
public interface Action extends TenantAwareBaseEntity {
/**
* indicating that target action has no force time {@link #hasForcedTime()}.
*/
public static final long NO_FORCE_TIME = 0L;
/**
* the {@link DistributionSet} which should be installed by this action.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds"))
private DistributionSet distributionSet;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target"))
private Target target;
@Column(name = "active")
private boolean active;
@Column(name = "action_type", nullable = false)
@Enumerated(EnumType.STRING)
private ActionType actionType;
@Column(name = "forced_time")
private long forcedTime;
@Column(name = "status")
private Status status;
@CascadeOnDelete
@OneToMany(mappedBy = "action", targetEntity = ActionStatus.class, fetch = FetchType.LAZY, cascade = {
CascadeType.REMOVE })
private List<ActionStatus> actionStatus;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup"))
private RolloutGroup rolloutGroup;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
private Rollout rollout;
/**
* Note: filled only in {@link Status#DOWNLOAD}.
*/
@Transient
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
private int downloadProgressPercent;
/**
* @return the distributionSet
*/
public DistributionSet getDistributionSet() {
return distributionSet;
}
DistributionSet getDistributionSet();
/**
* @param distributionSet
* the distributionSet to set
*/
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = distributionSet;
}
void setDistributionSet(DistributionSet distributionSet);
/**
* @return true when action is in state {@link Status#CANCELING} or
* {@link Status#CANCELED}, false otherwise
*/
public boolean isCancelingOrCanceled() {
return status == Status.CANCELING || status == Status.CANCELED;
}
boolean isCancelingOrCanceled();
public void setActive(final boolean active) {
this.active = active;
}
void setActive(boolean active);
public Status getStatus() {
return status;
}
Status getStatus();
public void setStatus(final Status status) {
this.status = status;
}
void setStatus(Status status);
public int getDownloadProgressPercent() {
return downloadProgressPercent;
}
int getDownloadProgressPercent();
public void setDownloadProgressPercent(final int downloadProgressPercent) {
this.downloadProgressPercent = downloadProgressPercent;
}
void setDownloadProgressPercent(int downloadProgressPercent);
public boolean isActive() {
return active;
}
boolean isActive();
public void setActionType(final ActionType actionType) {
this.actionType = actionType;
}
void setActionType(ActionType actionType);
/**
* @return the actionType
*/
public ActionType getActionType() {
return actionType;
}
ActionType getActionType();
public List<ActionStatus> getActionStatus() {
return actionStatus;
}
List<ActionStatus> getActionStatus();
public void setTarget(final Target target) {
this.target = target;
}
void setTarget(Target target);
public Target getTarget() {
return target;
}
Target getTarget();
public long getForcedTime() {
return forcedTime;
}
long getForcedTime();
public void setForcedTime(final long forcedTime) {
this.forcedTime = forcedTime;
}
void setForcedTime(long forcedTime);
public RolloutGroup getRolloutGroup() {
return rolloutGroup;
}
RolloutGroup getRolloutGroup();
public void setRolloutGroup(final RolloutGroup rolloutGroup) {
this.rolloutGroup = rolloutGroup;
}
void setRolloutGroup(RolloutGroup rolloutGroup);
public Rollout getRollout() {
return rollout;
}
Rollout getRollout();
public void setRollout(final Rollout rollout) {
this.rollout = rollout;
}
void setRollout(Rollout rollout);
/**
* checks if the {@link #forcedTime} is hit by the given
@@ -210,12 +83,7 @@ public class Action extends TenantAwareBaseEntity {
* {@link ActionType#TIMEFORCED} and the given {@code hitTimeMillis}
* is greater than the {@link #forcedTime} otherwise {@code false}
*/
public boolean isHitAutoForceTime(final long hitTimeMillis) {
if (actionType == ActionType.TIMEFORCED) {
return hitTimeMillis >= forcedTime;
}
return false;
}
boolean isHitAutoForceTime(long hitTimeMillis);
/**
* @return {@code true} if either the {@link #type} is
@@ -223,28 +91,12 @@ public class Action extends TenantAwareBaseEntity {
* then if the {@link #forcedTime} has been exceeded otherwise
* always {@code false}
*/
public boolean isForce() {
switch (actionType) {
case FORCED:
return true;
case TIMEFORCED:
return isHitAutoForceTime(System.currentTimeMillis());
default:
return false;
}
}
boolean isForce();
/**
* @return true when action is forced, false otherwise
*/
public boolean isForced() {
return actionType == ActionType.FORCED;
}
@Override
public String toString() {
return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]";
}
boolean isForced();
/**
* Action status as reported by the controller.
@@ -309,4 +161,5 @@ public class Action extends TenantAwareBaseEntity {
public enum ActionType {
FORCED, SOFT, TIMEFORCED;
}
}
}

View File

@@ -8,107 +8,15 @@
*/
package org.eclipse.hawkbit.repository.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.Table;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import com.google.common.base.Splitter;
public interface ActionStatus extends TenantAwareBaseEntity {
/**
* Entity to store the status for a specific action.
*/
@Table(name = "sp_action_status", indexes = { @Index(name = "sp_idx_action_status_01", columnList = "tenant,action"),
@Index(name = "sp_idx_action_status_02", columnList = "tenant,action,status"),
@Index(name = "sp_idx_action_status_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "ActionStatus.withMessages", attributeNodes = { @NamedAttributeNode("messages") })
@Entity
public class ActionStatus extends TenantAwareBaseEntity {
private static final long serialVersionUID = 1L;
Long getOccurredAt();
@Column(name = "target_occurred_at")
private Long occurredAt;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "action", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_act_stat_action"))
private Action action;
@Column(name = "status")
private Status status;
@CascadeOnDelete
@ElementCollection(fetch = FetchType.LAZY, targetClass = String.class)
@CollectionTable(name = "sp_action_status_messages", joinColumns = @JoinColumn(name = "action_status_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_stat_msg_act_stat")), indexes = {
@Index(name = "sp_idx_action_status_msgs_01", columnList = "action_status_id") })
@Column(name = "detail_message", length = 512)
private final List<String> messages = new ArrayList<>();
/**
* Creates a new {@link ActionStatus} object.
*
* @param action
* the action for this action status
* @param status
* the status for this action status
* @param occurredAt
* the occurred timestamp
*/
public ActionStatus(final Action action, final Status status, final Long occurredAt) {
this.action = action;
this.status = status;
this.occurredAt = occurredAt;
}
/**
* Creates a new {@link ActionStatus} object.
*
* @param action
* the action for this action status
* @param status
* the status for this action status
* @param occurredAt
* the occurred timestamp
* @param messages
* the messages which should be added to this action status
*/
public ActionStatus(final Action action, final Status status, final Long occurredAt, final String... messages) {
this.action = action;
this.status = status;
this.occurredAt = occurredAt;
for (final String msg : messages) {
addMessage(msg);
}
}
/**
* JPA default constructor.
*/
public ActionStatus() {
// JPA default constructor.
}
public Long getOccurredAt() {
return occurredAt;
}
public void setOccurredAt(final Long occurredAt) {
this.occurredAt = occurredAt;
}
void setOccurredAt(Long occurredAt);
/**
* Adds message including splitting in case it exceeds 512 length.
@@ -116,28 +24,16 @@ public class ActionStatus extends TenantAwareBaseEntity {
* @param message
* to add
*/
public final void addMessage(final String message) {
Splitter.fixedLength(512).split(message).forEach(messages::add);
}
void addMessage(String message);
public List<String> getMessages() {
return messages;
}
List<String> getMessages();
public Action getAction() {
return action;
}
Action getAction();
public void setAction(final Action action) {
this.action = action;
}
void setAction(Action action);
public Status getStatus() {
return status;
}
Status getStatus();
public void setStatus(final Status status) {
this.status = status;
}
void setStatus(Status status);
}
}

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.model;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -16,6 +17,7 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
* action's {@link ActionStatus}.
*
*/
// TODO: create interface
public class ActionWithStatusCount {
private final Long actionStatusCount;
private final Long actionId;
@@ -28,7 +30,7 @@ public class ActionWithStatusCount {
private final Long dsId;
private final String dsName;
private final String dsVersion;
private final Action action;
private final JpaAction action;
private final String rolloutName;
/**
@@ -78,7 +80,7 @@ public class ActionWithStatusCount {
this.actionStatusCount = actionStatusCount;
this.rolloutName = rolloutName;
action = new Action();
action = new JpaAction();
action.setActionType(actionType);
action.setActive(actionActive);
action.setForcedTime(actionForceTime);

View File

@@ -8,49 +8,16 @@
*/
package org.eclipse.hawkbit.repository.model;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
public interface Artifact extends TenantAwareBaseEntity {
/**
* Tenant specific locally stored artifact representation that is used by
* {@link SoftwareModule}.
*/
@MappedSuperclass
public abstract class Artifact extends TenantAwareBaseEntity {
private static final long serialVersionUID = 1L;
SoftwareModule getSoftwareModule();
@Column(name = "sha1_hash", length = 40, nullable = true)
private String sha1Hash;
void setSoftwareModule(SoftwareModule softwareModule);
@Column(name = "md5_hash", length = 32, nullable = true)
private String md5Hash;
String getMd5Hash();
@Column(name = "file_size")
private Long size;
String getSha1Hash();
public abstract SoftwareModule getSoftwareModule();
Long getSize();
public String getMd5Hash() {
return md5Hash;
}
public String getSha1Hash() {
return sha1Hash;
}
public void setMd5Hash(final String md5Hash) {
this.md5Hash = md5Hash;
}
public void setSha1Hash(final String sha1Hash) {
this.sha1Hash = sha1Hash;
}
public Long getSize() {
return size;
}
public void setSize(final Long size) {
this.size = size;
}
}
}

View File

@@ -10,171 +10,18 @@ package org.eclipse.hawkbit.repository.model;
import java.io.Serializable;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
import org.eclipse.hawkbit.eventbus.CacheFieldEntityListener;
import org.eclipse.hawkbit.eventbus.EntityPropertyChangeListener;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.hateoas.Identifiable;
/**
* Holder of the base attributes common to all entities.
*
*/
@MappedSuperclass
@Access(AccessType.FIELD)
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class })
public abstract class BaseEntity implements Serializable, Identifiable<Long> {
private static final long serialVersionUID = 1L;
public interface BaseEntity extends Serializable, Identifiable<Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
Long getCreatedAt();
private String createdBy;
private String lastModifiedBy;
private Long createdAt;
private Long lastModifiedAt;
String getCreatedBy();
@Version
@Column(name = "optlock_revision")
private long optLockRevision;
Long getLastModifiedAt();
/**
* Default constructor needed for JPA entities.
*/
public BaseEntity() {
// Default constructor needed for JPA entities.
}
String getLastModifiedBy();
@Access(AccessType.PROPERTY)
@Column(name = "created_at", insertable = true, updatable = false)
public Long getCreatedAt() {
return createdAt;
}
long getOptLockRevision();
@Access(AccessType.PROPERTY)
@Column(name = "created_by", insertable = true, updatable = false, length = 40)
public String getCreatedBy() {
return createdBy;
}
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_at", insertable = false, updatable = true)
public Long getLastModifiedAt() {
return lastModifiedAt;
}
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_by", insertable = false, updatable = true, length = 40)
public String getLastModifiedBy() {
return lastModifiedBy;
}
@CreatedBy
public void setCreatedBy(final String createdBy) {
this.createdBy = createdBy;
}
@LastModifiedBy
public void setLastModifiedBy(final String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
@CreatedDate
public void setCreatedAt(final Long createdAt) {
this.createdAt = createdAt;
}
@LastModifiedDate
public void setLastModifiedAt(final Long lastModifiedAt) {
this.lastModifiedAt = lastModifiedAt;
}
public long getOptLockRevision() {
return optLockRevision;
}
// for test purposes only
void setOptLockRevision(final long optLockRevision) {
this.optLockRevision = optLockRevision;
}
@Override
public Long getId() {
return id;
}
@Override
public String toString() {
return "BaseEntity [id=" + id + "]";
}
public void setId(final Long id) {
this.id = id;
}
/**
* Defined equals/hashcode strategy for the repository in general is that an
* entity is equal if it has the same {@link #getId()} and
* {@link #getOptLockRevision()} and class.
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() { // NOSONAR - as this is generated code
final int prime = 31;
int result = 1;
result = prime * result + (id == null ? 0 : id.hashCode());
result = prime * result + (int) (optLockRevision ^ optLockRevision >>> 32);
result = prime * result + this.getClass().getName().hashCode();
return result;
}
/**
* Defined equals/hashcode strategy for the repository in general is that an
* entity is equal if it has the same {@link #getId()} and
* {@link #getOptLockRevision()} and class.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
// code
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(this.getClass().isInstance(obj))) {
return false;
}
final BaseEntity other = (BaseEntity) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
if (optLockRevision != other.optLockRevision) {
return false;
}
return true;
}
}
}

View File

@@ -8,198 +8,47 @@
*/
package org.eclipse.hawkbit.repository.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
public interface DistributionSet extends NamedVersionedEntity {
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
import org.eclipse.persistence.annotations.CascadeOnDelete;
Set<DistributionSetTag> getTags();
/**
* <p>
* The {@link DistributionSet} is defined in the SP repository and contains at
* least an OS and an Agent Hub.
* </p>
*
* <p>
* A {@link Target} has exactly one target {@link DistributionSet} assigned.
* </p>
*
*/
@Entity
@Table(name = "sp_distribution_set", uniqueConstraints = {
@UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = {
@Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"),
@Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"),
@Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") })
@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"),
@NamedAttributeNode("tags"), @NamedAttributeNode("type") })
public class DistributionSet extends NamedVersionedEntity {
private static final long serialVersionUID = 1L;
@Column(name = "required_migration_step")
private boolean requiredMigrationStep = false;
@ManyToMany(targetEntity = SoftwareModule.class, fetch = FetchType.LAZY)
@JoinTable(name = "sp_ds_module", joinColumns = {
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = {
@JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) })
private final Set<SoftwareModule> modules = new HashSet<>();
@ManyToMany(targetEntity = DistributionSetTag.class)
@JoinTable(name = "sp_ds_dstag", joinColumns = {
@JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = {
@JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) })
private Set<DistributionSetTag> tags = new HashSet<>();
@Column(name = "deleted")
private boolean deleted = false;
@OneToMany(mappedBy = "assignedDistributionSet", targetEntity = Target.class, fetch = FetchType.LAZY)
private List<Target> assignedToTargets;
@OneToMany(mappedBy = "installedDistributionSet", targetEntity = TargetInfo.class, fetch = FetchType.LAZY)
private List<TargetInfo> installedAtTargets;
@OneToMany(mappedBy = "distributionSet", targetEntity = Action.class, fetch = FetchType.LAZY)
private List<Action> actions;
@CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE })
@JoinColumn(name = "ds_id", insertable = false, updatable = false)
private final List<DistributionSetMetadata> metadata = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
private DistributionSetType type;
@Column(name = "complete")
private boolean complete = false;
/**
* Default constructor.
*/
public DistributionSet() {
super();
}
/**
* 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 DistributionSet(final String name, final String version, final String description,
final DistributionSetType type, final Iterable<SoftwareModule> moduleList) {
super(name, version, description);
this.type = type;
if (moduleList != null) {
moduleList.forEach(this::addModule);
}
if (this.type != null) {
complete = this.type.checkComplete(this);
}
}
public Set<DistributionSetTag> getTags() {
return tags;
}
public boolean isDeleted() {
return deleted;
}
boolean isDeleted();
/**
* @return immutable list of meta data elements.
*/
public List<DistributionSetMetadata> getMetadata() {
return Collections.unmodifiableList(metadata);
}
List<DistributionSetMetadata> getMetadata();
public List<Action> getActions() {
return actions;
}
List<Action> getActions();
public boolean isRequiredMigrationStep() {
return requiredMigrationStep;
}
boolean isRequiredMigrationStep();
public DistributionSet setDeleted(final boolean deleted) {
this.deleted = deleted;
return this;
}
DistributionSet setDeleted(boolean deleted);
public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) {
requiredMigrationStep = isRequiredMigrationStep;
return this;
}
DistributionSet setRequiredMigrationStep(boolean isRequiredMigrationStep);
public DistributionSet setTags(final Set<DistributionSetTag> tags) {
this.tags = tags;
return this;
}
DistributionSet setTags(Set<DistributionSetTag> tags);
/**
* @return the assignedTargets
*/
public List<Target> getAssignedTargets() {
return assignedToTargets;
}
List<Target> getAssignedTargets();
/**
* @return the installedTargets
*/
public List<TargetInfo> getInstalledTargets() {
return installedAtTargets;
}
@Override
public String toString() {
return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision()
+ ", getId()=" + getId() + "]";
}
List<TargetInfo> getInstalledTargets();
/**
*
* @return unmodifiableSet of {@link SoftwareModule}.
*/
public Set<SoftwareModule> getModules() {
return Collections.unmodifiableSet(modules);
}
Set<SoftwareModule> getModules();
public DistributionSetIdName getDistributionSetIdName() {
return new DistributionSetIdName(getId(), getName(), getVersion());
}
DistributionSetIdName getDistributionSetIdName();
/**
* @param softwareModule
@@ -207,41 +56,7 @@ public class DistributionSet extends NamedVersionedEntity {
* if it already existed in the set
*
*/
public boolean addModule(final SoftwareModule softwareModule) {
// we cannot allow that modules are added without a type defined
if (type == null) {
throw new DistributionSetTypeUndefinedException();
}
// check if it is allowed to such a module to this DS type
if (!type.containsModuleType(softwareModule.getType())) {
throw new UnsupportedSoftwareModuleForThisDistributionSetException();
}
final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
if (found.isPresent()) {
return false;
}
final long allready = modules.stream()
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
if (allready >= softwareModule.getType().getMaxAssignments()) {
final Optional<SoftwareModule> sameKey = modules.stream()
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst();
modules.remove(sameKey.get());
}
if (modules.add(softwareModule)) {
complete = type.checkComplete(this);
return true;
}
return false;
}
boolean addModule(SoftwareModule softwareModule);
/**
* Removed given {@link SoftwareModule} from this DS instance.
@@ -250,19 +65,7 @@ public class DistributionSet extends NamedVersionedEntity {
* to remove
* @return <code>true</code> if element was found and removed
*/
public boolean removeModule(final SoftwareModule softwareModule) {
final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
if (found.isPresent()) {
modules.remove(found.get());
complete = type.checkComplete(this);
return true;
}
return false;
}
boolean removeModule(SoftwareModule softwareModule);
/**
* Searches through modules for the given type.
@@ -272,26 +75,12 @@ public class DistributionSet extends NamedVersionedEntity {
* @return SoftwareModule of given type or <code>null</code> if not in the
* list.
*/
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type))
.findFirst();
SoftwareModule findFirstModuleByType(SoftwareModuleType type);
if (result.isPresent()) {
return result.get();
}
DistributionSetType getType();
return null;
}
void setType(DistributionSetType type);
public DistributionSetType getType() {
return type;
}
boolean isComplete();
public void setType(final DistributionSetType type) {
this.type = type;
}
public boolean isComplete() {
return complete;
}
}
}

View File

@@ -8,73 +8,10 @@
*/
package org.eclipse.hawkbit.repository.model;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
public interface DistributionSetMetadata extends MetaData {
/**
* Meta data for {@link DistributionSet}.
*
*/
@IdClass(DsMetadataCompositeKey.class)
@Entity
@Table(name = "sp_ds_metadata")
public class DistributionSetMetadata extends MetaData {
private static final long serialVersionUID = 1L;
void setDistributionSet(DistributionSet distributionSet);
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds"))
private DistributionSet distributionSet;
DistributionSet getDistributionSet();
public DistributionSetMetadata() {
// default public constructor for JPA
}
public DistributionSetMetadata(final String key, final DistributionSet distributionSet, final String value) {
super(key, value);
this.distributionSet = distributionSet;
}
public DsMetadataCompositeKey getId() {
return new DsMetadataCompositeKey(distributionSet, getKey());
}
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = distributionSet;
}
public DistributionSet getDistributionSet() {
return distributionSet;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((distributionSet == null) ? 0 : distributionSet.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
}
final DistributionSetMetadata other = (DistributionSetMetadata) obj;
if (distributionSet == null) {
if (other.distributionSet != null) {
return false;
}
} else if (!distributionSet.equals(other.distributionSet)) {
return false;
}
return true;
}
}
}

View File

@@ -10,77 +10,8 @@ package org.eclipse.hawkbit.repository.model;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Index;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
public interface DistributionSetTag extends Tag {
/**
* A {@link DistributionSetTag} is used to describe DistributionSet attributes
* and use them also for filtering the DistributionSet list.
*
*/
@Entity
@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 DistributionSetTag extends Tag {
private static final long serialVersionUID = 1L;
List<DistributionSet> getAssignedToDistributionSet();
@ManyToMany(mappedBy = "tags", targetEntity = DistributionSet.class, fetch = FetchType.LAZY)
private List<DistributionSet> assignedToDistributionSet;
/**
* Public constructor.
*
* @param name
* of the {@link DistributionSetTag}
**/
public DistributionSetTag(final String name) {
super(name, null, null);
}
/**
* Public constructor.
*
* @param name
* of the {@link DistributionSetTag}
* @param description
* of the {@link DistributionSetTag}
* @param colour
* of tag in UI
*/
public DistributionSetTag(final String name, final String description, final String colour) {
super(name, description, colour);
}
DistributionSetTag() {
super();
}
public List<DistributionSet> getAssignedToDistributionSet() {
return assignedToDistributionSet;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof DistributionSetTag)) {
return false;
}
return true;
}
}
}

View File

@@ -8,109 +8,26 @@
*/
package org.eclipse.hawkbit.repository.model;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.eclipse.hawkbit.repository.jpa.model.DistributionSetTypeElement;
/**
* A distribution set type defines which software module types can or have to be
* {@link DistributionSet}.
*
*/
@Entity
@Table(name = "sp_distribution_set_type", indexes = {
@Index(name = "sp_idx_distribution_set_type_01", columnList = "tenant,deleted"),
@Index(name = "sp_idx_distribution_set_type_prim", columnList = "tenant,id") }, uniqueConstraints = {
@UniqueConstraint(columnNames = { "name", "tenant" }, name = "uk_dst_name"),
@UniqueConstraint(columnNames = { "type_key", "tenant" }, name = "uk_dst_key") })
public class DistributionSetType extends NamedEntity {
private static final long serialVersionUID = 1L;
@OneToMany(targetEntity = DistributionSetTypeElement.class, cascade = {
CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "distribution_set_type", insertable = false, updatable = false)
private final Set<DistributionSetTypeElement> elements = new HashSet<>();
@Column(name = "type_key", nullable = false, length = 64)
private String key;
@Column(name = "colour", nullable = true, length = 16)
private String colour;
@Column(name = "deleted")
private boolean deleted = false;
public DistributionSetType() {
// default public constructor for JPA
}
/**
* Standard constructor.
*
* @param key
* of the type (unique)
* @param name
* of the type (unique)
* @param description
* of the type
*/
public DistributionSetType(final String key, final String name, final String description) {
this(key, name, description, null);
}
/**
* Constructor.
*
* @param key
* of the type
* @param name
* of the type
* @param description
* of the type
* @param color
* of the type. It will be null by default
*/
public DistributionSetType(final String key, final String name, final String description, final String color) {
super(name, description);
this.key = key;
colour = color;
}
public interface DistributionSetType extends NamedEntity {
/**
* @return the deleted
*/
public boolean isDeleted() {
return deleted;
}
boolean isDeleted();
/**
* @param deleted
* the deleted to set
*/
public void setDeleted(final boolean deleted) {
this.deleted = deleted;
}
void setDeleted(boolean deleted);
public Set<SoftwareModuleType> getMandatoryModuleTypes() {
return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet());
}
Set<SoftwareModuleType> getMandatoryModuleTypes();
public Set<SoftwareModuleType> getOptionalModuleTypes() {
return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet());
}
Set<SoftwareModuleType> getOptionalModuleTypes();
/**
* Checks if the given {@link SoftwareModuleType} is in this
@@ -120,15 +37,7 @@ public class DistributionSetType extends NamedEntity {
* search for
* @return <code>true</code> if found
*/
public boolean containsModuleType(final SoftwareModuleType softwareModuleType) {
for (final DistributionSetTypeElement distributionSetTypeElement : elements) {
if (distributionSetTypeElement.getSmType().equals(softwareModuleType)) {
return true;
}
}
return false;
}
boolean containsModuleType(SoftwareModuleType softwareModuleType);
/**
* Checks if the given {@link SoftwareModuleType} is in this
@@ -139,11 +48,7 @@ public class DistributionSetType extends NamedEntity {
* search for
* @return <code>true</code> if found
*/
public boolean containsMandatoryModuleType(final SoftwareModuleType softwareModuleType) {
return elements.stream().filter(element -> element.isMandatory())
.filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent();
}
boolean containsMandatoryModuleType(SoftwareModuleType softwareModuleType);
/**
* Checks if the given {@link SoftwareModuleType} is in this
@@ -154,11 +59,7 @@ public class DistributionSetType extends NamedEntity {
* search for by {@link SoftwareModuleType#getId()}
* @return <code>true</code> if found
*/
public boolean containsMandatoryModuleType(final Long softwareModuleTypeId) {
return elements.stream().filter(element -> element.isMandatory())
.filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent();
}
boolean containsMandatoryModuleType(Long softwareModuleTypeId);
/**
* Checks if the given {@link SoftwareModuleType} is in this
@@ -169,11 +70,7 @@ public class DistributionSetType extends NamedEntity {
* search for
* @return <code>true</code> if found
*/
public boolean containsOptionalModuleType(final SoftwareModuleType softwareModuleType) {
return elements.stream().filter(element -> !element.isMandatory())
.filter(element -> element.getSmType().equals(softwareModuleType)).findFirst().isPresent();
}
boolean containsOptionalModuleType(SoftwareModuleType softwareModuleType);
/**
* Checks if the given {@link SoftwareModuleType} is in this
@@ -184,11 +81,7 @@ public class DistributionSetType extends NamedEntity {
* search by {@link SoftwareModuleType#getId()}
* @return <code>true</code> if found
*/
public boolean containsOptionalModuleType(final Long softwareModuleTypeId) {
return elements.stream().filter(element -> !element.isMandatory())
.filter(element -> element.getSmType().getId().equals(softwareModuleTypeId)).findFirst().isPresent();
}
boolean containsOptionalModuleType(Long softwareModuleTypeId);
/**
* Compares the modules of this {@link DistributionSetType} and the given
@@ -198,9 +91,7 @@ public class DistributionSetType extends NamedEntity {
* to compare with
* @return <code>true</code> if the lists are identical.
*/
public boolean areModuleEntriesIdentical(final DistributionSetType dsType) {
return new HashSet<DistributionSetTypeElement>(dsType.elements).equals(elements);
}
boolean areModuleEntriesIdentical(DistributionSetType dsType);
/**
* Adds {@link SoftwareModuleType} that is optional for the
@@ -210,11 +101,7 @@ public class DistributionSetType extends NamedEntity {
* to add
* @return updated instance
*/
public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) {
elements.add(new DistributionSetTypeElement(this, smType, false));
return this;
}
DistributionSetType addOptionalModuleType(SoftwareModuleType smType);
/**
* Adds {@link SoftwareModuleType} that is mandatory for the
@@ -224,11 +111,7 @@ public class DistributionSetType extends NamedEntity {
* to add
* @return updated instance
*/
public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) {
elements.add(new DistributionSetTypeElement(this, smType, true));
return this;
}
DistributionSetType addMandatoryModuleType(SoftwareModuleType smType);
/**
* Removes {@link SoftwareModuleType} from the list.
@@ -237,25 +120,11 @@ public class DistributionSetType extends NamedEntity {
* to remove
* @return updated instance
*/
public DistributionSetType removeModuleType(final Long smTypeId) {
// we search by id (standard equals compares also revison)
final Optional<DistributionSetTypeElement> found = elements.stream()
.filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst();
DistributionSetType removeModuleType(Long smTypeId);
if (found.isPresent()) {
elements.remove(found.get());
}
String getKey();
return this;
}
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
void setKey(String key);
/**
* @param distributionSet
@@ -263,26 +132,10 @@ public class DistributionSetType extends NamedEntity {
* @return <code>true</code> if the all mandatory software module types are
* in the system.
*/
public boolean checkComplete(final DistributionSet distributionSet) {
return distributionSet.getModules().stream().map(module -> module.getType()).collect(Collectors.toList())
.containsAll(getMandatoryModuleTypes());
}
boolean checkComplete(DistributionSet distributionSet);
public String getColour() {
return colour;
}
String getColour();
public void setColour(final String colour) {
this.colour = colour;
}
void setColour(final String colour);
public Set<DistributionSetTypeElement> getElements() {
return elements;
}
@Override
public String toString() {
return "DistributionSetType [key=" + key + ", isDeleted()=" + isDeleted() + ", getId()=" + getId() + "]";
}
}
}

View File

@@ -8,125 +8,20 @@
*/
package org.eclipse.hawkbit.repository.model;
import java.net.URL;
public interface ExternalArtifact extends Artifact {
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
ExternalArtifactProvider getExternalArtifactProvider();
/**
* External artifact representation with all the necessary information to
* generate an artifact {@link URL} at runtime.
*
*/
@Table(name = "sp_external_artifact", indexes = {
@Index(name = "sp_idx_external_artifact_prim", columnList = "id,tenant") })
@Entity
public class ExternalArtifact extends Artifact {
private static final long serialVersionUID = 1L;
String getUrl();
@ManyToOne
@JoinColumn(name = "provider", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_art_to_ext_provider"))
private ExternalArtifactProvider externalArtifactProvider;
String getUrlSuffix();
@Column(name = "url_suffix", length = 512)
private String urlSuffix;
// CascadeType.PERSIST as we register ourself at the BSM
@ManyToOne(optional = false, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_external_assigned_sm"))
private SoftwareModule softwareModule;
/**
* Default constructor.
*/
public ExternalArtifact() {
super();
}
/**
* Constructs {@link ExternalArtifact}.
*
* @param externalArtifactProvider
* of the artifact
* @param urlSuffix
* of the artifact
* @param softwareModule
* of the artifact
*/
public ExternalArtifact(@NotNull final ExternalArtifactProvider externalArtifactProvider, final String urlSuffix,
final SoftwareModule softwareModule) {
setSoftwareModule(softwareModule);
this.externalArtifactProvider = externalArtifactProvider;
if (urlSuffix != null) {
this.urlSuffix = urlSuffix;
} else {
this.urlSuffix = externalArtifactProvider.getDefaultSuffix();
}
}
/**
* @return the softwareModule
*/
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
public final void setSoftwareModule(final SoftwareModule softwareModule) {
this.softwareModule = softwareModule;
this.softwareModule.addArtifact(this);
}
public ExternalArtifactProvider getExternalArtifactProvider() {
return externalArtifactProvider;
}
public String getUrl() {
return new StringBuilder().append(externalArtifactProvider.getBasePath()).append(urlSuffix).toString();
}
public String getUrlSuffix() {
return urlSuffix;
}
public void setExternalArtifactProvider(final ExternalArtifactProvider externalArtifactProvider) {
this.externalArtifactProvider = externalArtifactProvider;
}
void setExternalArtifactProvider(ExternalArtifactProvider externalArtifactProvider);
/**
* @param urlSuffix
* the urlSuffix to set
*/
public void setUrlSuffix(final String urlSuffix) {
this.urlSuffix = urlSuffix;
}
void setUrlSuffix(String urlSuffix);
@Override
public int hashCode() { // NOSONAR - as this is generated
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof ExternalArtifact)) {
return false;
}
return true;
}
}
}

View File

@@ -8,69 +8,14 @@
*/
package org.eclipse.hawkbit.repository.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;
public interface ExternalArtifactProvider extends NamedEntity {
/**
* External repositories for artifact storage. The SP server provides URLs for
* the targets to download from these external resources but does not access
* them itself.
*
*/
@Table(name = "sp_external_provider", indexes = {
@Index(name = "sp_idx_external_provider_prim", columnList = "tenant,id") })
@Entity
public class ExternalArtifactProvider extends NamedEntity {
private static final long serialVersionUID = 1L;
String getBasePath();
@Column(name = "base_url", length = 512, nullable = false)
private String basePath;
String getDefaultSuffix();
@Column(name = "default_url_suffix", length = 512, nullable = true)
private String defaultSuffix;
void setBasePath(String basePath);
/**
* Constructs {@link ExternalArtifactProvider} based on given properties.
*
* @param name
* of the provided
* @param description
* which is optional
* @param baseURL
* of all {@link ExternalArtifact}s of the provider
* @param defaultUrlSuffix
* that is used if {@link ExternalArtifact#getUrlSuffix()} is
* empty.
*/
public ExternalArtifactProvider(final String name, final String description, final String baseURL,
final String defaultUrlSuffix) {
super(name, description);
basePath = baseURL;
defaultSuffix = defaultUrlSuffix;
}
void setDefaultSuffix(String defaultSuffix);
ExternalArtifactProvider() {
super();
defaultSuffix = "";
basePath = "";
}
public String getBasePath() {
return basePath;
}
public String getDefaultSuffix() {
return defaultSuffix;
}
public void setBasePath(final String basePath) {
this.basePath = basePath;
}
public void setDefaultSuffix(final String defaultSuffix) {
this.defaultSuffix = defaultSuffix;
}
}
}

View File

@@ -8,106 +8,8 @@
*/
package org.eclipse.hawkbit.repository.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
public interface LocalArtifact extends Artifact {
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSFile;
String getFilename();
/**
* Tenant specific locally stored artifact representation that is used by
* {@link SoftwareModule} . It contains all information that is provided by the
* user while all SP server generated information related to the artifact (hash,
* length) is stored directly with the binary itself.
*
*
*
*/
@Table(name = "sp_artifact", indexes = { @Index(name = "sp_idx_artifact_01", columnList = "tenant,software_module"),
@Index(name = "sp_idx_artifact_prim", columnList = "tenant,id") })
@Entity
public class LocalArtifact extends Artifact {
private static final long serialVersionUID = 1L;
@NotNull
@Column(name = "gridfs_file_name", length = 40)
private String gridFsFileName;
@NotNull
@Column(name = "provided_file_name", length = 256)
private String filename;
@ManyToOne(optional = false, cascade = { CascadeType.PERSIST })
@JoinColumn(name = "software_module", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_assigned_sm"))
private SoftwareModule softwareModule;
/**
* Default constructor.
*/
public LocalArtifact() {
super();
}
/**
* Constructs artifact.
*
* @param gridFsFileName
* that is the link to the {@link GridFS} entity.
* @param filename
* that is used by {@link GridFSFile} store.
* @param softwareModule
* of this artifact
*/
public LocalArtifact(@NotNull final String gridFsFileName, @NotNull final String filename,
final SoftwareModule softwareModule) {
setSoftwareModule(softwareModule);
this.gridFsFileName = gridFsFileName;
this.filename = filename;
}
@Override
public int hashCode() { // NOSONAR - as this is generated
final int prime = 31;
int result = super.hashCode();
result = prime * result + this.getClass().getName().hashCode();
return result;
}
@Override
public boolean equals(final Object obj) { // NOSONAR - as this is generated
if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof LocalArtifact)) {
return false;
}
return true;
}
@Override
public SoftwareModule getSoftwareModule() {
return softwareModule;
}
public final void setSoftwareModule(final SoftwareModule softwareModule) {
this.softwareModule = softwareModule;
this.softwareModule.addArtifact(this);
}
public String getGridFsFileName() {
return gridFsFileName;
}
public String getFilename() {
return filename;
}
}
}

Some files were not shown because too many files have changed in this diff Show More