cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring the tempFileCleanerTrigger scheduled job

Meffapefecy
Champ in-the-making
Champ in-the-making

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.

3 REPLIES 3

4535992
Star Collaborator
Star Collaborator

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;
    }
}
 
SOLUTON WITH XML
 
or you can do everythin with the xml:
    <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>
 

Meffapefecy
Champ in-the-making
Champ in-the-making

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?

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):

  • system.tempFileCleaner.maxFilesToDelete
  • system.tempFileCleaner.maxTimeToRun
  • system.cronJob.startDelayMilliseconds

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>