use of com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException in project acs-aem-commons by Adobe-Consulting-Services.
the class WorkflowInstanceRemoverScheduler method run.
@Override
@SuppressWarnings("squid:S2142")
public final void run() {
ResourceResolver adminResourceResolver = null;
try {
adminResourceResolver = resourceResolverFactory.getServiceResourceResolver(AUTH_INFO);
final long start = System.currentTimeMillis();
int count = workflowInstanceRemover.removeWorkflowInstances(adminResourceResolver, models, statuses, payloads, olderThan, batchSize, maxDuration);
if (log.isInfoEnabled()) {
log.info("Removed [ {} ] Workflow instances in {} ms", count, System.currentTimeMillis() - start);
}
} catch (LoginException e) {
log.error("Login Exception when getting admin resource resolver", e);
} catch (PersistenceException e) {
log.error("Persistence Exception when saving Workflow Instances removal", e);
} catch (WorkflowRemovalException e) {
log.error("Workflow Removal exception during Workflow Removal", e);
} catch (InterruptedException e) {
log.error("Interrupted Exception during Workflow Removal", e);
} catch (WorkflowRemovalForceQuitException e) {
log.info("Workflow Removal force quit", e);
} finally {
if (adminResourceResolver != null) {
adminResourceResolver.close();
}
}
}
use of com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException in project acs-aem-commons by Adobe-Consulting-Services.
the class WorkflowInstanceRemoverImpl method start.
private void start(final ResourceResolver resourceResolver) throws PersistenceException, WorkflowRemovalException, InterruptedException {
// Ensure forceQuit does not have a left-over value when starting a new run
this.forceQuit.set(false);
boolean running = false;
WorkflowRemovalStatus localStatus = this.getStatus();
if (localStatus != null) {
running = localStatus.isRunning();
}
if (running) {
log.warn("Unable to start workflow instance removal; Workflow removal already running.");
throw new WorkflowRemovalException("Workflow removal already started by " + this.getStatus().getInitiatedBy());
} else {
this.status.set(new WorkflowRemovalStatus(resourceResolver));
log.info("Starting workflow instance removal");
}
}
use of com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException in project acs-aem-commons by Adobe-Consulting-Services.
the class WorkflowInstanceRemoverImpl method removeWorkflowInstances.
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "squid:S3776", "squid:S1141" })
public int removeWorkflowInstances(final ResourceResolver resourceResolver, final Collection<String> modelIds, final Collection<String> statuses, final Collection<Pattern> payloads, final Calendar olderThan, final int batchSize, final int maxDurationInMins) throws PersistenceException, WorkflowRemovalException, InterruptedException, WorkflowRemovalForceQuitException {
final long start = System.currentTimeMillis();
long end = -1;
int count = 0;
int checkedCount = 0;
int workflowRemovedCount = 0;
if (maxDurationInMins > 0) {
// Max duration has been requested (greater than 0)
// Convert minutes to milliseconds
long maxDurationInMs = maxDurationInMins * MS_IN_ONE_MINUTE;
// Compute the end time
end = start + maxDurationInMs;
}
try {
this.start(resourceResolver);
final List<Resource> containerFolders = this.getWorkflowInstanceFolders(resourceResolver);
for (Resource containerFolder : containerFolders) {
log.debug("Checking [ {} ] for workflow instances to remove", containerFolder.getPath());
final Collection<Resource> sortedFolders = this.getSortedAndFilteredFolders(containerFolder);
for (final Resource folder : sortedFolders) {
int remaining = 0;
for (final Resource instance : folder.getChildren()) {
if (this.forceQuit.get()) {
throw new WorkflowRemovalForceQuitException();
} else if (end > 0 && System.currentTimeMillis() >= end) {
throw new WorkflowRemovalMaxDurationExceededException();
}
final ValueMap properties = instance.getValueMap();
if (!StringUtils.equals(NT_CQ_WORKFLOW, properties.get(JcrConstants.JCR_PRIMARYTYPE, String.class))) {
// Only process cq:Workflow's
remaining++;
continue;
}
checkedCount++;
final String instanceStatus = getStatus(instance);
final String model = properties.get(PN_MODEL_ID, String.class);
final Calendar startTime = properties.get(PN_STARTED_AT, Calendar.class);
final String payload = properties.get(PAYLOAD_PATH, String.class);
if (StringUtils.isBlank(payload)) {
log.warn("Unable to find payload for Workflow instance [ {} ]", instance.getPath());
remaining++;
continue;
} else if (CollectionUtils.isNotEmpty(statuses) && !statuses.contains(instanceStatus)) {
log.trace("Workflow instance [ {} ] has non-matching status of [ {} ]", instance.getPath(), instanceStatus);
remaining++;
continue;
} else if (CollectionUtils.isNotEmpty(modelIds) && !modelIds.contains(model)) {
log.trace("Workflow instance [ {} ] has non-matching model of [ {} ]", instance.getPath(), model);
remaining++;
continue;
} else if (olderThan != null && startTime != null && startTime.before(olderThan)) {
log.trace("Workflow instance [ {} ] has non-matching start time of [ {} ]", instance.getPath(), startTime);
remaining++;
continue;
} else {
if (CollectionUtils.isNotEmpty(payloads)) {
// Only evaluate payload patterns if they are provided
boolean match = false;
if (StringUtils.isNotEmpty(payload)) {
for (final Pattern pattern : payloads) {
if (payload.matches(pattern.pattern())) {
// payload matches a pattern
match = true;
break;
}
}
if (!match) {
// Not a match; skip to next workflow instance
log.trace("Workflow instance [ {} ] has non-matching payload path [ {} ]", instance.getPath(), payload);
remaining++;
continue;
}
}
}
try {
instance.adaptTo(Node.class).remove();
log.debug("Removed workflow instance at [ {} ]", instance.getPath());
workflowRemovedCount++;
count++;
} catch (RepositoryException e) {
log.error("Could not remove workflow instance at [ {} ]. Continuing...", instance.getPath(), e);
}
if (count % batchSize == 0) {
this.batchComplete(resourceResolver, checkedCount, workflowRemovedCount);
log.info("Removed a running total of [ {} ] workflow instances", count);
}
}
}
if (remaining == 0 && isWorkflowDatedFolder(folder) && !StringUtils.startsWith(folder.getName(), new SimpleDateFormat(WORKFLOW_FOLDER_FORMAT).format(new Date()))) {
// MUST match the YYYY-MM-DD(.*) pattern; do not try to remove root folders
try {
folder.adaptTo(Node.class).remove();
log.debug("Removed empty workflow folder node [ {} ]", folder.getPath());
// Incrementing only count to trigger batch save and not total since is not a WF
count++;
} catch (RepositoryException e) {
log.error("Could not remove workflow folder at [ {} ]", folder.getPath(), e);
}
}
}
// Save final batch if needed, and update tracking nodes
this.complete(resourceResolver, checkedCount, workflowRemovedCount);
}
} catch (PersistenceException e) {
this.forceQuit.set(false);
log.error("Error persisting changes with Workflow Removal", e);
this.error();
throw e;
} catch (WorkflowRemovalException e) {
this.forceQuit.set(false);
log.error("Error with Workflow Removal", e);
this.error();
throw e;
} catch (InterruptedException e) {
this.forceQuit.set(false);
log.error("Errors in persistence retries during Workflow Removal", e);
this.error();
throw e;
} catch (WorkflowRemovalForceQuitException e) {
this.forceQuit.set(false);
// Uncommon instance of using Exception to control flow; Force quitting is an extreme condition.
log.warn("Workflow removal was force quit. The removal state is unknown.");
this.internalForceQuit();
throw e;
} catch (WorkflowRemovalMaxDurationExceededException e) {
// Uncommon instance of using Exception to control flow; Exceeding max duration extreme condition.
log.warn("Workflow removal exceeded max duration of [ {} ] minutes. Final removal commit initiating...", maxDurationInMins);
this.complete(resourceResolver, checkedCount, count);
}
if (log.isInfoEnabled()) {
log.info("Workflow Removal Process Finished! " + "Removed a total of [ {} ] workflow instances in [ {} ] ms", count, System.currentTimeMillis() - start);
}
return count;
}
Aggregations