Refactoring/Improving source: repository 3 (slf4j) (#1603)
Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import java.util.stream.StreamSupport;
|
|||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
@@ -60,8 +61,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCond
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
@@ -74,10 +73,9 @@ import static org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupCreate.a
|
|||||||
/**
|
/**
|
||||||
* A Jpa implementation of {@link RolloutExecutor}
|
* A Jpa implementation of {@link RolloutExecutor}
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class JpaRolloutExecutor implements RolloutExecutor {
|
public class JpaRolloutExecutor implements RolloutExecutor {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(JpaRolloutExecutor.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max amount of targets that are handled in one transaction.
|
* Max amount of targets that are handled in one transaction.
|
||||||
*/
|
*/
|
||||||
@@ -148,7 +146,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(final Rollout rollout) {
|
public void execute(final Rollout rollout) {
|
||||||
LOGGER.debug("handle rollout {}", rollout.getId());
|
log.debug("handle rollout {}", rollout.getId());
|
||||||
|
|
||||||
switch (rollout.getStatus()) {
|
switch (rollout.getStatus()) {
|
||||||
case CREATING:
|
case CREATING:
|
||||||
@@ -170,13 +168,13 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
handleStopRollout((JpaRollout) rollout);
|
handleStopRollout((JpaRollout) rollout);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOGGER.error("Rollout in status {} not supposed to be handled!", rollout.getStatus());
|
log.error("Rollout in status {} not supposed to be handled!", rollout.getStatus());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleCreateRollout(final JpaRollout rollout) {
|
private void handleCreateRollout(final JpaRollout rollout) {
|
||||||
LOGGER.debug("handleCreateRollout called for rollout {}", rollout.getId());
|
log.debug("handleCreateRollout called for rollout {}", rollout.getId());
|
||||||
|
|
||||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(
|
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(
|
||||||
PageRequest.of(0, quotaManagement.getMaxRolloutGroupsPerRollout(), Sort.by(Direction.ASC, "id")),
|
PageRequest.of(0, quotaManagement.getMaxRolloutGroupsPerRollout(), Sort.by(Direction.ASC, "id")),
|
||||||
@@ -209,9 +207,9 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
|
|
||||||
if (!rolloutApprovalStrategy.isApprovalNeeded(rollout)) {
|
if (!rolloutApprovalStrategy.isApprovalNeeded(rollout)) {
|
||||||
rollout.setStatus(RolloutStatus.READY);
|
rollout.setStatus(RolloutStatus.READY);
|
||||||
LOGGER.debug("rollout {} creation done. Switch to READY.", rollout.getId());
|
log.debug("rollout {} creation done. Switch to READY.", rollout.getId());
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("rollout {} creation done. Switch to WAITING_FOR_APPROVAL.", rollout.getId());
|
log.debug("rollout {} creation done. Switch to WAITING_FOR_APPROVAL.", rollout.getId());
|
||||||
rollout.setStatus(RolloutStatus.WAITING_FOR_APPROVAL);
|
rollout.setStatus(RolloutStatus.WAITING_FOR_APPROVAL);
|
||||||
rolloutApprovalStrategy.onApprovalRequired(rollout);
|
rolloutApprovalStrategy.onApprovalRequired(rollout);
|
||||||
}
|
}
|
||||||
@@ -222,13 +220,13 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleDeleteRollout(final JpaRollout rollout) {
|
private void handleDeleteRollout(final JpaRollout rollout) {
|
||||||
LOGGER.debug("handleDeleteRollout called for {}", rollout.getId());
|
log.debug("handleDeleteRollout called for {}", rollout.getId());
|
||||||
|
|
||||||
// check if there are actions beyond schedule
|
// check if there are actions beyond schedule
|
||||||
boolean hardDeleteRolloutGroups = !actionRepository.existsByRolloutIdAndStatusNotIn(rollout.getId(),
|
boolean hardDeleteRolloutGroups = !actionRepository.existsByRolloutIdAndStatusNotIn(rollout.getId(),
|
||||||
Status.SCHEDULED);
|
Status.SCHEDULED);
|
||||||
if (hardDeleteRolloutGroups) {
|
if (hardDeleteRolloutGroups) {
|
||||||
LOGGER.debug("Rollout {} has no actions other than scheduled -> hard delete", rollout.getId());
|
log.debug("Rollout {} has no actions other than scheduled -> hard delete", rollout.getId());
|
||||||
hardDeleteRollout(rollout);
|
hardDeleteRollout(rollout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -265,7 +263,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleStopRollout(final JpaRollout rollout) {
|
private void handleStopRollout(final JpaRollout rollout) {
|
||||||
LOGGER.debug("handleStopRollout called for {}", rollout.getId());
|
log.debug("handleStopRollout called for {}", rollout.getId());
|
||||||
// clean up all scheduled actions
|
// clean up all scheduled actions
|
||||||
final Slice<JpaAction> scheduledActions = findScheduledActionsByRollout(rollout);
|
final Slice<JpaAction> scheduledActions = findScheduledActionsByRollout(rollout);
|
||||||
deleteScheduledActions(rollout, scheduledActions);
|
deleteScheduledActions(rollout, scheduledActions);
|
||||||
@@ -299,7 +297,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
|
|
||||||
private void handleReadyRollout(final Rollout rollout) {
|
private void handleReadyRollout(final Rollout rollout) {
|
||||||
if (rollout.getStartAt() != null && rollout.getStartAt() <= System.currentTimeMillis()) {
|
if (rollout.getStartAt() != null && rollout.getStartAt() <= System.currentTimeMillis()) {
|
||||||
LOGGER.debug(
|
log.debug(
|
||||||
"handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING",
|
"handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING",
|
||||||
rollout.getId());
|
rollout.getId());
|
||||||
rolloutManagement.start(rollout.getId());
|
rolloutManagement.start(rollout.getId());
|
||||||
@@ -307,7 +305,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleStartingRollout(final Rollout rollout) {
|
private void handleStartingRollout(final Rollout rollout) {
|
||||||
LOGGER.debug("handleStartingRollout called for rollout {}", rollout.getId());
|
log.debug("handleStartingRollout called for rollout {}", rollout.getId());
|
||||||
|
|
||||||
if (ensureAllGroupsAreScheduled(rollout)) {
|
if (ensureAllGroupsAreScheduled(rollout)) {
|
||||||
startFirstRolloutGroup(rollout);
|
startFirstRolloutGroup(rollout);
|
||||||
@@ -315,11 +313,11 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleRunningRollout(final JpaRollout rollout) {
|
private void handleRunningRollout(final JpaRollout rollout) {
|
||||||
LOGGER.debug("handleRunningRollout called for rollout {}", rollout.getId());
|
log.debug("handleRunningRollout called for rollout {}", rollout.getId());
|
||||||
|
|
||||||
if (rollout.isDynamic()) {
|
if (rollout.isDynamic()) {
|
||||||
if (fillDynamicRolloutGroupsWithTargets(rollout)) {
|
if (fillDynamicRolloutGroupsWithTargets(rollout)) {
|
||||||
LOGGER.debug("Dynamic group created for rollout {}", rollout.getId());
|
log.debug("Dynamic group created for rollout {}", rollout.getId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,12 +335,12 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
// to find the latest group which
|
// to find the latest group which
|
||||||
executeLatestRolloutGroup(rollout);
|
executeLatestRolloutGroup(rollout);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("Rollout {} has {} running groups", rollout.getId(), rolloutGroupsRunning.size());
|
log.debug("Rollout {} has {} running groups", rollout.getId(), rolloutGroupsRunning.size());
|
||||||
executeRolloutGroups(rollout, rolloutGroupsRunning, rollout.getRolloutGroups().get(rollout.getRolloutGroups().size() - 1));
|
executeRolloutGroups(rollout, rolloutGroupsRunning, rollout.getRolloutGroups().get(rollout.getRolloutGroups().size() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRolloutComplete(rollout)) {
|
if (isRolloutComplete(rollout)) {
|
||||||
LOGGER.info("Rollout {} is finished, setting FINISHED status", rollout);
|
log.info("Rollout {} is finished, setting FINISHED status", rollout);
|
||||||
rollout.setStatus(RolloutStatus.FINISHED);
|
rollout.setStatus(RolloutStatus.FINISHED);
|
||||||
rolloutRepository.save(rollout);
|
rolloutRepository.save(rollout);
|
||||||
}
|
}
|
||||||
@@ -365,7 +363,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher()
|
afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher()
|
||||||
.publishEvent(new RolloutUpdatedEvent(rollout, eventPublisherHolder.getApplicationId())));
|
.publishEvent(new RolloutUpdatedEvent(rollout, eventPublisherHolder.getApplicationId())));
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
LOGGER.error("Exception during deletion of actions of rollout {}", rollout, e);
|
log.error("Exception during deletion of actions of rollout {}", rollout, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -456,7 +454,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
// rollout because of error?
|
// rollout because of error?
|
||||||
final boolean isError = checkErrorState(rollout, evalProxy);
|
final boolean isError = checkErrorState(rollout, evalProxy);
|
||||||
if (isError) {
|
if (isError) {
|
||||||
LOGGER.info("Rollout {} {} has error, calling error action", rollout.getName(), rollout.getId());
|
log.info("Rollout {} {} has error, calling error action", rollout.getName(), rollout.getId());
|
||||||
callErrorAction(rollout, rolloutGroup);
|
callErrorAction(rollout, rolloutGroup);
|
||||||
} else {
|
} else {
|
||||||
// not in error so check finished state, do we need to
|
// not in error so check finished state, do we need to
|
||||||
@@ -492,7 +490,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
try {
|
try {
|
||||||
evaluationManager.getErrorActionEvaluator(rolloutGroup.getErrorAction()).exec(rollout, rolloutGroup);
|
evaluationManager.getErrorActionEvaluator(rolloutGroup.getErrorAction()).exec(rollout, rolloutGroup);
|
||||||
} catch (final EvaluatorNotConfiguredException e) {
|
} catch (final EvaluatorNotConfiguredException e) {
|
||||||
LOGGER.error("Something bad happened when accessing the error action bean {}",
|
log.error("Something bad happened when accessing the error action bean {}",
|
||||||
rolloutGroup.getErrorAction().name(), e);
|
rolloutGroup.getErrorAction().name(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -518,26 +516,26 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
return evaluationManager.getErrorConditionEvaluator(errorCondition).eval(rollout, rolloutGroup,
|
return evaluationManager.getErrorConditionEvaluator(errorCondition).eval(rollout, rolloutGroup,
|
||||||
rolloutGroup.getErrorConditionExp());
|
rolloutGroup.getErrorConditionExp());
|
||||||
} catch (final EvaluatorNotConfiguredException e) {
|
} catch (final EvaluatorNotConfiguredException e) {
|
||||||
LOGGER.error("Something bad happened when accessing the error condition bean {}", errorCondition.name(), e);
|
log.error("Something bad happened when accessing the error condition bean {}", errorCondition.name(), e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSuccessCondition(final Rollout rollout, final RolloutGroup rolloutGroup, final RolloutGroup evalProxy,
|
private boolean checkSuccessCondition(final Rollout rollout, final RolloutGroup rolloutGroup, final RolloutGroup evalProxy,
|
||||||
final RolloutGroupSuccessCondition successCondition) {
|
final RolloutGroupSuccessCondition successCondition) {
|
||||||
LOGGER.trace("Checking finish condition {} on rolloutgroup {}", successCondition, rolloutGroup);
|
log.trace("Checking finish condition {} on rolloutgroup {}", successCondition, rolloutGroup);
|
||||||
try {
|
try {
|
||||||
final boolean isFinished = evaluationManager.getSuccessConditionEvaluator(successCondition).eval(rollout,
|
final boolean isFinished = evaluationManager.getSuccessConditionEvaluator(successCondition).eval(rollout,
|
||||||
evalProxy, rolloutGroup.getSuccessConditionExp());
|
evalProxy, rolloutGroup.getSuccessConditionExp());
|
||||||
if (isFinished) {
|
if (isFinished) {
|
||||||
LOGGER.debug("Rolloutgroup {} is finished, starting next group", rolloutGroup);
|
log.debug("Rolloutgroup {} is finished, starting next group", rolloutGroup);
|
||||||
executeRolloutGroupSuccessAction(rollout, rolloutGroup);
|
executeRolloutGroupSuccessAction(rollout, rolloutGroup);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("Rolloutgroup {} is still running", rolloutGroup);
|
log.debug("Rolloutgroup {} is still running", rolloutGroup);
|
||||||
}
|
}
|
||||||
return isFinished;
|
return isFinished;
|
||||||
} catch (final EvaluatorNotConfiguredException e) {
|
} catch (final EvaluatorNotConfiguredException e) {
|
||||||
LOGGER.error("Something bad happened when accessing the finish condition or success action bean {}",
|
log.error("Something bad happened when accessing the finish condition or success action bean {}",
|
||||||
successCondition.name(), e);
|
successCondition.name(), e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -548,7 +546,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void startFirstRolloutGroup(final Rollout rollout) {
|
private void startFirstRolloutGroup(final Rollout rollout) {
|
||||||
LOGGER.debug("startFirstRolloutGroup called for rollout {}", rollout.getId());
|
log.debug("startFirstRolloutGroup called for rollout {}", rollout.getId());
|
||||||
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.STARTING);
|
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.STARTING);
|
||||||
final JpaRollout jpaRollout = (JpaRollout) rollout;
|
final JpaRollout jpaRollout = (JpaRollout) rollout;
|
||||||
|
|
||||||
@@ -643,7 +641,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
return rolloutGroupRepository.save(group);
|
return rolloutGroupRepository.save(group);
|
||||||
|
|
||||||
} catch (final TransactionException e) {
|
} catch (final TransactionException e) {
|
||||||
LOGGER.warn("Transaction assigning Targets to RolloutGroup failed", e);
|
log.warn("Transaction assigning Targets to RolloutGroup failed", e);
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -730,7 +728,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (final TransactionException e) {
|
} catch (final TransactionException e) {
|
||||||
LOGGER.warn("Transaction assigning Targets to RolloutGroup failed", e);
|
log.warn("Transaction assigning Targets to RolloutGroup failed", e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -817,7 +815,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
} while (actionsCreated > 0);
|
} while (actionsCreated > 0);
|
||||||
|
|
||||||
} catch (final TransactionException e) {
|
} catch (final TransactionException e) {
|
||||||
LOGGER.warn("Transaction assigning Targets to RolloutGroup failed", e);
|
log.warn("Transaction assigning Targets to RolloutGroup failed", e);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return totalActionsCreated;
|
return totalActionsCreated;
|
||||||
|
|||||||
@@ -12,22 +12,21 @@ package org.eclipse.hawkbit.repository.jpa;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.ContextAware;
|
import org.eclipse.hawkbit.ContextAware;
|
||||||
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
||||||
import org.eclipse.hawkbit.repository.RolloutHandler;
|
import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.integration.support.locks.LockRegistry;
|
import org.springframework.integration.support.locks.LockRegistry;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA implementation of {@link RolloutHandler}.
|
* JPA implementation of {@link RolloutHandler}.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class JpaRolloutHandler implements RolloutHandler {
|
public class JpaRolloutHandler implements RolloutHandler {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(JpaRolloutHandler.class);
|
|
||||||
|
|
||||||
private final TenantAware tenantAware;
|
private final TenantAware tenantAware;
|
||||||
private final RolloutManagement rolloutManagement;
|
private final RolloutManagement rolloutManagement;
|
||||||
@@ -73,18 +72,18 @@ public class JpaRolloutHandler implements RolloutHandler {
|
|||||||
final String handlerId = createRolloutLockKey(tenantAware.getCurrentTenant());
|
final String handlerId = createRolloutLockKey(tenantAware.getCurrentTenant());
|
||||||
final Lock lock = lockRegistry.obtain(handlerId);
|
final Lock lock = lockRegistry.obtain(handlerId);
|
||||||
if (!lock.tryLock()) {
|
if (!lock.tryLock()) {
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
LOGGER.trace("Could not perform lock {}", lock);
|
log.trace("Could not perform lock {}", lock);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOGGER.trace("Trigger handling {} rollouts.", rollouts.size());
|
log.trace("Trigger handling {} rollouts.", rollouts.size());
|
||||||
rollouts.forEach(rolloutId -> handleRolloutInNewTransaction(rolloutId, handlerId));
|
rollouts.forEach(rolloutId -> handleRolloutInNewTransaction(rolloutId, handlerId));
|
||||||
} finally {
|
} finally {
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
LOGGER.trace("Unlock lock {}", lock);
|
log.trace("Unlock lock {}", lock);
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
@@ -114,7 +113,7 @@ public class JpaRolloutHandler implements RolloutHandler {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
() -> LOGGER.error("Could not retrieve rollout with id {}. Will not continue with execution.",
|
() -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.",
|
||||||
rolloutId));
|
rolloutId));
|
||||||
return 0L;
|
return 0L;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.autoassign;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.ContextAware;
|
import org.eclipse.hawkbit.ContextAware;
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||||
@@ -21,8 +22,6 @@ import org.eclipse.hawkbit.repository.model.Action;
|
|||||||
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
@@ -33,10 +32,9 @@ import org.springframework.util.StringUtils;
|
|||||||
/**
|
/**
|
||||||
* Abstract implementation of an AutoAssignExecutor
|
* Abstract implementation of an AutoAssignExecutor
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
|
public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAutoAssignExecutor.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The message which is added to the action status when a distribution set is
|
* The message which is added to the action status when a distribution set is
|
||||||
* assigned to an target. First %s is the name of the target filter.
|
* assigned to an target. First %s is the name of the target filter.
|
||||||
@@ -115,10 +113,10 @@ public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
} catch (final RuntimeException ex) {
|
} catch (final RuntimeException ex) {
|
||||||
LOGGER.debug(
|
log.debug(
|
||||||
"Exception on forEachFilterWithAutoAssignDS execution for tenant {} with filter id {}. Continue with next filter query.",
|
"Exception on forEachFilterWithAutoAssignDS execution for tenant {} with filter id {}. Continue with next filter query.",
|
||||||
filterQuery.getTenant(), filterQuery.getId(), ex);
|
filterQuery.getTenant(), filterQuery.getId(), ex);
|
||||||
LOGGER.error(
|
log.error(
|
||||||
"Exception on forEachFilterWithAutoAssignDS execution for tenant {} with filter id {} and error message [{}]. "
|
"Exception on forEachFilterWithAutoAssignDS execution for tenant {} with filter id {} and error message [{}]. "
|
||||||
+ "Continue with next filter query.",
|
+ "Continue with next filter query.",
|
||||||
filterQuery.getTenant(), filterQuery.getId(), ex.getMessage());
|
filterQuery.getTenant(), filterQuery.getId(), ex.getMessage());
|
||||||
|
|||||||
@@ -11,19 +11,18 @@ package org.eclipse.hawkbit.repository.jpa.autoassign;
|
|||||||
|
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.repository.autoassign.AutoAssignExecutor;
|
import org.eclipse.hawkbit.repository.autoassign.AutoAssignExecutor;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.integration.support.locks.LockRegistry;
|
import org.springframework.integration.support.locks.LockRegistry;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scheduler to check target filters for auto assignment of distribution sets
|
* Scheduler to check target filters for auto assignment of distribution sets
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class AutoAssignScheduler {
|
public class AutoAssignScheduler {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AutoAssignScheduler.class);
|
|
||||||
|
|
||||||
private static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.autoassign.scheduler.fixedDelay:2000}";
|
private static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.autoassign.scheduler.fixedDelay:2000}";
|
||||||
|
|
||||||
@@ -83,11 +82,11 @@ public class AutoAssignScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Auto assign scheduled execution has acquired lock and started for each tenant.");
|
log.debug("Auto assign scheduled execution has acquired lock and started for each tenant.");
|
||||||
systemManagement.forEachTenant(tenant -> autoAssignExecutor.checkAllTargets());
|
systemManagement.forEachTenant(tenant -> autoAssignExecutor.checkAllTargets());
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
LOGGER.debug("Auto assign scheduled execution has released lock and finished.");
|
log.debug("Auto assign scheduled execution has released lock and finished.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -20,13 +20,12 @@ import java.util.EnumSet;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cleanup task for {@link Action} entities which can be used to delete
|
* A cleanup task for {@link Action} entities which can be used to delete
|
||||||
@@ -37,10 +36,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* The cleanup task can be enabled /disabled and configured on a per tenant
|
* The cleanup task can be enabled /disabled and configured on a per tenant
|
||||||
* basis.
|
* basis.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class AutoActionCleanup implements CleanupTask {
|
public class AutoActionCleanup implements CleanupTask {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AutoActionCleanup.class);
|
|
||||||
|
|
||||||
private static final String ID = "action-cleanup";
|
private static final String ID = "action-cleanup";
|
||||||
private static final boolean ACTION_CLEANUP_ENABLED_DEFAULT = false;
|
private static final boolean ACTION_CLEANUP_ENABLED_DEFAULT = false;
|
||||||
private static final long ACTION_CLEANUP_ACTION_EXPIRY_DEFAULT = TimeUnit.DAYS.toMillis(30);
|
private static final long ACTION_CLEANUP_ACTION_EXPIRY_DEFAULT = TimeUnit.DAYS.toMillis(30);
|
||||||
@@ -67,7 +65,7 @@ public class AutoActionCleanup implements CleanupTask {
|
|||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
if (!isEnabled()) {
|
if (!isEnabled()) {
|
||||||
LOGGER.debug("Action cleanup is disabled for this tenant...");
|
log.debug("Action cleanup is disabled for this tenant...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +73,7 @@ public class AutoActionCleanup implements CleanupTask {
|
|||||||
if (!status.isEmpty()) {
|
if (!status.isEmpty()) {
|
||||||
final long lastModified = System.currentTimeMillis() - getExpiry();
|
final long lastModified = System.currentTimeMillis() - getExpiry();
|
||||||
final int actionsCount = deploymentMgmt.deleteActionsByStatusAndLastModifiedBefore(status, lastModified);
|
final int actionsCount = deploymentMgmt.deleteActionsByStatusAndLastModifiedBefore(status, lastModified);
|
||||||
LOGGER.debug("Deleted {} actions in status {} which have not been modified since {} ({})", actionsCount,
|
log.debug("Deleted {} actions in status {} which have not been modified since {} ({})", actionsCount,
|
||||||
status, Instant.ofEpochMilli(lastModified), lastModified);
|
status, Instant.ofEpochMilli(lastModified), lastModified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.configuration;
|
package org.eclipse.hawkbit.repository.jpa.configuration;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constant class which holds only static constants used within the SP server.
|
* A constant class which holds only static constants used within the SP server.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,22 +28,12 @@ public final class Constants {
|
|||||||
* number.
|
* number.
|
||||||
*/
|
*/
|
||||||
public static final int MAX_ENTRIES_IN_STATEMENT = 999;
|
public static final int MAX_ENTRIES_IN_STATEMENT = 999;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Retryable#maxAttempts()
|
* @see Retryable#maxAttempts()
|
||||||
*/
|
*/
|
||||||
public static final int TX_RT_MAX = 10;
|
public static final int TX_RT_MAX = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Backoff#delay()
|
* @see Backoff#delay()
|
||||||
*/
|
*/
|
||||||
public static final long TX_RT_DELAY = 100;
|
public static final long TX_RT_DELAY = 100;
|
||||||
|
|
||||||
/**
|
|
||||||
* Constant class only private constructor.
|
|
||||||
*/
|
|
||||||
private Constants() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.configuration;
|
package org.eclipse.hawkbit.repository.jpa.configuration;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
@@ -30,6 +31,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
|
public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
|
||||||
|
|
||||||
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -24,16 +24,13 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
public class JpaEventEntityManager implements EventEntityManager {
|
public class JpaEventEntityManager implements EventEntityManager {
|
||||||
|
|
||||||
private final TenantAware tenantAware;
|
private final TenantAware tenantAware;
|
||||||
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param tenantAware
|
* @param tenantAware the tenant aware
|
||||||
* the tenant aware
|
* @param entityManager the entity manager
|
||||||
* @param entityManager
|
|
||||||
* the entity manager
|
|
||||||
*/
|
*/
|
||||||
public JpaEventEntityManager(final TenantAware tenantAware, final EntityManager entityManager) {
|
public JpaEventEntityManager(final TenantAware tenantAware, final EntityManager entityManager) {
|
||||||
this.tenantAware = tenantAware;
|
this.tenantAware = tenantAware;
|
||||||
@@ -45,5 +42,4 @@ public class JpaEventEntityManager implements EventEntityManager {
|
|||||||
final Class<E> entityType) {
|
final Class<E> entityType) {
|
||||||
return tenantAware.runAsTenant(tenant, () -> entityManager.find(entityType, id));
|
return tenantAware.runAsTenant(tenant, () -> entityManager.find(entityType, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,19 +12,18 @@ package org.eclipse.hawkbit.repository.jpa.executor;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* A Service which calls register runnable. This runnables will executed after a
|
* A Service which calls register runnable. This runnables will executed after a
|
||||||
* successful spring transaction commit.The class is thread safe.
|
* successful spring transaction commit.The class is thread safe.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSynchronizationAdapter
|
public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSynchronizationAdapter
|
||||||
implements AfterTransactionCommitExecutor {
|
implements AfterTransactionCommitExecutor {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AfterTransactionCommitDefaultServiceExecutor.class);
|
|
||||||
private static final ThreadLocal<List<Runnable>> THREAD_LOCAL_RUNNABLES = new ThreadLocal<>();
|
private static final ThreadLocal<List<Runnable>> THREAD_LOCAL_RUNNABLES = new ThreadLocal<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -32,13 +31,13 @@ public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSyn
|
|||||||
@SuppressWarnings({ "squid:S1217" })
|
@SuppressWarnings({ "squid:S1217" })
|
||||||
public void afterCommit() {
|
public void afterCommit() {
|
||||||
final List<Runnable> afterCommitRunnables = THREAD_LOCAL_RUNNABLES.get();
|
final List<Runnable> afterCommitRunnables = THREAD_LOCAL_RUNNABLES.get();
|
||||||
LOGGER.debug("Transaction successfully committed, executing {} runnables", afterCommitRunnables.size());
|
log.debug("Transaction successfully committed, executing {} runnables", afterCommitRunnables.size());
|
||||||
for (final Runnable afterCommitRunnable : afterCommitRunnables) {
|
for (final Runnable afterCommitRunnable : afterCommitRunnables) {
|
||||||
LOGGER.debug("Executing runnable {}", afterCommitRunnable);
|
log.debug("Executing runnable {}", afterCommitRunnable);
|
||||||
try {
|
try {
|
||||||
afterCommitRunnable.run();
|
afterCommitRunnable.run();
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
LOGGER.error("Failed to execute runnable " + afterCommitRunnable, e);
|
log.error("Failed to execute runnable " + afterCommitRunnable, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +46,7 @@ public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSyn
|
|||||||
// Exception squid:S1217 - we want to run this synchronous
|
// Exception squid:S1217 - we want to run this synchronous
|
||||||
@SuppressWarnings("squid:S1217")
|
@SuppressWarnings("squid:S1217")
|
||||||
public void afterCommit(final Runnable runnable) {
|
public void afterCommit(final Runnable runnable) {
|
||||||
LOGGER.debug("Submitting new runnable {} to run after transaction commit", runnable);
|
log.debug("Submitting new runnable {} to run after transaction commit", runnable);
|
||||||
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
if (TransactionSynchronizationManager.isSynchronizationActive()) {
|
||||||
List<Runnable> localRunnables = THREAD_LOCAL_RUNNABLES.get();
|
List<Runnable> localRunnables = THREAD_LOCAL_RUNNABLES.get();
|
||||||
if (localRunnables == null) {
|
if (localRunnables == null) {
|
||||||
@@ -58,7 +57,7 @@ public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSyn
|
|||||||
localRunnables.add(runnable);
|
localRunnables.add(runnable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOGGER.info("Transaction synchronization is NOT ACTIVE/ INACTIVE. Executing right now runnable {}", runnable);
|
log.info("Transaction synchronization is NOT ACTIVE/ INACTIVE. Executing right now runnable {}", runnable);
|
||||||
|
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
@@ -67,7 +66,7 @@ public class AfterTransactionCommitDefaultServiceExecutor extends TransactionSyn
|
|||||||
@SuppressWarnings({ "squid:S1217" })
|
@SuppressWarnings({ "squid:S1217" })
|
||||||
public void afterCompletion(final int status) {
|
public void afterCompletion(final int status) {
|
||||||
final String transactionStatus = status == STATUS_COMMITTED ? "COMMITTED" : "ROLLEDBACK";
|
final String transactionStatus = status == STATUS_COMMITTED ? "COMMITTED" : "ROLLEDBACK";
|
||||||
LOGGER.debug("Transaction completed after commit with status {}", transactionStatus);
|
log.debug("Transaction completed after commit with status {}", transactionStatus);
|
||||||
THREAD_LOCAL_RUNNABLES.remove();
|
THREAD_LOCAL_RUNNABLES.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
|
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
|
||||||
import org.eclipse.hawkbit.artifact.repository.ArtifactStoreException;
|
import org.eclipse.hawkbit.artifact.repository.ArtifactStoreException;
|
||||||
import org.eclipse.hawkbit.artifact.repository.HashNotMatchException;
|
import org.eclipse.hawkbit.artifact.repository.HashNotMatchException;
|
||||||
@@ -46,8 +47,6 @@ import org.eclipse.hawkbit.repository.model.Artifact;
|
|||||||
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -63,14 +62,12 @@ import jakarta.persistence.EntityManager;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA based {@link ArtifactManagement} implementation.
|
* JPA based {@link ArtifactManagement} implementation.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Validated
|
@Validated
|
||||||
public class JpaArtifactManagement implements ArtifactManagement {
|
public class JpaArtifactManagement implements ArtifactManagement {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(JpaArtifactManagement.class);
|
|
||||||
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
private final LocalArtifactRepository localArtifactRepository;
|
private final LocalArtifactRepository localArtifactRepository;
|
||||||
@@ -111,7 +108,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
|
|||||||
final Artifact existing = softwareModule.getArtifactByFilename(filename).orElse(null);
|
final Artifact existing = softwareModule.getArtifactByFilename(filename).orElse(null);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
if (artifactUpload.isOverrideExisting()) {
|
if (artifactUpload.isOverrideExisting()) {
|
||||||
LOG.debug("overriding existing artifact with new filename {}", filename);
|
log.debug("overriding existing artifact with new filename {}", filename);
|
||||||
} else {
|
} else {
|
||||||
throw new EntityAlreadyExistsException("File with that name already exists in the Software Module");
|
throw new EntityAlreadyExistsException("File with that name already exists in the Software Module");
|
||||||
}
|
}
|
||||||
@@ -204,7 +201,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
|
|||||||
@Override
|
@Override
|
||||||
public void afterCommit() {
|
public void afterCommit() {
|
||||||
try {
|
try {
|
||||||
LOG.debug("deleting artifact from repository {}", sha1Hash);
|
log.debug("deleting artifact from repository {}", sha1Hash);
|
||||||
artifactRepository.deleteBySha1(tenantAware.getCurrentTenant(), sha1Hash);
|
artifactRepository.deleteBySha1(tenantAware.getCurrentTenant(), sha1Hash);
|
||||||
} catch (final ArtifactStoreException e) {
|
} catch (final ArtifactStoreException e) {
|
||||||
throw new ArtifactDeleteFailedException(e);
|
throw new ArtifactDeleteFailedException(e);
|
||||||
@@ -319,7 +316,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
|
|||||||
artifact.setSha256Hash(result.getHashes().getSha256());
|
artifact.setSha256Hash(result.getHashes().getSha256());
|
||||||
artifact.setSize(result.getSize());
|
artifact.setSize(result.getSize());
|
||||||
|
|
||||||
LOG.debug("storing new artifact into repository {}", artifact);
|
log.debug("storing new artifact into repository {}", artifact);
|
||||||
return localArtifactRepository.save(AccessController.Operation.CREATE, artifact);
|
return localArtifactRepository.save(AccessController.Operation.CREATE, artifact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.util.Collection;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetInvalidationManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetInvalidationManagement;
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||||
@@ -29,19 +30,15 @@ import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation.Cancelat
|
|||||||
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidationCount;
|
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidationCount;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.integration.support.locks.LockRegistry;
|
import org.springframework.integration.support.locks.LockRegistry;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jpa implementation for {@link DistributionSetInvalidationManagement}
|
* Jpa implementation for {@link DistributionSetInvalidationManagement}
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class JpaDistributionSetInvalidationManagement implements DistributionSetInvalidationManagement {
|
public class JpaDistributionSetInvalidationManagement implements DistributionSetInvalidationManagement {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(JpaDistributionSetInvalidationManagement.class);
|
|
||||||
|
|
||||||
private final DistributionSetManagement distributionSetManagement;
|
private final DistributionSetManagement distributionSetManagement;
|
||||||
private final RolloutManagement rolloutManagement;
|
private final RolloutManagement rolloutManagement;
|
||||||
private final DeploymentManagement deploymentManagement;
|
private final DeploymentManagement deploymentManagement;
|
||||||
@@ -73,7 +70,7 @@ public class JpaDistributionSetInvalidationManagement implements DistributionSet
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateDistributionSet(final DistributionSetInvalidation distributionSetInvalidation) {
|
public void invalidateDistributionSet(final DistributionSetInvalidation distributionSetInvalidation) {
|
||||||
LOG.debug("Invalidate distribution sets {}", distributionSetInvalidation.getDistributionSetIds());
|
log.debug("Invalidate distribution sets {}", distributionSetInvalidation.getDistributionSetIds());
|
||||||
final String tenant = tenantAware.getCurrentTenant();
|
final String tenant = tenantAware.getCurrentTenant();
|
||||||
if (shouldRolloutsBeCanceled(distributionSetInvalidation.getCancelationType(),
|
if (shouldRolloutsBeCanceled(distributionSetInvalidation.getCancelationType(),
|
||||||
distributionSetInvalidation.isCancelRollouts())) {
|
distributionSetInvalidation.isCancelRollouts())) {
|
||||||
@@ -89,7 +86,7 @@ public class JpaDistributionSetInvalidationManagement implements DistributionSet
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
LOG.error("InterruptedException while invalidating distribution sets {}!",
|
log.error("InterruptedException while invalidating distribution sets {}!",
|
||||||
distributionSetInvalidation.getDistributionSetIds(), e);
|
distributionSetInvalidation.getDistributionSetIds(), e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
@@ -113,22 +110,22 @@ public class JpaDistributionSetInvalidationManagement implements DistributionSet
|
|||||||
final boolean cancelRollouts) {
|
final boolean cancelRollouts) {
|
||||||
final DistributionSet set = distributionSetManagement.getValidAndComplete(setId);
|
final DistributionSet set = distributionSetManagement.getValidAndComplete(setId);
|
||||||
distributionSetManagement.invalidate(set);
|
distributionSetManagement.invalidate(set);
|
||||||
LOG.debug("Distribution set {} marked as invalid.", setId);
|
log.debug("Distribution set {} marked as invalid.", setId);
|
||||||
|
|
||||||
// rollout cancellation should only be permitted with UPDATE_ROLLOUT permission
|
// rollout cancellation should only be permitted with UPDATE_ROLLOUT permission
|
||||||
if (shouldRolloutsBeCanceled(cancelationType, cancelRollouts)) {
|
if (shouldRolloutsBeCanceled(cancelationType, cancelRollouts)) {
|
||||||
LOG.debug("Cancel rollouts after ds invalidation. ID: {}", setId);
|
log.debug("Cancel rollouts after ds invalidation. ID: {}", setId);
|
||||||
rolloutManagement.cancelRolloutsForDistributionSet(set);
|
rolloutManagement.cancelRolloutsForDistributionSet(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do run as system to ensure all actions (even invisible) are canceled due to invalidation.
|
// Do run as system to ensure all actions (even invisible) are canceled due to invalidation.
|
||||||
systemSecurityContext.runAsSystem(() -> {
|
systemSecurityContext.runAsSystem(() -> {
|
||||||
if (cancelationType != CancelationType.NONE) {
|
if (cancelationType != CancelationType.NONE) {
|
||||||
LOG.debug("Cancel actions after ds invalidation. ID: {}", setId);
|
log.debug("Cancel actions after ds invalidation. ID: {}", setId);
|
||||||
deploymentManagement.cancelActionsForDistributionSet(cancelationType, set);
|
deploymentManagement.cancelActionsForDistributionSet(cancelationType, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.debug("Cancel auto assignments after ds invalidation. ID: {}", setId);
|
log.debug("Cancel auto assignments after ds invalidation. ID: {}", setId);
|
||||||
targetFilterQueryManagement.cancelAutoAssignmentForDistributionSet(setId);
|
targetFilterQueryManagement.cancelAutoAssignmentForDistributionSet(setId);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
|
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
|
||||||
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
@@ -48,8 +49,6 @@ import org.eclipse.hawkbit.repository.report.model.SystemUsageReportWithTenants;
|
|||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
@@ -68,14 +67,12 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA implementation of {@link SystemManagement}.
|
* JPA implementation of {@link SystemManagement}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Validated
|
@Validated
|
||||||
public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement {
|
public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, SystemManagement {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(JpaSystemManagement.class);
|
|
||||||
|
|
||||||
private static final int MAX_TENANTS_QUERY = 1000;
|
private static final int MAX_TENANTS_QUERY = 1000;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -262,7 +259,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
final TenantMetaData metaData = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
|
final TenantMetaData metaData = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
|
||||||
if (metaData == null) {
|
if (metaData == null) {
|
||||||
if (repositoryProperties.isImplicitTenantCreateAllowed()) {
|
if (repositoryProperties.isImplicitTenantCreateAllowed()) {
|
||||||
LOGGER.info("Tenant {} doesn't exist create metadata", tenant, new Exception("Thread dump"));
|
log.info("Tenant {} doesn't exist create metadata", tenant, new Exception("Thread dump"));
|
||||||
return createTenantMetadata0(tenant);
|
return createTenantMetadata0(tenant);
|
||||||
} else {
|
} else {
|
||||||
throw new EntityNotFoundException(TenantMetaData.class, tenant);
|
throw new EntityNotFoundException(TenantMetaData.class, tenant);
|
||||||
@@ -344,9 +341,9 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
try {
|
try {
|
||||||
consumer.accept(tenant);
|
consumer.accept(tenant);
|
||||||
} catch (final RuntimeException ex) {
|
} catch (final RuntimeException ex) {
|
||||||
LOGGER.debug("Exception on forEachTenant execution for tenant {}. Continue with next tenant.",
|
log.debug("Exception on forEachTenant execution for tenant {}. Continue with next tenant.",
|
||||||
tenant, ex);
|
tenant, ex);
|
||||||
LOGGER.error("Exception on forEachTenant execution for tenant {} with error message [{}]. "
|
log.error("Exception on forEachTenant execution for tenant {} with error message [{}]. "
|
||||||
+ "Continue with next tenant.", tenant, ex.getMessage());
|
+ "Continue with next tenant.", tenant, ex.getMessage());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
@@ -50,8 +51,6 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
|||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -68,14 +67,12 @@ import cz.jirutka.rsql.parser.RSQLParserException;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA implementation of {@link TargetFilterQueryManagement}.
|
* JPA implementation of {@link TargetFilterQueryManagement}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Validated
|
@Validated
|
||||||
public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement {
|
public class JpaTargetFilterQueryManagement implements TargetFilterQueryManagement {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(JpaTargetFilterQueryManagement.class);
|
|
||||||
|
|
||||||
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
||||||
private final TargetManagement targetManagement;
|
private final TargetManagement targetManagement;
|
||||||
|
|
||||||
@@ -331,7 +328,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
RSQLUtility.validateRsqlFor(query, TargetFields.class);
|
RSQLUtility.validateRsqlFor(query, TargetFields.class);
|
||||||
return true;
|
return true;
|
||||||
} catch (final RSQLParserException | RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParserException | RSQLParameterUnsupportedFieldException e) {
|
||||||
LOGGER.debug("The RSQL query '" + query + "' is invalid.", e);
|
log.debug("The RSQL query '" + query + "' is invalid.", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,6 +343,6 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
@Transactional
|
@Transactional
|
||||||
public void cancelAutoAssignmentForDistributionSet(final long distributionSetId) {
|
public void cancelAutoAssignmentForDistributionSet(final long distributionSetId) {
|
||||||
targetFilterQueryRepository.unsetAutoAssignDistributionSetAndActionTypeAndAccessContext(distributionSetId);
|
targetFilterQueryRepository.unsetAutoAssignDistributionSetAndActionTypeAndAccessContext(distributionSetId);
|
||||||
LOGGER.debug("Auto assignments for distribution sets {} deactivated", distributionSetId);
|
log.debug("Auto assignments for distribution sets {} deactivated", distributionSetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.repository.exception.TenantConfigurationValueChangeNotAllowedException;
|
import org.eclipse.hawkbit.repository.exception.TenantConfigurationValueChangeNotAllowedException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||||
@@ -31,8 +32,6 @@ import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
|||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException;
|
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
@@ -50,12 +49,11 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
/**
|
/**
|
||||||
* Central tenant configuration management operations of the SP server.
|
* Central tenant configuration management operations of the SP server.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Validated
|
@Validated
|
||||||
public class JpaTenantConfigurationManagement implements TenantConfigurationManagement {
|
public class JpaTenantConfigurationManagement implements TenantConfigurationManagement {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(JpaTenantConfigurationManagement.class);
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TenantConfigurationRepository tenantConfigurationRepository;
|
private TenantConfigurationRepository tenantConfigurationRepository;
|
||||||
|
|
||||||
@@ -241,7 +239,7 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana
|
|||||||
private void assertAutoCloseValueChange(final String key, final JpaTenantConfiguration valueChange) {
|
private void assertAutoCloseValueChange(final String key, final JpaTenantConfiguration valueChange) {
|
||||||
if (REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED.equals(key)
|
if (REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED.equals(key)
|
||||||
&& getConfigurationValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class).getValue()) {
|
&& getConfigurationValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class).getValue()) {
|
||||||
LOG.debug(
|
log.debug(
|
||||||
"The property '{}' must not be changed because the Multi-Assignments feature is currently enabled.",
|
"The property '{}' must not be changed because the Multi-Assignments feature is currently enabled.",
|
||||||
key);
|
key);
|
||||||
throw new TenantConfigurationValueChangeNotAllowedException();
|
throw new TenantConfigurationValueChangeNotAllowedException();
|
||||||
@@ -250,13 +248,13 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana
|
|||||||
|
|
||||||
private void assertMultiAssignmentsValueChange(final String key, final JpaTenantConfiguration valueChange) {
|
private void assertMultiAssignmentsValueChange(final String key, final JpaTenantConfiguration valueChange) {
|
||||||
if (MULTI_ASSIGNMENTS_ENABLED.equals(key) && !Boolean.parseBoolean(valueChange.getValue())) {
|
if (MULTI_ASSIGNMENTS_ENABLED.equals(key) && !Boolean.parseBoolean(valueChange.getValue())) {
|
||||||
LOG.debug("The Multi-Assignments '{}' feature cannot be disabled.", key);
|
log.debug("The Multi-Assignments '{}' feature cannot be disabled.", key);
|
||||||
throw new TenantConfigurationValueChangeNotAllowedException();
|
throw new TenantConfigurationValueChangeNotAllowedException();
|
||||||
}
|
}
|
||||||
if (MULTI_ASSIGNMENTS_ENABLED.equals(key) && Boolean.parseBoolean(valueChange.getValue())) {
|
if (MULTI_ASSIGNMENTS_ENABLED.equals(key) && Boolean.parseBoolean(valueChange.getValue())) {
|
||||||
JpaTenantConfiguration batchConfig = tenantConfigurationRepository.findByKey(BATCH_ASSIGNMENTS_ENABLED);
|
JpaTenantConfiguration batchConfig = tenantConfigurationRepository.findByKey(BATCH_ASSIGNMENTS_ENABLED);
|
||||||
if (batchConfig!=null && Boolean.parseBoolean(batchConfig.getValue())) {
|
if (batchConfig!=null && Boolean.parseBoolean(batchConfig.getValue())) {
|
||||||
LOG.debug("The Multi-Assignments '{}' feature cannot be enabled as it contradicts with " +
|
log.debug("The Multi-Assignments '{}' feature cannot be enabled as it contradicts with " +
|
||||||
"The Batch-Assignments feature, which is already enabled .", key);
|
"The Batch-Assignments feature, which is already enabled .", key);
|
||||||
throw new TenantConfigurationValueChangeNotAllowedException();
|
throw new TenantConfigurationValueChangeNotAllowedException();
|
||||||
}
|
}
|
||||||
@@ -267,7 +265,7 @@ public class JpaTenantConfigurationManagement implements TenantConfigurationMana
|
|||||||
if (BATCH_ASSIGNMENTS_ENABLED.equals(key) && Boolean.parseBoolean(valueChange.getValue())) {
|
if (BATCH_ASSIGNMENTS_ENABLED.equals(key) && Boolean.parseBoolean(valueChange.getValue())) {
|
||||||
JpaTenantConfiguration multiConfig = tenantConfigurationRepository.findByKey(MULTI_ASSIGNMENTS_ENABLED);
|
JpaTenantConfiguration multiConfig = tenantConfigurationRepository.findByKey(MULTI_ASSIGNMENTS_ENABLED);
|
||||||
if (multiConfig != null && Boolean.parseBoolean(multiConfig.getValue())) {
|
if (multiConfig != null && Boolean.parseBoolean(multiConfig.getValue())) {
|
||||||
LOG.debug("The Batch-Assignments '{}' feature cannot be enabled as it contradicts with " +
|
log.debug("The Batch-Assignments '{}' feature cannot be enabled as it contradicts with " +
|
||||||
"The Multi-Assignments feature, which is already enabled .", key);
|
"The Multi-Assignments feature, which is already enabled .", key);
|
||||||
throw new TenantConfigurationValueChangeNotAllowedException();
|
throw new TenantConfigurationValueChangeNotAllowedException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.model;
|
package org.eclipse.hawkbit.repository.jpa.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -45,6 +46,7 @@ import jakarta.validation.constraints.NotNull;
|
|||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
|
||||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||||
@@ -70,12 +72,9 @@ import org.eclipse.persistence.annotations.ConversionValue;
|
|||||||
import org.eclipse.persistence.annotations.Convert;
|
import org.eclipse.persistence.annotations.Convert;
|
||||||
import org.eclipse.persistence.annotations.ObjectTypeConverter;
|
import org.eclipse.persistence.annotations.ObjectTypeConverter;
|
||||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JPA implementation of {@link Target}.
|
* JPA implementation of {@link Target}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "sp_target", indexes = {
|
@Table(name = "sp_target", indexes = {
|
||||||
@@ -88,12 +87,12 @@ import org.slf4j.LoggerFactory;
|
|||||||
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for
|
||||||
// sub entities
|
// sub entities
|
||||||
@SuppressWarnings("squid:S2160")
|
@SuppressWarnings("squid:S2160")
|
||||||
|
@Slf4j
|
||||||
public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAwareEntity {
|
public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAwareEntity {
|
||||||
|
|
||||||
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(JpaTarget.class);
|
|
||||||
|
|
||||||
private static final List<String> TARGET_UPDATE_EVENT_IGNORE_FIELDS = Arrays.asList("lastTargetQuery", "address",
|
private static final List<String> TARGET_UPDATE_EVENT_IGNORE_FIELDS = Arrays.asList("lastTargetQuery", "address",
|
||||||
"optLockRevision", "lastModifiedAt", "lastModifiedBy");
|
"optLockRevision", "lastModifiedAt", "lastModifiedBy");
|
||||||
|
|
||||||
@@ -347,7 +346,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
|
|||||||
try {
|
try {
|
||||||
return URI.create(address);
|
return URI.create(address);
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
LOG.warn("Invalid address provided. Cloud not be configured to URI", e);
|
log.warn("Invalid address provided. Cloud not be configured to URI", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.rollout;
|
package org.eclipse.hawkbit.repository.jpa.rollout;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.RolloutHandler;
|
import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,10 +20,9 @@ import org.springframework.scheduling.annotation.Scheduled;
|
|||||||
* delay between the checks be configured using the property from
|
* delay between the checks be configured using the property from
|
||||||
* {#PROP_SCHEDULER_DELAY_PLACEHOLDER}.
|
* {#PROP_SCHEDULER_DELAY_PLACEHOLDER}.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class RolloutScheduler {
|
public class RolloutScheduler {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RolloutScheduler.class);
|
|
||||||
|
|
||||||
private static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.rollout.scheduler.fixedDelay:2000}";
|
private static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.rollout.scheduler.fixedDelay:2000}";
|
||||||
|
|
||||||
private final SystemManagement systemManagement;
|
private final SystemManagement systemManagement;
|
||||||
@@ -58,7 +56,7 @@ public class RolloutScheduler {
|
|||||||
*/
|
*/
|
||||||
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
||||||
public void runningRolloutScheduler() {
|
public void runningRolloutScheduler() {
|
||||||
LOGGER.debug("rollout schedule checker has been triggered.");
|
log.debug("rollout schedule checker has been triggered.");
|
||||||
|
|
||||||
// run this code in system code privileged to have the necessary
|
// run this code in system code privileged to have the necessary
|
||||||
// permission to query and create entities.
|
// permission to query and create entities.
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ package org.eclipse.hawkbit.repository.jpa.rollout.condition;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager class to collect all instances of
|
* Manager class to collect all instances of
|
||||||
@@ -21,10 +20,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
* {@link RolloutGroupActionEvaluator} for specific conditions and actions. The
|
* {@link RolloutGroupActionEvaluator} for specific conditions and actions. The
|
||||||
* corresponding instance can be fetched by providing the action/condition.
|
* corresponding instance can be fetched by providing the action/condition.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class RolloutGroupEvaluationManager {
|
public class RolloutGroupEvaluationManager {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RolloutGroupEvaluationManager.class);
|
|
||||||
|
|
||||||
private final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition>> errorConditionEvaluators;
|
private final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition>> errorConditionEvaluators;
|
||||||
private final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition>> successConditionEvaluators;
|
private final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition>> successConditionEvaluators;
|
||||||
private final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction>> errorActionEvaluators;
|
private final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction>> errorActionEvaluators;
|
||||||
@@ -82,7 +80,7 @@ public class RolloutGroupEvaluationManager {
|
|||||||
private static <T extends Enum<T>> RolloutGroupActionEvaluator<T> findFirstActionEvaluator(
|
private static <T extends Enum<T>> RolloutGroupActionEvaluator<T> findFirstActionEvaluator(
|
||||||
final List<RolloutGroupActionEvaluator<T>> evaluators, final T action) {
|
final List<RolloutGroupActionEvaluator<T>> evaluators, final T action) {
|
||||||
return evaluators.stream().filter(evaluator -> evaluator.getAction() == action).findFirst().orElseThrow(() -> {
|
return evaluators.stream().filter(evaluator -> evaluator.getAction() == action).findFirst().orElseThrow(() -> {
|
||||||
LOGGER.warn("Could not find suitable evaluator for the '{}' action.", action.name());
|
log.warn("Could not find suitable evaluator for the '{}' action.", action.name());
|
||||||
throw new EvaluatorNotConfiguredException(action.name());
|
throw new EvaluatorNotConfiguredException(action.name());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -91,9 +89,8 @@ public class RolloutGroupEvaluationManager {
|
|||||||
final List<RolloutGroupConditionEvaluator<T>> evaluators, final T condition) {
|
final List<RolloutGroupConditionEvaluator<T>> evaluators, final T condition) {
|
||||||
return evaluators.stream().filter(evaluator -> evaluator.getCondition() == condition).findFirst()
|
return evaluators.stream().filter(evaluator -> evaluator.getCondition() == condition).findFirst()
|
||||||
.orElseThrow(() -> {
|
.orElseThrow(() -> {
|
||||||
LOGGER.warn("Could not find suitable evaluator for the '{}' condition.", condition.name());
|
log.warn("Could not find suitable evaluator for the '{}' condition.", condition.name());
|
||||||
throw new EvaluatorNotConfiguredException(condition.name());
|
throw new EvaluatorNotConfiguredException(condition.name());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,23 +9,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.rollout.condition;
|
package org.eclipse.hawkbit.repository.jpa.rollout.condition;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates if the {@link RolloutGroup#getErrorConditionExp()} is reached.
|
* Evaluates if the {@link RolloutGroup#getErrorConditionExp()} is reached.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class ThresholdRolloutGroupErrorCondition
|
public class ThresholdRolloutGroupErrorCondition
|
||||||
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition> {
|
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition> {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupErrorCondition.class);
|
|
||||||
|
|
||||||
private final ActionRepository actionRepository;
|
private final ActionRepository actionRepository;
|
||||||
|
|
||||||
public ThresholdRolloutGroupErrorCondition(final ActionRepository actionRepository) {
|
public ThresholdRolloutGroupErrorCondition(final ActionRepository actionRepository) {
|
||||||
@@ -54,7 +50,7 @@ public class ThresholdRolloutGroupErrorCondition
|
|||||||
// calculate threshold
|
// calculate threshold
|
||||||
return ((float) error / (float) totalGroup) > ((float) threshold / 100F);
|
return ((float) error / (float) totalGroup) > ((float) threshold / 100F);
|
||||||
} catch (final NumberFormatException e) {
|
} catch (final NumberFormatException e) {
|
||||||
LOGGER.error("Cannot evaluate condition expression " + expression, e);
|
log.error("Cannot evaluate condition expression " + expression, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,20 +9,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.rollout.condition;
|
package org.eclipse.hawkbit.repository.jpa.rollout.condition;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Threshold to calculate if the {@link RolloutGroup#getSuccessConditionExp()} is reached and the
|
* Threshold to calculate if the {@link RolloutGroup#getSuccessConditionExp()} is reached and the
|
||||||
* next rollout group can get started.
|
* next rollout group can get started.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class ThresholdRolloutGroupSuccessCondition
|
public class ThresholdRolloutGroupSuccessCondition
|
||||||
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition> {
|
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition> {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupSuccessCondition.class);
|
|
||||||
|
|
||||||
private final ActionRepository actionRepository;
|
private final ActionRepository actionRepository;
|
||||||
|
|
||||||
@@ -55,9 +54,8 @@ public class ThresholdRolloutGroupSuccessCondition
|
|||||||
return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F);
|
return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F);
|
||||||
|
|
||||||
} catch (final NumberFormatException e) {
|
} catch (final NumberFormatException e) {
|
||||||
LOGGER.error("Cannot evaluate condition expression " + expression, e);
|
log.error("Cannot evaluate condition expression " + expression, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,17 +15,15 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import cz.jirutka.rsql.parser.ast.ComparisonNode;
|
import cz.jirutka.rsql.parser.ast.ComparisonNode;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldNameProvider> {
|
public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldNameProvider> {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFieldNameRSQLVisitor.class);
|
|
||||||
|
|
||||||
private final Class<A> fieldNameProvider;
|
private final Class<A> fieldNameProvider;
|
||||||
|
|
||||||
protected AbstractFieldNameRSQLVisitor(final Class<A> fieldNameProvider) {
|
protected AbstractFieldNameRSQLVisitor(final Class<A> fieldNameProvider) {
|
||||||
@@ -38,7 +36,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
|
|||||||
if (graph.length != 0) {
|
if (graph.length != 0) {
|
||||||
enumName = graph[0];
|
enumName = graph[0];
|
||||||
}
|
}
|
||||||
LOGGER.debug("get field identifier by name {} of enum type {}", enumName, fieldNameProvider);
|
log.debug("get field identifier by name {} of enum type {}", enumName, fieldNameProvider);
|
||||||
try {
|
try {
|
||||||
return Enum.valueOf(fieldNameProvider, enumName.toUpperCase());
|
return Enum.valueOf(fieldNameProvider, enumName.toUpperCase());
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
|
|||||||
@@ -41,14 +41,13 @@ import cz.jirutka.rsql.parser.ast.LogicalNode;
|
|||||||
import cz.jirutka.rsql.parser.ast.Node;
|
import cz.jirutka.rsql.parser.ast.Node;
|
||||||
import cz.jirutka.rsql.parser.ast.OrNode;
|
import cz.jirutka.rsql.parser.ast.OrNode;
|
||||||
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||||
import org.eclipse.hawkbit.repository.FieldValueConverter;
|
import org.eclipse.hawkbit.repository.FieldValueConverter;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.SimpleTypeConverter;
|
import org.springframework.beans.SimpleTypeConverter;
|
||||||
import org.springframework.beans.TypeMismatchException;
|
import org.springframework.beans.TypeMismatchException;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
import org.springframework.orm.jpa.vendor.Database;
|
||||||
@@ -59,17 +58,13 @@ import org.springframework.util.StringUtils;
|
|||||||
* An implementation of the {@link RSQLVisitor} to visit the parsed tokens and
|
* An implementation of the {@link RSQLVisitor} to visit the parsed tokens and
|
||||||
* build JPA where clauses.
|
* build JPA where clauses.
|
||||||
*
|
*
|
||||||
* @param <A>
|
* @param <A> the enum for providing the field name of the entity field to filter on.
|
||||||
* the enum for providing the field name of the entity field to
|
* @param <T> the entity type referenced by the root
|
||||||
* filter on.
|
|
||||||
* @param <T>
|
|
||||||
* the entity type referenced by the root
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> extends AbstractFieldNameRSQLVisitor<A>
|
public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> extends AbstractFieldNameRSQLVisitor<A>
|
||||||
implements RSQLVisitor<List<Predicate>, String> {
|
implements RSQLVisitor<List<Predicate>, String> {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(JpaQueryRsqlVisitor.class);
|
|
||||||
|
|
||||||
public static final Character LIKE_WILDCARD = '*';
|
public static final Character LIKE_WILDCARD = '*';
|
||||||
private static final char ESCAPE_CHAR = '\\';
|
private static final char ESCAPE_CHAR = '\\';
|
||||||
private static final List<String> NO_JOINS_OPERATOR = List.of("!=", "=out=");
|
private static final List<String> NO_JOINS_OPERATOR = List.of("!=", "=out=");
|
||||||
@@ -296,9 +291,9 @@ public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> exten
|
|||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
// we could not transform the given string value into the enum
|
// we could not transform the given string value into the enum
|
||||||
// type, so ignore it and return null and do not filter
|
// type, so ignore it and return null and do not filter
|
||||||
LOGGER.info("given value {} cannot be transformed into the correct enum type {}", value.toUpperCase(),
|
log.info("given value {} cannot be transformed into the correct enum type {}", value.toUpperCase(),
|
||||||
javaType);
|
javaType);
|
||||||
LOGGER.debug("value cannot be transformed to an enum", e);
|
log.debug("value cannot be transformed to an enum", e);
|
||||||
|
|
||||||
throw new RSQLParameterUnsupportedFieldException("field {" + node.getSelector()
|
throw new RSQLParameterUnsupportedFieldException("field {" + node.getSelector()
|
||||||
+ "} must be one of the following values {" + Arrays.stream(tmpEnumType.getEnumConstants())
|
+ "} must be one of the following values {" + Arrays.stream(tmpEnumType.getEnumConstants())
|
||||||
@@ -596,7 +591,7 @@ public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> exten
|
|||||||
if (!CollectionUtils.isEmpty(accept)) {
|
if (!CollectionUtils.isEmpty(accept)) {
|
||||||
childs.addAll(accept);
|
childs.addAll(accept);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("visit logical node children but could not parse it, ignoring {}", node2);
|
log.debug("visit logical node children but could not parse it, ignoring {}", node2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return childs;
|
return childs;
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ import jakarta.persistence.criteria.CriteriaQuery;
|
|||||||
import jakarta.persistence.criteria.Predicate;
|
import jakarta.persistence.criteria.Predicate;
|
||||||
import jakarta.persistence.criteria.Root;
|
import jakarta.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.text.StrLookup;
|
import org.apache.commons.lang3.text.StrLookup;
|
||||||
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
@@ -24,8 +27,6 @@ import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldExc
|
|||||||
import org.eclipse.hawkbit.repository.rsql.RsqlVisitorFactoryHolder;
|
import org.eclipse.hawkbit.repository.rsql.RsqlVisitorFactoryHolder;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
import org.springframework.orm.jpa.vendor.Database;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@@ -69,19 +70,11 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
|||||||
* <em>lastControllerRequestAt=le=${OVERDUE_TS}</em><br>
|
* <em>lastControllerRequestAt=le=${OVERDUE_TS}</em><br>
|
||||||
* It is possible to escape a macro expression by using a second '$':
|
* It is possible to escape a macro expression by using a second '$':
|
||||||
* $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded.
|
* $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public final class RSQLUtility {
|
public final class RSQLUtility {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RSQLUtility.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* private constructor due utility class.
|
|
||||||
*/
|
|
||||||
private RSQLUtility() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a JPA {@link Specification} which corresponds with the given RSQL
|
* Builds a JPA {@link Specification} which corresponds with the given RSQL
|
||||||
* query. The specification can be used to filter for JPA entities with the
|
* query. The specification can be used to filter for JPA entities with the
|
||||||
@@ -138,7 +131,7 @@ public final class RSQLUtility {
|
|||||||
|
|
||||||
private static Node parseRsql(final String rsql) {
|
private static Node parseRsql(final String rsql) {
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Parsing rsql string {}", rsql);
|
log.debug("Parsing rsql string {}", rsql);
|
||||||
final Set<ComparisonOperator> operators = RSQLOperators.defaultOperators();
|
final Set<ComparisonOperator> operators = RSQLOperators.defaultOperators();
|
||||||
return new RSQLParser(operators).parse(rsql.toLowerCase());
|
return new RSQLParser(operators).parse(rsql.toLowerCase());
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.TargetFields;
|
import org.eclipse.hawkbit.repository.TargetFields;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||||
@@ -32,8 +33,6 @@ import org.eclipse.hawkbit.repository.rsql.SuggestionContext;
|
|||||||
import org.eclipse.hawkbit.repository.rsql.SyntaxErrorContext;
|
import org.eclipse.hawkbit.repository.rsql.SyntaxErrorContext;
|
||||||
import org.eclipse.hawkbit.repository.rsql.ValidationOracleContext;
|
import org.eclipse.hawkbit.repository.rsql.ValidationOracleContext;
|
||||||
import org.eclipse.persistence.exceptions.ConversionException;
|
import org.eclipse.persistence.exceptions.ConversionException;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -51,12 +50,10 @@ import cz.jirutka.rsql.parser.RSQLParserException;
|
|||||||
* There is a feature request on the GitHub project
|
* There is a feature request on the GitHub project
|
||||||
* <a href="https://github.com/jirutka/rsql-parser/issues/22">https://github.com
|
* <a href="https://github.com/jirutka/rsql-parser/issues/22">https://github.com
|
||||||
* /jirutka/rsql-parser/issues/22</a>
|
* /jirutka/rsql-parser/issues/22</a>
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RsqlParserValidationOracle.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValidationOracleContext suggest(final String rsqlQuery, final int cursorPosition) {
|
public ValidationOracleContext suggest(final String rsqlQuery, final int cursorPosition) {
|
||||||
|
|
||||||
@@ -76,10 +73,10 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
|||||||
setExceptionDetails(rsqlQuery, new Exception(ex.getCause().getCause()), expectedTokens);
|
setExceptionDetails(rsqlQuery, new Exception(ex.getCause().getCause()), expectedTokens);
|
||||||
errorContext.setErrorMessage(getCustomMessage(ex.getCause().getMessage(), expectedTokens));
|
errorContext.setErrorMessage(getCustomMessage(ex.getCause().getMessage(), expectedTokens));
|
||||||
suggestionContext.setSuggestions(expectedTokens);
|
suggestionContext.setSuggestions(expectedTokens);
|
||||||
LOGGER.trace("Syntax exception on parsing :", ex);
|
log.trace("Syntax exception on parsing :", ex);
|
||||||
} catch (final RSQLParameterUnsupportedFieldException | IllegalArgumentException ex) {
|
} catch (final RSQLParameterUnsupportedFieldException | IllegalArgumentException ex) {
|
||||||
errorContext.setErrorMessage(getCustomMessage(ex.getMessage(), null));
|
errorContext.setErrorMessage(getCustomMessage(ex.getMessage(), null));
|
||||||
LOGGER.trace("Illegal argument on parsing :", ex);
|
log.trace("Illegal argument on parsing :", ex);
|
||||||
} catch (@SuppressWarnings("squid:S1166") final ConversionException | JpaSystemException e) {
|
} catch (@SuppressWarnings("squid:S1166") final ConversionException | JpaSystemException e) {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
||||||
@@ -25,8 +28,6 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
@@ -38,16 +39,11 @@ import org.springframework.util.StringUtils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for deployment related topics.
|
* Utility class for deployment related topics.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public final class DeploymentHelper {
|
public final class DeploymentHelper {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DeploymentHelper.class);
|
|
||||||
|
|
||||||
private DeploymentHelper() {
|
|
||||||
// utility class
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called, when cancellation has been successful. It sets the
|
* This method is called, when cancellation has been successful. It sets the
|
||||||
* action to canceled, resets the meta data of the target and in case there
|
* action to canceled, resets the meta data of the target and in case there
|
||||||
@@ -147,7 +143,7 @@ public final class DeploymentHelper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String user = username.get();
|
final String user = username.get();
|
||||||
LOG.debug("Switching user context from '{}' to '{}'", currentUser, user);
|
log.debug("Switching user context from '{}' to '{}'", currentUser, user);
|
||||||
tenantAware.runAsTenantAsUser(tenantAware.getCurrentTenant(), user, () -> {
|
tenantAware.runAsTenantAsUser(tenantAware.getCurrentTenant(), user, () -> {
|
||||||
handler.run();
|
handler.run();
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -13,20 +13,15 @@ import java.util.function.ToLongFunction;
|
|||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to check quotas.
|
* Helper class to check quotas.
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public final class QuotaHelper {
|
public final class QuotaHelper {
|
||||||
|
|
||||||
/**
|
|
||||||
* Class logger
|
|
||||||
*/
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(QuotaHelper.class);
|
|
||||||
|
|
||||||
private static final String MAX_ASSIGNMENT_QUOTA_EXCEEDED = "Quota exceeded: Cannot assign %s entities at once. The maximum is %s.";
|
private static final String MAX_ASSIGNMENT_QUOTA_EXCEEDED = "Quota exceeded: Cannot assign %s entities at once. The maximum is %s.";
|
||||||
|
|
||||||
private QuotaHelper() {
|
private QuotaHelper() {
|
||||||
@@ -112,13 +107,13 @@ public final class QuotaHelper {
|
|||||||
|
|
||||||
// check if the quota is unlimited
|
// check if the quota is unlimited
|
||||||
if (limit <= 0) {
|
if (limit <= 0) {
|
||||||
LOG.debug("Quota 'Max {} entities per {}' is unlimited.", type, parentType);
|
log.debug("Quota 'Max {} entities per {}' is unlimited.", type, parentType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requested > limit) {
|
if (requested > limit) {
|
||||||
final String parentIdStr = parentId != null ? String.valueOf(parentId) : "<new>";
|
final String parentIdStr = parentId != null ? String.valueOf(parentId) : "<new>";
|
||||||
LOG.warn("Cannot assign {} {} entities to {} '{}' because of the configured quota limit {}.", requested,
|
log.warn("Cannot assign {} {} entities to {} '{}' because of the configured quota limit {}.", requested,
|
||||||
type, parentType, parentIdStr, limit);
|
type, parentType, parentIdStr, limit);
|
||||||
throw new AssignmentQuotaExceededException(type, parentType, parentId, requested, limit);
|
throw new AssignmentQuotaExceededException(type, parentType, parentId, requested, limit);
|
||||||
}
|
}
|
||||||
@@ -126,7 +121,7 @@ public final class QuotaHelper {
|
|||||||
if (parentId != null && countFct != null) {
|
if (parentId != null && countFct != null) {
|
||||||
final long currentCount = countFct.applyAsLong(parentId);
|
final long currentCount = countFct.applyAsLong(parentId);
|
||||||
if (currentCount + requested > limit) {
|
if (currentCount + requested > limit) {
|
||||||
LOG.warn(
|
log.warn(
|
||||||
"Cannot assign {} {} entities to {} '{}' because of the configured quota limit {}. Currently, there are {} {} entities assigned.",
|
"Cannot assign {} {} entities to {} '{}' because of the configured quota limit {}. Currently, there are {} {} entities assigned.",
|
||||||
requested, type, parentType, parentId, limit, currentCount, type);
|
requested, type, parentType, parentId, limit, currentCount, type);
|
||||||
throw new AssignmentQuotaExceededException(type, parentType, parentId, requested, limit);
|
throw new AssignmentQuotaExceededException(type, parentType, parentId, requested, limit);
|
||||||
@@ -146,7 +141,7 @@ public final class QuotaHelper {
|
|||||||
public static void assertAssignmentRequestSizeQuota(final long requested, final long limit) {
|
public static void assertAssignmentRequestSizeQuota(final long requested, final long limit) {
|
||||||
if (requested > limit) {
|
if (requested > limit) {
|
||||||
final String message = String.format(MAX_ASSIGNMENT_QUOTA_EXCEEDED, requested, limit);
|
final String message = String.format(MAX_ASSIGNMENT_QUOTA_EXCEEDED, requested, limit);
|
||||||
LOG.warn(message);
|
log.warn(message);
|
||||||
throw new AssignmentQuotaExceededException(message);
|
throw new AssignmentQuotaExceededException(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user