Tony CHEMIT pushed to branch develop-7.x at ultreiaio / ird-observe Commits: ae6dc319 by tchemit at 2020-04-14T00:44:33+02:00 Accumulation de fichiers - Closes #1462 (report v7) - - - - - 27 changed files: - client-configuration/src/main/config/Client.ini - client-configuration/src/main/i18n/getters/config.getter - client-configuration/src/main/java/fr/ird/observe/client/configuration/ClientConfig.java - client-core/src/main/java/fr/ird/observe/client/ObserveRunner.java - client-core/src/main/java/fr/ird/observe/client/ObserveSwingApplicationContext.java - client-core/src/main/java/fr/ird/observe/client/db/ObserveDataSourcesManager.java - client-core/src/main/java/fr/ird/observe/client/db/ObserveSwingDataSource.java - client-core/src/main/java/fr/ird/observe/client/ui/actions/main/menu/config/ShowConfigAction.java - observe-i18n/src/main/i18n/translations/observe_en_GB.properties - observe-i18n/src/main/i18n/translations/observe_es_ES.properties - observe-i18n/src/main/i18n/translations/observe_fr_FR.properties - − persistence/src/main/java/fr/ird/observe/persistence/AbstractObserveTopiaDao.java - − persistence/src/main/java/fr/ird/observe/persistence/ObserveTopiaConfiguration.java - − persistence/src/main/java/fr/ird/observe/persistence/ObserveTopiaConfigurationFactory.java - − persistence/src/main/java/fr/ird/observe/persistence/ObserveTopiaIdFactory.java - pom.xml - server-configuration/pom.xml - server-configuration/src/main/config/Server.ini - server-configuration/src/main/i18n/getters/config.getter - server-configuration/src/main/java/fr/ird/observe/server/configuration/ServerConfig.java - server-core/src/main/java/fr/ird/observe/server/ObserveWebApplicationContext.java - services-local/src/main/java/fr/ird/observe/services/local/ObserveSecurityHelper.java - services-local/src/main/java/fr/ird/observe/services/local/ObserveTopiaApplicationContextFactory.java - services-local/src/main/java/fr/ird/observe/services/local/service/DataSourceServiceLocal.java - services-local/src/test/java/fr/ird/observe/services/local/LocalTestClassResource.java - + services/src/main/java/fr/ird/observe/services/service/CleanTemporaryFilesTask.java - + services/src/main/java/fr/ird/observe/services/service/CleanTemporaryFilesTaskConfiguration.java Changes: ===================================== client-configuration/src/main/config/Client.ini ===================================== @@ -130,8 +130,8 @@ defaultValue = ${data.directory}/validation-report transient = true final = true -[option tmpDirectory] -description = observe.config.defaultTmpDirectory.description +[option temporaryDirectory] +description = observe.config.temporaryDirectory.description key = tmp.directory type = file defaultValue = ${data.directory}/tmp @@ -599,6 +599,12 @@ key = ui.seineBycatchObservedSystem type = fr.ird.observe.validation.SeineBycatchObservedSystemConfig defaultValue = {\"fr.ird.observe.entities.referentiel.Species#1239832684290#0.04680507324710936\": [\"fr.ird.observe.entities.referentiel.seine.ObservedSystem#0#1.0\",\"fr.ird.observe.entities.referentiel.seine.ObservedSystem#0#1.1\"]} +[option temporaryFilesTimeout] +description = observe.config.temporaryFilesTimeout.description +key = observe.config.temporaryFilesTimeout +type = int +defaultValue = 120 + [action help] description = observe.action.commandline.help action = "fr.ird.observe.client.ObserveCLAction#help" ===================================== client-configuration/src/main/i18n/getters/config.getter ===================================== @@ -30,7 +30,6 @@ observe.config.defaultLocalDbDirectory.description observe.config.defaultMapDirectory.description observe.config.defaultReportDirectory.description observe.config.defaultResourcesDirectory.description -observe.config.defaultTmpDirectory.description observe.config.defaultValidationReportDirectory.description observe.config.devMode observe.config.floatingObjectPresets.description @@ -78,6 +77,8 @@ observe.config.speciesList.seine.schoolEstimate observe.config.speciesList.seine.targetCatch observe.config.swingSessionFile.description observe.config.temperature.format +observe.config.temporaryDirectory.description +observe.config.temporaryFilesTimeout.description observe.config.ui.autoPopupNumberEditor observe.config.ui.changeSynchroSrc observe.config.ui.dcp.error.color ===================================== client-configuration/src/main/java/fr/ird/observe/client/configuration/ClientConfig.java ===================================== @@ -30,6 +30,7 @@ import fr.ird.observe.client.constants.DbMode; import fr.ird.observe.dto.FloatingObjectPreset; import fr.ird.observe.dto.presets.RemoteDataSourceConfiguration; import fr.ird.observe.dto.presets.ServerDataSourceConfiguration; +import fr.ird.observe.services.service.CleanTemporaryFilesTaskConfiguration; import io.ultreia.java4all.config.ApplicationConfig; import io.ultreia.java4all.config.ApplicationConfigInit; import io.ultreia.java4all.config.ApplicationConfigScope; @@ -66,7 +67,7 @@ import static io.ultreia.java4all.i18n.I18n.t; * @author Tony Chemit - dev@tchemit.fr * @since 1.0 */ -public class ClientConfig extends GeneratedClientConfig implements NavigationTreeConfig { +public class ClientConfig extends GeneratedClientConfig implements NavigationTreeConfig, CleanTemporaryFilesTaskConfiguration { public static final String DB_NAME = "obstuna"; public static final List<ClientConfigOption> MAP_LAYERS = ImmutableList.of( ===================================== client-core/src/main/java/fr/ird/observe/client/ObserveRunner.java ===================================== @@ -37,7 +37,6 @@ import io.ultreia.java4all.i18n.runtime.boot.UserI18nBootLoader; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.Converter; import org.apache.commons.beanutils.converters.DateConverter; -import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -71,7 +70,7 @@ import static fr.ird.observe.client.configuration.ClientConfigOption.INITIAL_DB_ import static fr.ird.observe.client.configuration.ClientConfigOption.MAP_DIRECTORY; import static fr.ird.observe.client.configuration.ClientConfigOption.REPORT_DIRECTORY; import static fr.ird.observe.client.configuration.ClientConfigOption.RESOURCES_DIRECTORY; -import static fr.ird.observe.client.configuration.ClientConfigOption.TMP_DIRECTORY; +import static fr.ird.observe.client.configuration.ClientConfigOption.TEMPORARY_DIRECTORY; import static fr.ird.observe.client.configuration.ClientConfigOption.VALIDATION_REPORT_DIRECTORY; import static io.ultreia.java4all.i18n.I18n.t; @@ -402,10 +401,7 @@ public abstract class ObserveRunner extends ApplicationRunner { // 2 - tmp directory - resourceManager.createDirectory(config, TMP_DIRECTORY); - - // suppression du contenu du répertoire temporaire - FileUtils.cleanDirectory(config.getTmpDirectory()); + resourceManager.createDirectory(config, TEMPORARY_DIRECTORY); // 3 - backup directory ===================================== client-core/src/main/java/fr/ird/observe/client/ObserveSwingApplicationContext.java ===================================== @@ -36,6 +36,7 @@ import fr.ird.observe.dto.decoration.DecoratorService; import fr.ird.observe.dto.referential.ReferentialLocale; import fr.ird.observe.services.ObserveDataSourceConfigurationMainFactory; import fr.ird.observe.services.ObserveServiceMainFactory; +import fr.ird.observe.services.service.CleanTemporaryFilesTask; import fr.ird.observe.spi.DtoModelHelper; import fr.ird.observe.validation.ValidatorDto; import fr.ird.observe.validation.ValidatorsManager; @@ -53,6 +54,7 @@ import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.Objects; +import java.util.Timer; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -65,6 +67,7 @@ import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.DATA_ import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.DATA_SOURCES_MANAGER; import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.DATA_SOURCE_CONFIGURATION_FACTORY; import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.DECORATOR_SERVICE; +import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.DELETE_TEMPORARY_FILES_TASK; import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.FLOATING_OBJECT_REFERENCES_MANAGER; import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.H2_SERVER; import static fr.ird.observe.client.ObserveSwingApplicationContext.Entries.H2_SERVER_MODE; @@ -130,7 +133,7 @@ public class ObserveSwingApplicationContext extends DefaultApplicationContext im BACKUP_MANAGER.set(new BackupsManager(config.getBackupDirectory().toPath(), config.getBackupsFile().toPath())); LOCAL_DATABASE_BACKUP_TIMER.set(new ScheduledThreadPoolExecutor(1)); OBSERVE_SWING_SESSION_HELPER.set(new ObserveSwingSessionHelper(config.getSwingSessionFile())); - + DELETE_TEMPORARY_FILES_TASK.set(CleanTemporaryFilesTask.create(config)); lock = new Object(); } @@ -174,6 +177,10 @@ public class ObserveSwingApplicationContext extends DefaultApplicationContext im return DATA_SOURCES_MANAGER.get(); } + public Timer getCleanTemporaryFilesTask() { + return DELETE_TEMPORARY_FILES_TASK.get(); + } + public DecoratorService getDecoratorService() { return DECORATOR_SERVICE.get(); } @@ -319,7 +326,6 @@ public class ObserveSwingApplicationContext extends DefaultApplicationContext im toClose.add(OBSERVE_SWING_SESSION_HELPER); toClose.add(BACKUP_MANAGER); toClose.add(DATA_SOURCES_MANAGER); - for (Entries closeable : toClose) { try { log.info("Closing " + closeable.objectName); @@ -329,7 +335,7 @@ public class ObserveSwingApplicationContext extends DefaultApplicationContext im } } ObserveServiceMainFactory.get().close(); - + closeDeleteTemporaryFilesTimer(); // fermeture du context principal clear(); @@ -347,6 +353,13 @@ public class ObserveSwingApplicationContext extends DefaultApplicationContext im super.finalize(); } + void closeDeleteTemporaryFilesTimer() { + try { + getCleanTemporaryFilesTask().cancel(); + } catch (Exception e) { + log.error("Could not terminates delete temporary files timer...", e); + } + } enum Entries { CONFIG("Config", ClientConfig.class), @@ -359,6 +372,7 @@ public class ObserveSwingApplicationContext extends DefaultApplicationContext im DATA_SOURCES_MANAGER("Data sources manager", ObserveDataSourcesManager.class), FLOATING_OBJECT_REFERENCES_MANAGER("Floating object referenfences manager", FloatingObjectPresetsManager.class), OBSERVE_SWING_SESSION_HELPER("Swing session Helper", ObserveSwingSessionHelper.class), + DELETE_TEMPORARY_FILES_TASK(" Delete temporary files task", Timer.class), VALIDATION_CONTEXT("Validation context", ClientValidationContext.class), MAIN_UI("Main UI", ObserveMainUI.class), ACTIONS("Command line Actions", ObserveCLAction.class), ===================================== client-core/src/main/java/fr/ird/observe/client/db/ObserveDataSourcesManager.java ===================================== @@ -171,7 +171,7 @@ public class ObserveDataSourcesManager implements Closeable { ClientConfig config = applicationContext.getConfig(); ObserveDataSourceConfigurationMainFactory configurationMainFactory = applicationContext.getObserveDataSourceConfigurationMainFactory(); - File tmpDirectory = config.getTmpDirectory(); + File tmpDirectory = config.getTemporaryDirectory(); File dbDirectory = new File(tmpDirectory, ClientConfig.DB_NAME + UUID.randomUUID().toString()); ===================================== client-core/src/main/java/fr/ird/observe/client/db/ObserveSwingDataSource.java ===================================== @@ -477,7 +477,7 @@ public class ObserveSwingDataSource extends AbstractSerializableBean implements Locale locale = config.getLocale(); - File tmpDirectory = config.getTmpDirectory(); + File tmpDirectory = config.getTemporaryDirectory(); ReferentialLocale referentialLocale = ReferentialLocale.valueOf(locale); ===================================== client-core/src/main/java/fr/ird/observe/client/ui/actions/main/menu/config/ShowConfigAction.java ===================================== @@ -291,7 +291,7 @@ public class ShowConfigAction extends MenuActionSupport { helper.addOption(ClientConfigOption.DB_DIRECTORY); helper.addOption(ClientConfigOption.BACKUP_DIRECTORY); helper.addOption(ClientConfigOption.IMPORT_DIRECTORY); - helper.addOption(ClientConfigOption.TMP_DIRECTORY); + helper.addOption(ClientConfigOption.TEMPORARY_DIRECTORY); helper.addOption(ClientConfigOption.VALIDATION_REPORT_DIRECTORY); helper.addOption(ClientConfigOption.RESOURCES_DIRECTORY); helper.addOption(ClientConfigOption.SWING_SESSION_FILE); ===================================== observe-i18n/src/main/i18n/translations/observe_en_GB.properties ===================================== @@ -1738,7 +1738,6 @@ observe.config.defaultLocalDbDirectory.description=Default directory where to st observe.config.defaultMapDirectory.description=Default directory where to store map layers observe.config.defaultReportDirectory.description=Default directory where to store report definition files observe.config.defaultResourcesDirectory.description=Default user resources directory -observe.config.defaultTmpDirectory.description=Default temporary directory used by application and clean at each launch. observe.config.defaultValidationReportDirectory.description=Default validation report directory observe.config.devMode=Dev mode observe.config.floatingObjectPresets.description=Floating Objects references @@ -1786,6 +1785,8 @@ observe.config.speciesList.seine.schoolEstimate=Species for school esitmates observe.config.speciesList.seine.targetCatch=Species for target catches observe.config.swingSessionFile.description=Swing session file. observe.config.temperature.format=Default temperature format +observe.config.temporaryDirectory.description=Default temporary directory used by application and clean at each launch. +observe.config.temporaryFilesTimeout.description=Temporary files delete (in hours) observe.config.ui.autoPopupNumberEditor=Flag sets to true when number editor show automaticly popup observe.config.ui.changeSynchroSrc=Flag sets to true if you can change local source in admin tasks observe.config.ui.dcp.error.color=Color to notify errors while validating floating object materials. ===================================== observe-i18n/src/main/i18n/translations/observe_es_ES.properties ===================================== @@ -1738,7 +1738,6 @@ observe.config.defaultLocalDbDirectory.description=Directorio de almacenamiento observe.config.defaultMapDirectory.description=El directorio donde se ubican los mapas. observe.config.defaultReportDirectory.description=Directorio por defecto de los informes de la aplicación observe.config.defaultResourcesDirectory.description=Directorio de almacenamiento de los recursos de usuario como las traducciones o la consultas de informes -observe.config.defaultTmpDirectory.description=Directorio temporal por defecto observe.config.defaultValidationReportDirectory.description=Directorio por defecto de almacenamiento de los informes de validación observe.config.devMode=Modo desarrollador observe.config.floatingObjectPresets.description=Objetos flotantes de referencia @@ -1786,6 +1785,8 @@ observe.config.speciesList.seine.schoolEstimate=Especies para las estimaciones observe.config.speciesList.seine.targetCatch=Especies par las capturas objetivo observe.config.swingSessionFile.description=Copia de seguridad del estado del UI. observe.config.temperature.format=Unidad de temperatura +observe.config.temporaryDirectory.description=Directorio temporal por defecto +observe.config.temporaryFilesTimeout.description=Temporary files delete (in hours) \#TODO observe.config.ui.autoPopupNumberEditor=Para mostrar automáticamente el editor numérico durante la edición de un número observe.config.ui.changeSynchroSrc=Para autorizar la seleción de la base fuente durante las operaciones sobre la base observe.config.ui.dcp.error.color=Color para notificar los errores sobre la composición de dcps ===================================== observe-i18n/src/main/i18n/translations/observe_fr_FR.properties ===================================== @@ -1738,7 +1738,6 @@ observe.config.defaultLocalDbDirectory.description=Le répertoire où est stock observe.config.defaultMapDirectory.description=Le répertoire où sont stockées les cartes. observe.config.defaultReportDirectory.description=Répertoire par défaut des rapports de l'application observe.config.defaultResourcesDirectory.description=Le répertoire où sont stockées les ressources de l'utilisateur comme les traductions ou les requêtes de rapports. -observe.config.defaultTmpDirectory.description=Le répertoire temporaire par défaut observe.config.defaultValidationReportDirectory.description=Le répertoire par défaut où sont stockés les rapports de validation observe.config.devMode=Mode développeur observe.config.floatingObjectPresets.description=Objets flottants de référence @@ -1786,6 +1785,8 @@ observe.config.speciesList.seine.schoolEstimate=Espèces pour les estimations observe.config.speciesList.seine.targetCatch=Espèces pour les captures cible observe.config.swingSessionFile.description=Fichier de sauvegarde des états des UI. observe.config.temperature.format=Unité de température +observe.config.temporaryDirectory.description=Le répertoire temporaire par défaut +observe.config.temporaryFilesTimeout.description=Nettoyage des fichiers temporaires (en heures) observe.config.ui.autoPopupNumberEditor=Pour afficher automatiquement l'éditeur numérique lors de l'édition d'un nombre observe.config.ui.changeSynchroSrc=Pour autoriser la sélection de la base source dans les opérations sur base observe.config.ui.dcp.error.color=Couleur pour notifier les erreurs sur la composition des dcps ===================================== persistence/src/main/java/fr/ird/observe/persistence/AbstractObserveTopiaDao.java deleted ===================================== @@ -1,77 +0,0 @@ -package fr.ird.observe.persistence; - -/* - * #%L - * ObServe :: Persistence - * %% - * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import fr.ird.observe.entities.ObserveEntity; -import org.nuiton.topia.persistence.internal.AbstractTopiaDao; -import org.nuiton.topia.persistence.support.TopiaSqlQuery; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.Date; -import java.util.List; -import java.util.Map; - -public abstract class AbstractObserveTopiaDao<E extends ObserveEntity> extends AbstractTopiaDao<E> { - - private final GetLastupdateDateSqlQuery getLastUpdateDateSqlQuery; - - protected AbstractObserveTopiaDao() { - String schemaName = getTopiaEntityEnum().dbSchemaName(); - String tableName = getTopiaEntityEnum().dbTableName(); - getLastUpdateDateSqlQuery = new GetLastupdateDateSqlQuery(schemaName, tableName); - } - - public Date getLastUpdateDate() { - return topiaSqlSupport.findSingleResult(getLastUpdateDateSqlQuery); - } - - public <O> List<O> findAllFromHql(String hql, Map<String, Object> hqlParameters) { - return findAll(hql, hqlParameters); - } - - private static class GetLastupdateDateSqlQuery extends TopiaSqlQuery<Timestamp> { - - protected final String sql; - - private GetLastupdateDateSqlQuery(String schemaName, String tableName) { - this.sql = "SELECT max(" + ObserveEntity.PROPERTY_LAST_UPDATE_DATE + ") FROM " + schemaName + "." + tableName; - } - - @Override - public PreparedStatement prepareQuery(Connection connection) throws SQLException { - return connection.prepareStatement(sql); - } - - @Override - public Timestamp prepareResult(ResultSet set) throws SQLException { - return set.getTimestamp(1); - } - - } - - -} ===================================== persistence/src/main/java/fr/ird/observe/persistence/ObserveTopiaConfiguration.java deleted ===================================== @@ -1,84 +0,0 @@ -package fr.ird.observe.persistence; - -/* - * #%L - * ObServe :: Persistence - * %% - * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import org.nuiton.topia.persistence.BeanTopiaConfiguration; -import org.nuiton.topia.persistence.HibernateAvailableSettings; -import org.nuiton.topia.persistence.jdbc.JdbcConfiguration; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.Properties; -import java.util.TreeMap; - -/** - * Created on 23/08/15. - * - * @author Tony Chemit - dev@tchemit.fr - */ -public class ObserveTopiaConfiguration extends BeanTopiaConfiguration { - - private static final long serialVersionUID = 1L; - - private final boolean h2Configuration; - protected final boolean showSql; - private static final Map<String, String> HIBERNATE_GLOBAL_PROPERTIES; - - static { - - Properties p = new Properties(); - try (InputStream stream = ObserveTopiaPersistenceContext.class.getResourceAsStream("/hibernate.properties")) { - try { - p.load(stream); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } catch (IOException e) { - throw new IllegalStateException(e); - } - HIBERNATE_GLOBAL_PROPERTIES = new TreeMap<>(); - for (String s : p.stringPropertyNames()) { - HIBERNATE_GLOBAL_PROPERTIES.put(s, p.getProperty(s)); - } - - } - - public ObserveTopiaConfiguration(JdbcConfiguration jdbcConfiguration, boolean h2Configuration, boolean showSql) { - super(jdbcConfiguration); - this.h2Configuration = h2Configuration; - this.showSql = showSql; - if (showSql) { - hibernateExtraConfiguration.put(HibernateAvailableSettings.SHOW_SQL, Boolean.TRUE.toString()); - } - hibernateExtraConfiguration.putAll(HIBERNATE_GLOBAL_PROPERTIES); - } - - public boolean isH2Configuration() { - return h2Configuration; - } - - public boolean isShowSql() { - return showSql; - } -} ===================================== persistence/src/main/java/fr/ird/observe/persistence/ObserveTopiaConfigurationFactory.java deleted ===================================== @@ -1,143 +0,0 @@ -package fr.ird.observe.persistence; - -/* - * #%L - * ObServe :: Persistence - * %% - * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import org.nuiton.topia.persistence.jdbc.JdbcConfiguration; -import org.nuiton.topia.persistence.jdbc.JdbcConfigurationBuilder; -import org.nuiton.topia.service.migration.TopiaMigrationService; -import org.nuiton.topia.service.script.TopiaSqlScriptGeneratorServiceImpl; - -import java.io.File; - -/** - * Created on 23/08/15. - * - * @author Tony Chemit - dev@tchemit.fr - */ -public class ObserveTopiaConfigurationFactory { - - /** l'url d'acces a la base locale */ - private static final String H2_LOCAL_URL = - "jdbc:h2:file:%s;" + - // on peut aussi utiliser file, socket - "FILE_LOCK=file;" + - //1 or 2 is needed to restore avec crash - // 0: logging is disabled (faster), - // 1: logging of the data is enabled, but logging of the index - // changes is disabled (default), 2: logging of both data and index - // changes are enabled - "LOG=0;" + - // on peut aussi utiliser hsqldb, mysql ou postgresql - "MODE=postgresql;" + - //"MODE=hsqldb;" + - // Sets the default lock timeout (in milliseconds) in this - // database that is used for the new sessions. - "DEFAULT_LOCK_TIMEOUT=100;" + - // -1: the database is never closed until the close delay is set to - // some other rev or SHUTDOWN is called., 0: no delay (default; the - // database is closed if the last connection to it is closed)., n: - // the database is left open for n second after the last connection - // is closed. - "DB_CLOSE_DELAY=0;" + - // 0: no locking (should only be used for testing), - // 1: table level locking (default), - // 2: table level locking with garbage collection (if the - // application does not close all connections). - // LOCK_MODE 3 (READ_COMMITTED). Table level locking, but only when - // writing (no read locks). - "LOCK_MODE=3;" + - // Levels: 0=off, 1=error, 2=info, 3=debug. - "TRACE_LEVEL_FILE=0;" + - // on system.out: 0=off, 1=error, 2=info, 3=debug. - "TRACE_LEVEL_SYSTEM_OUT=0;" + - // maximumn cache to improve performance... - "CACHE_SIZE=65536;" + - // avoid timeout on reading tables (see http://stackoverflow.com/questions/4162557/timeout-error-trying-to-lock-tabl...) - "MVCC=true"; - - private static final JdbcConfigurationBuilder JDBC_CONFIGURATION_BUILDER = new JdbcConfigurationBuilder(); - private static final Logger log = LogManager.getLogger(ObserveTopiaConfigurationFactory.class); - - public static ObserveTopiaConfiguration forPostgresqlDatabase(String jdbcUrl, - String username, - String password, - boolean initSchema, - boolean traceSql) { - - JdbcConfiguration jdbcConfiguration = JDBC_CONFIGURATION_BUILDER.forPostgresqlDatabase(jdbcUrl, username, password); - - ObserveTopiaConfiguration topiaConfiguration = createTopiaConfiguration(jdbcConfiguration, - initSchema, - false, - traceSql); - - log.debug("PG topia configuration: " + topiaConfiguration); - return topiaConfiguration; - - } - - public static ObserveTopiaConfiguration forH2Database(File dbDirectory, - String dbName, - String username, - String password, - boolean initSchema, - boolean traceSql) { - - String dbPath = new File(dbDirectory, dbName).getPath(); - String jdbcUrl = String.format(H2_LOCAL_URL, dbPath); - - JdbcConfiguration jdbcConfiguration = JDBC_CONFIGURATION_BUILDER.forH2Database(jdbcUrl, username, password); - - ObserveTopiaConfiguration topiaConfiguration = createTopiaConfiguration(jdbcConfiguration, - initSchema, - true, - traceSql); - - log.debug("H2 topia configuration: " + topiaConfiguration); - return topiaConfiguration; - - } - - private static ObserveTopiaConfiguration createTopiaConfiguration(JdbcConfiguration jdbcConfiguration, - boolean initSchema, - boolean h2Configuration, - boolean traceSql) { - - ObserveTopiaConfiguration topiaConfiguration = new ObserveTopiaConfiguration(jdbcConfiguration, h2Configuration, traceSql); - topiaConfiguration.setTopiaIdFactoryClass(ObserveTopiaIdFactory.class); - topiaConfiguration.setInitSchema(initSchema); - topiaConfiguration.setValidateSchema(false); - topiaConfiguration.setUseHikariForJdbcConnectionPooling(true); - - log.debug("jdbcUrl: " + topiaConfiguration.getJdbcConnectionUrl()); - - topiaConfiguration.addDeclaredService(ObserveTopiaApplicationContext.MIGRATION_SERVICE_NAME, TopiaMigrationService.class); - topiaConfiguration.addDeclaredService(ObserveTopiaApplicationContext.SQL_SCRIPT_GENERATOR_BATCH_SERVICE_NAME, TopiaSqlScriptGeneratorServiceImpl.class); - - return topiaConfiguration; - - } - -} ===================================== persistence/src/main/java/fr/ird/observe/persistence/ObserveTopiaIdFactory.java deleted ===================================== @@ -1,90 +0,0 @@ -package fr.ird.observe.persistence; - -/* - * #%L - * ObServe :: Persistence - * %% - * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.topia.persistence.internal.LegacyTopiaIdFactory; - -/** - * Created on 21/08/15. - * - * @author Tony Chemit - dev@tchemit.fr - */ -public class ObserveTopiaIdFactory extends LegacyTopiaIdFactory { - - private static final Logger log = LogManager.getLogger(ObserveTopiaIdFactory.class); - - private static final long serialVersionUID = 1L; - - public <E extends TopiaEntity> String newTopiaId(Class<E> entityType) { - - double random = Math.random(); - while (Double.toString(random).contains("E-")) { - random = Math.random(); - } - return newTopiaId(entityType, random + ""); - } - - public <E extends TopiaEntity> boolean isTopiaId(Class<E> entityClass, String str) { - boolean isTopiaId = false; - if (str != null && !str.endsWith(getSeparator())) { - String[] split = str.split(getSeparator()); - if (split.length == 3) { - String className = split[0]; - isTopiaId = entityClass.getName().equals(className); - for (int index = 1; index < split.length; index++) { - isTopiaId &= StringUtils.isNumeric(split[index]); - } - } - } - return isTopiaId; - } - - @Override - public boolean isTopiaId(String str) { - boolean isTopiaId = false; - if (str != null && !str.endsWith(getSeparator())) { - String[] split = str.split(getSeparator()); - if (split.length == 3) { - String className = split[0]; - try { - Class.forName(className); - isTopiaId = true; - for (int index = 1; index < split.length; index++) { - isTopiaId &= StringUtils.isNumeric(split[index]); - } - } catch (ClassNotFoundException eee) { - // nothing to do, just return false - if (log.isDebugEnabled()) { - log.debug(eee); - } - } - } - } - return isTopiaId; - } - -} ===================================== pom.xml ===================================== @@ -26,7 +26,7 @@ <parent> <groupId>io.ultreia.maven</groupId> <artifactId>pom</artifactId> - <version>2020.15</version> + <version>2020.17</version> </parent> <groupId>fr.ird.observe</groupId> @@ -155,7 +155,7 @@ <maven.build.timestamp.format>dd/MM/yyyy HH:mm z</maven.build.timestamp.format> <buildDate>${maven.build.timestamp}</buildDate> - <observeToolkitVersion>3.7.27</observeToolkitVersion> + <observeToolkitVersion>3.7.28</observeToolkitVersion> <!--<lib.version.java4all.http>1.0.13</lib.version.java4all.http>--> <lib.version.nuiton.validation>3.1</lib.version.nuiton.validation> <!--<lib.version.java4all.config>1.0.3</lib.version.java4all.config>--> @@ -165,7 +165,7 @@ <lib.version.java4all.eugene>3.0-alpha-26</lib.version.java4all.eugene> <!-- <lib.version.java4all.jaxx>3.0-alpha-56</lib.version.java4all.jaxx>--> <!--<lib.version.java4all.i18n>4.0-beta-8-SNAPSHOT</lib.version.java4all.i18n>--> - <lib.version.java4all.topia>1.1.16</lib.version.java4all.topia> + <lib.version.java4all.topia>1.1.17</lib.version.java4all.topia> <lib.version.nuiton.utils>3.0</lib.version.nuiton.utils> <!--<lib.version.nuiton.topia>3.6-SNAPSHOT</lib.version.nuiton.topia>--> <!--<lib.version.java4all.eugene>3.0-alpha-21</lib.version.java4all.eugene>--> ===================================== server-configuration/pom.xml ===================================== @@ -112,6 +112,12 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> + <dependency> + <groupId>fr.ird.observe</groupId> + <artifactId>services</artifactId> + <version>7.5.1-SNAPSHOT</version> + <scope>compile</scope> + </dependency> </dependencies> ===================================== server-configuration/src/main/config/Server.ini ===================================== @@ -117,3 +117,9 @@ key = observeweb.httpTimeout type = int defaultValue = 30000 +[option temporaryFilesTimeout] +description = observe.config.temporaryFilesTimeout.description +key = observeweb.temporaryFilesTimeout +type = int +defaultValue = 120 + ===================================== server-configuration/src/main/i18n/getters/config.getter ===================================== @@ -1,4 +1,5 @@ ObserveWebApplicationConfig.description +observe.config.temporaryFilesTimeout.description observe.model.version observeweb.adminApiKey.description observeweb.apiUrl.description ===================================== server-configuration/src/main/java/fr/ird/observe/server/configuration/ServerConfig.java ===================================== @@ -25,6 +25,7 @@ package fr.ird.observe.server.configuration; import com.google.common.io.CharSource; import com.google.common.io.Resources; import fr.ird.observe.dto.ObserveUtil; +import fr.ird.observe.services.service.CleanTemporaryFilesTaskConfiguration; import io.ultreia.java4all.config.ApplicationConfig; import io.ultreia.java4all.config.ArgumentsParserException; import org.apache.logging.log4j.LogManager; @@ -44,7 +45,7 @@ import java.nio.file.Paths; * * @author Tony Chemit - dev@tchemit.fr */ -public class ServerConfig extends GeneratedServerConfig { +public class ServerConfig extends GeneratedServerConfig implements CleanTemporaryFilesTaskConfiguration { private static final String DEFAULT_OBSERVE_WEB_CONFIGURATION_FILENAME = "observe-server.conf"; /** Logger. */ ===================================== server-core/src/main/java/fr/ird/observe/server/ObserveWebApplicationContext.java ===================================== @@ -42,20 +42,26 @@ import fr.ird.observe.services.ObserveServiceFactory; import fr.ird.observe.services.ObserveServiceInitializer; import fr.ird.observe.services.ObserveServiceMainFactory; import fr.ird.observe.services.configuration.ObserveDataSourceConfiguration; +import fr.ird.observe.services.service.CleanTemporaryFilesTask; import fr.ird.observe.services.service.ObserveService; import fr.ird.observe.services.service.actions.consolidate.dcp.FloatingObjectModification; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.debux.webmotion.server.call.HttpContext; import org.nuiton.version.Version; import javax.servlet.ServletContext; import java.io.Closeable; import java.io.IOException; +import java.util.Timer; /** * @author Tony Chemit - dev@tchemit.fr */ public class ObserveWebApplicationContext implements Closeable { + private static final Logger log = LogManager.getLogger(ObserveWebApplicationContext.class); + public static final String APPLICATION_CONTEXT_PARAMETER = ObserveWebApplicationContext.class.getName(); public static final String MISSING_APPLICATION_CONTEXT = @@ -74,6 +80,8 @@ public class ObserveWebApplicationContext implements Closeable { protected ObserveWebSecurityApplicationContext securityApplicationContext; + private Timer deleteTemporaryFilesTimer; + public static ObserveWebApplicationContext getApplicationContext(HttpContext context) { ServletContext servletContext = context.getServletContext(); @@ -125,6 +133,10 @@ public class ObserveWebApplicationContext implements Closeable { } }; + if (deleteTemporaryFilesTimer != null) { + closeDeleteTemporaryFilesTimer(); + } + deleteTemporaryFilesTimer = CleanTemporaryFilesTask.create(getApplicationConfiguration()); } @@ -147,6 +159,8 @@ public class ObserveWebApplicationContext implements Closeable { @Override public void close() throws IOException { + closeDeleteTemporaryFilesTimer(); + // Supprimer le cache des sessions securityApplicationContext.close(); @@ -154,6 +168,13 @@ public class ObserveWebApplicationContext implements Closeable { mainServiceFactory.close(); } + void closeDeleteTemporaryFilesTimer() { + try { + deleteTemporaryFilesTimer.cancel(); + } catch (Exception e) { + log.error("Could not terminates delete temporary files timer...", e); + } + } public ObserveDtoGsonSupplier getGsonSupplier() { return gsonSupplier; ===================================== services-local/src/main/java/fr/ird/observe/services/local/ObserveSecurityHelper.java ===================================== @@ -27,6 +27,7 @@ import com.google.common.collect.Sets; import fr.ird.observe.dto.ObserveDbRole; import fr.ird.observe.dto.db.ObserveDbUserDto; import fr.ird.observe.persistence.Entities; +import fr.ird.observe.persistence.ObserveTopiaConfiguration; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; @@ -86,20 +87,21 @@ public class ObserveSecurityHelper { OBSERVE_LONGLINE_SCHEMA_NAME); private static final Logger log = LogManager.getLogger(ObserveSecurityHelper.class); private final JdbcPostgresHelper jdbcHelper; + private final Path temporaryDirectory; - public ObserveSecurityHelper(JdbcConfiguration jdbcConfiguration) { + public ObserveSecurityHelper(ObserveTopiaConfiguration jdbcConfiguration) { this.jdbcHelper = new JdbcPostgresHelper(jdbcConfiguration); + this.temporaryDirectory = jdbcConfiguration.getTemporaryDirectory(); } public void applySecurity(Set<ObserveDbUserDto> users) { if (users == null) { throw new NullPointerException("users can not be null"); } - Path scriptPath; try { - scriptPath = Files.createTempFile("topia-sql-script-", ".sql"); + scriptPath = Files.createTempFile(temporaryDirectory, "topia-sql-script-", ".sql"); } catch (IOException e) { throw new IllegalStateException("Can't create temporary path", e); } ===================================== services-local/src/main/java/fr/ird/observe/services/local/ObserveTopiaApplicationContextFactory.java ===================================== @@ -149,6 +149,7 @@ public class ObserveTopiaApplicationContextFactory { configuration.getJdbcUrl(), configuration.getUsername(), String.valueOf(configuration.getPassword()), + configuration.getTemporaryDirectory(), initSchema, configuration.isTraceSql() ); @@ -174,6 +175,7 @@ public class ObserveTopiaApplicationContextFactory { configuration.getDbName(), configuration.getUsername(), String.valueOf(configuration.getPassword()), + configuration.getTemporaryDirectory(), initSchema, configuration.isTraceSql() ); ===================================== services-local/src/main/java/fr/ird/observe/services/local/service/DataSourceServiceLocal.java ===================================== @@ -70,6 +70,7 @@ import org.nuiton.version.Versions; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.util.LinkedHashSet; import java.util.Optional; import java.util.Set; @@ -110,6 +111,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS Preconditions.checkState(dataSourceConfiguration instanceof ObserveDataSourceConfigurationTopiaSupport); ObserveDataSourceConfigurationTopiaSupport dataSourceConfigurationTopiaSupport = (ObserveDataSourceConfigurationTopiaSupport) dataSourceConfiguration; + Path temporaryDirectory = serviceContext.getTemporaryDirectoryRoot().toPath(); ObserveDataSourceInformation dataSourceInformation; if (dataSourceConfigurationTopiaSupport.isH2Database()) { @@ -143,7 +145,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS h2DataSourceConfiguration.getDbName(), h2DataSourceConfiguration.getUsername(), new String(h2DataSourceConfiguration.getPassword()), - false, + temporaryDirectory, false, false); @@ -167,7 +169,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS ObserveTopiaConfiguration topiaConfiguration = ObserveTopiaConfigurationFactory.forPostgresqlDatabase(pgDataSourceConfiguration.getJdbcUrl(), pgDataSourceConfiguration.getUsername(), new String(pgDataSourceConfiguration.getPassword()), - false, + temporaryDirectory, false, false); try { @@ -190,6 +192,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS @Override public ObserveDataSourceInformation checkCanConnect(ObserveDataSourceConfiguration dataSourceConfiguration) throws DatabaseNotFoundException, DatabaseConnexionNotAuthorizedException { + Path temporaryDirectory = getTemporaryDirectory(dataSourceConfiguration); Preconditions.checkState(dataSourceConfiguration instanceof ObserveDataSourceConfigurationTopiaSupport); ObserveDataSourceConfigurationTopiaSupport dataSourceConfigurationTopiaSupport = (ObserveDataSourceConfigurationTopiaSupport) dataSourceConfiguration; @@ -226,6 +229,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS h2DataSourceConfiguration.getDbName(), h2DataSourceConfiguration.getUsername(), new String(h2DataSourceConfiguration.getPassword()), + temporaryDirectory, false, false); @@ -250,6 +254,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS ObserveTopiaConfiguration topiaConfiguration = ObserveTopiaConfigurationFactory.forPostgresqlDatabase(pgDataSourceConfiguration.getJdbcUrl(), pgDataSourceConfiguration.getUsername(), new String(pgDataSourceConfiguration.getPassword()), + temporaryDirectory, false, false); @@ -269,13 +274,22 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS } + Path getTemporaryDirectory(ObserveDataSourceConfiguration dataSourceConfiguration) { + Path temporaryDirectory = dataSourceConfiguration.getTemporaryDirectory(); + if (temporaryDirectory == null) { + temporaryDirectory = serviceContext.getTemporaryDirectoryRoot().toPath(); + dataSourceConfiguration.setTemporaryDirectory(temporaryDirectory); + } + return temporaryDirectory; + } + @Override public ObserveDataSourceConnectionTopia create(ObserveDataSourceConfiguration dataSourceConfiguration, DataSourceCreateConfigurationDto dataSourceCreateConfiguration) throws IncompatibleDataSourceCreateConfigurationException, DataSourceCreateWithNoReferentialImportException, BabModelVersionException, DatabaseConnexionNotAuthorizedException, DatabaseNotFoundException { dataSourceCreateConfiguration.validateConfiguration(); - + Path temporaryDirectory = getTemporaryDirectory(dataSourceConfiguration); boolean initSchema = !dataSourceCreateConfiguration.isImportDatabase(); ObserveTopiaApplicationContext topiaApplicationContext = ObserveTopiaApplicationContextFactory.createTopiaApplicationContext((ObserveDataSourceConfigurationTopiaSupport) dataSourceConfiguration, initSchema); @@ -294,10 +308,9 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS } else { // base postgres // on realise les import dans un base H2 temporaire - // FIXME il faut obtenir le repertoit temporaire d'observe plutot que celui du système File tmpDir; try { - tmpDir = Files.createTempDirectory("obstuna").toFile(); + tmpDir = Files.createTempDirectory(temporaryDirectory, "obstuna").toFile(); } catch (IOException e) { throw new IllegalStateException("could not create temporary directory ", e); } @@ -322,8 +335,6 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS if (!databaseFile.delete()) { throw new IllegalStateException("could not delete " + databaseFile); } - - } } else { @@ -429,7 +440,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS dataSourceService.close(); } } - log.info(String.format("Import data%s", request.isAddReferential() ? " and referential." : ".")); + log.info("Import data" + (request.isAddReferential() ? " and referential." : ".")); topiaApplicationContext.executeSqlStatements(dataDump); } @@ -460,7 +471,8 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS @Override public ObserveDataSourceConnectionTopia open(ObserveDataSourceConfiguration dataSourceConfiguration) throws DatabaseNotFoundException, DatabaseConnexionNotAuthorizedException, BabModelVersionException { - + Path temporaryDirectory = getTemporaryDirectory(dataSourceConfiguration); + log.debug("Will use temporary directory: " + temporaryDirectory); ObserveDataSourceInformation dataSourceInformation = checkCanConnect(dataSourceConfiguration); Version dbVersion = dataSourceInformation.getVersion(); @@ -562,6 +574,9 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS @Override public void applySecurity(ObserveDataSourceConfiguration dataSourceConfiguration, ImmutableSet<ObserveDbUserDto> users) { + Path temporaryDirectory = getTemporaryDirectory(dataSourceConfiguration); + log.debug("Will use temporary directory: " + temporaryDirectory); + // pas de securité pour les bases autres que postgresql if (dataSourceConfiguration instanceof ObserveDataSourceConfigurationTopiaPG) { @@ -580,6 +595,9 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS @Override public void migrateData(ObserveDataSourceConfiguration dataSourceConfiguration) { + Path temporaryDirectory = getTemporaryDirectory(dataSourceConfiguration); + log.debug("Will use temporary directory: " + temporaryDirectory); + ObserveTopiaApplicationContext topiaApplicationContext = ObserveTopiaApplicationContextFactory.getOrCreateTopiaApplicationContext((ObserveDataSourceConfigurationTopiaSupport) dataSourceConfiguration); topiaApplicationContext.getMigrationService().runSchemaMigration(); } ===================================== services-local/src/test/java/fr/ird/observe/services/local/LocalTestClassResource.java ===================================== @@ -105,6 +105,7 @@ public class LocalTestClassResource extends TestClassResourceSupport { if (log.isInfoEnabled()) { log.info("Create shared database: " + dbVersion.toString() + "/" + dbName + " to " + sharedDatabaseFile); } + sharedDatabaseConfiguration.setTemporaryDirectory(getTemporaryDirectoryRoot()); try (DataSourceService dataSourceService = newService(sharedDatabaseConfiguration, DataSourceService.class)) { DataSourceCreateConfigurationDto createConfiguration = new DataSourceCreateConfigurationDto(); @@ -139,12 +140,14 @@ public class LocalTestClassResource extends TestClassResourceSupport { } dataSourceConfiguration.setModelVersion(ObserveTestConfiguration.getModelVersion()); + dataSourceConfiguration.setTemporaryDirectory(getTemporaryDirectoryRoot()); return dataSourceConfiguration; } public <S extends ObserveService> S newService(ObserveDataSourceConfiguration dataSourceConfiguration, Class<S> serviceType) { + dataSourceConfiguration.setTemporaryDirectory(getTemporaryDirectoryRoot()); ObserveServiceInitializer observeServiceInitializer = ObserveServiceInitializer.create( Locale.FRANCE, ReferentialLocale.FR, ===================================== services/src/main/java/fr/ird/observe/services/service/CleanTemporaryFilesTask.java ===================================== @@ -0,0 +1,119 @@ +package fr.ird.observe.services.service; + +/*- + * #%L + * ObServe :: Services API + * %% + * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Calendar; +import java.util.Date; +import java.util.Objects; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +/** + * To clean temporaries files. + * + * @author Tony Chemit - dev@tchemit.fr + * @since 8.0 + */ + +public class CleanTemporaryFilesTask extends TimerTask { + + private static final Logger log = LogManager.getLogger(CleanTemporaryFilesTask.class); + + private final CleanTemporaryFilesTaskConfiguration configuration; + + public static Timer create(CleanTemporaryFilesTaskConfiguration configuration) { + Timer result = new Timer("Delete temporary files daemon", true); + result.scheduleAtFixedRate(new CleanTemporaryFilesTask(configuration), new Date(), TimeUnit.HOURS.toMillis(1)); + return result; + } + + public CleanTemporaryFilesTask(CleanTemporaryFilesTaskConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public void run() { + + Path temporaryDirectory = configuration.getTemporaryDirectory().toPath(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(new Date()); + calendar.add(Calendar.HOUR_OF_DAY, -configuration.getTemporaryFilesTimeout()); + Date deleteBefore = calendar.getTime(); + long deleteBeforeTime = deleteBefore.getTime(); + + log.info(String.format("Delete temporary files in directory %s before %s", temporaryDirectory, deleteBefore)); + delete(temporaryDirectory, deleteBeforeTime); + } + + private boolean delete(Path path, long deleteBeforeTime) { + try { + Files.walk(path).forEach(p -> { + if (Objects.equals(path, p)) { + return; + } + if (Files.isDirectory(p)) { + boolean deleted = delete(p, deleteBeforeTime); + if (deleted) { + delete0(p, deleteBeforeTime); + } + } + if (Files.isRegularFile(p)) { + delete0(p, deleteBeforeTime); + } + }); + if (Files.isRegularFile(path)) { + return Files.notExists(path); + } + if (Files.isDirectory(path)) { + return isDirEmpty(path); + } + return false; + } catch (IOException e) { + throw new RuntimeException(String.format("Could not walk through temporary directory: %s", path), e); + } + } + + private static boolean isDirEmpty(final Path directory) throws IOException { + try(DirectoryStream<Path> dirStream = Files.newDirectoryStream(directory)) { + return !dirStream.iterator().hasNext(); + } + } + private void delete0(Path p, long deleteBeforeTime) { + try { + if (Files.getLastModifiedTime(p).toMillis() < deleteBeforeTime) { + log.info("Delete temporary file: " + p); + Files.delete(p); + } + } catch (IOException e) { + log.error("Something wrong while process file: " + p, e); + } + } +} ===================================== services/src/main/java/fr/ird/observe/services/service/CleanTemporaryFilesTaskConfiguration.java ===================================== @@ -0,0 +1,40 @@ +package fr.ird.observe.services.service; + +/*- + * #%L + * ObServe :: Services API + * %% + * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import java.io.File; + +/** + * @author Tony Chemit - dev@tchemit.fr + * @since 7.5.1 + */ +public interface CleanTemporaryFilesTaskConfiguration { + + File getTemporaryDirectory(); + + void setTemporaryDirectory(File temporaryDirectory); + + int getTemporaryFilesTimeout(); + + void setTemporaryFilesTimeout(int temporaryFilesTimeout); +} View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/ae6dc3197bb87eab35ec106cbb... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/ae6dc3197bb87eab35ec106cbb... You're receiving this email because of your account on gitlab.com.