Search in sources :

Example 1 with WorkflowRemovalMaxDurationExceededException

use of com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalMaxDurationExceededException 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;
}
Also used : Pattern(java.util.regex.Pattern) ValueMap(org.apache.sling.api.resource.ValueMap) Calendar(java.util.Calendar) Node(javax.jcr.Node) Resource(org.apache.sling.api.resource.Resource) RepositoryException(javax.jcr.RepositoryException) WorkflowRemovalException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException) Date(java.util.Date) PersistenceException(org.apache.sling.api.resource.PersistenceException) WorkflowRemovalMaxDurationExceededException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalMaxDurationExceededException) SimpleDateFormat(java.text.SimpleDateFormat) WorkflowRemovalForceQuitException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException)

Aggregations

WorkflowRemovalException (com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException)1 WorkflowRemovalForceQuitException (com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException)1 WorkflowRemovalMaxDurationExceededException (com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalMaxDurationExceededException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Calendar (java.util.Calendar)1 Date (java.util.Date)1 Pattern (java.util.regex.Pattern)1 Node (javax.jcr.Node)1 RepositoryException (javax.jcr.RepositoryException)1 PersistenceException (org.apache.sling.api.resource.PersistenceException)1 Resource (org.apache.sling.api.resource.Resource)1 ValueMap (org.apache.sling.api.resource.ValueMap)1