Feature horizontal scalability (#305)
Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
committed by
Kai Zimmermann
parent
07cb62a3dd
commit
866bc72114
@@ -10,6 +10,8 @@ package org.eclipse.hawkbit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
@@ -26,6 +28,8 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
||||
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
|
||||
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.JpaArtifactManagement;
|
||||
import org.eclipse.hawkbit.repository.jpa.JpaControllerManagement;
|
||||
import org.eclipse.hawkbit.repository.jpa.JpaDeploymentManagement;
|
||||
@@ -45,20 +49,19 @@ import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler;
|
||||
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
|
||||
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignScheduler;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||
import org.eclipse.hawkbit.repository.jpa.event.JpaEventEntityManager;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParserValidationOracle;
|
||||
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
|
||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -77,7 +80,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* General configuration for hawkBit's Repository.
|
||||
@@ -93,8 +95,6 @@ import com.google.common.eventbus.EventBus;
|
||||
@EnableScheduling
|
||||
@EntityScan("org.eclipse.hawkbit.repository.jpa.model")
|
||||
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@@ -163,14 +163,6 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
return EntityInterceptorHolder.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the singleton instance of the {@link CacheManagerHolder}
|
||||
*/
|
||||
@Bean
|
||||
public CacheManagerHolder cacheManagerHolder() {
|
||||
return CacheManagerHolder.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the singleton instance of the
|
||||
@@ -273,9 +265,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TenantStatsManagement tenantStatsManagement() {
|
||||
final TenantStatsManagement mgmt = new JpaTenantStatsManagement();
|
||||
eventBus.register(mgmt);
|
||||
return mgmt;
|
||||
return new JpaTenantStatsManagement();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -400,6 +390,32 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
return new JpaEntityFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link EventEntityManagerHolder} bean.
|
||||
*
|
||||
* @return a new {@link EventEntityManagerHolder}
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EventEntityManagerHolder eventEntityManagerHolder() {
|
||||
return EventEntityManagerHolder.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link EventEntityManager} bean.
|
||||
*
|
||||
* @param aware
|
||||
* the tenant aware
|
||||
* @param entityManager
|
||||
* the entitymanager
|
||||
* @return a new {@link EventEntityManager}
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EventEntityManager eventEntityManager(final TenantAware aware, final EntityManager entityManager) {
|
||||
return new JpaEventEntityManager(aware, entityManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link AutoAssignChecker} bean.
|
||||
*
|
||||
@@ -415,9 +431,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AutoAssignChecker autoAssignChecker(TargetFilterQueryManagement targetFilterQueryManagement,
|
||||
TargetManagement targetManagement, DeploymentManagement deploymentManagement,
|
||||
PlatformTransactionManager transactionManager) {
|
||||
public AutoAssignChecker autoAssignChecker(final TargetFilterQueryManagement targetFilterQueryManagement,
|
||||
final TargetManagement targetManagement, final DeploymentManagement deploymentManagement,
|
||||
final PlatformTransactionManager transactionManager) {
|
||||
return new AutoAssignChecker(targetFilterQueryManagement, targetManagement, deploymentManagement,
|
||||
transactionManager);
|
||||
}
|
||||
@@ -437,8 +453,10 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public AutoAssignScheduler autoAssignScheduler(TenantAware tenantAware, SystemManagement systemManagement,
|
||||
SystemSecurityContext systemSecurityContext, AutoAssignChecker autoAssignChecker) {
|
||||
public AutoAssignScheduler autoAssignScheduler(final TenantAware tenantAware,
|
||||
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext,
|
||||
final AutoAssignChecker autoAssignChecker) {
|
||||
return new AutoAssignScheduler(tenantAware, systemManagement, systemSecurityContext, autoAssignChecker);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -24,10 +23,10 @@ import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
|
||||
import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheWriteNotify;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus_;
|
||||
@@ -41,7 +40,6 @@ import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
@@ -49,10 +47,13 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
|
||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
@@ -86,9 +87,6 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
@Autowired
|
||||
private TargetInfoRepository targetInfoRepository;
|
||||
|
||||
@Autowired
|
||||
private SoftwareModuleRepository softwareModuleRepository;
|
||||
|
||||
@Autowired
|
||||
private ActionStatusRepository actionStatusRepository;
|
||||
|
||||
@@ -105,11 +103,17 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
private TenantConfigurationManagement tenantConfigurationManagement;
|
||||
|
||||
@Autowired
|
||||
private CacheWriteNotify cacheWriteNotify;
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Autowired
|
||||
private SystemSecurityContext systemSecurityContext;
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public String getPollingTime() {
|
||||
final TenantConfigurationKey configurationKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
|
||||
@@ -178,12 +182,6 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
return actionRepository.findFirstByTargetAndActive(new Sort(Direction.ASC, "id"), (JpaTarget) target, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SoftwareModule> findSoftwareModulesByDistributionSet(final DistributionSet distributionSet) {
|
||||
return Collections
|
||||
.unmodifiableList(softwareModuleRepository.findByAssignedTo((JpaDistributionSet) distributionSet));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action findActionWithDetails(final Long actionId) {
|
||||
return actionRepository.findById(actionId);
|
||||
@@ -480,7 +478,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
@Override
|
||||
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
|
||||
final Long shippedBytesOverall) {
|
||||
cacheWriteNotify.downloadProgress(statusId, requestedBytes, shippedBytesSinceLast, shippedBytesOverall);
|
||||
eventPublisher.publishEvent(new DownloadProgressEvent(tenantAware.getCurrentTenant(), shippedBytesSinceLast,
|
||||
applicationContext.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,12 +30,10 @@ import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.ActionFields;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
|
||||
@@ -51,11 +49,9 @@ 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.rsql.RSQLUtility;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
@@ -63,20 +59,22 @@ 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.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
@@ -90,7 +88,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* JPA implementation for {@link DeploymentManagement}.
|
||||
@@ -110,9 +107,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
@Autowired
|
||||
private DistributionSetRepository distributoinSetRepository;
|
||||
|
||||
@Autowired
|
||||
private SoftwareModuleRepository softwareModuleRepository;
|
||||
|
||||
@Autowired
|
||||
private TargetRepository targetRepository;
|
||||
|
||||
@@ -129,14 +123,14 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
private AuditorAware<String> auditorProvider;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
@Autowired
|
||||
private SystemSecurityContext systemSecurityContext;
|
||||
|
||||
@Autowired
|
||||
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||
|
||||
@@ -316,21 +310,18 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
|
||||
LOG.debug("assignDistribution({}) finished {}", set, result);
|
||||
|
||||
final List<JpaSoftwareModule> softwareModules = softwareModuleRepository.findByAssignedTo(set);
|
||||
|
||||
// detaching as it is not necessary to persist the set itself
|
||||
entityManager.detach(set);
|
||||
|
||||
sendDistributionSetAssignmentEvent(targets, targetIdsCancellList, targetIdsToActions, softwareModules);
|
||||
sendDistributionSetAssignmentEvent(targets, targetIdsCancellList, targetIdsToActions);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void sendDistributionSetAssignmentEvent(final List<JpaTarget> targets, final Set<Long> targetIdsCancellList,
|
||||
final Map<String, JpaAction> targetIdsToActions, final List<JpaSoftwareModule> softwareModules) {
|
||||
final Map<String, JpaAction> targetIdsToActions) {
|
||||
targets.stream().filter(t -> !!!targetIdsCancellList.contains(t.getId()))
|
||||
.forEach(t -> assignDistributionSetEvent(t, targetIdsToActions.get(t.getControllerId()).getId(),
|
||||
softwareModules));
|
||||
.forEach(t -> assignDistributionSetEvent(targetIdsToActions.get(t.getControllerId())));
|
||||
}
|
||||
|
||||
private static JpaAction createTargetAction(final Map<String, TargetWithActionType> targetsWithActionMap,
|
||||
@@ -349,17 +340,11 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
return actionForTarget;
|
||||
}
|
||||
|
||||
private void assignDistributionSetEvent(final JpaTarget target, final Long actionId,
|
||||
final List<JpaSoftwareModule> modules) {
|
||||
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
|
||||
private void assignDistributionSetEvent(final Action action) {
|
||||
((JpaTargetInfo) action.getTarget().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(), target,
|
||||
actionId, softwareModules));
|
||||
});
|
||||
afterCommit.afterCommit(() -> eventPublisher
|
||||
.publishEvent(new TargetAssignDistributionSetEvent(action, applicationContext.getId())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,7 +416,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
|
||||
/**
|
||||
* Sends the {@link CancelTargetAssignmentEvent} for a specific target to
|
||||
* the {@link EventBus}.
|
||||
* the eventPublisher.
|
||||
*
|
||||
* @param target
|
||||
* the Target which has been assigned to a distribution set
|
||||
@@ -439,7 +424,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
||||
* the action id of the assignment
|
||||
*/
|
||||
private void cancelAssignDistributionSetEvent(final Target target, final Long actionId) {
|
||||
afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target, actionId)));
|
||||
afterCommit.afterCommit(() -> eventPublisher
|
||||
.publishEvent(new CancelTargetAssignmentEvent(target, actionId, applicationContext.getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -534,11 +520,7 @@ 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<JpaSoftwareModule> softwareModules = softwareModuleRepository
|
||||
.findByAssignedTo((JpaDistributionSet) savedAction.getDistributionSet());
|
||||
// send distribution set assignment event
|
||||
|
||||
assignDistributionSetEvent((JpaTarget) savedAction.getTarget(), savedAction.getId(), softwareModules);
|
||||
assignDistributionSetEvent(savedAction);
|
||||
}
|
||||
return savedAction;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,7 @@ 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.eventbus.event.DistributionDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityLockedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
@@ -57,6 +56,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -68,7 +69,6 @@ import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link DistributionSetManagement}.
|
||||
@@ -103,7 +103,10 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
private ActionRepository actionRepository;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
@@ -146,18 +149,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
}
|
||||
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0,
|
||||
toBeChangedDSs.size(), Collections.emptyList(),
|
||||
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag,
|
||||
tenantAware.getCurrentTenant());
|
||||
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag);
|
||||
} else {
|
||||
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(),
|
||||
0, Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)),
|
||||
Collections.emptyList(), myTag, tenantAware.getCurrentTenant());
|
||||
Collections.emptyList(), myTag);
|
||||
}
|
||||
|
||||
final DistributionSetTagAssignmentResult resultAssignment = result;
|
||||
afterCommit.afterCommit(() -> eventBus
|
||||
.post(new DistributionSetTagAssigmentResultEvent(resultAssignment, tenantAware.getCurrentTenant())));
|
||||
|
||||
// no reason to persist the tag
|
||||
entityManager.detach(myTag);
|
||||
return result;
|
||||
@@ -187,7 +185,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
|
||||
// soft delete assigned
|
||||
if (!assigned.isEmpty()) {
|
||||
Long[] dsIds = assigned.toArray(new Long[assigned.size()]);
|
||||
final Long[] dsIds = assigned.toArray(new Long[assigned.size()]);
|
||||
distributionSetRepository.deleteDistributionSet(dsIds);
|
||||
targetFilterQueryRepository.unsetAutoAssignDistributionSet(dsIds);
|
||||
}
|
||||
@@ -203,8 +201,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
distributionSetRepository.deleteByIdIn(toHardDelete);
|
||||
}
|
||||
|
||||
Arrays.stream(distributionSetIDs)
|
||||
.forEach(dsId -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), dsId)));
|
||||
Arrays.stream(distributionSetIDs).forEach(dsId -> eventPublisher.publishEvent(
|
||||
new DistributionSetDeletedEvent(tenantAware.getCurrentTenant(), dsId, applicationContext.getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -710,16 +708,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
|
||||
allDs.forEach(ds -> ds.addTag(tag));
|
||||
|
||||
final List<DistributionSet> save = Collections.unmodifiableList(distributionSetRepository.save(allDs));
|
||||
|
||||
afterCommit.afterCommit(() -> {
|
||||
|
||||
final DistributionSetTagAssignmentResult result = new DistributionSetTagAssignmentResult(0, save.size(), 0,
|
||||
save, Collections.emptyList(), tag, tenantAware.getCurrentTenant());
|
||||
eventBus.post(new DistributionSetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant()));
|
||||
});
|
||||
|
||||
return save;
|
||||
return Collections.unmodifiableList(distributionSetRepository.save(allDs));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,6 @@ import org.eclipse.hawkbit.repository.report.model.SeriesTime;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -81,7 +80,6 @@ public class JpaReportManagement implements ReportManagement {
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Override
|
||||
@Cacheable("targetStatus")
|
||||
public DataReportSeries<TargetUpdateStatus> targetStatus() {
|
||||
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
@@ -106,7 +104,44 @@ public class JpaReportManagement implements ReportManagement {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("distributionUsageAssigned")
|
||||
public DataReportSeries<SeriesTime> targetsLastPoll() {
|
||||
|
||||
final LocalDateTime now = LocalDateTime.now();
|
||||
final LocalDateTime beforeHour = now.minusHours(1);
|
||||
final LocalDateTime beforeDay = now.minusDays(1);
|
||||
final LocalDateTime beforeWeek = now.minusWeeks(1);
|
||||
final LocalDateTime beforeMonth = now.minusMonths(1);
|
||||
final LocalDateTime beforeYear = now.minusYears(1);
|
||||
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
final List<DataReportSeriesItem<SeriesTime>> resultList = new ArrayList<>();
|
||||
|
||||
// hours
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.HOUR,
|
||||
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, beforeHour, now)).getSingleResult()));
|
||||
// days
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.DAY, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeDay, beforeHour)).getSingleResult()));
|
||||
// weeks
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.WEEK, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeWeek, beforeDay)).getSingleResult()));
|
||||
// months
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MONTH, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeMonth, beforeWeek)).getSingleResult()));
|
||||
// years
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.YEAR, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeYear, beforeMonth)).getSingleResult()));
|
||||
// years
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MORE_THAN_YEAR,
|
||||
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, beforeYear)).getSingleResult()));
|
||||
// never
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.NEVER,
|
||||
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, null)).getSingleResult()));
|
||||
|
||||
return new DataReportSeries<>("TargetLastPoll", resultList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InnerOuterDataReportSeries<String>> distributionUsageAssigned(final int topXEntries) {
|
||||
|
||||
// top X entries distribution usage
|
||||
@@ -132,7 +167,6 @@ public class JpaReportManagement implements ReportManagement {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("distributionUsageInstalled")
|
||||
public List<InnerOuterDataReportSeries<String>> distributionUsageInstalled(final int topXEntries) {
|
||||
// top X entries distribution usage
|
||||
final CriteriaBuilder cbTopX = entityManager.getCriteriaBuilder();
|
||||
@@ -157,7 +191,6 @@ public class JpaReportManagement implements ReportManagement {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("targetsCreatedOverPeriod")
|
||||
public <T extends Serializable> DataReportSeries<T> targetsCreatedOverPeriod(final DateType<T> dateType,
|
||||
final LocalDateTime from, final LocalDateTime to) {
|
||||
final Query createNativeQuery = entityManager
|
||||
@@ -208,7 +241,6 @@ public class JpaReportManagement implements ReportManagement {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("feedbackReceivedOverTime")
|
||||
public <T extends Serializable> DataReportSeries<T> feedbackReceivedOverTime(final DateType<T> dateType,
|
||||
final LocalDateTime from, final LocalDateTime to) {
|
||||
final Query createNativeQuery = entityManager
|
||||
@@ -223,47 +255,8 @@ public class JpaReportManagement implements ReportManagement {
|
||||
return new DataReportSeries<>("FeedbackRecieved", reportItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable("targetsLastPoll")
|
||||
public DataReportSeries<SeriesTime> targetsLastPoll() {
|
||||
|
||||
final LocalDateTime now = LocalDateTime.now();
|
||||
final LocalDateTime beforeHour = now.minusHours(1);
|
||||
final LocalDateTime beforeDay = now.minusDays(1);
|
||||
final LocalDateTime beforeWeek = now.minusWeeks(1);
|
||||
final LocalDateTime beforeMonth = now.minusMonths(1);
|
||||
final LocalDateTime beforeYear = now.minusYears(1);
|
||||
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
final List<DataReportSeriesItem<SeriesTime>> resultList = new ArrayList<>();
|
||||
|
||||
// hours
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.HOUR,
|
||||
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, beforeHour, now)).getSingleResult()));
|
||||
// days
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.DAY, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeDay, beforeHour)).getSingleResult()));
|
||||
// weeks
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.WEEK, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeWeek, beforeDay)).getSingleResult()));
|
||||
// months
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MONTH, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeMonth, beforeWeek)).getSingleResult()));
|
||||
// years
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.YEAR, entityManager
|
||||
.createQuery(createCountSelectTargetsLastPoll(cb, beforeYear, beforeMonth)).getSingleResult()));
|
||||
// years
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.MORE_THAN_YEAR,
|
||||
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, beforeYear)).getSingleResult()));
|
||||
// never
|
||||
resultList.add(new DataReportSeriesItem<SeriesTime>(SeriesTime.NEVER,
|
||||
entityManager.createQuery(createCountSelectTargetsLastPoll(cb, null, null)).getSingleResult()));
|
||||
|
||||
return new DataReportSeries<>("TargetLastPoll", resultList);
|
||||
}
|
||||
|
||||
private CriteriaQuery<Long> createCountSelectTargetsLastPoll(final CriteriaBuilder cb, final LocalDateTime from,
|
||||
final LocalDateTime to) {
|
||||
private static CriteriaQuery<Long> createCountSelectTargetsLastPoll(final CriteriaBuilder cb,
|
||||
final LocalDateTime from, final LocalDateTime to) {
|
||||
|
||||
Long start = null;
|
||||
Long end = null;
|
||||
@@ -289,8 +282,8 @@ public class JpaReportManagement implements ReportManagement {
|
||||
return countSelect;
|
||||
}
|
||||
|
||||
private List<InnerOuterDataReportSeries<String>> mapDistirbutionUsageResultToDataReport(final int topXEntries,
|
||||
final List<Object[]> resultListTop) {
|
||||
private static List<InnerOuterDataReportSeries<String>> mapDistirbutionUsageResultToDataReport(
|
||||
final int topXEntries, final List<Object[]> resultListTop) {
|
||||
final List<InnerOuterDataReportSeries<String>> innerOuterReport = new ArrayList<>();
|
||||
final Map<DSName, InnerOuter> map = new LinkedHashMap<>();
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ import org.eclipse.hawkbit.repository.RolloutFields;
|
||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheWriteNotify;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
|
||||
@@ -54,6 +54,7 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -110,15 +111,15 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private NoCountPagingRepository criteriaNoCountDao;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager txManager;
|
||||
|
||||
@Autowired
|
||||
private CacheWriteNotify cacheWriteNotify;
|
||||
|
||||
@Autowired
|
||||
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||
|
||||
@@ -249,13 +250,6 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
int groupIndex = 0;
|
||||
final Long totalCount = savedRollout.getTotalTargets();
|
||||
final int groupSize = (int) Math.ceil((double) totalCount / (double) amountOfGroups);
|
||||
// validate if the amount of groups that will be created are the amount
|
||||
// of groups that the client what's to have created.
|
||||
int amountGroupValidated = amountOfGroups;
|
||||
final int amountGroupCreation = (int) (Math.ceil((double) totalCount / (double) groupSize));
|
||||
if (amountGroupCreation == (amountOfGroups - 1)) {
|
||||
amountGroupValidated--;
|
||||
}
|
||||
RolloutGroup lastSavedGroup = null;
|
||||
while (pageIndex < totalCount) {
|
||||
groupIndex++;
|
||||
@@ -282,11 +276,11 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
|
||||
targetGroup
|
||||
.forEach(target -> rolloutTargetGroupRepository.save(new RolloutTargetGroup(savedGroup, target)));
|
||||
cacheWriteNotify.rolloutGroupCreated(groupIndex, savedRollout.getId(), savedGroup.getId(),
|
||||
amountGroupValidated, groupIndex);
|
||||
eventPublisher.publishEvent(new RolloutGroupCreatedEvent(group, context.getId()));
|
||||
pageIndex += groupSize;
|
||||
}
|
||||
|
||||
savedRollout.setRolloutGroupsCreated(groupIndex);
|
||||
savedRollout.setStatus(RolloutStatus.READY);
|
||||
return rolloutRepository.save(savedRollout);
|
||||
}
|
||||
|
||||
@@ -598,12 +598,10 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
||||
|
||||
@Override
|
||||
public List<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) {
|
||||
return Collections
|
||||
.unmodifiableList(softwareModuleMetadataRepository
|
||||
.findAll((Specification<JpaSoftwareModuleMetadata>) (root, query,
|
||||
cb) -> cb.and(cb.equal(
|
||||
root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id),
|
||||
softwareModuleId))));
|
||||
return Collections.unmodifiableList(softwareModuleMetadataRepository
|
||||
.findAll((Specification<JpaSoftwareModuleMetadata>) (root, query, cb) -> cb
|
||||
.and(cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id),
|
||||
softwareModuleId))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,12 +17,12 @@ import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TagFields;
|
||||
import org.eclipse.hawkbit.repository.TagManagement;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
@@ -33,8 +33,11 @@ import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -44,8 +47,6 @@ import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* JP>A implementation of {@link TagManagement}.
|
||||
*
|
||||
@@ -67,14 +68,17 @@ public class JpaTagManagement implements TagManagement {
|
||||
private DistributionSetRepository distributionSetRepository;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private AfterTransactionCommitExecutor afterCommit;
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
@Autowired
|
||||
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||
|
||||
@@ -96,7 +100,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
|
||||
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagCreatedEvent(save)));
|
||||
afterCommit.afterCommit(
|
||||
() -> eventPublisher.publishEvent(new TargetTagCreatedEvent(save, applicationContext.getId())));
|
||||
|
||||
return save;
|
||||
}
|
||||
@@ -115,7 +120,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
});
|
||||
|
||||
final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags));
|
||||
afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new TargetTagCreatedEvent(tag))));
|
||||
afterCommit.afterCommit(() -> save.forEach(
|
||||
tag -> eventPublisher.publishEvent(new TargetTagCreatedEvent(tag, applicationContext.getId()))));
|
||||
return save;
|
||||
}
|
||||
|
||||
@@ -137,7 +143,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
// finally delete the tag itself
|
||||
targetTagRepository.deleteByName(targetTagName);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagDeletedEvent(tag)));
|
||||
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
|
||||
new TargetTagDeletedEvent(tenantAware.getCurrentTenant(), tag.getId(), applicationContext.getId())));
|
||||
|
||||
}
|
||||
|
||||
@@ -174,7 +181,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
checkNotNull(targetTag.getName());
|
||||
checkNotNull(targetTag.getId());
|
||||
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
|
||||
afterCommit.afterCommit(() -> eventBus.post(new TargetTagUpdateEvent(save)));
|
||||
afterCommit.afterCommit(() -> eventPublisher
|
||||
.publishEvent(new TargetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
|
||||
return save;
|
||||
}
|
||||
|
||||
@@ -197,7 +205,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
|
||||
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagCreatedEvent(save)));
|
||||
afterCommit.afterCommit(() -> eventPublisher
|
||||
.publishEvent(new DistributionSetTagCreatedEvent(save, applicationContext.getId())));
|
||||
return save;
|
||||
}
|
||||
|
||||
@@ -216,8 +225,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
}
|
||||
final List<DistributionSetTag> save = Collections
|
||||
.unmodifiableList(distributionSetTagRepository.save(distributionSetTags));
|
||||
afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new DistributionSetTagCreatedEvent(tag))));
|
||||
|
||||
afterCommit.afterCommit(() -> save.forEach(tag -> eventPublisher
|
||||
.publishEvent(new DistributionSetTagCreatedEvent(tag, applicationContext.getId()))));
|
||||
return save;
|
||||
}
|
||||
|
||||
@@ -238,7 +247,9 @@ public class JpaTagManagement implements TagManagement {
|
||||
|
||||
distributionSetTagRepository.deleteByName(tagName);
|
||||
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagDeletedEvent(tag)));
|
||||
afterCommit.afterCommit(
|
||||
() -> eventPublisher.publishEvent(new DistributionSetTagDeletedEvent(tenantAware.getCurrentTenant(),
|
||||
tag.getId(), applicationContext.getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -248,7 +259,8 @@ public class JpaTagManagement implements TagManagement {
|
||||
checkNotNull(distributionSetTag.getName());
|
||||
checkNotNull(distributionSetTag.getId());
|
||||
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
|
||||
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagUpdateEvent(save)));
|
||||
afterCommit.afterCommit(() -> eventPublisher.publishEvent(
|
||||
new DistributionSetTagUpdateEvent(save, EventPublisherHolder.getInstance().getApplicationId())));
|
||||
|
||||
return save;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
@@ -32,8 +31,8 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.repository.FilterParams;
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent;
|
||||
import org.eclipse.hawkbit.repository.TimestampCalculator;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||
@@ -56,6 +55,8 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -71,7 +72,6 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* JPA implementation of {@link TargetManagement}.
|
||||
@@ -97,7 +97,10 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
private NoCountPagingRepository criteriaNoCountDao;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
@@ -218,7 +221,8 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
public void deleteTargets(final Collection<Long> targetIDs) {
|
||||
targetRepository.deleteByIdIn(targetIDs);
|
||||
|
||||
targetIDs.forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId)));
|
||||
targetIDs.forEach(targetId -> eventPublisher.publishEvent(
|
||||
new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId, applicationContext.getId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -368,8 +372,6 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(0, 0, alreadyAssignedTargets.size(),
|
||||
Collections.emptyList(), alreadyAssignedTargets, tag);
|
||||
|
||||
afterCommit.afterCommit(
|
||||
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -380,9 +382,6 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)),
|
||||
Collections.emptyList(), tag);
|
||||
|
||||
afterCommit.afterCommit(
|
||||
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
|
||||
|
||||
// no reason to persist the tag
|
||||
entityManager.detach(tag);
|
||||
return result;
|
||||
@@ -396,15 +395,7 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds));
|
||||
|
||||
allTargets.forEach(target -> target.addTag(tag));
|
||||
final List<Target> save = Collections.unmodifiableList(targetRepository.save(allTargets));
|
||||
|
||||
afterCommit.afterCommit(() -> {
|
||||
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save,
|
||||
Collections.emptyList(), tag);
|
||||
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
|
||||
});
|
||||
|
||||
return save;
|
||||
return Collections.unmodifiableList(targetRepository.save(allTargets));
|
||||
}
|
||||
|
||||
private List<Target> unAssignTag(final Collection<Target> targets, final TargetTag tag) {
|
||||
@@ -413,13 +404,7 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
|
||||
toUnassign.forEach(target -> target.removeTag(tag));
|
||||
|
||||
final List<Target> save = Collections.unmodifiableList(targetRepository.save(toUnassign));
|
||||
afterCommit.afterCommit(() -> {
|
||||
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(),
|
||||
Collections.emptyList(), save, tag);
|
||||
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
|
||||
});
|
||||
return save;
|
||||
return Collections.unmodifiableList(targetRepository.save(toUnassign));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -612,11 +597,6 @@ public class JpaTargetManagement implements TargetManagement {
|
||||
return countByCriteriaAPI(specList);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
void destroy() {
|
||||
eventBus.unregister(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Modifying
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
|
||||
@@ -46,8 +48,8 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
|
||||
public <T> TenantConfigurationValue<T> getConfigurationValue(final TenantConfigurationKey configurationKey,
|
||||
final Class<T> propertyType) {
|
||||
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(
|
||||
final TenantConfigurationKey configurationKey, final Class<T> propertyType) {
|
||||
validateTenantConfigurationDataType(configurationKey, propertyType);
|
||||
|
||||
final TenantConfiguration tenantConfiguration = tenantConfigurationRepository
|
||||
@@ -75,7 +77,7 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(
|
||||
public <T extends Serializable> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(
|
||||
final TenantConfigurationKey configurationKey, final Class<T> propertyType,
|
||||
final TenantConfiguration tenantConfiguration) {
|
||||
if (tenantConfiguration != null) {
|
||||
@@ -95,7 +97,8 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> TenantConfigurationValue<T> getConfigurationValue(final TenantConfigurationKey configurationKey) {
|
||||
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(
|
||||
final TenantConfigurationKey configurationKey) {
|
||||
return getConfigurationValue(configurationKey, configurationKey.getDataType());
|
||||
}
|
||||
|
||||
@@ -122,8 +125,8 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
|
||||
@CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Modifying
|
||||
public <T> TenantConfigurationValue<T> addOrUpdateConfiguration(final TenantConfigurationKey configurationKey,
|
||||
final T value) {
|
||||
public <T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(
|
||||
final TenantConfigurationKey configurationKey, final T value) {
|
||||
|
||||
if (!configurationKey.getDataType().isAssignableFrom(value.getClass())) {
|
||||
throw new TenantConfigurationValidatorException(String.format(
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
@@ -43,7 +44,7 @@ public interface RolloutRepository
|
||||
* @return the count of the updated rows. Zero if no row has been updated
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
|
||||
@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);
|
||||
|
||||
@@ -89,13 +89,13 @@ public interface SoftwareModuleRepository
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param set
|
||||
* @param setId
|
||||
* to search for
|
||||
* @return all {@link SoftwareModule}s that are assigned to given
|
||||
* {@link DistributionSet}
|
||||
*/
|
||||
@EntityGraph(value = "SoftwareModule.artifacts", type = EntityGraphType.LOAD)
|
||||
List<JpaSoftwareModule> findByAssignedTo(JpaDistributionSet set);
|
||||
List<JpaSoftwareModule> findByAssignedToId(Long setId);
|
||||
|
||||
/**
|
||||
* @param pageable
|
||||
|
||||
@@ -15,7 +15,6 @@ 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;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
@@ -53,6 +52,5 @@ public interface TargetInfoRepository {
|
||||
*
|
||||
* @return persisted or updated {@link Entity}
|
||||
*/
|
||||
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
|
||||
<S extends JpaTargetInfo> S save(S entity);
|
||||
}
|
||||
|
||||
@@ -41,9 +41,6 @@ import com.google.common.collect.Maps;
|
||||
* {@link Aspect} catches persistence exceptions and wraps them to custom
|
||||
* specific exceptions Additionally it checks and prevents access to certain
|
||||
* packages. Logging aspect which logs the call stack
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Aspect
|
||||
public class ExceptionMappingAspectHandler implements Ordered {
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
|
||||
/**
|
||||
* Marks an field within a JPA entity as transient and this field should be
|
||||
* loaded from a configured {@link CacheManager} by using the JPA entity
|
||||
* listeners.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @see CacheFieldEntityListener
|
||||
*/
|
||||
@Target({ FIELD })
|
||||
@Retention(RUNTIME)
|
||||
@Transient
|
||||
public @interface CacheField {
|
||||
|
||||
/**
|
||||
* @return the cache key name for this cacheable field which is used to
|
||||
* store the value.
|
||||
*/
|
||||
String key();
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
|
||||
|
||||
/**
|
||||
* RepositoryConstants for cache keys used in multiple classes.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @see CacheFieldEntityListener
|
||||
* @see CacheWriteNotify
|
||||
* @see CacheField
|
||||
*
|
||||
*/
|
||||
public final class CacheKeys {
|
||||
|
||||
/**
|
||||
* The cache key name for the {@link UpdateActionStatus} download progress
|
||||
* event.
|
||||
*/
|
||||
public static final String DOWNLOAD_PROGRESS_PERCENT = "download.progress.percent";
|
||||
public static final String ROLLOUT_GROUP_CREATED = "rollout.group.created";
|
||||
public static final String ROLLOUT_GROUP_TOTAL = "rollout.group.total";
|
||||
|
||||
/**
|
||||
* utility class only private constructor.
|
||||
*/
|
||||
private CacheKeys() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the cache key for a specific entity. The cache key must be
|
||||
* different for each different identifiable entity by its ID.
|
||||
*
|
||||
* @param entityId
|
||||
* the ID of the entity to build the specific cache key for this
|
||||
* entity
|
||||
* @param cacheKey
|
||||
* the cache key for the field to be cached
|
||||
* @return the combined cache key based on the given {@code entityId} and
|
||||
* {@code cacheKey}
|
||||
*/
|
||||
public static String entitySpecificCacheKey(final String entityId, final String cacheKey) {
|
||||
return entityId + "." + cacheKey;
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.math.DoubleMath;
|
||||
|
||||
/**
|
||||
* An service which combines the functionality for functional use cases to write
|
||||
* into the cache an notify the writing to the cache to the {@link EventBus}.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class CacheWriteNotify {
|
||||
private static final int DOWNLOAD_PROGRESS_MAX = 100;
|
||||
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
/**
|
||||
* writes the download progress into the cache
|
||||
* {@link CacheKeys#DOWNLOAD_PROGRESS_PERCENT} and notifies the
|
||||
* {@link EventBus} with a {@link DownloadProgressEvent}.
|
||||
*
|
||||
* @param statusId
|
||||
* the ID of the {@link ActionStatus}
|
||||
* @param requestedBytes
|
||||
* requested bytes of the request
|
||||
* @param shippedBytesSinceLast
|
||||
* since last event
|
||||
* @param shippedBytesOverall
|
||||
* for the download request
|
||||
*/
|
||||
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
|
||||
final Long shippedBytesOverall) {
|
||||
|
||||
final Cache cache = cacheManager.getCache(ActionStatus.class.getName());
|
||||
final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId),
|
||||
CacheKeys.DOWNLOAD_PROGRESS_PERCENT);
|
||||
|
||||
final int progressPercent = DoubleMath.roundToInt(shippedBytesOverall * 100.0 / requestedBytes,
|
||||
RoundingMode.DOWN);
|
||||
|
||||
if (progressPercent < DOWNLOAD_PROGRESS_MAX) {
|
||||
cache.put(cacheKey, progressPercent);
|
||||
} else {
|
||||
// in case we reached progress 100 delete the cache value again
|
||||
// because otherwise he will
|
||||
// keep there forever
|
||||
cache.evict(cacheKey);
|
||||
}
|
||||
|
||||
eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, requestedBytes,
|
||||
shippedBytesSinceLast, shippedBytesOverall));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the {@link CacheKeys#ROLLOUT_GROUP_CREATED} and
|
||||
* {@link CacheKeys#ROLLOUT_GROUP_TOTAL} into the cache and notfies the
|
||||
* {@link EventBus} with a {@link RolloutGroupCreatedEvent}.
|
||||
*
|
||||
* @param revision
|
||||
* the revision of the event
|
||||
* @param rolloutId
|
||||
* the ID of the rollout the group has been created
|
||||
* @param rolloutGroupId
|
||||
* the ID of the rollout group which has been created
|
||||
* @param totalRolloutGroup
|
||||
* the total number of rollout groups for this rollout
|
||||
* @param createdRolloutGroup
|
||||
* the number of already created groups of the rollout
|
||||
*/
|
||||
public void rolloutGroupCreated(final long revision, final Long rolloutId, final Long rolloutGroupId,
|
||||
final int totalRolloutGroup, final int createdRolloutGroup) {
|
||||
|
||||
final Cache cache = cacheManager.getCache(Rollout.class.getName());
|
||||
final String cacheKeyGroupTotal = CacheKeys.entitySpecificCacheKey(String.valueOf(rolloutId),
|
||||
CacheKeys.ROLLOUT_GROUP_TOTAL);
|
||||
final String cacheKeyGroupCreated = CacheKeys.entitySpecificCacheKey(String.valueOf(rolloutId),
|
||||
CacheKeys.ROLLOUT_GROUP_CREATED);
|
||||
if (createdRolloutGroup < totalRolloutGroup) {
|
||||
cache.put(cacheKeyGroupTotal, totalRolloutGroup);
|
||||
cache.put(cacheKeyGroupCreated, createdRolloutGroup);
|
||||
} else {
|
||||
// in case we reached progress 100 delete the cache value again
|
||||
// because otherwise he will keep there forever
|
||||
cache.evict(cacheKeyGroupTotal);
|
||||
cache.evict(cacheKeyGroupCreated);
|
||||
}
|
||||
eventBus.post(new RolloutGroupCreatedEvent(tenantAware.getCurrentTenant(), revision, rolloutId, rolloutGroupId,
|
||||
totalRolloutGroup, createdRolloutGroup));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cacheManager
|
||||
* the cacheManager to set
|
||||
*/
|
||||
void setCacheManager(final CacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param eventBus
|
||||
* the eventBus to set
|
||||
*/
|
||||
void setEventBus(final EventBus eventBus) {
|
||||
this.eventBus = eventBus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tenantAware
|
||||
* the tenantAware to set
|
||||
*/
|
||||
void setTenantAware(final TenantAware tenantAware) {
|
||||
this.tenantAware = tenantAware;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.event;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* A TenantAwareEvent entity manager, which loads an entity by id and type for
|
||||
* remote events.
|
||||
*/
|
||||
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
|
||||
public class JpaEventEntityManager implements EventEntityManager {
|
||||
|
||||
private final TenantAware tenantAware;
|
||||
|
||||
private final EntityManager entityManager;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tenantAware
|
||||
* the tenant aware
|
||||
* @param entityManager
|
||||
* the entity manager
|
||||
*/
|
||||
public JpaEventEntityManager(final TenantAware tenantAware, final EntityManager entityManager) {
|
||||
this.tenantAware = tenantAware;
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends TenantAwareBaseEntity> E findEntity(final String tenant, final Long id,
|
||||
final Class<E> entityType) {
|
||||
return tenantAware.runAsTenant(tenant, () -> entityManager.find(entityType, id));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/**
|
||||
* 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.eventbus;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.EventSubscriber;
|
||||
import org.eclipse.hawkbit.eventbus.event.Event;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.eventbus.AllowConcurrentEvents;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
/**
|
||||
* Collects and merges fine grained events to more generic events and push them
|
||||
* in a fixed delay on the events bus. This helps for code which are not
|
||||
* interested in all fine grained events, e.g. UI code. The UI code is not
|
||||
* interested in handling the flood of events, so collecting the events and
|
||||
* merge them to one event together and post them in a fixed interval is easier
|
||||
* to consume e.g. for push notifications on UI.
|
||||
*
|
||||
*/
|
||||
@EventSubscriber
|
||||
@Service
|
||||
public class EventMerger {
|
||||
|
||||
private static final Set<RolloutEventKey> rolloutEvents = ConcurrentHashMap.newKeySet();
|
||||
private static final Set<RolloutEventKey> rolloutGroupEvents = ConcurrentHashMap.newKeySet();
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
/**
|
||||
* Checks if there are events to publish in the fixed interval.
|
||||
*/
|
||||
@Scheduled(initialDelay = 10000, fixedDelay = 2000)
|
||||
public void rolloutEventScheduler() {
|
||||
final Iterator<RolloutEventKey> rolloutIterator = rolloutEvents.iterator();
|
||||
while (rolloutIterator.hasNext()) {
|
||||
final RolloutEventKey eventKey = rolloutIterator.next();
|
||||
eventBus.post(new RolloutChangeEvent(1, eventKey.tenant, eventKey.rolloutId));
|
||||
rolloutIterator.remove();
|
||||
}
|
||||
|
||||
final Iterator<RolloutEventKey> rolloutGroupIterator = rolloutGroupEvents.iterator();
|
||||
while (rolloutGroupIterator.hasNext()) {
|
||||
final RolloutEventKey eventKey = rolloutGroupIterator.next();
|
||||
eventBus.post(new RolloutGroupChangeEvent(1, eventKey.tenant, eventKey.rolloutId, eventKey.rolloutGroupId));
|
||||
rolloutGroupIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the event bus to retrieve all necessary events to collect and
|
||||
* merge.
|
||||
*
|
||||
* @param event
|
||||
* the event on the event bus
|
||||
*/
|
||||
@Subscribe
|
||||
@AllowConcurrentEvents
|
||||
public void onEvent(final Event event) {
|
||||
Long rolloutId = null;
|
||||
Long rolloutGroupId = null;
|
||||
if (event instanceof ActionCreatedEvent) {
|
||||
rolloutId = getRolloutId(((ActionCreatedEvent) event).getEntity().getRollout());
|
||||
rolloutGroupId = getRolloutGroupId(((ActionCreatedEvent) event).getEntity().getRolloutGroup());
|
||||
} else if (event instanceof ActionPropertyChangeEvent) {
|
||||
rolloutId = getRolloutId(((ActionPropertyChangeEvent) event).getEntity().getRollout());
|
||||
rolloutGroupId = getRolloutGroupId(((ActionPropertyChangeEvent) event).getEntity().getRolloutGroup());
|
||||
} else if (event instanceof RolloutPropertyChangeEvent) {
|
||||
rolloutId = ((RolloutPropertyChangeEvent) event).getEntity().getId();
|
||||
} else if (event instanceof RolloutGroupCreatedEvent) {
|
||||
rolloutId = ((RolloutGroupCreatedEvent) event).getRolloutId();
|
||||
rolloutGroupId = ((RolloutGroupCreatedEvent) event).getRolloutGroupId();
|
||||
} else if (event instanceof RolloutGroupPropertyChangeEvent) {
|
||||
final RolloutGroup rolloutGroup = ((RolloutGroupPropertyChangeEvent) event).getEntity();
|
||||
rolloutId = rolloutGroup.getRollout().getId();
|
||||
rolloutGroupId = rolloutGroup.getId();
|
||||
}
|
||||
|
||||
if (rolloutId != null) {
|
||||
rolloutEvents.add(new RolloutEventKey(rolloutId, event.getTenant()));
|
||||
if (rolloutGroupId != null) {
|
||||
rolloutGroupEvents.add(new RolloutEventKey(rolloutId, rolloutGroupId, event.getTenant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Long getRolloutGroupId(final RolloutGroup rolloutGroup) {
|
||||
if (rolloutGroup != null) {
|
||||
return rolloutGroup.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Long getRolloutId(final Rollout rollout) {
|
||||
if (rollout != null) {
|
||||
return rollout.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rollout key in the concurrent set to be hold.
|
||||
*
|
||||
* @author Michael Hirsch
|
||||
*
|
||||
*/
|
||||
private static final class RolloutEventKey {
|
||||
private final Long rolloutId;
|
||||
private final String tenant;
|
||||
private final Long rolloutGroupId;
|
||||
|
||||
private RolloutEventKey(final Long rolloutId, final Long rolloutGroupId, final String tenant) {
|
||||
this.rolloutGroupId = rolloutGroupId;
|
||||
this.rolloutId = rolloutId;
|
||||
this.tenant = tenant;
|
||||
}
|
||||
|
||||
private RolloutEventKey(final Long rolloutId, final String tenant) {
|
||||
this(rolloutId, null, tenant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {// NOSONAR - as this is generated
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((rolloutGroupId == null) ? 0 : rolloutGroupId.hashCode());
|
||||
result = prime * result + ((rolloutId == null) ? 0 : rolloutId.hashCode());
|
||||
result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {// NOSONAR - as this is
|
||||
// generated
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final RolloutEventKey other = (RolloutEventKey) obj;
|
||||
if (rolloutGroupId == null) {
|
||||
if (other.rolloutGroupId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!rolloutGroupId.equals(other.rolloutGroupId)) {
|
||||
return false;
|
||||
}
|
||||
if (rolloutId == null) {
|
||||
if (other.rolloutId != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!rolloutId.equals(other.rolloutId)) {
|
||||
return false;
|
||||
}
|
||||
if (tenant == null) {
|
||||
if (other.tenant != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!tenant.equals(other.tenant)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@Access(AccessType.FIELD)
|
||||
@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class,
|
||||
EntityInterceptorListener.class })
|
||||
@EntityListeners({ AuditingEntityListener.class, EntityPropertyChangeListener.class, EntityInterceptorListener.class })
|
||||
public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ import javax.persistence.PrePersist;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder;
|
||||
import org.eclipse.persistence.annotations.Multitenant;
|
||||
import org.eclipse.persistence.annotations.MultitenantType;
|
||||
import org.eclipse.persistence.annotations.TenantDiscriminatorColumn;
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/**
|
||||
* 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.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import javax.persistence.PostLoad;
|
||||
import javax.persistence.PostRemove;
|
||||
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.Cache.ValueWrapper;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.hateoas.Identifiable;
|
||||
|
||||
/**
|
||||
* An JPA entity listener which enriches the JPA entity fields which are
|
||||
* annotated with {@link CacheField} with values from the {@link CacheManager}.
|
||||
* Only JPA entities which are implementing {@link Identifiable} can be handled
|
||||
* by this entity listener cause the cache keys are calculated with the ID of
|
||||
* the entity.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CacheFieldEntityListener {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CacheFieldEntityListener.class);
|
||||
|
||||
/**
|
||||
* enriches the JPA entities after loading the entity from the SQL database.
|
||||
*
|
||||
* @param target
|
||||
* the target which has been loaded from the database
|
||||
*/
|
||||
@PostLoad
|
||||
public void postLoad(final Object target) {
|
||||
if (target instanceof Identifiable) {
|
||||
final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager();
|
||||
@SuppressWarnings("rawtypes")
|
||||
final String id = ((Identifiable) target).getId().toString();
|
||||
final Class<? extends Object> type = target.getClass();
|
||||
findCacheFields(type, id, (field, cacheKey, id1) -> {
|
||||
final Cache cache = cacheManager.getCache(type.getName());
|
||||
final ValueWrapper valueWrapper = cache.get(CacheKeys.entitySpecificCacheKey(id1.toString(), cacheKey));
|
||||
if (valueWrapper != null && valueWrapper.get() != null) {
|
||||
FieldUtils.writeField(field, target, valueWrapper.get(), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* deletes the associated cache fields from the cache when deleted the
|
||||
* entity from the database.
|
||||
*
|
||||
* @param target
|
||||
* the entity which has been deleted
|
||||
*/
|
||||
@PostRemove
|
||||
public void postDelete(final Object target) {
|
||||
if (target instanceof Identifiable) {
|
||||
final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager();
|
||||
@SuppressWarnings("rawtypes")
|
||||
final String id = ((Identifiable) target).getId().toString();
|
||||
final Class<? extends Object> type = target.getClass();
|
||||
findCacheFields(type, id, (field, cacheKey, id1) -> {
|
||||
final Cache cache = cacheManager.getCache(type.getName());
|
||||
cache.evict(CacheKeys.entitySpecificCacheKey(id1.toString(), cacheKey));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void findCacheFields(final Class<? extends Object> type, final Serializable id,
|
||||
final CacheFieldCallback callback) {
|
||||
final Field[] declaredFields = type.getDeclaredFields();
|
||||
for (final Field field : declaredFields) {
|
||||
if (field.getAnnotation(CacheField.class) != null) {
|
||||
try {
|
||||
final CacheField annotation = field.getAnnotation(CacheField.class);
|
||||
callback.fromCache(field, annotation.key(), id);
|
||||
} catch (final IllegalAccessException e) {
|
||||
LOGGER.error("cannot access the field {} for the entity {}, ignoring the cacheable field", field,
|
||||
type, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface CacheFieldCallback {
|
||||
/**
|
||||
* callback methods which is called by the
|
||||
* {@link CacheFieldEntityListener#findCacheFields(Class, Serializable, CacheFieldCallback)}
|
||||
* in case a field is annotated with {@link CacheField}.
|
||||
*
|
||||
* @param field
|
||||
* the field which is annotaed with {@link CacheField}
|
||||
* @param cacheKey
|
||||
* the configured cache key in the annotation
|
||||
* {@link CacheField#key()}
|
||||
* @param id
|
||||
* the ID of the entity
|
||||
* @throws IllegalAccessException
|
||||
* in case the field cannot be accessed
|
||||
*/
|
||||
void fromCache(final Field field, final String cacheKey, Serializable id) throws IllegalAccessException;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,16 +30,15 @@ import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
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.Target;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
@@ -187,13 +186,14 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(this));
|
||||
EventPublisherHolder.getInstance().getEventPublisher()
|
||||
.publishEvent(new ActionCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus()
|
||||
.post(new ActionPropertyChangeEvent(this, EntityPropertyChangeHelper.getChangeSet(descriptorEvent)));
|
||||
EventPublisherHolder.getInstance().getEventPublisher()
|
||||
.publishEvent(new ActionUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,11 +25,8 @@ import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedAttributeNode;
|
||||
import javax.persistence.NamedEntityGraph;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
@@ -72,13 +69,6 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
|
||||
@Column(name = "detail_message", length = 512)
|
||||
private List<String> messages;
|
||||
|
||||
/**
|
||||
* Note: filled only in {@link Status#DOWNLOAD}.
|
||||
*/
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
|
||||
private short downloadProgressPercent;
|
||||
|
||||
/**
|
||||
* Creates a new {@link ActionStatus} object.
|
||||
*
|
||||
@@ -121,11 +111,6 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
|
||||
// JPA default constructor.
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getDownloadProgressPercent() {
|
||||
return downloadProgressPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getOccurredAt() {
|
||||
return occurredAt;
|
||||
|
||||
@@ -12,9 +12,9 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
@@ -34,14 +34,11 @@ import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
|
||||
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
@@ -52,8 +49,13 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.eclipse.persistence.queries.UpdateObjectQuery;
|
||||
import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord;
|
||||
import org.eclipse.persistence.sessions.changesets.ObjectChangeSet;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* Jpa implementation of {@link DistributionSet}.
|
||||
@@ -347,27 +349,40 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(this));
|
||||
publishEventWithEventPublisher(
|
||||
new DistributionSetCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
|
||||
|
||||
final Map<String, PropertyChange> changeSet = EntityPropertyChangeHelper.getChangeSet(descriptorEvent);
|
||||
EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(this));
|
||||
publishEventWithEventPublisher(
|
||||
new DistributionSetUpdateEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
|
||||
if (changeSet.containsKey(DELETED_PROPERTY)) {
|
||||
final Boolean newDeleted = (Boolean) changeSet.get(DELETED_PROPERTY).getNewValue();
|
||||
if (newDeleted) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId()));
|
||||
}
|
||||
if (isSoftDeleted(descriptorEvent)) {
|
||||
publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(),
|
||||
EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId()));
|
||||
publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(),
|
||||
EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
private static void publishEventWithEventPublisher(final ApplicationEvent event) {
|
||||
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(event);
|
||||
}
|
||||
|
||||
private static boolean isSoftDeleted(final DescriptorEvent event) {
|
||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
||||
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
|
||||
.filter(record -> record instanceof DirectToFieldChangeRecord)
|
||||
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
|
||||
|
||||
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
|
||||
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,12 +28,9 @@ import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
@@ -86,12 +83,7 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
|
||||
@Column(name = "total_targets")
|
||||
private long totalTargets;
|
||||
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL)
|
||||
private int rolloutGroupsTotal;
|
||||
|
||||
@Transient
|
||||
@CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED)
|
||||
@Column(name = "rollout_groups_created")
|
||||
private int rolloutGroupsCreated;
|
||||
|
||||
@Transient
|
||||
@@ -172,14 +164,6 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
|
||||
this.totalTargets = totalTargets;
|
||||
}
|
||||
|
||||
public int getRolloutGroupsTotal() {
|
||||
return rolloutGroupsTotal;
|
||||
}
|
||||
|
||||
public void setRolloutGroupsTotal(final int rolloutGroupsTotal) {
|
||||
this.rolloutGroupsTotal = rolloutGroupsTotal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRolloutGroupsCreated() {
|
||||
return rolloutGroupsCreated;
|
||||
@@ -215,8 +199,8 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus()
|
||||
.post(new RolloutPropertyChangeEvent(this, EntityPropertyChangeHelper.getChangeSet(descriptorEvent)));
|
||||
EventPublisherHolder.getInstance().getEventPublisher()
|
||||
.publishEvent(new RolloutUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,11 @@ import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
/**
|
||||
@@ -256,8 +255,9 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(
|
||||
new RolloutGroupPropertyChangeEvent(this, EntityPropertyChangeHelper.getChangeSet(descriptorEvent)));
|
||||
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new RolloutGroupUpdatedEvent(this,
|
||||
|
||||
EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,10 +37,9 @@ import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
@@ -49,6 +48,7 @@ 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.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
@@ -278,16 +278,19 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(this));
|
||||
EventPublisherHolder.getInstance().getEventPublisher()
|
||||
.publishEvent(new TargetCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(this));
|
||||
EventPublisherHolder.getInstance().getEventPublisher()
|
||||
.publishEvent(new TargetUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new TargetDeletedEvent(getTenant(), getId()));
|
||||
EventPublisherHolder.getInstance().getEventPublisher()
|
||||
.publishEvent(new TargetDeletedEvent(getTenant(), getId(), EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,16 +40,16 @@ import javax.persistence.Transient;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.PollStatus;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||
@@ -338,7 +338,8 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareE
|
||||
|
||||
@Override
|
||||
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(this));
|
||||
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
|
||||
new TargetUpdatedEvent(this.getTarget(), EventPublisherHolder.getInstance().getApplicationId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* 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.helper;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.CacheManager;
|
||||
|
||||
/**
|
||||
* A singleton bean which holds the {@link CacheManager} to have to the cache
|
||||
* manager in beans not instantiated by spring e.g. JPA entities or
|
||||
* {@link CacheFieldEntityListener} which cannot be autowired.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final class CacheManagerHolder {
|
||||
|
||||
private static final CacheManagerHolder SINGLETON = new CacheManagerHolder();
|
||||
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
private CacheManagerHolder() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cache manager holder singleton instance
|
||||
*/
|
||||
public static CacheManagerHolder getInstance() {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cacheManager
|
||||
*/
|
||||
public CacheManager getCacheManager() {
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normally not used when using spring-boot then the cachemanager is
|
||||
* autowired to the CacheManagerHolder, but for testing purposes.
|
||||
*
|
||||
* @param cacheManager
|
||||
* the cache manager to set for the cache manager holder.
|
||||
*/
|
||||
public void setCacheManager(final CacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* 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.helper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent.PropertyChange;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
|
||||
import org.eclipse.persistence.queries.UpdateObjectQuery;
|
||||
import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord;
|
||||
|
||||
/**
|
||||
* Helper class to get the change set for the property changes in the Entity.
|
||||
*
|
||||
*/
|
||||
public final class EntityPropertyChangeHelper {
|
||||
|
||||
private EntityPropertyChangeHelper() {
|
||||
// noop
|
||||
}
|
||||
|
||||
/**
|
||||
* To get the map of entity property change set
|
||||
*
|
||||
* @param clazz
|
||||
* @param event
|
||||
* @return the map of the changeSet
|
||||
*/
|
||||
public static Map<String, PropertyChange> getChangeSet(final DescriptorEvent event) {
|
||||
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
|
||||
return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord)
|
||||
.map(record -> (DirectToFieldChangeRecord) record)
|
||||
.collect(Collectors.toMap(record -> record.getAttribute(),
|
||||
record -> new PropertyChange(record.getOldValue(), record.getNewValue())));
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import org.eclipse.hawkbit.repository.FieldValueConverter;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
alter table sp_ds_module drop constraint fk_ds_module_ds;
|
||||
alter table sp_ds_module
|
||||
add constraint fk_ds_module_ds
|
||||
foreign key (ds_id)
|
||||
references sp_distribution_set (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table sp_ds_module drop constraint fk_ds_module_module;
|
||||
alter table sp_ds_module
|
||||
add constraint fk_ds_module_module
|
||||
foreign key (module_id)
|
||||
references sp_base_software_module (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table sp_external_artifact drop constraint fk_external_assigned_sm;
|
||||
alter table sp_external_artifact
|
||||
add constraint fk_external_assigned_sm
|
||||
foreign key (software_module)
|
||||
references sp_base_software_module (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table sp_artifact drop constraint fk_assigned_sm;
|
||||
alter table sp_artifact
|
||||
add constraint fk_assigned_sm
|
||||
foreign key (software_module)
|
||||
references sp_base_software_module (id)
|
||||
on delete cascade;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE sp_rollout ADD column rollout_groups_created BIGINT;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
alter table sp_ds_module drop FOREIGN KEY fk_ds_module_ds;
|
||||
alter table sp_ds_module
|
||||
add constraint fk_ds_module_ds
|
||||
foreign key (ds_id)
|
||||
references sp_distribution_set (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table sp_ds_module drop FOREIGN KEY fk_ds_module_module;
|
||||
alter table sp_ds_module
|
||||
add constraint fk_ds_module_module
|
||||
foreign key (module_id)
|
||||
references sp_base_software_module (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table sp_external_artifact drop FOREIGN KEY fk_external_assigned_sm;
|
||||
alter table sp_external_artifact
|
||||
add constraint fk_external_assigned_sm
|
||||
foreign key (software_module)
|
||||
references sp_base_software_module (id)
|
||||
on delete cascade;
|
||||
|
||||
alter table sp_artifact drop FOREIGN KEY fk_assigned_sm;
|
||||
alter table sp_artifact
|
||||
add constraint fk_assigned_sm
|
||||
foreign key (software_module)
|
||||
references sp_base_software_module (id)
|
||||
on delete cascade;
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE sp_rollout ADD column rollout_groups_created BIGINT;
|
||||
|
||||
@@ -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.event.remote;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.eclipse.hawkbit.event.BusProtoStuffMessageConverter;
|
||||
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.junit.Before;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.bus.event.RemoteApplicationEvent;
|
||||
import org.springframework.cloud.bus.jackson.BusJacksonAutoConfiguration;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.support.MutableMessageHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.converter.AbstractMessageConverter;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
public abstract class AbstractRemoteEventTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private BusProtoStuffMessageConverter busProtoStuffMessageConverter;
|
||||
|
||||
private AbstractMessageConverter jacksonMessageConverter;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
final BusJacksonAutoConfiguration autoConfiguration = new BusJacksonAutoConfiguration();
|
||||
this.jacksonMessageConverter = autoConfiguration.busJsonConverter();
|
||||
ReflectionTestUtils.setField(jacksonMessageConverter, "packagesToScan",
|
||||
new String[] { "org.eclipse.hawkbit.repository.event.remote",
|
||||
ClassUtils.getPackageName(RemoteApplicationEvent.class) });
|
||||
((InitializingBean) jacksonMessageConverter).afterPropertiesSet();
|
||||
|
||||
}
|
||||
|
||||
private Message<?> createProtoStuffMessage(final TenantAwareEvent event) {
|
||||
final Map<String, Object> headers = Maps.newLinkedHashMap();
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, BusProtoStuffMessageConverter.APPLICATION_BINARY_PROTOSTUFF);
|
||||
return busProtoStuffMessageConverter.toMessage(event, new MutableMessageHeaders(headers));
|
||||
}
|
||||
|
||||
private Message<String> createJsonMessage(final Object event) {
|
||||
final Map<String, MimeType> headers = Maps.newLinkedHashMap();
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
|
||||
try {
|
||||
final String json = new ObjectMapper().writeValueAsString(event);
|
||||
final Message<String> message = MessageBuilder.withPayload(json).copyHeaders(headers).build();
|
||||
return message;
|
||||
} catch (final JsonProcessingException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Message<?> createMessageWithImmutableHeader(final TenantAwareEvent event) {
|
||||
final Map<String, Object> headers = Maps.newLinkedHashMap();
|
||||
return busProtoStuffMessageConverter.toMessage(event, new MessageHeaders(headers));
|
||||
}
|
||||
|
||||
protected TenantAwareEvent createJacksonEvent(final TenantAwareEvent event) {
|
||||
final Message<?> message = createJsonMessage(event);
|
||||
return (TenantAwareEvent) jacksonMessageConverter.fromMessage(message, event.getClass());
|
||||
}
|
||||
|
||||
protected TenantAwareEvent createProtoStuffEvent(final TenantAwareEvent event) {
|
||||
final Message<?> message = createProtoStuffMessage(event);
|
||||
return (TenantAwareEvent) busProtoStuffMessageConverter.fromMessage(message, event.getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 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.event.remote;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Entity Id Events")
|
||||
public class RemoteIdEventTest extends AbstractRemoteEventTest {
|
||||
|
||||
private static final long ENTITY_ID = 1L;
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the is ds id correct reloaded")
|
||||
public void testDistributionSetDeletedEvent() {
|
||||
assertAndCreateRemoteEvent(DistributionSetDeletedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the ds tag id is correct reloaded")
|
||||
public void testDistributionSetTagDeletedEvent() {
|
||||
assertAndCreateRemoteEvent(DistributionSetTagDeletedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target id is correct reloaded")
|
||||
public void testTargetDeletedEvent() {
|
||||
assertAndCreateRemoteEvent(TargetDeletedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target tag id is correct reloaded")
|
||||
public void testTargetTagDeletedEvent() {
|
||||
assertAndCreateRemoteEvent(TargetTagDeletedEvent.class);
|
||||
}
|
||||
|
||||
protected void assertAndCreateRemoteEvent(final Class<? extends RemoteIdEvent> eventType) {
|
||||
|
||||
final Constructor<?> constructor = Arrays.stream(eventType.getDeclaredConstructors())
|
||||
.filter(con -> con.getParameterCount() == 3).findAny()
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given event is not RemoteIdEvent compatible"));
|
||||
|
||||
try {
|
||||
final RemoteIdEvent event = (RemoteIdEvent) constructor.newInstance("tenant", ENTITY_ID, "Node");
|
||||
assertEntity(ENTITY_ID, event);
|
||||
} catch (final ReflectiveOperationException e) {
|
||||
fail("Exception should not happen " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected RemoteIdEvent assertEntity(final long id, final RemoteIdEvent event) {
|
||||
assertThat(event.getEntityId()).isSameAs(id);
|
||||
|
||||
RemoteIdEvent underTestCreatedEvent = (RemoteIdEvent) createProtoStuffEvent(event);
|
||||
assertThat(underTestCreatedEvent.getEntityId()).isEqualTo(id);
|
||||
|
||||
underTestCreatedEvent = (RemoteIdEvent) createJacksonEvent(event);
|
||||
assertThat(underTestCreatedEvent.getEntityId()).isEqualTo(id);
|
||||
|
||||
return underTestCreatedEvent;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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.event.remote;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
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.Target;
|
||||
import org.junit.Test;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("RemoteTenantAwareEvent Tests")
|
||||
public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that a immutable header is not work")
|
||||
public void testMessageWithImmutableHeader() {
|
||||
final DownloadProgressEvent downloadProgressEvent = new DownloadProgressEvent("DEFAULT", 3L, "Node");
|
||||
|
||||
try {
|
||||
createMessageWithImmutableHeader(downloadProgressEvent);
|
||||
fail("MessageConversionException should happen");
|
||||
} catch (final MessageConversionException e) {
|
||||
// ok
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the download progress reloading by remote events works")
|
||||
public void reloadDownloadProgessByRemoteEvent() {
|
||||
final DownloadProgressEvent downloadProgressEvent = new DownloadProgressEvent("DEFAULT", 3L, "Node");
|
||||
|
||||
DownloadProgressEvent remoteEvent = (DownloadProgressEvent) createProtoStuffEvent(downloadProgressEvent);
|
||||
assertThat(downloadProgressEvent).isEqualTo(remoteEvent);
|
||||
|
||||
remoteEvent = (DownloadProgressEvent) createJacksonEvent(downloadProgressEvent);
|
||||
assertThat(downloadProgressEvent).isEqualTo(remoteEvent);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that target assignment event works")
|
||||
public void testTargetAssignDistributionSetEvent() {
|
||||
final DistributionSet dsA = testdataFactory.createDistributionSet("");
|
||||
final JpaAction generateAction = (JpaAction) entityFactory.generateAction();
|
||||
generateAction.setActionType(ActionType.FORCED);
|
||||
final Target generateTarget = entityFactory.generateTarget("Test");
|
||||
final Target target = targetManagement.createTarget(generateTarget);
|
||||
generateAction.setTarget(target);
|
||||
generateAction.setDistributionSet(dsA);
|
||||
final Action action = actionRepository.save(generateAction);
|
||||
|
||||
final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent(action,
|
||||
serviceMatcher.getServiceId());
|
||||
|
||||
TargetAssignDistributionSetEvent underTest = (TargetAssignDistributionSetEvent) createProtoStuffEvent(
|
||||
assignmentEvent);
|
||||
assertTargetAssignDistributionSetEvent(action, underTest);
|
||||
|
||||
underTest = (TargetAssignDistributionSetEvent) createJacksonEvent(assignmentEvent);
|
||||
assertTargetAssignDistributionSetEvent(action, underTest);
|
||||
}
|
||||
|
||||
private void assertTargetAssignDistributionSetEvent(final Action action,
|
||||
final TargetAssignDistributionSetEvent underTest) {
|
||||
assertThat(underTest.getActionId()).isNotNull();
|
||||
assertThat(underTest.getControllerId()).isNotNull();
|
||||
assertThat(underTest.getDistributionSetId()).isNotNull();
|
||||
|
||||
assertThat(underTest.getActionId()).isEqualTo(action.getId());
|
||||
assertThat(underTest.getControllerId()).isEqualTo(action.getTarget().getControllerId());
|
||||
assertThat(underTest.getDistributionSetId()).isEqualTo(action.getDistributionSet().getId());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* 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.event.remote.entity;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.AbstractRemoteEventTest;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Entity Events")
|
||||
public abstract class AbstractRemoteEntityEventTest<E> extends AbstractRemoteEventTest {
|
||||
|
||||
protected RemoteEntityEvent<?> assertAndCreateRemoteEvent(final Class<? extends RemoteEntityEvent<?>> eventType) {
|
||||
final E baseEntity = createEntity();
|
||||
final RemoteEntityEvent<?> event = createRemoteEvent(baseEntity, eventType);
|
||||
assertEntity(baseEntity, event);
|
||||
return event;
|
||||
}
|
||||
|
||||
protected RemoteEntityEvent<?> createRemoteEvent(final E baseEntity,
|
||||
final Class<? extends RemoteEntityEvent<?>> eventType) {
|
||||
|
||||
Constructor<?> constructor = null;
|
||||
for (final Constructor<?> constructors : eventType.getDeclaredConstructors()) {
|
||||
if (constructors.getParameterCount() == 2) {
|
||||
constructor = constructors;
|
||||
}
|
||||
}
|
||||
|
||||
if (constructor == null) {
|
||||
throw new IllegalArgumentException("No suitable constructor foundes");
|
||||
}
|
||||
|
||||
try {
|
||||
return (RemoteEntityEvent<?>) constructor.newInstance(baseEntity, "Node");
|
||||
} catch (final ReflectiveOperationException e) {
|
||||
fail("Exception should not happen " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected RemoteEntityEvent<?> assertEntity(final E baseEntity, final RemoteEntityEvent<?> event) {
|
||||
assertThat(event.getEntity()).isSameAs(baseEntity);
|
||||
|
||||
RemoteEntityEvent<?> underTestCreatedEvent = (RemoteEntityEvent<?>) createProtoStuffEvent(event);
|
||||
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
|
||||
|
||||
underTestCreatedEvent = (RemoteEntityEvent<?>) createJacksonEvent(event);
|
||||
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
|
||||
return underTestCreatedEvent;
|
||||
}
|
||||
|
||||
protected abstract E createEntity();
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test ActionCreatedEvent and ActionUpdatedEvent")
|
||||
public class ActionEventTest extends AbstractRemoteEntityEventTest<Action> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the action entity reloading by remote created works")
|
||||
public void testActionCreatedEvent() {
|
||||
assertAndCreateRemoteEvent(ActionCreatedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the action entity reloading by remote updated works")
|
||||
public void testActionUpdatedEvent() {
|
||||
assertAndCreateRemoteEvent(ActionUpdatedEvent.class);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Action createEntity() {
|
||||
final JpaAction generateAction = (JpaAction) entityFactory.generateAction();
|
||||
generateAction.setActionType(ActionType.FORCED);
|
||||
final Target generateTarget = entityFactory.generateTarget("Test");
|
||||
final Target target = targetManagement.createTarget(generateTarget);
|
||||
generateAction.setTarget(target);
|
||||
return actionRepository.save(generateAction);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test DistributionSetCreatedEvent and DistributionSetUpdateEvent")
|
||||
public class DistributionSetEventTest extends AbstractRemoteEntityEventTest<DistributionSet> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the distribution set entity reloading by remote created event works")
|
||||
public void testDistributionSetCreatedEvent() {
|
||||
assertAndCreateRemoteEvent(DistributionSetCreatedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the distribution set entity reloading by remote updated event works")
|
||||
public void testDistributionSetUpdateEvent() {
|
||||
assertAndCreateRemoteEvent(DistributionSetUpdateEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DistributionSet createEntity() {
|
||||
return distributionSetManagement.createDistributionSet(entityFactory.generateDistributionSet("incomplete", "2",
|
||||
"incomplete", distributionSetManagement.findDistributionSetTypeByKey("os"), null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test DistributionSetTagCreatedEvent and DistributionSetTagUpdateEvent")
|
||||
public class DistributionSetTagEventTest extends AbstractRemoteEntityEventTest<DistributionSetTag> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the distribution set tag entity reloading by remote created event works")
|
||||
public void testDistributionSetTagCreatedEvent() {
|
||||
assertAndCreateRemoteEvent(DistributionSetTagCreatedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the distribution set tag entity reloading by remote updated event works")
|
||||
public void testDistributionSetTagUpdateEvent() {
|
||||
assertAndCreateRemoteEvent(DistributionSetTagUpdateEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DistributionSetTag createEntity() {
|
||||
return tagManagement.createDistributionSetTag(entityFactory.generateDistributionSetTag("tag1"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test RolloutUpdatedEvent")
|
||||
public class RolloutEventTest extends AbstractRemoteEntityEventTest<Rollout> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the rollout entity reloading by remote updated event works")
|
||||
public void testRolloutUpdatedEvent() {
|
||||
assertAndCreateRemoteEvent(RolloutUpdatedEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rollout createEntity() {
|
||||
targetManagement.createTarget(entityFactory.generateTarget("12345"));
|
||||
final DistributionSet ds = distributionSetManagement
|
||||
.createDistributionSet(entityFactory.generateDistributionSet("incomplete", "2", "incomplete",
|
||||
distributionSetManagement.findDistributionSetTypeByKey("os"), null));
|
||||
|
||||
final Rollout rollout = entityFactory.generateRollout();
|
||||
rollout.setName("exampleRollout");
|
||||
rollout.setTargetFilterQuery("controllerId==*");
|
||||
rollout.setDistributionSet(ds);
|
||||
|
||||
final JpaRollout entity = (JpaRollout) rolloutManagement.createRollout(rollout, 10,
|
||||
new RolloutGroupConditionBuilder().successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10")
|
||||
.build());
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* 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.event.remote.entity;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||
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.RolloutGroup.RolloutGroupSuccessCondition;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test RolloutGroupCreatedEvent and RolloutGroupUpdatedEvent")
|
||||
public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<RolloutGroup> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the rollout group entity reloading by remote created event works")
|
||||
public void testRolloutGroupCreatedEvent() {
|
||||
final RolloutGroupCreatedEvent createdEvent = (RolloutGroupCreatedEvent) assertAndCreateRemoteEvent(
|
||||
RolloutGroupCreatedEvent.class);
|
||||
assertThat(createdEvent.getRolloutId()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the rollout group entity reloading by remote updated event works")
|
||||
public void testRolloutGroupUpdatedEvent() {
|
||||
assertAndCreateRemoteEvent(RolloutGroupUpdatedEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RolloutGroup createEntity() {
|
||||
targetManagement.createTarget(entityFactory.generateTarget(UUID.randomUUID().toString()));
|
||||
final DistributionSet ds = distributionSetManagement
|
||||
.createDistributionSet(entityFactory.generateDistributionSet(UUID.randomUUID().toString(), "2",
|
||||
"incomplete", distributionSetManagement.findDistributionSetTypeByKey("os"), null));
|
||||
|
||||
final Rollout rollout = entityFactory.generateRollout();
|
||||
rollout.setName(UUID.randomUUID().toString());
|
||||
rollout.setTargetFilterQuery("controllerId==*");
|
||||
rollout.setDistributionSet(ds);
|
||||
|
||||
final JpaRollout entity = (JpaRollout) rolloutManagement.createRollout(rollout, 10,
|
||||
new RolloutGroupConditionBuilder().successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10")
|
||||
.build());
|
||||
|
||||
return rolloutManagement.findRolloutById(entity.getId()).getRolloutGroups().get(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.event.remote.entity;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test TargetCreatedEvent, TargetUpdatedEvent and CancelTargetAssignmentEvent")
|
||||
public class TargetEventTest extends AbstractRemoteEntityEventTest<Target> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target entity reloading by remote created event works")
|
||||
public void testTargetCreatedEvent() {
|
||||
assertAndCreateRemoteEvent(TargetCreatedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target entity reloading by remote updated event works")
|
||||
public void testTargetUpdatedEvent() {
|
||||
assertAndCreateRemoteEvent(TargetUpdatedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that cancel target assignment event works")
|
||||
public void testCancelTargetAssignmentEvent() {
|
||||
final Target target = createEntity();
|
||||
final CancelTargetAssignmentEvent assignmentEvent = new CancelTargetAssignmentEvent(target, 1L, "node");
|
||||
final CancelTargetAssignmentEvent underTest = (CancelTargetAssignmentEvent) assertEntity(target,
|
||||
assignmentEvent);
|
||||
|
||||
assertThat(underTest.getActionId()).isNotNull();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Target createEntity() {
|
||||
return targetManagement.createTarget(entityFactory.generateTarget("12345"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Test TargetTagCreatedEvent and TargetTagUpdateEvent")
|
||||
public class TargetTagEventTest extends AbstractRemoteEntityEventTest<TargetTag> {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target tag entity reloading by remote created event works")
|
||||
public void testTargetTagCreatedEvent() {
|
||||
assertAndCreateRemoteEvent(TargetTagCreatedEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target tag entity reloading by remote updated event works")
|
||||
public void testTargetTagUpdateEventt() {
|
||||
assertAndCreateRemoteEvent(TargetTagUpdateEvent.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TargetTag createEntity() {
|
||||
return tagManagement.createTargetTag(entityFactory.generateTargetTag("tag1"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,9 +22,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
@@ -41,20 +40,22 @@ 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.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
@@ -69,8 +70,21 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
@Stories("Deployment Management")
|
||||
public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
private EventHandlerStub eventHandlerStub;
|
||||
|
||||
private CancelEventHandlerStub cancelEventHandlerStub;
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
@Before
|
||||
public void addHandler() {
|
||||
eventHandlerStub = new EventHandlerStub();
|
||||
applicationContext.addApplicationListener(eventHandlerStub);
|
||||
|
||||
cancelEventHandlerStub = new CancelEventHandlerStub();
|
||||
applicationContext.addApplicationListener(cancelEventHandlerStub);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test verifies that the repistory retrieves the action including all defined (lazy) details.")
|
||||
@@ -86,6 +100,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(action.getTarget()).as("Target in action").isNotNull();
|
||||
assertThat(action.getTarget().getAssignedDistributionSet()).as("AssignedDistributionSet of target in action")
|
||||
.isNotNull();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -377,9 +392,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Test
|
||||
@Description("Simple deployment or distribution set to target assignment test.")
|
||||
public void assignDistributionSet2Targets() throws InterruptedException {
|
||||
|
||||
final EventHandlerMock eventHandlerMock = new EventHandlerMock(20);
|
||||
eventBus.register(eventHandlerMock);
|
||||
eventHandlerStub.setExpectedNumberOfEvents(20);
|
||||
|
||||
final String myCtrlIDPref = "myCtrlID";
|
||||
final Iterable<Target> savedNakedTargets = targetManagement
|
||||
@@ -425,7 +438,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
final List<TargetAssignDistributionSetEvent> events = eventHandlerMock.getEvents(10, TimeUnit.SECONDS);
|
||||
final List<TargetAssignDistributionSetEvent> events = eventHandlerStub.getEvents(10, TimeUnit.SECONDS);
|
||||
|
||||
assertTargetAssignDistributionSetEvents(savedDeployedTargets, ds, events);
|
||||
}
|
||||
@@ -433,8 +446,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Test
|
||||
@Description("Test that it is not possible to assign a distribution set that is not complete.")
|
||||
public void failDistributionSetAssigmentThatIsNotComplete() throws InterruptedException {
|
||||
final EventHandlerMock eventHandlerMock = new EventHandlerMock(0);
|
||||
eventBus.register(eventHandlerMock);
|
||||
eventHandlerStub.setExpectedNumberOfEvents(0);
|
||||
|
||||
final List<Target> targets = testdataFactory.createTargets(10);
|
||||
|
||||
@@ -454,21 +466,20 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
} catch (final IncompleteDistributionSetException ex) {
|
||||
}
|
||||
|
||||
// give some chance to receive events asynchronously
|
||||
Thread.sleep(1L);
|
||||
final List<TargetAssignDistributionSetEvent> events = eventHandlerStub.getEvents(5, TimeUnit.SECONDS);
|
||||
assertThat(events).as("events should be empty").isEmpty();
|
||||
|
||||
incomplete.addModule(os);
|
||||
final DistributionSet nowComplete = distributionSetManagement.updateDistributionSet(incomplete);
|
||||
|
||||
// give some chance to receive events asynchronously
|
||||
Thread.sleep(300);
|
||||
final List<TargetAssignDistributionSetEvent> events = eventHandlerMock.getEvents(1, TimeUnit.MILLISECONDS);
|
||||
assertThat(events).as("events should be empty").isEmpty();
|
||||
|
||||
final EventHandlerMock eventHandlerMockAfterCompletionOfDs = new EventHandlerMock(10);
|
||||
eventBus.register(eventHandlerMockAfterCompletionOfDs);
|
||||
eventHandlerStub.setExpectedNumberOfEvents(10);
|
||||
|
||||
assertThat(deploymentManagement.assignDistributionSet(nowComplete, targets).getAssigned())
|
||||
.as("assign ds doesn't work").isEqualTo(10);
|
||||
assertTargetAssignDistributionSetEvents(targets, nowComplete,
|
||||
eventHandlerMockAfterCompletionOfDs.getEvents(10, TimeUnit.SECONDS));
|
||||
|
||||
assertTargetAssignDistributionSetEvents(targets, nowComplete, eventHandlerStub.getEvents(15, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -485,15 +496,12 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// Each of the four targets get one assignment (4 * 1 = 4)
|
||||
final int expectedNumberOfEventsForAssignment = 4;
|
||||
final EventHandlerMock eventHandlerMock = new EventHandlerMock(expectedNumberOfEventsForAssignment);
|
||||
eventBus.register(eventHandlerMock);
|
||||
eventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForAssignment);
|
||||
|
||||
// Each of the four targets get two more assignment the which are
|
||||
// cancelled (4 * 2 = 8)
|
||||
final int expectedNumberOfEventsForCancel = 8;
|
||||
final CancelEventHandlerMock cancelEventHandlerMock = new CancelEventHandlerMock(
|
||||
expectedNumberOfEventsForCancel);
|
||||
eventBus.register(cancelEventHandlerMock);
|
||||
cancelEventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForCancel);
|
||||
|
||||
final DeploymentResult deploymentResult = prepareComplexRepo(undeployedTargetPrefix, noOfUndeployedTargets,
|
||||
deployedTargetPrefix, noOfDeployedTargets, noOfDistributionSets, "myTestDS");
|
||||
@@ -535,10 +543,10 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
.doesNotContain(Iterables.toArray(deployedTargetsFromDB, JpaTarget.class));
|
||||
|
||||
// For each of the 4 targets 1 distribution sets gets assigned
|
||||
eventHandlerMock.getEvents(10, TimeUnit.SECONDS);
|
||||
eventHandlerStub.getEvents(10, TimeUnit.SECONDS);
|
||||
|
||||
// For each of the 4 targets 2 distribution sets gets cancelled
|
||||
cancelEventHandlerMock.getEvents(10, TimeUnit.SECONDS);
|
||||
cancelEventHandlerStub.getEvents(10, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
@@ -825,7 +833,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(dsA.getOptLockRevision()).as("lock revision is wrong").isEqualTo(
|
||||
distributionSetManagement.findDistributionSetByIdWithDetails(dsA.getId()).getOptLockRevision());
|
||||
|
||||
final List<Target> targs = new ArrayList<Target>();
|
||||
final List<Target> targs = new ArrayList<>();
|
||||
targs.add(targ);
|
||||
final Iterable<Target> savedTargs = deploymentManagement.assignDistributionSet(dsA, targs).getAssignedEntity();
|
||||
targ = savedTargs.iterator().next();
|
||||
@@ -934,17 +942,20 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
private void assertTargetAssignDistributionSetEvents(final List<Target> targets, final DistributionSet ds,
|
||||
final List<TargetAssignDistributionSetEvent> events) {
|
||||
assertThat(events).isNotEmpty();
|
||||
for (final Target myt : targets) {
|
||||
boolean found = false;
|
||||
for (final TargetAssignDistributionSetEvent event : events) {
|
||||
if (event.getTarget().getControllerId().equals(myt.getControllerId())) {
|
||||
if (event.getControllerId().equals(myt.getControllerId())) {
|
||||
found = true;
|
||||
final List<Action> activeActionsByTarget = deploymentManagement.findActiveActionsByTarget(myt);
|
||||
assertThat(activeActionsByTarget).as("size of active actions for target is wrong").isNotEmpty();
|
||||
assertThat(event.getActionId()).as("Action id in database and event do not match")
|
||||
.isEqualTo(activeActionsByTarget.get(0).getId());
|
||||
assertThat(event.getSoftwareModules()).as("softwaremodule size is not correct")
|
||||
.containsOnly(ds.getModules().toArray(new SoftwareModule[ds.getModules().size()]));
|
||||
|
||||
assertThat(distributionSetManagement.findDistributionSetById(event.getDistributionSetId())
|
||||
.getModules()).as("softwaremodule size is not correct")
|
||||
.containsOnly(ds.getModules().toArray(new SoftwareModule[ds.getModules().size()]));
|
||||
}
|
||||
}
|
||||
assertThat(found).as("No event found for controller " + myt.getControllerId()).isTrue();
|
||||
@@ -952,19 +963,17 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
private class DeploymentResult
|
||||
private class DeploymentResult {
|
||||
final List<Long> deployedTargetIDs = new ArrayList<>();
|
||||
final List<Long> undeployedTargetIDs = new ArrayList<>();
|
||||
final List<Long> distributionSetIDs = new ArrayList<>();
|
||||
|
||||
{
|
||||
final List<Long> deployedTargetIDs = new ArrayList<Long>();
|
||||
final List<Long> undeployedTargetIDs = new ArrayList<Long>();
|
||||
final List<Long> distributionSetIDs = new ArrayList<Long>();
|
||||
|
||||
private final List<Target> undeployedTargets = new ArrayList<Target>();
|
||||
private final List<Target> deployedTargets = new ArrayList<Target>();
|
||||
private final List<DistributionSet> distributionSets = new ArrayList<DistributionSet>();
|
||||
private final List<Target> undeployedTargets = new ArrayList<>();
|
||||
private final List<Target> deployedTargets = new ArrayList<>();
|
||||
private final List<DistributionSet> distributionSets = new ArrayList<>();
|
||||
|
||||
public DeploymentResult(final Iterable<Target> deployedTs, final Iterable<Target> undeployedTs,
|
||||
final Iterable<DistributionSet> dss, final String deployedTargetPrefix,
|
||||
@@ -982,101 +991,97 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the distributionSetIDs
|
||||
*/
|
||||
public List<Long> getDistributionSetIDs() {
|
||||
return distributionSetIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public List<Long> getDeployedTargetIDs() {
|
||||
return deployedTargetIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public List<Target> getUndeployedTargets() {
|
||||
return undeployedTargets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public List<DistributionSet> getDistributionSets() {
|
||||
return distributionSets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public List<Target> getDeployedTargets() {
|
||||
return deployedTargets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the undeployedTargetIDs
|
||||
*/
|
||||
public List<Long> getUndeployedTargetIDs() {
|
||||
return undeployedTargetIDs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class EventHandlerMock {
|
||||
protected static class EventHandlerStub implements ApplicationListener<TargetAssignDistributionSetEvent> {
|
||||
private final List<TargetAssignDistributionSetEvent> events = Collections.synchronizedList(new LinkedList<>());
|
||||
private final CountDownLatch latch;
|
||||
private final int expectedNumberOfEvents;
|
||||
private CountDownLatch latch;
|
||||
private int expectedNumberOfEvents;
|
||||
|
||||
private EventHandlerMock(final int expectedNumberOfEvents) {
|
||||
/**
|
||||
* @param expectedNumberOfEvents
|
||||
* the expectedNumberOfEvents to set
|
||||
*/
|
||||
public void setExpectedNumberOfEvents(final int expectedNumberOfEvents) {
|
||||
events.clear();
|
||||
this.expectedNumberOfEvents = expectedNumberOfEvents;
|
||||
this.latch = new CountDownLatch(expectedNumberOfEvents);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleEvent(final TargetAssignDistributionSetEvent event) {
|
||||
events.add(event);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public List<TargetAssignDistributionSetEvent> getEvents(final long timeout, final TimeUnit unit)
|
||||
throws InterruptedException {
|
||||
latch.await(timeout, unit);
|
||||
final List<TargetAssignDistributionSetEvent> handledEvents = new LinkedList<>(events);
|
||||
final List<TargetAssignDistributionSetEvent> handledEvents = Collections
|
||||
.unmodifiableList(new LinkedList<>(events));
|
||||
assertThat(handledEvents).as("Did not receive the expected amount of events (" + expectedNumberOfEvents
|
||||
+ ") within timeout. Received events are " + handledEvents).hasSize(expectedNumberOfEvents);
|
||||
|
||||
return handledEvents;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final TargetAssignDistributionSetEvent event) {
|
||||
if (latch == null) {
|
||||
return;
|
||||
}
|
||||
events.add(event);
|
||||
latch.countDown();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class CancelEventHandlerMock {
|
||||
private static class CancelEventHandlerStub implements ApplicationListener<CancelTargetAssignmentEvent> {
|
||||
private final List<CancelTargetAssignmentEvent> events = Collections.synchronizedList(new LinkedList<>());
|
||||
private final CountDownLatch latch;
|
||||
private final int expectedNumberOfEvents;
|
||||
private CountDownLatch latch;
|
||||
private int expectedNumberOfEvents;
|
||||
|
||||
private CancelEventHandlerMock(final int expectedNumberOfEvents) {
|
||||
public void setExpectedNumberOfEvents(final int expectedNumberOfEvents) {
|
||||
events.clear();
|
||||
this.expectedNumberOfEvents = expectedNumberOfEvents;
|
||||
this.latch = new CountDownLatch(expectedNumberOfEvents);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleEvent(final CancelTargetAssignmentEvent event) {
|
||||
events.add(event);
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public List<CancelTargetAssignmentEvent> getEvents(final long timeout, final TimeUnit unit)
|
||||
throws InterruptedException {
|
||||
latch.await(timeout, unit);
|
||||
final List<CancelTargetAssignmentEvent> handledEvents = new LinkedList<CancelTargetAssignmentEvent>(events);
|
||||
final List<CancelTargetAssignmentEvent> handledEvents = new LinkedList<>(events);
|
||||
assertThat(handledEvents).as("Did not receive the expected amount of events (" + expectedNumberOfEvents
|
||||
+ ") within timeout. Received events are " + handledEvents).hasSize(expectedNumberOfEvents);
|
||||
return handledEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final CancelTargetAssignmentEvent event) {
|
||||
if (latch == null) {
|
||||
return;
|
||||
}
|
||||
events.add(event);
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
@@ -35,6 +34,7 @@ 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.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.ReportManagement;
|
||||
import org.eclipse.hawkbit.repository.ReportManagement.DateTypes;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||
@@ -30,6 +29,7 @@ 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.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
|
||||
@@ -269,7 +269,7 @@ public class TagManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that a deleted tag is removed from the repository as defined.")
|
||||
public void deleteTargetTas() {
|
||||
public void deleteTargetTags() {
|
||||
|
||||
// create test data
|
||||
final Iterable<JpaTargetTag> tags = createTargetsWithTags();
|
||||
|
||||
@@ -29,7 +29,6 @@ import javax.persistence.Query;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
@@ -39,6 +38,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.Tag;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetIdName;
|
||||
|
||||
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -222,7 +223,7 @@ public class TenantConfigurationManagementTest extends AbstractJpaIntegrationTes
|
||||
public void requestConfigValueWithWrongType() {
|
||||
try {
|
||||
tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
||||
Object.class);
|
||||
Serializable.class);
|
||||
Assert.fail("");
|
||||
} catch (final TenantConfigurationValidatorException e) {
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@Features("Unit Tests - Repository")
|
||||
@Stories("CacheKeys")
|
||||
public class CacheKeysTest {
|
||||
|
||||
@Test
|
||||
public void entitySpecificCacheKeyPattern() {
|
||||
final String knownEntityId = "123";
|
||||
final String knownCacheKey = "someField";
|
||||
final String entitySpecificCacheKey = CacheKeys.entitySpecificCacheKey(knownEntityId, knownCacheKey);
|
||||
assertThat(entitySpecificCacheKey).isEqualTo(knownEntityId + "." + knownCacheKey);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
* 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.cache;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@Features("Unit Tests - Repository")
|
||||
@Stories("CacheWriteNotify")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CacheWriteNotifyTest {
|
||||
|
||||
@Mock
|
||||
private EventBus eventBusMock;
|
||||
|
||||
@Mock
|
||||
private CacheManager cacheManagerMock;
|
||||
|
||||
@Mock
|
||||
private Cache cacheMock;
|
||||
|
||||
@Mock
|
||||
private TenantAware tenantAwareMock;
|
||||
|
||||
private CacheWriteNotify underTest;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
underTest = new CacheWriteNotify();
|
||||
underTest.setEventBus(eventBusMock);
|
||||
underTest.setCacheManager(cacheManagerMock);
|
||||
underTest.setTenantAware(tenantAwareMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void downloadgProgressIsCachedAndEventSent() {
|
||||
final long knownStatusId = 1;
|
||||
|
||||
when(cacheManagerMock.getCache(ActionStatus.class.getName())).thenReturn(cacheMock);
|
||||
when(tenantAwareMock.getCurrentTenant()).thenReturn("default");
|
||||
|
||||
underTest.downloadProgress(knownStatusId, 500L, 100L, 100L);
|
||||
|
||||
verify(cacheManagerMock).getCache(eq(ActionStatus.class.getName()));
|
||||
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, 20);
|
||||
verify(eventBusMock).post(any(DownloadProgressEvent.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,33 +6,31 @@
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.eventbus;
|
||||
package org.eclipse.hawkbit.repository.jpa.event;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.hawkbit.eventbus.event.Event;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
|
||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.event.RepositoryEntityEventTest.RepositoryTestConfiguration;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.fest.assertions.api.Assertions;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Description;
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
@@ -40,17 +38,15 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@Features("Component Tests - Repository")
|
||||
@Stories("Entity Events")
|
||||
@SpringApplicationConfiguration(classes = RepositoryTestConfiguration.class)
|
||||
public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private EventBus eventBus;
|
||||
|
||||
private final MyEventListener eventListener = new MyEventListener();
|
||||
private MyEventListener eventListener;
|
||||
|
||||
@Before
|
||||
public void beforeTest() {
|
||||
eventListener.queue.clear();
|
||||
eventBus.register(eventListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,19 +73,6 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(targetUpdatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target info update event is published when a target info has been updated")
|
||||
public void targetInfoUpdateEventIsPublished() throws InterruptedException {
|
||||
final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345"));
|
||||
controllerManagament.updateTargetStatus(createdTarget.getTargetInfo(), TargetUpdateStatus.PENDING,
|
||||
System.currentTimeMillis(), URI.create("http://127.0.0.1"));
|
||||
|
||||
final TargetInfoUpdateEvent targetInfoUpdatedEvent = eventListener.waitForEvent(TargetInfoUpdateEvent.class, 1,
|
||||
TimeUnit.SECONDS);
|
||||
assertThat(targetInfoUpdatedEvent).isNotNull();
|
||||
assertThat(targetInfoUpdatedEvent.getEntity().getTarget().getId()).isEqualTo(createdTarget.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that the target deleted event is published when a target has been deleted")
|
||||
public void targetDeletedEventIsPublished() throws InterruptedException {
|
||||
@@ -100,7 +83,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
|
||||
final TargetDeletedEvent targetDeletedEvent = eventListener.waitForEvent(TargetDeletedEvent.class, 1,
|
||||
TimeUnit.SECONDS);
|
||||
assertThat(targetDeletedEvent).isNotNull();
|
||||
assertThat(targetDeletedEvent.getTargetId()).isEqualTo(createdTarget.getId());
|
||||
assertThat(targetDeletedEvent.getEntityId()).isEqualTo(createdTarget.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,8 +95,8 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
|
||||
final DistributionSet createDistributionSet = distributionSetManagement
|
||||
.createDistributionSet(generateDistributionSet);
|
||||
|
||||
final DistributionCreatedEvent dsCreatedEvent = eventListener.waitForEvent(DistributionCreatedEvent.class, 1,
|
||||
TimeUnit.SECONDS);
|
||||
final DistributionSetCreatedEvent dsCreatedEvent = eventListener.waitForEvent(DistributionSetCreatedEvent.class,
|
||||
1, TimeUnit.SECONDS);
|
||||
assertThat(dsCreatedEvent).isNotNull();
|
||||
assertThat(dsCreatedEvent.getEntity().getId()).isEqualTo(createDistributionSet.getId());
|
||||
}
|
||||
@@ -130,24 +113,33 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
distributionSetManagement.deleteDistributionSet(createDistributionSet);
|
||||
|
||||
final DistributionDeletedEvent dsDeletedEvent = eventListener.waitForEvent(DistributionDeletedEvent.class, 1,
|
||||
TimeUnit.SECONDS);
|
||||
final DistributionSetDeletedEvent dsDeletedEvent = eventListener.waitForEvent(DistributionSetDeletedEvent.class,
|
||||
1, TimeUnit.SECONDS);
|
||||
assertThat(dsDeletedEvent).isNotNull();
|
||||
assertThat(dsDeletedEvent.getDistributionSetId()).isEqualTo(createDistributionSet.getId());
|
||||
assertThat(dsDeletedEvent.getEntityId()).isEqualTo(createDistributionSet.getId());
|
||||
}
|
||||
|
||||
private class MyEventListener {
|
||||
public static class RepositoryTestConfiguration {
|
||||
|
||||
private final BlockingQueue<Event> queue = new LinkedBlockingQueue<>();
|
||||
@Bean
|
||||
public MyEventListener myEventListenerBean() {
|
||||
return new MyEventListener();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onEvent(final Event event) {
|
||||
}
|
||||
|
||||
private static class MyEventListener {
|
||||
|
||||
private final BlockingQueue<TenantAwareEvent> queue = new LinkedBlockingQueue<>();
|
||||
|
||||
@EventListener(classes = TenantAwareEvent.class)
|
||||
public void onEvent(final TenantAwareEvent event) {
|
||||
queue.offer(event);
|
||||
}
|
||||
|
||||
public <T> T waitForEvent(final Class<T> eventType, final long timeout, final TimeUnit timeUnit)
|
||||
throws InterruptedException {
|
||||
Event event = null;
|
||||
TenantAwareEvent event = null;
|
||||
while ((event = queue.poll(timeout, timeUnit)) != null) {
|
||||
if (event.getClass().isAssignableFrom(eventType)) {
|
||||
return (T) event;
|
||||
@@ -1,129 +0,0 @@
|
||||
/**
|
||||
* 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.eventbus;
|
||||
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.CacheFieldEntityListener;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.support.SimpleValueWrapper;
|
||||
import org.springframework.hateoas.Identifiable;
|
||||
|
||||
import ru.yandex.qatools.allure.annotations.Features;
|
||||
import ru.yandex.qatools.allure.annotations.Stories;
|
||||
|
||||
@Features("Unit Tests - Repository")
|
||||
@Stories("EventBus")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CacheFieldEntityListenerTest {
|
||||
|
||||
private static final String TEST_CACHE_FIELD = "testCacheField";
|
||||
|
||||
@Mock
|
||||
private CacheManager cacheManagerMock;
|
||||
|
||||
@Mock
|
||||
private Cache cacheMock;
|
||||
|
||||
private CacheFieldEntityListener underTest;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
// mock
|
||||
when(cacheManagerMock.getCache(anyString())).thenReturn(cacheMock);
|
||||
|
||||
underTest = new CacheFieldEntityListener();
|
||||
CacheManagerHolder.getInstance().setCacheManager(cacheManagerMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postLoadSetsCacheFields() {
|
||||
final String entityId = "123";
|
||||
final String normalFieldValue = "bumlux";
|
||||
final TestEntity testObject = new TestEntity(entityId, normalFieldValue);
|
||||
final int expectedTestValue = -1;
|
||||
|
||||
when(cacheMock.get(CacheKeys.entitySpecificCacheKey(entityId, TEST_CACHE_FIELD)))
|
||||
.thenReturn(new SimpleValueWrapper(expectedTestValue));
|
||||
|
||||
// pre verify everything is ok
|
||||
assertThat(testObject.getCacheField()).isNotEqualTo(expectedTestValue);
|
||||
assertThat(testObject.getNormalField()).isEqualTo(normalFieldValue);
|
||||
|
||||
// test
|
||||
underTest.postLoad(testObject);
|
||||
|
||||
assertThat(testObject.getNormalField()).isEqualTo(normalFieldValue);
|
||||
// now cache value should be like the value in the mock of the cache
|
||||
assertThat(testObject.getCacheField()).isEqualTo(expectedTestValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postRemoveEvictsCacheField() {
|
||||
final String entityId = "123";
|
||||
final String normalFieldValue = "bumlux";
|
||||
final TestEntity testObject = new TestEntity(entityId, normalFieldValue);
|
||||
// test
|
||||
underTest.postDelete(testObject);
|
||||
|
||||
verify(cacheMock).evict(eq(CacheKeys.entitySpecificCacheKey(entityId, TEST_CACHE_FIELD)));
|
||||
}
|
||||
|
||||
private final class TestEntity implements Identifiable<String> {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String normalField;
|
||||
|
||||
@CacheField(key = TEST_CACHE_FIELD)
|
||||
private int cacheField;
|
||||
|
||||
private TestEntity(final String id, final String normalFieldValue) {
|
||||
this.id = id;
|
||||
this.normalField = normalFieldValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.hateoas.Identifiable#getId()
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the normalField
|
||||
*/
|
||||
String getNormalField() {
|
||||
return normalField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cacheField
|
||||
*/
|
||||
int getCacheField() {
|
||||
return cacheField;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,13 @@ import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.TimestampCalculator;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -18,8 +18,9 @@ import java.time.Instant;
|
||||
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
|
||||
import org.eclipse.hawkbit.repository.TimestampCalculator;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
|
||||
logging.level.=INFO
|
||||
logging.level.org.eclipse.persistence=ERROR
|
||||
|
||||
spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value}
|
||||
spring.data.mongodb.port=28017
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
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
|
||||
|
||||
-->
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml" />
|
||||
|
||||
<!-- <logger name="org.eclipse.persistence" level="DEBUG" /> -->
|
||||
|
||||
<Root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</Root>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user