02-12-2024 10:43 AM
Hello,
I'm looking to configure the scheduled job tempFileCleanerTrigger as described in the documentation here: https://docs.alfresco.com/content-services/7.1/develop/repo-ext-points/scheduled-jobs/#out-of-the-bo.... The goal is to modify its execution frequency and the duration for retaining temporary files.
I'm not yet very familiar with Alfresco and I can't seem to find the scheduled-jobs-context.xml file mentioned in this documentation.
Can you confirm if it's possible to configure this job and how to do it?
Thank you.
02-13-2024 09:38 AM
Yes you can do something like this:
SOLUTON WITH JAVA
Here the bean on the xxx-context.xml file:
<bean id="xxxtempFileCleanerCommon" class="xxx.TempFileCleanerThread" init-method="init"> <property name="threadPoolExecutor" ref="defaultAsyncThreadPool" /> </bean>
and here tha java class:
class TempFileCleanerThread { public static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TempFileCleanerThread.class); public TempFileCleanerThread() {} @Autowired @Qualifier("defaultAsyncThreadPool") protected ThreadPoolExecutor threadPoolExecutor; public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) { this.threadPoolExecutor = threadPoolExecutor; } public void init() { Runnable runnable = new TempFileCleaner(); threadPoolExecutor.execute(runnable); } }
public class TempFileCleaner extends Thread { private int protectHours = 1; private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(TempFileCleaner.class.getName()); public TempFileCleaner() { } public void run() { while(true) { doJob(); try { Thread.sleep(1000 * 60 * 60); //1 ora } catch (InterruptedException e) { logger.info("TempFileCleaner Interrupted!"); break; } } } public void close() { logger.info("Chiusura TempFileCleaner Checker..."); this.interrupt(); } /** * Gets a list of all files in the {@link TempFileProvider#ALFRESCO_TEMP_FILE_DIR temp directory} * and deletes all those that are older than the given number of hours. */ public void doJob() { // get the number of hours to protect the temp files if (protectHours < 0 || protectHours > 8760) { throw new IllegalArgumentException("Hours to protect temp files must be 0 <= x <= 8760"); } String directoryName = TempFileProvider.TEMP_FILE_DIR; //long now = System.currentTimeMillis(); long now = Calendar.getInstance().getTimeInMillis();//GWT COMPATIBILE long aFewHoursBack = now - (3600L * 1000L * protectHours); long aLongTimeBack = now - (24 * 3600L * 1000L); File tempDir = TempFileProvider.getTempDir(directoryName); int count = removeFiles(tempDir, aFewHoursBack, aLongTimeBack, false); // don't delete this directory // done // if (logger.isDebugEnabled()) { logger.debug("Removed " + count + " files from temp directory: " + tempDir); } } /** * Removes all temporary files created before the given time. * <p> * The delete will cascade down through directories as well. * * @param removeBefore only remove files created <b>before</b> this time * @return Returns the number of files removed */ public static int removeFiles(long removeBefore) { File tempDir = TempFileProvider.getTempDir(); return removeFiles(tempDir, removeBefore, removeBefore, false); } /** * @param directory the directory to clean out - the directory will optionally be removed * @param removeBefore only remove files created <b>before</b> this time * @param removeDir true if the directory must be removed as well, otherwise false * @return Returns the number of files removed */ private static int removeFiles(File directory, long removeBefore, long longLifeBefore, boolean removeDir) { if (!directory.isDirectory()) { throw new IllegalArgumentException("Expected a directory to clear: " + directory); } // check if there is anything to to if (!directory.exists()) { return 0; } // list all files File[] files = directory.listFiles(); int count = 0; for (File file : files) { if (file.isDirectory()) { if(TempFileProvider.isLongLifeTempDir(file)) { // long life for this folder and its children int countRemoved = removeFiles(file, longLifeBefore, longLifeBefore, true); // if (logger.isDebugEnabled()) { logger.debug("Removed " + countRemoved + " files from temp directory: " + file); } } else { // enter subdirectory and clean it out and remove itsynetics int countRemoved = removeFiles(file, removeBefore, longLifeBefore, true); // if (logger.isDebugEnabled()) { logger.debug("Removed " + countRemoved + " files from directory: " + file); } } } else { // it is a file - check the created time if (file.lastModified() > removeBefore) { // file is not old enough continue; } // it is a file - attempt a delete try { // if(logger.isDebugEnabled()) { logger.debug("Deleting temp file: " + file); } file.delete(); count++; } catch (Throwable e) { logger.info("Failed to remove temp file: " + file); } } } // must we delete the directory we are in? if (removeDir) { // the directory must be removed if empty try { File[] listing = directory.listFiles(); if(listing != null && listing.length == 0) { // directory is empty // if(logger.isDebugEnabled()) { logger.debug("Deleting empty directory: " + directory); } directory.delete(); } } catch (Throwable e) { logger.debug("Failed to remove temp directory: " + directory, e); } } // done return count; } }
<bean id="xxxtempFileCleanerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="cronExpression" value="0 30 * * * ?" /> <!-- Repeat hourly on the half hour --> <property name="startDelay" value="${system.cronJob.startDelayMilliseconds}"/> <property name="jobDetail"> <bean id="tempFileCleanerJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.alfresco.util.TempFileProvider$TempFileCleanerJob"/> <property name="jobDataAsMap"> <map> <entry key="protectHours" value="1"/> <entry key="maxFilesToDelete" value="${system.tempFileCleaner.maxFilesToDelete:#{null}}"/> <entry key="maxTimeToRun" value="${system.tempFileCleaner.maxTimeToRun:#{null}}"/> </map> </property> </bean> </property> </bean>
02-14-2024 04:18 AM
Hello,
Thank you for this response. So if I understand correctly, I need to create the file scheduler-context.xml (with the elements provided here) and place it on the corresponding Alfresco server? If that's the case, I must admit I don't understand why to create a file for a native Alfresco job.
Alternatively, is it possible to configure directly in alfresco-global.properties, without any further modifications or addition of files, for example by adding properties like webscripts.tempFileCleanerJobDetail.protectHours or webscripts.tempFileCleanerJobDetail.cronexpression?
02-14-2024 06:22 AM
Simple answer no. Wihtout developing any code you can only customize these global properties to apply on the default temp file cleaner of alfresco (is not advisable to do this unless you know how this stuff work):
sadly the cron is not in a variable is hard coded on the default xml, so you are "forced" to write your own "xx-context.xml" file.
Here the defaults beans on Alfresco 23.1.0 Community Edition just as example
<bean id="tempFileCleanerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="cronExpression" value="0 30 * * * ?" /> <!-- Repeat hourly on the half hour --> <property name="startDelay" value="${system.cronJob.startDelayMilliseconds}"/> <property name="jobDetail"> <bean id="tempFileCleanerJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.alfresco.util.TempFileProvider$TempFileCleanerJob"/> <property name="jobDataAsMap"> <map> <entry key="protectHours" value="1"/> <entry key="maxFilesToDelete" value="${system.tempFileCleaner.maxFilesToDelete:#{null}}"/> <entry key="maxTimeToRun" value="${system.tempFileCleaner.maxTimeToRun:#{null}}"/> </map> </property> </bean> </property> </bean> <bean id="webscripts.tempFileCleanerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="cronExpression" value="0 0 * * * ?" /> <!-- Repeat hourly on the start hour --> <property name="startDelay" value="${system.cronJob.startDelayMilliseconds}"/> <property name="jobDetail"> <bean id="webscripts.tempFileCleanerJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.alfresco.util.TempFileProvider$TempFileCleanerJob"/> <property name="jobDataAsMap"> <map> <entry key="protectHours" value="1"/> <entry key="directoryName" value="${webscripts.tempDirectoryName}"/> <entry key="maxFilesToDelete" value="${system.tempFileCleaner.maxFilesToDelete:#{null}}"/> <entry key="maxTimeToRun" value="${system.tempFileCleaner.maxTimeToRun:#{null}}"/> </map> </property> </bean> </property> </bean>
Explore our Alfresco products with the links below. Use labels to filter content by product module.