Small refactoring (#2115)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -198,8 +198,7 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<Action> giveConfirmationForActiveActions(final AutoConfirmationStatus autoConfirmationStatus) {
|
private List<Action> giveConfirmationForActiveActions(final AutoConfirmationStatus autoConfirmationStatus) {
|
||||||
final Target target = autoConfirmationStatus.getTarget();
|
return findActiveActionsHavingStatus(autoConfirmationStatus.getTarget().getControllerId(), Status.WAIT_FOR_CONFIRMATION).stream()
|
||||||
return findActiveActionsHavingStatus(target.getControllerId(), Status.WAIT_FOR_CONFIRMATION).stream()
|
|
||||||
.map(action -> autoConfirmAction(action, autoConfirmationStatus))
|
.map(action -> autoConfirmAction(action, autoConfirmationStatus))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,10 +298,11 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
final DistributionSet jpaDistributionSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
|
final DistributionSet jpaDistributionSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
|
||||||
final Long distSetTypeId = jpaDistributionSet.getType().getId();
|
final Long distSetTypeId = jpaDistributionSet.getType().getId();
|
||||||
|
|
||||||
return targetRepository.count(AccessController.Operation.UPDATE,
|
return targetRepository.count(
|
||||||
|
AccessController.Operation.UPDATE,
|
||||||
combineWithAnd(List.of(
|
combineWithAnd(List.of(
|
||||||
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
|
RSQLUtility.buildRsqlSpecification(
|
||||||
virtualPropertyReplacer, database),
|
targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database),
|
||||||
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))));
|
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.repository.jpa.model;
|
|||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -148,7 +147,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
|||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
@OneToOne(fetch = FetchType.LAZY, mappedBy = "target", orphanRemoval = true)
|
@OneToOne(fetch = FetchType.LAZY, mappedBy = "target", cascade = { CascadeType.ALL }, orphanRemoval = true)
|
||||||
@PrimaryKeyJoinColumn
|
@PrimaryKeyJoinColumn
|
||||||
private JpaAutoConfirmationStatus autoConfirmationStatus;
|
private JpaAutoConfirmationStatus autoConfirmationStatus;
|
||||||
|
|
||||||
|
|||||||
@@ -294,8 +294,7 @@ public class BaseEntityRepositoryACM<T extends AbstractJpaTenantAwareBaseEntity>
|
|||||||
final R repository, @NonNull final AccessController<T> accessController) {
|
final R repository, @NonNull final AccessController<T> accessController) {
|
||||||
Objects.requireNonNull(repository);
|
Objects.requireNonNull(repository);
|
||||||
Objects.requireNonNull(accessController);
|
Objects.requireNonNull(accessController);
|
||||||
final BaseEntityRepositoryACM<T> repositoryACM =
|
final BaseEntityRepositoryACM<T> repositoryACM = new BaseEntityRepositoryACM<>(repository, accessController);
|
||||||
new BaseEntityRepositoryACM<>(repository, accessController);
|
|
||||||
final R acmProxy = (R) Proxy.newProxyInstance(
|
final R acmProxy = (R) Proxy.newProxyInstance(
|
||||||
Thread.currentThread().getContextClassLoader(),
|
Thread.currentThread().getContextClassLoader(),
|
||||||
repository.getClass().getInterfaces(),
|
repository.getClass().getInterfaces(),
|
||||||
@@ -312,6 +311,7 @@ public class BaseEntityRepositoryACM<T extends AbstractJpaTenantAwareBaseEntity>
|
|||||||
}
|
}
|
||||||
if (method.getName().startsWith("find") || method.getName().startsWith("get")) {
|
if (method.getName().startsWith("find") || method.getName().startsWith("get")) {
|
||||||
final Object result = method.invoke(repository, args);
|
final Object result = method.invoke(repository, args);
|
||||||
|
// Iterable, List, Page, Slice
|
||||||
if (Iterable.class.isAssignableFrom(method.getReturnType())) {
|
if (Iterable.class.isAssignableFrom(method.getReturnType())) {
|
||||||
for (final Object e : (Iterable<?>) result) {
|
for (final Object e : (Iterable<?>) result) {
|
||||||
if (repository.getDomainClass().isAssignableFrom(e.getClass())) {
|
if (repository.getDomainClass().isAssignableFrom(e.getClass())) {
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
* Spring data repositories for {@link TargetFilterQuery}s.
|
* Spring data repositories for {@link TargetFilterQuery}s.
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public interface TargetFilterQueryRepository
|
public interface TargetFilterQueryRepository extends BaseEntityRepository<JpaTargetFilterQuery> {
|
||||||
extends BaseEntityRepository<JpaTargetFilterQuery> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find customer target filter by name
|
* Find customer target filter by name
|
||||||
@@ -37,8 +36,7 @@ public interface TargetFilterQueryRepository
|
|||||||
Optional<TargetFilterQuery> findByName(String name);
|
Optional<TargetFilterQuery> findByName(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the auto assign distribution sets and action types to null which
|
* Sets the auto assign distribution sets and action types to null which match the ds ids.
|
||||||
* match the ds ids.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* No access control applied
|
* No access control applied
|
||||||
*
|
*
|
||||||
@@ -46,12 +44,11 @@ public interface TargetFilterQueryRepository
|
|||||||
*/
|
*/
|
||||||
@Modifying
|
@Modifying
|
||||||
@Transactional
|
@Transactional
|
||||||
@Query("update JpaTargetFilterQuery d set d.autoAssignDistributionSet = NULL, d.autoAssignActionType = NULL, d.accessControlContext = NULL where d.autoAssignDistributionSet in :ids")
|
@Query("UPDATE JpaTargetFilterQuery d SET d.autoAssignDistributionSet = NULL, d.autoAssignActionType = NULL, d.accessControlContext = NULL WHERE d.autoAssignDistributionSet.id IN :ids")
|
||||||
void unsetAutoAssignDistributionSetAndActionTypeAndAccessContext(@Param("ids") Long... dsIds);
|
void unsetAutoAssignDistributionSetAndActionTypeAndAccessContext(@Param("ids") Long... dsIds);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts all target filters that have a given auto assign distribution set
|
* Counts all target filters that have a given auto assign distribution set assigned.
|
||||||
* assigned.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* No access control applied
|
* No access control applied
|
||||||
*
|
*
|
||||||
@@ -61,10 +58,8 @@ public interface TargetFilterQueryRepository
|
|||||||
long countByAutoAssignDistributionSetId(long autoAssignDistributionSetId);
|
long countByAutoAssignDistributionSetId(long autoAssignDistributionSetId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety
|
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety reasons (this is a "delete everything" query after all) we add
|
||||||
* reasons (this is a "delete everything" query after all) we add the tenant
|
* the tenant manually to query even if this will by done by {@link EntityManager} anyhow. The DB should take care of optimizing this away.
|
||||||
* manually to query even if this will by done by {@link EntityManager}
|
|
||||||
* anyhow. The DB should take care of optimizing this away.
|
|
||||||
*
|
*
|
||||||
* @param tenant to delete data from
|
* @param tenant to delete data from
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -863,21 +863,18 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Expect(type = TargetPollEvent.class, count = 3),
|
@Expect(type = TargetPollEvent.class, count = 3),
|
||||||
@Expect(type = TargetUpdatedEvent.class, count = 1) })
|
@Expect(type = TargetUpdatedEvent.class, count = 1) })
|
||||||
void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
|
void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
|
||||||
|
|
||||||
final String controllerId = "12345";
|
final String controllerId = "12345";
|
||||||
final String targetName = "UpdatedName";
|
final String targetName = "UpdatedName";
|
||||||
|
|
||||||
final Target newTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST);
|
final Target newTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST);
|
||||||
assertThat(newTarget.getName()).isEqualTo(controllerId);
|
assertThat(newTarget.getName()).isEqualTo(controllerId);
|
||||||
|
|
||||||
final Target firstTimeUpdatedTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId,
|
final Target firstTimeUpdatedTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(
|
||||||
LOCALHOST, targetName, null);
|
controllerId, LOCALHOST, targetName, null);
|
||||||
assertThat(firstTimeUpdatedTarget.getName()).isEqualTo(targetName);
|
assertThat(firstTimeUpdatedTarget.getName()).isEqualTo(targetName);
|
||||||
|
|
||||||
// Name should not change to default (name=targetId) if target is
|
// Name should not change to default (name=targetId) if target is updated without new name provided
|
||||||
// updated without new name provided
|
final Target secondTimeUpdatedTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST);
|
||||||
final Target secondTimeUpdatedTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId,
|
|
||||||
LOCALHOST);
|
|
||||||
assertThat(secondTimeUpdatedTarget.getName()).isEqualTo(targetName);
|
assertThat(secondTimeUpdatedTarget.getName()).isEqualTo(targetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import org.springframework.test.context.TestContext;
|
|||||||
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
import org.springframework.test.context.support.AbstractTestExecutionListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test rule to setup and verify the event count for a method.
|
* Test rule to set up and verify the event count for a method.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class EventVerifier extends AbstractTestExecutionListener {
|
public class EventVerifier extends AbstractTestExecutionListener {
|
||||||
@@ -53,7 +53,7 @@ public class EventVerifier extends AbstractTestExecutionListener {
|
|||||||
* {@code @Before} annotations which are actually counted to the executed
|
* {@code @Before} annotations which are actually counted to the executed
|
||||||
* test-method and maybe fire events which are not covered / recognized by
|
* test-method and maybe fire events which are not covered / recognized by
|
||||||
* the test-method itself and reset the counter again.
|
* the test-method itself and reset the counter again.
|
||||||
*
|
* <p/>
|
||||||
* Note that this approach is only working when using a single-thread
|
* Note that this approach is only working when using a single-thread
|
||||||
* executor in the ApplicationEventMultiCaster, so the order of the events
|
* executor in the ApplicationEventMultiCaster, so the order of the events
|
||||||
* keep the same.
|
* keep the same.
|
||||||
@@ -74,7 +74,7 @@ public class EventVerifier extends AbstractTestExecutionListener {
|
|||||||
public void afterTestMethod(final TestContext testContext) {
|
public void afterTestMethod(final TestContext testContext) {
|
||||||
final Optional<Expect[]> expectedEvents = getExpectationsFrom(testContext.getTestMethod());
|
final Optional<Expect[]> expectedEvents = getExpectationsFrom(testContext.getTestMethod());
|
||||||
try {
|
try {
|
||||||
expectedEvents.ifPresent(events -> afterTest(events));
|
expectedEvents.ifPresent(this::afterTest);
|
||||||
} finally {
|
} finally {
|
||||||
expectedEvents.ifPresent(listener -> removeEventListener(testContext));
|
expectedEvents.ifPresent(listener -> removeEventListener(testContext));
|
||||||
}
|
}
|
||||||
@@ -85,10 +85,8 @@ public class EventVerifier extends AbstractTestExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void beforeTest(final TestContext testContext) {
|
private void beforeTest(final TestContext testContext) {
|
||||||
final ConfigurableApplicationContext context = (ConfigurableApplicationContext) testContext
|
|
||||||
.getApplicationContext();
|
|
||||||
eventCaptor = new EventCaptor();
|
eventCaptor = new EventCaptor();
|
||||||
context.addApplicationListener(eventCaptor);
|
((ConfigurableApplicationContext) testContext.getApplicationContext()).addApplicationListener(eventCaptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void afterTest(final Expect[] expectedEvents) {
|
private void afterTest(final Expect[] expectedEvents) {
|
||||||
@@ -97,39 +95,33 @@ public class EventVerifier extends AbstractTestExecutionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void verifyRightCountOfEvents(final Expect[] expectedEvents) {
|
private void verifyRightCountOfEvents(final Expect[] expectedEvents) {
|
||||||
|
|
||||||
for (final Expect expectedEvent : expectedEvents) {
|
for (final Expect expectedEvent : expectedEvents) {
|
||||||
try {
|
try {
|
||||||
Awaitility.await().atMost(5, TimeUnit.SECONDS)
|
Awaitility.await()
|
||||||
|
.atMost(5, TimeUnit.SECONDS)
|
||||||
.until(() -> eventCaptor.getCountFor(expectedEvent.type()), equalTo(expectedEvent.count()));
|
.until(() -> eventCaptor.getCountFor(expectedEvent.type()), equalTo(expectedEvent.count()));
|
||||||
|
|
||||||
} catch (final ConditionTimeoutException ex) {
|
} catch (final ConditionTimeoutException ex) {
|
||||||
fail("Did not receive the expected amount of events form " + expectedEvent.type() + " Expected: "
|
fail(String.format(
|
||||||
+ expectedEvent.count() + " but was: " + eventCaptor.getCountFor(expectedEvent.type()));
|
"Did not receive the expected amount of events form %s Expected: %d but was: %d",
|
||||||
|
expectedEvent.type(), expectedEvent.count(), eventCaptor.getCountFor(expectedEvent.type())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyAllEventsCounted(final Expect[] expectedEvents) {
|
private void verifyAllEventsCounted(final Expect[] expectedEvents) {
|
||||||
|
|
||||||
final Set<Class<?>> diffSet = eventCaptor.diff(expectedEvents);
|
final Set<Class<?>> diffSet = eventCaptor.diff(expectedEvents);
|
||||||
if (diffSet.size() > 0) {
|
if (!diffSet.isEmpty()) {
|
||||||
final StringBuilder failMessage = new StringBuilder("Missing event verification for ");
|
final StringBuilder failMessage = new StringBuilder("Missing event verification for ");
|
||||||
final Iterator<Class<?>> itr = diffSet.iterator();
|
for (final Class<?> element : diffSet) {
|
||||||
while (itr.hasNext()) {
|
|
||||||
final Class<?> element = itr.next();
|
|
||||||
final int count = eventCaptor.getCountFor(element);
|
final int count = eventCaptor.getCountFor(element);
|
||||||
failMessage.append(element + " with count: " + count + " ");
|
failMessage.append(element).append(" with count: ").append(count).append(" ");
|
||||||
}
|
}
|
||||||
fail(failMessage.toString());
|
fail(failMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeEventListener(final TestContext testContext) {
|
private void removeEventListener(final TestContext testContext) {
|
||||||
final ApplicationEventMulticaster multicaster = testContext.getApplicationContext()
|
testContext.getApplicationContext().getBean(ApplicationEventMulticaster.class).removeApplicationListener(eventCaptor);
|
||||||
.getBean(ApplicationEventMulticaster.class);
|
|
||||||
multicaster.removeApplicationListener(eventCaptor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EventCaptor implements ApplicationListener<RemoteApplicationEvent> {
|
private static class EventCaptor implements ApplicationListener<RemoteApplicationEvent> {
|
||||||
|
|||||||
Reference in New Issue
Block a user