Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added triggeredBy for rollouts and autoassignment #1017

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ public interface TenantAware {
*/
String getCurrentTenant();

/**
* @return the username of the currently logged-in user
*/
String getCurrentUsername();

/**
* Gives the possibility to run a certain code under a specific given
* {@code tenant}. Only the given {@link TenantRunner} is executed under the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,14 @@ public interface DeploymentManagement {
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> assignDistributionSets(
@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
List<DistributionSetAssignmentResult> assignDistributionSets(@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);

/**
* Assigns {@link DistributionSet}s to {@link Target}s according to the
* {@link DeploymentRequest}.
*
* @param initiatedBy
* the username of the user who initiated the assignment
* @param deploymentRequests
* information about all target-ds-assignments that shall be made
* @param actionMessage
Expand All @@ -107,7 +108,7 @@ List<DistributionSetAssignmentResult> assignDistributionSets(
*
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> assignDistributionSets(
List<DistributionSetAssignmentResult> assignDistributionSets(String initiatedBy,
@Valid @NotEmpty List<DeploymentRequest> deploymentRequests, String actionMessage);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ default boolean isCancelingOrCanceled() {
*/
String getExternalRef();

/**
* @return the username that initiated this action (directly or indirectly)
*/
String getInitiatedBy();

/**
* checks if the {@link #getForcedTime()} is hit by the given
* {@code hitTimeMillis}, by means if the given milliseconds are greater
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,8 @@ public interface TargetFilterQuery extends TenantAwareBaseEntity {
*/
Optional<Integer> getAutoAssignWeight();

/**
* @return the user that triggered the auto assignment
*/
String getAutoAssignInitiatedBy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ void cancelAssignDistributionSetEvent(final Target target, final Long actionId)
new CancelTargetAssignmentEvent(target, actionId, eventPublisherHolder.getApplicationId())));
}

JpaAction createTargetAction(final TargetWithActionType targetWithActionType, final List<JpaTarget> targets,
final JpaDistributionSet set) {
JpaAction createTargetAction(final String initiatedBy, final TargetWithActionType targetWithActionType,
final List<JpaTarget> targets, final JpaDistributionSet set) {
final Optional<JpaTarget> optTarget = targets.stream()
.filter(t -> t.getControllerId().equals(targetWithActionType.getControllerId())).findFirst();

Expand All @@ -219,6 +219,7 @@ JpaAction createTargetAction(final TargetWithActionType targetWithActionType, fi
actionForTarget.setMaintenanceWindowSchedule(targetWithActionType.getMaintenanceSchedule());
actionForTarget.setMaintenanceWindowDuration(targetWithActionType.getMaintenanceWindowDuration());
actionForTarget.setMaintenanceWindowTimeZone(targetWithActionType.getMaintenanceWindowTimeZone());
actionForTarget.setInitiatedBy(initiatedBy);
return actionForTarget;
}).orElseGet(() -> {
LOG.warn("Cannot find target for targetWithActionType '{}'.", targetWithActionType.getControllerId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,33 +182,34 @@ public List<DistributionSetAssignmentResult> offlineAssignedDistributionSets(
.map(entry -> DeploymentManagement.deploymentRequest(entry.getKey(), entry.getValue()).build())
.collect(Collectors.toList());

return assignDistributionSets(deploymentRequests, null, offlineDsAssignmentStrategy);
return assignDistributionSets(tenantAware.getCurrentUsername(), deploymentRequests, null,
offlineDsAssignmentStrategy);
}

@Override
@Transactional(isolation = Isolation.READ_COMMITTED)
public List<DistributionSetAssignmentResult> assignDistributionSets(
final List<DeploymentRequest> deploymentRequests) {
return assignDistributionSets(deploymentRequests, null);
return assignDistributionSets(tenantAware.getCurrentUsername(), deploymentRequests, null);
}

@Override
@Transactional(isolation = Isolation.READ_COMMITTED)
public List<DistributionSetAssignmentResult> assignDistributionSets(
public List<DistributionSetAssignmentResult> assignDistributionSets(final String initiatedBy,
final List<DeploymentRequest> deploymentRequests, final String actionMessage) {
WeightValidationHelper.usingContext(systemSecurityContext, tenantConfigurationManagement)
.validate(deploymentRequests);
return assignDistributionSets(deploymentRequests, actionMessage, onlineDsAssignmentStrategy);
return assignDistributionSets(initiatedBy, deploymentRequests, actionMessage, onlineDsAssignmentStrategy);
}

private List<DistributionSetAssignmentResult> assignDistributionSets(
private List<DistributionSetAssignmentResult> assignDistributionSets(final String initiatedBy,
final List<DeploymentRequest> deploymentRequests, final String actionMessage,
final AbstractDsAssignmentStrategy strategy) {
final List<DeploymentRequest> validatedRequests = validateRequestForAssignments(deploymentRequests);
final Map<Long, List<TargetWithActionType>> assignmentsByDsIds = convertRequest(validatedRequests);

final List<DistributionSetAssignmentResult> results = assignmentsByDsIds.entrySet().stream()
.map(entry -> assignDistributionSetToTargetsWithRetry(entry.getKey(), entry.getValue(), actionMessage,
.map(entry -> assignDistributionSetToTargetsWithRetry(initiatedBy, entry.getKey(), entry.getValue(), actionMessage,
strategy))
.collect(Collectors.toList());
strategy.sendDeploymentEvents(results);
Expand Down Expand Up @@ -238,11 +239,11 @@ private static void checkIfRequiresMultiAssignment(final Collection<DeploymentRe
}
}

private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(final Long dsID,
private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(final String initiatedBy, final Long dsID,
final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) {
final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback = retryContext -> assignDistributionSetToTargets(
dsID, targetsWithActionType, actionMessage, assignmentStrategy);
initiatedBy, dsID, targetsWithActionType, actionMessage, assignmentStrategy);
return retryTemplate.execute(retryCallback);
}

Expand All @@ -260,6 +261,8 @@ private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(
* status to {@link TargetUpdateStatus#IN_SYNC} <br/>
* D. does not send a {@link TargetAssignDistributionSetEvent}.<br/>
*
* @param initiatedBy
* the username of the user who initiated the assignment
* @param dsID
* the ID of the distribution set to assign
* @param targetsWithActionType
Expand All @@ -274,7 +277,7 @@ private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(
* {@link SoftwareModuleType} are not assigned as define by the
* {@link DistributionSetType}.
*/
private DistributionSetAssignmentResult assignDistributionSetToTargets(final Long dsID,
private DistributionSetAssignmentResult assignDistributionSetToTargets(final String initiatedBy, final Long dsID,
final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) {

Expand All @@ -296,8 +299,9 @@ private DistributionSetAssignmentResult assignDistributionSetToTargets(final Lon
final List<TargetWithActionType> existingTargetsWithActionType = targetsWithActionType.stream()
.filter(target -> existingTargetIds.contains(target.getControllerId())).collect(Collectors.toList());

final List<JpaAction> assignedActions = doAssignDistributionSetToTargets(existingTargetsWithActionType,
actionMessage, assignmentStrategy, distributionSetEntity, targetEntities);
final List<JpaAction> assignedActions = doAssignDistributionSetToTargets(initiatedBy,
existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSetEntity,
targetEntities);
return buildAssignmentResult(distributionSetEntity, assignedActions, existingTargetsWithActionType.size());
}

Expand All @@ -310,7 +314,7 @@ private DistributionSetAssignmentResult allTargetsAlreadyAssignedResult(
Collections.emptyList());
}

private List<JpaAction> doAssignDistributionSetToTargets(
private List<JpaAction> doAssignDistributionSetToTargets(final String initiatedBy,
final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy, final JpaDistributionSet distributionSetEntity,
final List<JpaTarget> targetEntities) {
Expand All @@ -325,8 +329,8 @@ private List<JpaAction> doAssignDistributionSetToTargets(
targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets);
setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity,
targetEntitiesIdsChunks);
final List<JpaAction> assignedActions = createActions(targetsWithActionType, targetEntities, assignmentStrategy,
distributionSetEntity);
final List<JpaAction> assignedActions = createActions(initiatedBy, targetsWithActionType, targetEntities,
assignmentStrategy, distributionSetEntity);
// create initial action status when action is created so we remember
// the initial running status because we will change the status
// of the action itself and with this action status we have a nicer
Expand Down Expand Up @@ -417,12 +421,15 @@ private void setAssignedDistributionSetAndTargetUpdateStatus(final AbstractDsAss
assignmentStrategy.setAssignedDistributionSetAndTargetStatus(set, targetIdsChunks, currentUser);
}

private List<JpaAction> createActions(final Collection<TargetWithActionType> targetsWithActionType,
final List<JpaTarget> targets, final AbstractDsAssignmentStrategy assignmentStrategy,
final JpaDistributionSet set) {
private List<JpaAction> createActions(final String initiatedBy,
final Collection<TargetWithActionType> targetsWithActionType, final List<JpaTarget> targets,
final AbstractDsAssignmentStrategy assignmentStrategy, final JpaDistributionSet set) {

return targetsWithActionType.stream().map(twt -> assignmentStrategy.createTargetAction(twt, targets, set))
.filter(Objects::nonNull).map(actionRepository::save).collect(Collectors.toList());
return targetsWithActionType.stream()
.map(twt -> assignmentStrategy.createTargetAction(initiatedBy, twt, targets, set))
.filter(Objects::nonNull)
.map(actionRepository::save)
.collect(Collectors.toList());
}

private void createActionsStatus(final Collection<JpaAction> actions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ private void createScheduledAction(final Collection<Target> targets, final Distr
action.setStatus(Status.SCHEDULED);
action.setRollout(rollout);
action.setRolloutGroup(rolloutGroup);
action.setInitiatedBy(rollout.getCreatedBy());
rollout.getWeight().ifPresent(action::setWeight);
actionRepository.save(action);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.jpa.utils.WeightValidationHelper;
import org.eclipse.hawkbit.repository.jpa.utils.TenantConfigHelper;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
Expand Down Expand Up @@ -240,6 +240,7 @@ public TargetFilterQuery updateAutoAssignDS(final AutoAssignDistributionSetUpdat
targetFilterQuery.setAutoAssignDistributionSet(null);
targetFilterQuery.setAutoAssignActionType(null);
targetFilterQuery.setAutoAssignWeight(null);
targetFilterQuery.setAutoAssignInitiatedBy(null);
} else {
WeightValidationHelper.usingContext(systemSecurityContext, tenantConfigurationManagement).validate(update);
// we cannot be sure that the quota was enforced at creation time
Expand All @@ -248,8 +249,10 @@ public TargetFilterQuery updateAutoAssignDS(final AutoAssignDistributionSetUpdat
// auto-assign distribution set when creating a target filter query
assertMaxTargetsQuota(targetFilterQuery.getQuery());
final JpaDistributionSet ds = findDistributionSetAndThrowExceptionIfNotFound(update.getDsId());
final String initiatedBy = TenantAwareHolder.getInstance().getTenantAware().getCurrentUsername();
a-sayyed marked this conversation as resolved.
Show resolved Hide resolved
verifyDistributionSetAndThrowExceptionIfNotValid(ds);
targetFilterQuery.setAutoAssignDistributionSet(ds);
targetFilterQuery.setAutoAssignInitiatedBy(initiatedBy);
targetFilterQuery.setAutoAssignActionType(sanitizeAutoAssignActionType(update.getActionType()));
targetFilterQuery.setAutoAssignWeight(update.getWeight());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ void setAssignedDistributionSetAndTargetStatus(final JpaDistributionSet set, fin
}

@Override
protected JpaAction createTargetAction(final TargetWithActionType targetWithActionType,
protected JpaAction createTargetAction(final String initiatedBy, final TargetWithActionType targetWithActionType,
final List<JpaTarget> targets, final JpaDistributionSet set) {
final JpaAction result = super.createTargetAction(targetWithActionType, targets, set);
final JpaAction result = super.createTargetAction(initiatedBy, targetWithActionType, targets, set);
if (result != null) {
result.setStatus(Status.FINISHED);
result.setActive(Boolean.FALSE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,9 @@ void setAssignedDistributionSetAndTargetStatus(final JpaDistributionSet set, fin
}

@Override
JpaAction createTargetAction(final TargetWithActionType targetWithActionType, final List<JpaTarget> targets,
final JpaDistributionSet set) {
final JpaAction result = super.createTargetAction(targetWithActionType, targets, set);
JpaAction createTargetAction(final String initiatedBy, final TargetWithActionType targetWithActionType,
final List<JpaTarget> targets, final JpaDistributionSet set) {
final JpaAction result = super.createTargetAction(initiatedBy, targetWithActionType, targets, set);
if (result != null) {
result.setStatus(Status.RUNNING);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
* Checks if targets need a new distribution set (DS) based on the target filter
Expand Down Expand Up @@ -146,7 +147,10 @@ private int runTransactionalAssignment(final TargetFilterQuery targetFilterQuery
targetFilterQuery.getAutoAssignWeight().orElse(null), PAGE_SIZE);
final int count = deploymentRequests.size();
if (count > 0) {
deploymentManagement.assignDistributionSets(deploymentRequests, actionMessage);
final String initiatedBy = StringUtils.isEmpty(targetFilterQuery.getAutoAssignInitiatedBy()) ?
a-sayyed marked this conversation as resolved.
Show resolved Hide resolved
targetFilterQuery.getCreatedBy() :
targetFilterQuery.getAutoAssignInitiatedBy();
deploymentManagement.assignDistributionSets(initiatedBy, deploymentRequests, actionMessage);
}
return count;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
@Column(name = "external_ref", length = Action.EXTERNAL_REF_MAX_LENGTH)
private String externalRef;

@Column(name = "initiated_by", updatable = false, nullable = false, length = 64)
a-sayyed marked this conversation as resolved.
Show resolved Hide resolved
private String initiatedBy;

@Override
public DistributionSet getDistributionSet() {
return distributionSet;
Expand Down Expand Up @@ -363,4 +366,13 @@ public void setExternalRef(final String externalRef) {
public String getExternalRef() {
return externalRef;
}

public void setInitiatedBy(final String initiatedBy) {
this.initiatedBy = initiatedBy;
}

@Override
public String getInitiatedBy() {
return initiatedBy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity
@Column(name = "auto_assign_weight", nullable = true)
private Integer autoAssignWeight;

@Column(name = "auto_assign_initiated_by", nullable = true, length = 64)
a-sayyed marked this conversation as resolved.
Show resolved Hide resolved
private String autoAssignInitiatedBy;

public JpaTargetFilterQuery() {
// Default constructor for JPA.
}
Expand Down Expand Up @@ -149,6 +152,14 @@ public void setAutoAssignWeight(final Integer weight) {
this.autoAssignWeight = weight;
}

public String getAutoAssignInitiatedBy() {
return autoAssignInitiatedBy;
}

public void setAutoAssignInitiatedBy(final String autoAssignInitiatedBy) {
this.autoAssignInitiatedBy = autoAssignInitiatedBy;
}

@Override
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE sp_action ADD COLUMN initiated_by VARCHAR(64) NOT NULL;
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_initiated_by VARCHAR(64);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE sp_action ADD COLUMN initiated_by VARCHAR(64) NOT NULL;
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_initiated_by VARCHAR(64);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE sp_action ADD COLUMN initiated_by VARCHAR(64) NOT NULL;
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_initiated_by VARCHAR(64);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER TABLE sp_action
ADD COLUMN initiated_by VARCHAR (64) NOT NULL;

ALTER TABLE sp_target_filter_query
ADD COLUMN auto_assign_initiated_by VARCHAR (64);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE sp_action ADD initiated_by VARCHAR(64) NOT NULL;
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_initiated_by VARCHAR(64);
a-sayyed marked this conversation as resolved.
Show resolved Hide resolved
Loading