Introduce cache for rollouts status computation. (#509)

* Introduce cache for rollouts status computation.

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

* Disable cache during tests.

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

* Move cache into core.

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

* package private event listener.

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

* Fix cache invalidation.

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

* Fix sonar issues.

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

* Fixed a test that assumes that target to group assignment follows a rule
which si not the case.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-05-22 17:36:42 +02:00
committed by GitHub
parent 4dd422cc21
commit a4dd4ce191
9 changed files with 345 additions and 29 deletions

View File

@@ -392,7 +392,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* id of {@link Rollout}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rollout.id = ?1 GROUP BY a.rollout.id,a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus( a.rollout.id, a.status , COUNT(a.id)) FROM JpaAction a WHERE a.rollout.id = ?1 GROUP BY a.rollout.id,a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutId(Long rolloutId);
/**
@@ -403,7 +403,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* id of {@link RolloutGroup}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rolloutGroup.id = ?1 GROUP BY a.rolloutGroup.id, a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.id)) FROM JpaAction a WHERE a.rolloutGroup.id = ?1 GROUP BY a.rolloutGroup.id, a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutGroupId(Long rolloutGroupId);
/**
@@ -414,7 +414,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* list of id of {@link RolloutGroup}
* @return list of objects with status and target count
*/
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.target)) FROM JpaAction a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status")
@Query("SELECT NEW org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus(a.rolloutGroup.id, a.status , COUNT(a.id)) FROM JpaAction a WHERE a.rolloutGroup.id IN ?1 GROUP BY a.rolloutGroup.id, a.status")
List<TotalTargetCountActionStatus> getStatusCountByRolloutGroupId(List<Long> rolloutGroupId);
/**

View File

@@ -25,6 +25,7 @@ import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.RolloutGroupFields;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutStatusCache;
import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -79,6 +80,9 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
@Autowired
private VirtualPropertyReplacer virtualPropertyReplacer;
@Autowired
private RolloutStatusCache rolloutStatusCache;
@Override
public Optional<RolloutGroup> findRolloutGroupById(final Long rolloutGroupId) {
return Optional.ofNullable(rolloutGroupRepository.findOne(rolloutGroupId));
@@ -159,8 +163,13 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
final JpaRolloutGroup jpaRolloutGroup = (JpaRolloutGroup) rolloutGroup.get();
final List<TotalTargetCountActionStatus> rolloutStatusCountItems = actionRepository
.getStatusCountByRolloutGroupId(rolloutGroupId);
List<TotalTargetCountActionStatus> rolloutStatusCountItems = rolloutStatusCache
.getRolloutGroupStatus(rolloutGroupId);
if (rolloutStatusCountItems.isEmpty()) {
rolloutStatusCountItems = actionRepository.getStatusCountByRolloutGroupId(rolloutGroupId);
rolloutStatusCache.putRolloutGroupStatus(rolloutGroupId, rolloutStatusCountItems);
}
final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(rolloutStatusCountItems,
Long.valueOf(jpaRolloutGroup.getTotalTargets()));
@@ -169,11 +178,25 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
}
private Map<Long, List<TotalTargetCountActionStatus>> getStatusCountItemForRolloutGroup(
final List<Long> rolloutGroupIds) {
final List<TotalTargetCountActionStatus> resultList = actionRepository
.getStatusCountByRolloutGroupId(rolloutGroupIds);
return resultList.stream().collect(Collectors.groupingBy(TotalTargetCountActionStatus::getId));
private Map<Long, List<TotalTargetCountActionStatus>> getStatusCountItemForRolloutGroup(final List<Long> groupIds) {
final Map<Long, List<TotalTargetCountActionStatus>> fromCache = rolloutStatusCache
.getRolloutGroupStatus(groupIds);
final List<Long> rolloutGroupIds = groupIds.stream().filter(id -> !fromCache.containsKey(id))
.collect(Collectors.toList());
if (!rolloutGroupIds.isEmpty()) {
final List<TotalTargetCountActionStatus> resultList = actionRepository
.getStatusCountByRolloutGroupId(rolloutGroupIds);
final Map<Long, List<TotalTargetCountActionStatus>> fromDb = resultList.stream()
.collect(Collectors.groupingBy(TotalTargetCountActionStatus::getId));
rolloutStatusCache.putRolloutGroupStatus(fromDb);
fromCache.putAll(fromDb);
}
return fromCache;
}
@Override

View File

@@ -29,6 +29,7 @@ import org.eclipse.hawkbit.repository.RolloutFields;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutHelper;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.RolloutStatusCache;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.builder.GenericRolloutUpdate;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
@@ -139,6 +140,9 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
@Autowired
private QuotaManagement quotaManagement;
@Autowired
private RolloutStatusCache rolloutStatusCache;
JpaRolloutManagement(final TargetManagement targetManagement, final DeploymentManagement deploymentManagement,
final RolloutGroupManagement rolloutGroupManagement,
final DistributionSetManagement distributionSetManagement, final ApplicationContext context,
@@ -970,21 +974,41 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
return rollout;
}
final List<TotalTargetCountActionStatus> rolloutStatusCountItems = actionRepository
.getStatusCountByRolloutId(rolloutId);
List<TotalTargetCountActionStatus> rolloutStatusCountItems = rolloutStatusCache.getRolloutStatus(rolloutId);
if (rolloutStatusCountItems.isEmpty()) {
rolloutStatusCountItems = actionRepository.getStatusCountByRolloutId(rolloutId);
rolloutStatusCache.putRolloutStatus(rolloutId, rolloutStatusCountItems);
}
final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(rolloutStatusCountItems,
rollout.get().getTotalTargets());
((JpaRollout) rollout.get()).setTotalTargetCountStatus(totalTargetCountStatus);
return rollout;
}
private Map<Long, List<TotalTargetCountActionStatus>> getStatusCountItemForRollout(final List<Long> rolloutIds) {
private Map<Long, List<TotalTargetCountActionStatus>> getStatusCountItemForRollout(final List<Long> rollouts) {
if (rollouts.isEmpty()) {
return null;
}
final Map<Long, List<TotalTargetCountActionStatus>> fromCache = rolloutStatusCache.getRolloutStatus(rollouts);
final List<Long> rolloutIds = rollouts.stream().filter(id -> !fromCache.containsKey(id))
.collect(Collectors.toList());
if (!rolloutIds.isEmpty()) {
final List<TotalTargetCountActionStatus> resultList = actionRepository
.getStatusCountByRolloutId(rolloutIds);
return resultList.stream().collect(Collectors.groupingBy(TotalTargetCountActionStatus::getId));
final Map<Long, List<TotalTargetCountActionStatus>> fromDb = resultList.stream()
.collect(Collectors.groupingBy(TotalTargetCountActionStatus::getId));
rolloutStatusCache.putRolloutStatus(fromDb);
fromCache.putAll(fromDb);
}
return null;
return fromCache;
}
private void setRolloutStatusDetails(final Slice<JpaRollout> rollouts) {

View File

@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.PropertiesQuotaManagement;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.RolloutStatusCache;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TagManagement;
@@ -132,6 +133,12 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return new PropertiesQuotaManagement(securityProperties);
}
@Bean
@ConditionalOnMissingBean
RolloutStatusCache rolloutStatusCache(final TenantAware tenantAware) {
return new RolloutStatusCache(tenantAware);
}
/**
* @param distributionSetManagement
* to loading the {@link DistributionSetType}

View File

@@ -19,7 +19,9 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.assertj.core.api.Condition;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
@@ -630,8 +632,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
// 5 targets are in the group and the DS has been assigned
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
.findRolloutGroupsByRolloutId(createdRollout.getId(), PAGE).getContent();
final Page<Target> targets = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(0).getId(),
PAGE);
final Page<Target> targets = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(0).getId(), PAGE);
final List<Target> targetList = targets.getContent();
assertThat(targetList.size()).isEqualTo(5);
@@ -1028,7 +1029,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verify that the expected targets in the expected order are returned for the rollout groups.")
@Description("Verify that the expected targets are returned for the rollout groups.")
public void findRolloutGroupTargetsWithRsqlParam() {
final int amountTargetsForRollout = 15;
@@ -1049,27 +1050,33 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
// Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts();
final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName),
"Target belongs into rollout");
myRollout = rolloutManagement.findRolloutById(myRollout.getId()).get();
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
.findRolloutGroupsByRolloutId(myRollout.getId(), PAGE).getContent();
Page<Target> targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(0).getId(),
rsqlParam, new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "controllerId")));
rsqlParam, new OffsetBasedPageRequest(0, 100));
final List<Target> targetlistGroup1 = targetPage.getContent();
assertThat(targetlistGroup1.size()).isEqualTo(5);
assertThat(targetlistGroup1.get(0).getControllerId()).isEqualTo("MyRollout--00000");
assertThat(targetlistGroup1.stream().map(Target::getControllerId).collect(Collectors.toList()))
.are(targetBelongsInRollout);
targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(1).getId(), rsqlParam,
new OffsetBasedPageRequest(0, 100, new Sort(Direction.DESC, "controllerId")));
new OffsetBasedPageRequest(0, 100));
final List<Target> targetlistGroup2 = targetPage.getContent();
assertThat(targetlistGroup2.size()).isEqualTo(5);
assertThat(targetlistGroup2.get(0).getControllerId()).isEqualTo("MyRollout--00009");
assertThat(targetlistGroup2.stream().map(Target::getControllerId).collect(Collectors.toList()))
.are(targetBelongsInRollout);
targetPage = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroups.get(2).getId(), rsqlParam,
new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "controllerId")));
new OffsetBasedPageRequest(0, 100));
final List<Target> targetlistGroup3 = targetPage.getContent();
assertThat(targetlistGroup3.size()).isEqualTo(5);
assertThat(targetlistGroup3.get(0).getControllerId()).isEqualTo("MyRollout--00010");
assertThat(targetlistGroup3.stream().map(Target::getControllerId).collect(Collectors.toList()))
.are(targetBelongsInRollout);
}
@@ -1128,8 +1135,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
final List<RolloutGroup> groups = rolloutGroupManagement
.findRolloutGroupsByRolloutId(myRollout.getId(), PAGE).getContent();
final List<RolloutGroup> groups = rolloutGroupManagement.findRolloutGroupsByRolloutId(myRollout.getId(), PAGE)
.getContent();
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
assertThat(groups.get(0).getTotalTargets()).isEqualTo(1);
@@ -1301,8 +1308,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1);
final List<RolloutGroup> groups = rolloutGroupManagement
.findRolloutGroupsByRolloutId(myRollout.getId(), PAGE).getContent();
final List<RolloutGroup> groups = rolloutGroupManagement.findRolloutGroupsByRolloutId(myRollout.getId(), PAGE)
.getContent();
;
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
assertThat(groups.get(0).getTotalTargets()).isEqualTo(amountTargetsInGroup1);