
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