Introduce new tenant configuration events (#1059)

* Introduce new events that are triggered when changes are made to the tenant configuration.
* Add new events to EventTypes
* Fix DeploymentManagement tests.
* Fix AmqpMessageDispatcherServiceIntegration tests.
* Fix DdiRootControlle test.
* Remove unused imports.
* TenantConfigUpdatedEvent should implement EntityUpdatedEvent

Signed-off-by: Michael Herdt <Michael.Herdt@bosch.io>
This commit is contained in:
Michael Herdt
2021-03-19 11:00:59 +01:00
committed by GitHub
parent 10e69de838
commit 84740a2b1c
8 changed files with 211 additions and 18 deletions

View File

@@ -38,6 +38,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -171,7 +172,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 0),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void assignMultipleDsInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "assignMultipleDsInMultiAssignMode";
@@ -255,7 +257,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void cancelActionInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "cancelActionInMultiAssignMode";
@@ -287,7 +290,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetPollEvent.class, count = 1) })
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void finishActionInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "finishActionInMultiAssignMode";
@@ -313,7 +317,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 0),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void assignDsMultipleTimesInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "assignDsMultipleTimesInMultiAssignMode";
@@ -360,7 +365,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = RolloutCreatedEvent.class, count = 2), @Expect(type = RolloutUpdatedEvent.class, count = 6),
@Expect(type = RolloutGroupCreatedEvent.class, count = 2),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 4) })
@Expect(type = RolloutGroupUpdatedEvent.class, count = 4),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void startRolloutsWithSameDsInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "startRolloutsWithSameDsInMultiAssignMode";
@@ -390,7 +396,8 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
@Expect(type = TargetAttributesRequestedEvent.class, count = 2),
@Expect(type = RolloutCreatedEvent.class, count = 3), @Expect(type = RolloutUpdatedEvent.class, count = 9),
@Expect(type = RolloutGroupCreatedEvent.class, count = 3),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 6) })
@Expect(type = RolloutGroupUpdatedEvent.class, count = 6),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void startMultipleRolloutsAndFinishInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "startMultipleRolloutsAndFinishInMultiAssignMode";

View File

@@ -0,0 +1,59 @@
/**
* Copyright (c) 2020 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.event.remote;
import org.eclipse.hawkbit.repository.event.entity.EntityDeletedEvent;
/**
*
* Defines the remote event of deleting a {@link org.eclipse.hawkbit.repository.model.TenantConfiguration}.
*/
public class TenantConfigurationDeletedEvent extends RemoteIdEvent implements EntityDeletedEvent {
private static final long serialVersionUID = 2L;
private String configKey;
private String configValue;
/**
* Default constructor.
*/
public TenantConfigurationDeletedEvent() {
// for serialization libs like jackson
}
/**
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param configKey
* the config key
* @param configValue
* the config value
* @param entityClass
* the entity class
* @param applicationId
* the origin application id
*/
public TenantConfigurationDeletedEvent(final String tenant, final Long entityId, final String configKey,
final String configValue, final String entityClass, final String applicationId) {
super(entityId, tenant, entityClass, applicationId);
this.configKey = configKey;
this.configValue = configValue;
}
public String getConfigKey() {
return configKey;
}
public String getConfigValue() {
return configValue;
}
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2020 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.event.entity.EntityCreatedEvent;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
/**
* Defines the remote event of creating a new {@link TenantConfiguration}.
*
*/
public class TenantConfigurationCreatedEvent extends RemoteEntityEvent<TenantConfiguration>
implements EntityCreatedEvent {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TenantConfigurationCreatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param baseEntity
* the tenantConfiguration
* @param applicationId
* the origin application id
*/
public TenantConfigurationCreatedEvent(final TenantConfiguration baseEntity, final String applicationId) {
super(baseEntity, applicationId);
}
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2020 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.event.entity.EntityUpdatedEvent;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
/**
* Defines the remote event of updating a {@link TenantConfiguration}.
*
*/
public class TenantConfigurationUpdatedEvent extends RemoteEntityEvent<TenantConfiguration>
implements EntityUpdatedEvent {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public TenantConfigurationUpdatedEvent() {
// for serialization libs like jackson
}
/**
* Constructor.
*
* @param baseEntity
* the tenantConfiguration
* @param applicationId
* the origin application id
*/
public TenantConfigurationUpdatedEvent(final TenantConfiguration baseEntity, final String applicationId) {
super(baseEntity, applicationId);
}
}

View File

@@ -29,6 +29,7 @@ import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetFilterQueryDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.TenantConfigurationDeletedEvent;
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;
@@ -52,6 +53,8 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryUpdat
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent;
/**
* The {@link EventType} class declares the event-type and it's corresponding
@@ -138,6 +141,11 @@ public class EventType {
// deployment event for assignments and /or cancellations
TYPES.put(38, MultiActionAssignEvent.class);
TYPES.put(39, MultiActionCancelEvent.class);
// tenant configuration
TYPES.put(40, TenantConfigurationCreatedEvent.class);
TYPES.put(41, TenantConfigurationUpdatedEvent.class);
TYPES.put(42, TenantConfigurationDeletedEvent.class);
}
private int value;

View File

@@ -16,7 +16,12 @@ import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.eclipse.hawkbit.repository.event.remote.TenantConfigurationDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent;
import org.eclipse.hawkbit.repository.model.TenantConfiguration;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.persistence.descriptors.DescriptorEvent;
/**
* A JPA entity which stores the tenant specific configuration.
@@ -28,7 +33,8 @@ import org.eclipse.hawkbit.repository.model.TenantConfiguration;
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
// sub entities
@SuppressWarnings("squid:S2160")
public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity implements TenantConfiguration {
public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity
implements TenantConfiguration, EventAwareEntity {
private static final long serialVersionUID = 1L;
@Column(name = "conf_key", length = TenantConfiguration.KEY_MAX_SIZE, nullable = false, updatable = false)
@@ -79,4 +85,22 @@ public class JpaTenantConfiguration extends AbstractJpaTenantAwareBaseEntity imp
this.value = value;
}
@Override
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TenantConfigurationCreatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
new TenantConfigurationUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId()));
}
@Override
public void fireDeleteEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher()
.publishEvent(new TenantConfigurationDeletedEvent(getTenant(), getId(), getKey(), getValue(),
getClass().getName(), EventPublisherHolder.getInstance().getApplicationId()));
}
}

View File

@@ -38,6 +38,8 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdated
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;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
@@ -499,7 +501,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 4), @Expect(type = ActionCreatedEvent.class, count = 4),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void multiOfflineAssignment() {
final List<String> targetIds = testdataFactory.createTargets(2).stream().map(Target::getControllerId)
.collect(Collectors.toList());
@@ -530,7 +533,9 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 10),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2) })
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
@Expect(type = TenantConfigurationUpdatedEvent.class, count = 1) })
public void assignDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
@@ -568,7 +573,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = MultiActionCancelEvent.class, count = 0),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0) })
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void previousAssignmentsAreNotCanceledInMultiAssignMode() {
enableMultiAssignments();
final List<Target> targets = testdataFactory.createTargets(10);
@@ -609,8 +615,9 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = MultiActionAssignEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0) })
public void multiassignmentInOneRequest() {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void multiAssignmentInOneRequest() {
final List<Target> targets = testdataFactory.createTargets(2);
final List<DistributionSet> distributionSets = testdataFactory.createDistributionSets(2);
final List<DeploymentRequest> deploymentRequests = createAssignmentRequests(distributionSets, targets, 34);
@@ -640,7 +647,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = MultiActionAssignEvent.class, count = 1),
@Expect(type = MultiActionCancelEvent.class, count = 4),
@Expect(type = ActionUpdatedEvent.class, count = 4),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0) })
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void cancelMultiAssignmentActions() {
final List<Target> targets = testdataFactory.createTargets(2);
final List<DistributionSet> distributionSets = testdataFactory.createDistributionSets(2);
@@ -732,7 +740,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 3), @Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = MultiActionAssignEvent.class, count = 1) })
@Expect(type = MultiActionAssignEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void duplicateAssignmentsInRequestAreOnlyRemovedIfMultiassignmentDisabled() {
final String targetId = testdataFactory.createTarget().getControllerId();
final Long dsId = testdataFactory.createDistributionSet().getId();
@@ -759,7 +768,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0) })
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void maxActionsPerTargetIsCheckedBeforeAssignmentExecution() {
final int maxActions = quotaManagement.getMaxActionsPerTarget();
final String controllerId = testdataFactory.createTarget().getControllerId();
@@ -810,7 +820,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = MultiActionAssignEvent.class, count = 2) })
@Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void weightValidatedAndSaved() {
final String targetId = testdataFactory.createTarget().getControllerId();
final Long dsId = testdataFactory.createDistributionSet().getId();

View File

@@ -45,6 +45,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleTypeCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
@@ -199,8 +200,9 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
@Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.")
@WithUser(principal = "knownpricipal", allSpPermissions = false)
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
public void pollWithModifiedGloablPollingTime() throws Exception {
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
public void pollWithModifiedGlobalPollingTime() throws Exception {
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
"00:02:00");