All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.forms.common.servlet.TempCleanUpTask Maven / Gradle / Ivy

/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2014 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/

package com.adobe.forms.common.servlet;

import com.adobe.forms.common.utils.FormsConstants;
import org.apache.felix.scr.annotations.*;
import org.apache.felix.scr.annotations.Properties;
import org.apache.sling.api.resource.*;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.util.*;


/**
 * This scheduler service processes the uuid folders present inside /tmp/fd/af and deletes it
 * scheduling can be configured in "scheduler.expression" .
 */
@Component(immediate = true, metatype = true, label = "AEM Forms Temporary Storage Cleaning Task", description = "Cleans the temporary storage used by AEM Forms")
@Service(value = Runnable.class)
@Properties({
        @Property(name = "scheduler.expression", value = "0 0 12 * * ?", label = "Cron expression scheduling this job", description = "Cron expression scheduling this job. Default is every hour. See http://www.docjar.com/docs/api/org/quartz/CronTrigger.html for a description of the format for this value"),
        @Property(name = "scheduler.concurrent", boolValue = false, propertyPrivate = true)})
public class TempCleanUpTask implements Runnable {

    private final Logger log = LoggerFactory.getLogger(TempCleanUpTask.class);
    private Calendar todaysDate = Calendar.getInstance();
    private final String[] queryPaths = FormsConstants.FD_TEMP_PATHS;

    @Reference
    private SlingRepository slingRepository;

    @Reference
    private ResourceResolverFactory resourceResolverFactory;

    @Property(name = "Duration for Temporary Storage", value = "24", label = "Cleans the temporary folder older than(In Hours)", description = "Service will delete temporary nodes that were created before the (duration_temp_storage) from the current time")
    private static final Integer DURATION_TEMP_STORAGE = 24;
    private int duration_temp_storage;

    @Property(name = "Duration for Anonymous Storage", value = "1", label = "Cleans the anonymous temporary folder older than(In Hours)", description = "Service will delete anonymous temporary nodes that were created before the (duration_temp_storage) from the current time")
    private static final Integer DURATION_ANONYMOUS_STORAGE = 1;
    private int duration_anonymous_storage;

    @SuppressWarnings("UnusedDeclaration")
    protected void activate(ComponentContext context) {
        Dictionary props = context.getProperties();
        duration_temp_storage = OsgiUtil.toInteger (props.get("Duration for Temporary Storage"), DURATION_TEMP_STORAGE);
        duration_anonymous_storage = OsgiUtil.toInteger (props.get("Duration for Anonymous Storage"), DURATION_ANONYMOUS_STORAGE);
    }

    public void run() {
        Session session = null;
        try {
            //Note: We are using service session only for below purpose:
            // 1. Get All the nodes under /tmp/fd/af which are older than a particular time stamp
            // 2. And then all these nodes are deleted for clean up
            session = slingRepository.loginService(null,null);
            final List staleNodesList = new ArrayList();
            getTempNodes(session,staleNodesList);
            // getAnonymousTempNodes(session,staleNodesList);
            for (final Node staleNode : staleNodesList) {
                try {
                    staleNode.remove();
                } catch (final Exception e) {
                    log.error("Error while removing the node [ " + staleNode.getPath() + "]", e);
                }
            }
            session.save();
        } catch (final RepositoryException e) {
            log.error("Error while processing the uuid nodes list.", e);
        } finally {
            if (session != null && session.isLive()) {
                session.logout();
            }
        }
    }

    /**
     * Adds all the temp nodes to the list which have gone stale and needs to be cleaned.
     * @param session
     * @param staleNodesList
     */
    private void getTempNodes(final Session session, final List staleNodesList) {
        try {
            for(int i=0; i< queryPaths.length; i++) {
                final Node res = session.getNode(queryPaths[i]);
                final NodeIterator nit = res.getNodes();
                while (nit.hasNext()) {
                    final Node tmpNode = nit.nextNode();
                    // all uuid folders would have tmpNode property set
                    if (tmpNode.hasProperty("tmpNode")) {
                        isNodeStale(tmpNode, duration_temp_storage, staleNodesList);
                    }
                }
            }
        } catch (final RepositoryException e) {
            log.error("Error while querying for temp storages", e);
        }
    }

    /**
     * Adds all the anonymous temp nodes to the list which have gone stale and needs to be cleaned.
     * @param session
     * @param staleNodesList
     */
    private void getAnonymousTempNodes(final Session session, List staleNodesList) {
        try {
            for(int i=0; i< queryPaths.length; i++) {
                ResourceResolver resolver = resourceResolverFactory.getServiceResourceResolver(null);
                String query = "SELECT * FROM nt:base " +
                        "WHERE " + FormsConstants.GUIDE_COMPONENT_TYPE + "='" + FormsConstants.ANONYMOUS_TEMP_STORAGE +
                        "' AND jcr:path LIKE '" + queryPaths[i] + "%'";
                Iterator anonymousResources = resolver.findResources(query, "sql");
                while (anonymousResources.hasNext()) {
                    final Node tmpNode = anonymousResources.next().adaptTo(Node.class);
                    // all uuid folders created anonymously will have guideComponentType property set
                    if (tmpNode.hasProperty(FormsConstants.GUIDE_COMPONENT_TYPE) &&
                            FormsConstants.ANONYMOUS_TEMP_STORAGE.equals(tmpNode.getProperty(FormsConstants.GUIDE_COMPONENT_TYPE).getString())) {
                        isNodeStale(tmpNode, duration_anonymous_storage, staleNodesList);
                    }
                }
            }
        } catch (final RepositoryException e) {
            log.error("Error while querying for temp storages", e);
        } catch (final LoginException e) {
            log.error("Cannot provide  serviceResourceResolver", e);
        }
    }

    /**
     * All the nodes created or modified after the duration are marked stale and listed for cleaning.
     * @param tmpNode
     * @param duration
     * @param staleNodesList
     */
    private void isNodeStale(Node tmpNode, int duration, List staleNodesList) {
        try {
            Calendar date = null;
            if (tmpNode.hasProperty("jcr:lastModified")) {
                date = tmpNode.getProperty("jcr:lastModified").getDate();
            } else {
                date = tmpNode.getProperty("jcr:created").getDate();
            }
            // add the duration_temp_storage as hours
            date.add(Calendar.HOUR_OF_DAY, duration);
            // if this value is less than duration specified for anonymous storage.
            if (date.compareTo(todaysDate) <= 0) {
                staleNodesList.add(tmpNode);
            }
        } catch (final RepositoryException e) {
            log.error("Error while comparing dates for temp storages", e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy