Performance optimizations for Multi-Assignments (#858)

* Add remote event test for the new MultiActionEvent
* Improve test descriptions
* Improve sendMultiActionRequestMessages
* Moved action filtering to the database query level (#12)
* Use @ExpectedEvents instead of EventHandlerStubs
* Removed @Param from 'existsByTargetControllerIdAndStatusAndActiveIsTrue'
* Reverted metadata initialization
* Fix hawkBit bot findings

Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>
Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com>
This commit is contained in:
Stefan Behl
2019-07-19 14:47:29 +02:00
committed by GitHub
parent 749218098f
commit 4e9308a949
15 changed files with 133 additions and 243 deletions

View File

@@ -127,6 +127,20 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
@Query("SELECT CASE WHEN COUNT(a)>0 THEN 'true' ELSE 'false' END FROM JpaAction a JOIN a.target t WHERE t.controllerId=:controllerId AND a.active=1")
boolean activeActionExistsForControllerId(@Param("controllerId") String controllerId);
/**
* Check if any active actions with given action status and given controller
* ID exist.
*
* @param controllerId
* of the target to check for actions
* @param currentStatus
* of the active action to look for
*
* @return <code>true</code> if one or more active actions for the given
* controllerId and action status are found
*/
boolean existsByTargetControllerIdAndStatusAndActiveIsTrue(String controllerId, Action.Status currentStatus);
/**
* Retrieves latest {@link Action} for given target and
* {@link SoftwareModule}.

View File

@@ -8,8 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -39,8 +37,6 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;
import com.google.common.collect.Lists;
@@ -51,8 +47,6 @@ import com.google.common.collect.Lists;
*/
public class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
private static final Pageable ACTION_PAGE_REQUEST = PageRequest.of(0, MAX_ACTION_COUNT);
private final Supplier<Boolean> multiAssignmentsConfig;
OnlineDsAssignmentStrategy(final TargetRepository targetRepository,
@@ -196,8 +190,8 @@ public class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
}
private boolean hasPendingCancellations(final Target target) {
return actionRepository.findByActiveAndTarget(ACTION_PAGE_REQUEST, target.getControllerId(), true).getContent()
.stream().anyMatch(action -> action.getStatus() == Status.CANCELING);
return actionRepository.existsByTargetControllerIdAndStatusAndActiveIsTrue(target.getControllerId(),
Status.CANCELING);
}
/**

View File

@@ -79,13 +79,15 @@ public abstract class AbstractRemoteEventTest extends AbstractJpaIntegrationTest
return busProtoStuffMessageConverter.toMessage(event, new MessageHeaders(headers));
}
protected TenantAwareEvent createJacksonEvent(final TenantAwareEvent event) {
final Message<?> message = createJsonMessage(event);
return (TenantAwareEvent) jacksonMessageConverter.fromMessage(message, event.getClass());
@SuppressWarnings("unchecked")
protected <T extends TenantAwareEvent> T createJacksonEvent(final T event) {
final Message<String> message = createJsonMessage(event);
return (T) jacksonMessageConverter.fromMessage(message, event.getClass());
}
protected TenantAwareEvent createProtoStuffEvent(final TenantAwareEvent event) {
@SuppressWarnings("unchecked")
protected <T extends TenantAwareEvent> T createProtoStuffEvent(final T event) {
final Message<?> message = createProtoStuffMessage(event);
return (TenantAwareEvent) busProtoStuffMessageConverter.fromMessage(message, event.getClass());
return (T) busProtoStuffMessageConverter.fromMessage(message, event.getClass());
}
}

View File

@@ -94,10 +94,10 @@ public class RemoteIdEventTest extends AbstractRemoteEventTest {
protected void assertEntity(final RemoteIdEvent event) {
assertThat(event.getEntityId()).isSameAs(ENTITY_ID);
final RemoteIdEvent protoStuffEvent = (RemoteIdEvent) createProtoStuffEvent(event);
final RemoteIdEvent protoStuffEvent = createProtoStuffEvent(event);
assertDeserializeEvent(protoStuffEvent, event);
final RemoteIdEvent jacksonEvent = (RemoteIdEvent) createJacksonEvent(event);
final RemoteIdEvent jacksonEvent = createJacksonEvent(event);
assertDeserializeEvent(jacksonEvent, event);
}

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.event.remote;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.model.Action;
@@ -18,7 +19,6 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionProperties;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
import org.junit.Test;
import io.qameta.allure.Description;
@@ -29,47 +29,71 @@ import io.qameta.allure.Story;
@Story("RemoteTenantAwareEvent Tests")
public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
private static final String TENANT_DEFAULT = "DEFAULT";
private static final String APPLICATION_ID_DEFAULT = "Node";
@Test
@Description("Verifies that the download progress reloading by remote events works")
public void reloadDownloadProgessByRemoteEvent() {
final DownloadProgressEvent downloadProgressEvent = new DownloadProgressEvent("DEFAULT", 1L, 3L, "Node");
@Description("Verifies that a MultiActionEvent can be properly serialized and deserialized")
public void testMultiActionEvent() {
DownloadProgressEvent remoteEvent = (DownloadProgressEvent) createProtoStuffEvent(downloadProgressEvent);
assertThat(downloadProgressEvent).isEqualTo(remoteEvent);
final List<String> controllerIds = Arrays.asList("id0", "id1", "id2", "id3",
"id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng");
final MultiActionEvent event = new MultiActionEvent(TENANT_DEFAULT, APPLICATION_ID_DEFAULT, controllerIds);
final MultiActionEvent remoteEventProtoStuff = createProtoStuffEvent(event);
assertThat(event).isEqualTo(remoteEventProtoStuff);
assertThat(remoteEventProtoStuff.getControllerIds()).containsExactlyElementsOf(controllerIds);
final MultiActionEvent remoteEventJackson = createJacksonEvent(event);
assertThat(event).isEqualTo(remoteEventJackson);
assertThat(remoteEventJackson.getControllerIds()).containsExactlyElementsOf(controllerIds);
remoteEvent = (DownloadProgressEvent) createJacksonEvent(downloadProgressEvent);
assertThat(downloadProgressEvent).isEqualTo(remoteEvent);
}
@Test
@Description("Verifies that target assignment event works")
@Description("Verifies that a DownloadProgressEvent can be properly serialized and deserialized")
public void reloadDownloadProgessByRemoteEvent() {
final DownloadProgressEvent downloadProgressEvent = new DownloadProgressEvent(TENANT_DEFAULT, 1L, 3L,
APPLICATION_ID_DEFAULT);
final DownloadProgressEvent remoteEventProtoStuff = createProtoStuffEvent(downloadProgressEvent);
assertThat(downloadProgressEvent).isEqualTo(remoteEventProtoStuff);
final DownloadProgressEvent remoteEventJackson = createJacksonEvent(downloadProgressEvent);
assertThat(downloadProgressEvent).isEqualTo(remoteEventJackson);
}
@Test
@Description("Verifies that a TargetAssignDistributionSetEvent can be properly serialized and deserialized")
public void testTargetAssignDistributionSetEvent() {
final DistributionSet dsA = testdataFactory.createDistributionSet("");
final JpaAction generateAction = new JpaAction();
generateAction.setActionType(ActionType.FORCED);
final Target target = testdataFactory.createTarget("Test");
generateAction.setTarget(target);
generateAction.setTarget(testdataFactory.createTarget("Test"));
generateAction.setDistributionSet(dsA);
generateAction.setStatus(Status.RUNNING);
final Action action = actionRepository.save(generateAction);
final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent(
action.getTenant(), dsA.getId(), Arrays.asList(action), serviceMatcher.getServiceId(),
action.isMaintenanceWindowAvailable());
TargetAssignDistributionSetEvent underTest = (TargetAssignDistributionSetEvent) createProtoStuffEvent(
assignmentEvent);
assertTargetAssignDistributionSetEvent(action, underTest);
final TargetAssignDistributionSetEvent remoteEventProtoStuff = createProtoStuffEvent(assignmentEvent);
assertTargetAssignDistributionSetEvent(action, remoteEventProtoStuff);
underTest = (TargetAssignDistributionSetEvent) createJacksonEvent(assignmentEvent);
assertTargetAssignDistributionSetEvent(action, underTest);
final TargetAssignDistributionSetEvent remoteEventJackson = createJacksonEvent(assignmentEvent);
assertTargetAssignDistributionSetEvent(action, remoteEventJackson);
}
private void assertTargetAssignDistributionSetEvent(final Action action,
final TargetAssignDistributionSetEvent underTest) {
assertThat(underTest.getActions().size()).isEqualTo(1);
ActionProperties actionProperties = underTest.getActions().get(action.getTarget().getControllerId());
final ActionProperties actionProperties = underTest.getActions().get(action.getTarget().getControllerId());
assertThat(actionProperties).isNotNull();
assertThat(actionProperties).isEqualToComparingFieldByField(new ActionProperties(action));
assertThat(underTest.getDistributionSetId()).isEqualTo(action.getDistributionSet().getId());

View File

@@ -57,10 +57,10 @@ public abstract class AbstractRemoteEntityEventTest<E> extends AbstractRemoteEve
protected RemoteEntityEvent<?> assertEntity(final E baseEntity, final RemoteEntityEvent<?> event) {
assertThat(event.getEntity()).isSameAs(baseEntity);
RemoteEntityEvent<?> underTestCreatedEvent = (RemoteEntityEvent<?>) createProtoStuffEvent(event);
RemoteEntityEvent<?> underTestCreatedEvent = createProtoStuffEvent(event);
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
underTestCreatedEvent = (RemoteEntityEvent<?>) createJacksonEvent(event);
underTestCreatedEvent = createJacksonEvent(event);
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
return underTestCreatedEvent;
}

View File

@@ -74,12 +74,12 @@ public class ActionEventTest extends AbstractRemoteEntityEventTest<Action> {
assertThat(event.getEntity()).isSameAs(baseEntity);
assertThat(event.getRolloutId()).isEqualTo(1L);
AbstractActionEvent underTestCreatedEvent = (AbstractActionEvent) createProtoStuffEvent(event);
AbstractActionEvent underTestCreatedEvent = createProtoStuffEvent(event);
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
assertThat(underTestCreatedEvent.getRolloutId()).isEqualTo(1L);
assertThat(underTestCreatedEvent.getRolloutGroupId()).isEqualTo(2L);
underTestCreatedEvent = (AbstractActionEvent) createJacksonEvent(event);
underTestCreatedEvent = createJacksonEvent(event);
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
assertThat(underTestCreatedEvent.getRolloutId()).isEqualTo(1L);
assertThat(underTestCreatedEvent.getRolloutGroupId()).isEqualTo(2L);

View File

@@ -76,11 +76,11 @@ public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<Rollout
assertThat(event.getEntity()).isSameAs(baseEntity);
assertThat(event.getRolloutId()).isEqualTo(1L);
AbstractRolloutGroupEvent underTestCreatedEvent = (AbstractRolloutGroupEvent) createProtoStuffEvent(event);
AbstractRolloutGroupEvent underTestCreatedEvent = createProtoStuffEvent(event);
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
assertThat(underTestCreatedEvent.getRolloutId()).isEqualTo(1L);
underTestCreatedEvent = (AbstractRolloutGroupEvent) createJacksonEvent(event);
underTestCreatedEvent = createJacksonEvent(event);
assertThat(underTestCreatedEvent.getEntity()).isEqualTo(baseEntity);
assertThat(underTestCreatedEvent.getRolloutId()).isEqualTo(1L);

View File

@@ -17,10 +17,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -31,6 +28,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
@@ -48,7 +46,6 @@ import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionProperties;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
@@ -60,11 +57,7 @@ import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
@@ -90,22 +83,6 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
private static final boolean STATE_ACTIVE = true;
private static final boolean STATE_INACTIVE = false;
private EventHandlerStub eventHandlerStub;
private CancelEventHandlerStub cancelEventHandlerStub;
@Autowired
private ConfigurableApplicationContext applicationContext;
@Before
public void addHandler() {
eventHandlerStub = new EventHandlerStub();
applicationContext.addApplicationListener(eventHandlerStub);
cancelEventHandlerStub = new CancelEventHandlerStub();
applicationContext.addApplicationListener(cancelEventHandlerStub);
}
@Test
@Description("Verifies that management get access react as specfied on calls for non existing entities by means "
+ "of Optional not present.")
@@ -276,7 +253,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Description("Test verifies that an assignment with automatic cancelation works correctly even if the update is split into multiple partitions on the database.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10),
@Expect(type = TargetUpdatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)),
@Expect(type = CancelTargetAssignmentEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10),
@Expect(type = ActionUpdatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10),
@@ -581,12 +558,15 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
* {@link TargetRepository#assignDistributionSet(DistributionSet, Iterable)}
* and checking the active action and the action history of the targets.
*
* @throws InterruptedException
*/
@Test
@Description("Simple deployment or distribution set to target assignment test.")
public void assignDistributionSet2Targets() throws InterruptedException {
eventHandlerStub.setExpectedNumberOfEvents(1);
@ExpectEvents({@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 30), @Expect(type = ActionCreatedEvent.class, count = 20),
@Expect(type = TargetUpdatedEvent.class, count = 20),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
public void assignDistributionSet2Targets() {
final String myCtrlIDPref = "myCtrlID";
final Iterable<Target> savedNakedTargets = testdataFactory.createTargets(10, myCtrlIDPref, "first description");
@@ -631,17 +611,19 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
assertThat(ua.getDistributionSet()).as("action has wrong ds").isEqualTo(ds);
}
}
final List<TargetAssignDistributionSetEvent> events = eventHandlerStub.getEvents(10, TimeUnit.SECONDS);
assertTargetAssignDistributionSetEvents(savedDeployedTargets, ds, events);
}
@Test
@Description("Test that it is not possible to assign a distribution set that is not complete.")
public void failDistributionSetAssigmentThatIsNotComplete() throws InterruptedException {
eventHandlerStub.setExpectedNumberOfEvents(0);
@ExpectEvents({@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 10), @Expect(type = ActionCreatedEvent.class, count = 10),
@Expect(type = TargetUpdatedEvent.class, count = 10),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 2),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1)
})
public void failDistributionSetAssigmentThatIsNotComplete() throws InterruptedException {
final List<Target> targets = testdataFactory.createTargets(10);
final SoftwareModule ah = testdataFactory.createSoftwareModuleApp();
@@ -656,51 +638,32 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
} catch (final IncompleteDistributionSetException ex) {
}
// give some chance to receive events asynchronously
Thread.sleep(1L);
final List<TargetAssignDistributionSetEvent> events = eventHandlerStub.getEvents(5, TimeUnit.SECONDS);
assertThat(events).as("events should be empty").isEmpty();
final DistributionSet nowComplete = distributionSetManagement.assignSoftwareModules(incomplete.getId(),
Sets.newHashSet(os.getId()));
eventHandlerStub.setExpectedNumberOfEvents(1);
assertThat(assignDistributionSet(nowComplete, targets).getAssigned()).as("assign ds doesn't work")
.isEqualTo(10);
assertTargetAssignDistributionSetEvents(targets, nowComplete, eventHandlerStub.getEvents(15, TimeUnit.SECONDS));
}
@Test
@Description("Multiple deployments or distribution set to target assignment test. Expected behaviour is that a new deployment "
+ "overides unfinished old one which are canceled as part of the operation.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 5 + 4),
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 5 + 4),
@Expect(type = TargetUpdatedEvent.class, count = 3 * 4),
@Expect(type = ActionCreatedEvent.class, count = 3 * 4),
@Expect(type = ActionUpdatedEvent.class, count = 4 * 2),
@Expect(type = CancelTargetAssignmentEvent.class, count = 4 * 2),
@Expect(type = DistributionSetCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 9),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1) })
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2)})
public void mutipleDeployments() throws InterruptedException {
final String undeployedTargetPrefix = "undep-T";
final int noOfUndeployedTargets = 5;
final String deployedTargetPrefix = "dep-T";
final int noOfDeployedTargets = 4;
final int noOfDistributionSets = 3;
// One assigment per DS
final int expectedNumberOfEventsForAssignment = 1;
eventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForAssignment);
// Each of the four targets get two more assignment the which are
// cancelled (4 * 2 = 8)
final int expectedNumberOfEventsForCancel = 8;
cancelEventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForCancel);
final DeploymentResult deploymentResult = prepareComplexRepo(undeployedTargetPrefix, noOfUndeployedTargets,
deployedTargetPrefix, noOfDeployedTargets, noOfDistributionSets, "myTestDS");
@@ -739,13 +702,6 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
.doesNotContain(Iterables.toArray(undeployedTargetsFromDB, JpaTarget.class));
assertThat(undeployedTargetsFromDB).as("content of undeployed target is wrong").containsAll(savedNakedTargets)
.doesNotContain(Iterables.toArray(deployedTargetsFromDB, JpaTarget.class));
// For each of the 4 targets 1 distribution sets gets assigned
eventHandlerStub.getEvents(10, TimeUnit.SECONDS);
// For each of the 4 targets 2 distribution sets gets cancelled
cancelEventHandlerStub.getEvents(10, TimeUnit.SECONDS);
}
@Test
@@ -1111,22 +1067,6 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
}
private void assertTargetAssignDistributionSetEvents(final List<Target> targets, final DistributionSet ds,
final List<TargetAssignDistributionSetEvent> events) {
assertThat(events).hasSize(1);
final TargetAssignDistributionSetEvent event = events.get(0);
assertThat(event).isNotNull();
assertThat(event.getDistributionSetId()).isEqualTo(ds.getId());
final List<Long> eventActionIds = event.getActions().values().stream().map(ActionProperties::getId)
.collect(Collectors.toList());
final List<Long> targetActiveActionIds = targets.stream()
.map(t -> deploymentManagement.findActiveActionsByTarget(PAGE, t.getControllerId()).getContent())
.flatMap(List::stream).map(Action::getId).collect(Collectors.toList());
assertThat(eventActionIds).containsOnlyElementsOf(targetActiveActionIds);
}
private class DeploymentResult {
final List<Long> deployedTargetIDs = new ArrayList<>();
final List<Long> undeployedTargetIDs = new ArrayList<>();
@@ -1178,73 +1118,6 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
}
protected static class EventHandlerStub implements ApplicationListener<TargetAssignDistributionSetEvent> {
private final List<TargetAssignDistributionSetEvent> events = Collections.synchronizedList(new LinkedList<>());
private CountDownLatch latch;
private int expectedNumberOfEvents;
/**
* @param expectedNumberOfEvents
* the expectedNumberOfEvents to set
*/
public void setExpectedNumberOfEvents(final int expectedNumberOfEvents) {
events.clear();
this.expectedNumberOfEvents = expectedNumberOfEvents;
this.latch = new CountDownLatch(expectedNumberOfEvents);
}
public List<TargetAssignDistributionSetEvent> getEvents(final long timeout, final TimeUnit unit)
throws InterruptedException {
latch.await(timeout, unit);
final List<TargetAssignDistributionSetEvent> handledEvents = Collections
.unmodifiableList(new LinkedList<>(events));
assertThat(handledEvents).as("Did not receive the expected amount of events (" + expectedNumberOfEvents
+ ") within timeout. Received events are " + handledEvents).hasSize(expectedNumberOfEvents);
return handledEvents;
}
@Override
public void onApplicationEvent(final TargetAssignDistributionSetEvent event) {
if (latch == null) {
return;
}
events.add(event);
latch.countDown();
}
}
private static class CancelEventHandlerStub implements ApplicationListener<CancelTargetAssignmentEvent> {
private final List<CancelTargetAssignmentEvent> events = Collections.synchronizedList(new LinkedList<>());
private CountDownLatch latch;
private int expectedNumberOfEvents;
public void setExpectedNumberOfEvents(final int expectedNumberOfEvents) {
events.clear();
this.expectedNumberOfEvents = expectedNumberOfEvents;
this.latch = new CountDownLatch(expectedNumberOfEvents);
}
public List<CancelTargetAssignmentEvent> getEvents(final long timeout, final TimeUnit unit)
throws InterruptedException {
latch.await(timeout, unit);
final List<CancelTargetAssignmentEvent> handledEvents = new LinkedList<>(events);
assertThat(handledEvents).as("Did not receive the expected amount of events (" + expectedNumberOfEvents
+ ") within timeout. Received events are " + handledEvents).hasSize(expectedNumberOfEvents);
return handledEvents;
}
@Override
public void onApplicationEvent(final CancelTargetAssignmentEvent event) {
if (latch == null) {
return;
}
events.add(event);
latch.countDown();
}
}
private void enableMultiAssignments() {
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED, true);
}