use of com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException 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.WorkflowRemovalForceQuitException 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;
}
use of com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException in project acs-aem-commons by Adobe-Consulting-Services.
the class RemoveServlet method doPost.
@Override
public final void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
List<String> statuses = new ArrayList<String>();
List<String> models = new ArrayList<String>();
List<Pattern> payloads = new ArrayList<Pattern>();
Calendar olderThan = null;
try {
JSONObject params = new JSONObject(request.getParameter("params"));
JSONArray jsonArray = params.optJSONArray(PARAM_WORKFLOW_STATUSES);
for (int i = 0; i < jsonArray.length(); i++) {
statuses.add(jsonArray.getString(i));
}
jsonArray = params.optJSONArray(PARAM_WORKFLOW_MODELS);
for (int i = 0; i < jsonArray.length(); i++) {
models.add(jsonArray.getString(i));
}
jsonArray = params.optJSONArray(PARAM_WORKFLOW_PAYLOADS);
for (int i = 0; i < jsonArray.length(); i++) {
final JSONObject tmp = jsonArray.getJSONObject(i);
final String pattern = tmp.optString("pattern");
if (StringUtils.isNotBlank(pattern)) {
payloads.add(Pattern.compile(pattern));
}
}
final Long ts = params.optLong(PARAM_OLDER_THAN);
if (ts != null && ts > 0) {
olderThan = Calendar.getInstance();
olderThan.setTimeInMillis(ts * MS_IN_SECOND);
}
int batchSize = params.optInt(PARAM_BATCH_SIZE);
if (batchSize < 1) {
batchSize = DEFAULT_BATCH_SIZE;
}
int maxDuration = params.optInt(PARAM_MAX_DURATION);
if (maxDuration < 1) {
maxDuration = DEFAULT_MAX_DURATION;
}
workflowInstanceRemover.removeWorkflowInstances(request.getResourceResolver(), models, statuses, payloads, olderThan, batchSize, maxDuration);
} catch (WorkflowRemovalForceQuitException e) {
response.setStatus(599);
response.getWriter().write("Workflow removal force quit");
} catch (Exception e) {
log.error("An error occurred while attempting to remove workflow instances.", e);
response.setStatus(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR);
if (response.getWriter() != null) {
response.getWriter().write(e.getMessage());
}
}
}
Aggregations