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;
|
||||
|
||||
Reference in New Issue
Block a user