Search in sources :

Example 1 with WorkflowRemovalForceQuitException

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();
        }
    }
}
Also used : ResourceResolver(org.apache.sling.api.resource.ResourceResolver) PersistenceException(org.apache.sling.api.resource.PersistenceException) LoginException(org.apache.sling.api.resource.LoginException) WorkflowRemovalException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException) WorkflowRemovalForceQuitException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException)

Example 2 with WorkflowRemovalForceQuitException

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;
}
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)

Example 3 with WorkflowRemovalForceQuitException

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());
        }
    }
}
Also used : Pattern(java.util.regex.Pattern) JSONObject(org.apache.sling.commons.json.JSONObject) Calendar(java.util.Calendar) ArrayList(java.util.ArrayList) JSONArray(org.apache.sling.commons.json.JSONArray) ServletException(javax.servlet.ServletException) WorkflowRemovalForceQuitException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException) IOException(java.io.IOException) WorkflowRemovalForceQuitException(com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException)

Aggregations

WorkflowRemovalForceQuitException (com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalForceQuitException)3 WorkflowRemovalException (com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalException)2 Calendar (java.util.Calendar)2 Pattern (java.util.regex.Pattern)2 PersistenceException (org.apache.sling.api.resource.PersistenceException)2 WorkflowRemovalMaxDurationExceededException (com.adobe.acs.commons.workflow.bulk.removal.WorkflowRemovalMaxDurationExceededException)1 IOException (java.io.IOException)1 SimpleDateFormat (java.text.SimpleDateFormat)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 Node (javax.jcr.Node)1 RepositoryException (javax.jcr.RepositoryException)1 ServletException (javax.servlet.ServletException)1 LoginException (org.apache.sling.api.resource.LoginException)1 Resource (org.apache.sling.api.resource.Resource)1 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)1 ValueMap (org.apache.sling.api.resource.ValueMap)1 JSONArray (org.apache.sling.commons.json.JSONArray)1 JSONObject (org.apache.sling.commons.json.JSONObject)1