added triggeredBy for rollouts and autoassignment (#1017)
* added triggeredBy for rollouts and autoassignment Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * use createdBy as fallback for triggeredBy in AutoAssignChecker Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * removed 'NOT NULL' from db migration scripts for JpaTargetFilterQuery Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * fixed tests Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * fixed review findings Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * inlined redundant method in JpaDeploymentManagement Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * added tests + renamed property to 'initiatedBy' Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com> * fixed review findings Signed-off-by: Ahmed Sayed <ahmed.sayed@bosch-si.com>
This commit is contained in:
@@ -201,8 +201,8 @@ public abstract class AbstractDsAssignmentStrategy {
|
||||
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();
|
||||
|
||||
@@ -219,6 +219,7 @@ public abstract class AbstractDsAssignmentStrategy {
|
||||
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());
|
||||
|
||||
@@ -182,33 +182,34 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
.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);
|
||||
@@ -238,11 +239,11 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -260,6 +261,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
* 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
|
||||
@@ -274,7 +277,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
* {@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) {
|
||||
|
||||
@@ -296,8 +299,9 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -310,7 +314,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
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) {
|
||||
@@ -325,8 +329,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
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
|
||||
@@ -417,12 +421,15 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
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,
|
||||
|
||||
@@ -624,6 +624,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
|
||||
action.setStatus(Status.SCHEDULED);
|
||||
action.setRollout(rollout);
|
||||
action.setRolloutGroup(rolloutGroup);
|
||||
action.setInitiatedBy(rollout.getCreatedBy());
|
||||
rollout.getWeight().ifPresent(action::setWeight);
|
||||
actionRepository.save(action);
|
||||
});
|
||||
|
||||
@@ -35,13 +35,13 @@ 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;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
@@ -74,6 +74,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
private final QuotaManagement quotaManagement;
|
||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
private final TenantAware tenantAware;
|
||||
|
||||
private final Database database;
|
||||
|
||||
@@ -81,7 +82,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
final TargetRepository targetRepository, final VirtualPropertyReplacer virtualPropertyReplacer,
|
||||
final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement,
|
||||
final Database database, final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
final SystemSecurityContext systemSecurityContext) {
|
||||
final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware) {
|
||||
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
||||
this.targetRepository = targetRepository;
|
||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
||||
@@ -90,6 +91,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
this.database = database;
|
||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.tenantAware = tenantAware;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -240,6 +242,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
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
|
||||
@@ -250,6 +253,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
final JpaDistributionSet ds = findDistributionSetAndThrowExceptionIfNotFound(update.getDsId());
|
||||
verifyDistributionSetAndThrowExceptionIfNotValid(ds);
|
||||
targetFilterQuery.setAutoAssignDistributionSet(ds);
|
||||
targetFilterQuery.setAutoAssignInitiatedBy(tenantAware.getCurrentUsername());
|
||||
targetFilterQuery.setAutoAssignActionType(sanitizeAutoAssignActionType(update.getActionType()));
|
||||
targetFilterQuery.setAutoAssignWeight(update.getWeight());
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@ public class OfflineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
@@ -127,9 +127,9 @@ public class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -533,6 +533,8 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
* to access quotas
|
||||
* @param properties
|
||||
* JPA properties
|
||||
* @param tenantAware
|
||||
* the {@link TenantAware} bean holding the tenant information
|
||||
*
|
||||
* @return a new {@link TargetFilterQueryManagement}
|
||||
*/
|
||||
@@ -543,10 +545,10 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
||||
final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement,
|
||||
final JpaProperties properties, final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
final SystemSecurityContext systemSecurityContext) {
|
||||
final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware) {
|
||||
return new JpaTargetFilterQueryManagement(targetFilterQueryRepository, targetRepository,
|
||||
virtualPropertyReplacer, distributionSetManagement, quotaManagement, properties.getDatabase(),
|
||||
tenantConfigurationManagement, systemSecurityContext);
|
||||
tenantConfigurationManagement, systemSecurityContext, tenantAware);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||
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
|
||||
@@ -146,12 +147,19 @@ public class AutoAssignChecker implements AutoAssignExecutor {
|
||||
targetFilterQuery.getAutoAssignWeight().orElse(null), PAGE_SIZE);
|
||||
final int count = deploymentRequests.size();
|
||||
if (count > 0) {
|
||||
deploymentManagement.assignDistributionSets(deploymentRequests, actionMessage);
|
||||
deploymentManagement.assignDistributionSets(getAutoAssignmentInitiatedBy(targetFilterQuery),
|
||||
deploymentRequests, actionMessage);
|
||||
}
|
||||
return count;
|
||||
});
|
||||
}
|
||||
|
||||
private static String getAutoAssignmentInitiatedBy(final TargetFilterQuery targetFilterQuery) {
|
||||
return StringUtils.isEmpty(targetFilterQuery.getAutoAssignInitiatedBy()) ?
|
||||
targetFilterQuery.getCreatedBy() :
|
||||
targetFilterQuery.getAutoAssignInitiatedBy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all matching targets with the designated action from the target
|
||||
* management
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@EntityListeners({ AuditingEntityListener.class, EntityPropertyChangeListener.class, EntityInterceptorListener.class })
|
||||
public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected static final int USERNAME_FIELD_LENGTH = 64;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@@ -67,7 +68,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Column(name = "created_by", insertable = true, updatable = false, nullable = false, length = 64)
|
||||
@Column(name = "created_by", insertable = true, updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
@@ -81,7 +82,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
||||
|
||||
@Override
|
||||
@Access(AccessType.PROPERTY)
|
||||
@Column(name = "last_modified_by", insertable = true, updatable = true, nullable = false, length = 64)
|
||||
@Column(name = "last_modified_by", insertable = true, updatable = true, nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||
public String getLastModifiedBy() {
|
||||
return lastModifiedBy;
|
||||
}
|
||||
|
||||
@@ -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 = USERNAME_FIELD_LENGTH)
|
||||
private String initiatedBy;
|
||||
|
||||
@Override
|
||||
public DistributionSet getDistributionSet() {
|
||||
return distributionSet;
|
||||
@@ -363,4 +366,13 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
||||
public String getExternalRef() {
|
||||
return externalRef;
|
||||
}
|
||||
|
||||
public void setInitiatedBy(final String initiatedBy) {
|
||||
this.initiatedBy = initiatedBy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInitiatedBy() {
|
||||
return initiatedBy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = USERNAME_FIELD_LENGTH)
|
||||
private String autoAssignInitiatedBy;
|
||||
|
||||
public JpaTargetFilterQuery() {
|
||||
// Default constructor for JPA.
|
||||
}
|
||||
@@ -149,6 +152,14 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity
|
||||
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(
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE sp_action ADD initiated_by VARCHAR(64) NOT NULL;
|
||||
ALTER TABLE sp_target_filter_query ADD auto_assign_initiated_by VARCHAR(64);
|
||||
Reference in New Issue
Block a user