Provide API for auto assignment check for specific device (#1262)

* Extend the auto assign executor to execute a auto assignment check for a specific device.

Signed-off-by: Michael Herdt <Michael.Herdt@bosch.io>

* add tests and handle exceptions

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* add unit test

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* add Copyright header

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* fix Copyright header

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* add authorization

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* fix exception handling and authorization

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* renaming

Signed-off-by: Stefan Klotz <stefan.klotz@bosch.io>

* Rename auto assignment functions

Signed-off-by: Michael Herdt <Michael.Herdt@bosch.io>

Co-authored-by: Stefan Klotz <stefan.klotz@bosch.io>
This commit is contained in:
Michael Herdt
2022-07-12 15:47:38 +02:00
committed by GitHub
parent 1ec5eb6ede
commit 5c95c4ce28
8 changed files with 647 additions and 334 deletions

View File

@@ -16,6 +16,7 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -53,6 +54,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.model.TargetMetadataCompositeKey;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -853,6 +855,25 @@ public class JpaTargetManagement implements TargetManagement {
return targetRepository.exists(TargetSpecifications.hasControllerId(controllerId));
}
@Override
public boolean isTargetMatchingQueryAndDSNotAssignedAndCompatible(final String controllerId,
final long distributionSetId, final String targetFilterQuery) {
RSQLUtility.validateRsqlFor(targetFilterQuery, TargetFields.class);
final DistributionSet ds = distributionSetManagement.get(distributionSetId)
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, distributionSetId));
final Long distSetTypeId = ds.getType().getId();
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer,
database),
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId),
TargetSpecifications.hasControllerId(controllerId));
final Specification<JpaTarget> combinedSpecification = Objects
.requireNonNull(SpecificationsBuilder.combineWithAnd(specList));
return targetRepository.exists(combinedSpecification);
}
@Override
public Page<Target> findByControllerAttributesRequested(final Pageable pageReq) {
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageReq,

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa.autoassign;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -64,12 +65,21 @@ public class AutoAssignChecker extends AbstractAutoAssignExecutor {
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void check() {
public void checkAllTargets() {
LOGGER.debug("Auto assign check call for tenant {} started", getTenantAware().getCurrentTenant());
forEachFilterWithAutoAssignDS(this::checkByTargetFilterQueryAndAssignDS);
LOGGER.debug("Auto assign check call for tenant {} finished", getTenantAware().getCurrentTenant());
}
@Override
public void checkSingleTarget(String controllerId) {
LOGGER.debug("Auto assign check call for tenant {} and device {} started", getTenantAware().getCurrentTenant(),
controllerId);
forEachFilterWithAutoAssignDS(filter -> checkForDevice(controllerId, filter));
LOGGER.debug("Auto assign check call for tenant {} and device {} finished", getTenantAware().getCurrentTenant(),
controllerId);
}
/**
* Fetches the distribution set, gets all controllerIds and assigns the DS
* to them. Catches PersistenceException and own exceptions derived from
@@ -104,4 +114,23 @@ public class AutoAssignChecker extends AbstractAutoAssignExecutor {
LOGGER.debug("Auto assign check call for tenant {} and target filter query id {} finished",
getTenantAware().getCurrentTenant(), targetFilterQuery.getId());
}
private void checkForDevice(final String controllerId, final TargetFilterQuery targetFilterQuery) {
LOGGER.debug("Auto assign check call for tenant {} and target filter query id {} for device {} started",
getTenantAware().getCurrentTenant(), targetFilterQuery.getId(), controllerId);
try {
final boolean controllerIdMatches = targetManagement.isTargetMatchingQueryAndDSNotAssignedAndCompatible(
controllerId, targetFilterQuery.getAutoAssignDistributionSet().getId(),
targetFilterQuery.getQuery());
if (controllerIdMatches) {
runTransactionalAssignment(targetFilterQuery, Collections.singletonList(controllerId));
}
} catch (final PersistenceException | AbstractServerRtException e) {
LOGGER.error("Error during auto assign check of target filter query id {}", targetFilterQuery.getId(), e);
}
LOGGER.debug("Auto assign check call for tenant {} and target filter query id {} finished",
getTenantAware().getCurrentTenant(), targetFilterQuery.getId());
}
}

View File

@@ -83,7 +83,7 @@ public class AutoAssignScheduler {
try {
LOGGER.debug("Auto assign scheduled execution has aquired lock and started for each tenant.");
systemManagement.forEachTenant(tenant -> autoAssignExecutor.check());
systemManagement.forEachTenant(tenant -> autoAssignExecutor.checkAllTargets());
} finally {
lock.unlock();
LOGGER.debug("Auto assign scheduled execution has released lock and finished.");