[Git][ultreiaio/ird-observe][develop] Accumulation de fichiers - Closes #1462
Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 31be83c4 by tchemit at 2020-04-14T00:49:37+02:00 Accumulation de fichiers - Closes #1462 - - - - - 26 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/ClientUIContext.java - client-core/src/main/java/fr/ird/observe/client/ObserveSwingApplicationContext.java - client-core/src/main/java/fr/ird/observe/client/datasource/api/ObserveDataSourcesManager.java - client-core/src/main/java/fr/ird/observe/client/datasource/api/ObserveSwingDataSource.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/entities/AbstractObserveTopiaDao.java - − persistence/src/main/java/fr/ird/observe/entities/ObserveTopiaConfiguration.java - − persistence/src/main/java/fr/ird/observe/entities/ObserveTopiaConfigurationFactory.java - persistence/src/test/java/fr/ird/observe/persistence/ObserveTopiaApplicationContextTest.java → persistence/src/test/java/fr/ird/observe/entities/ObserveTopiaApplicationContextTest.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 - persistence/src/main/java/fr/ird/observe/entities/ObserveTopiaIdFactory.java → services/src/main/java/fr/ird/observe/services/service/CleanTemporaryFilesTaskConfiguration.java Changes: ===================================== client-configuration/src/main/config/Client.ini ===================================== @@ -146,8 +146,16 @@ defaultValue = ${dcp.presets.directory}/ps/logbook transient = true final = true +[option temporaryDirectory] +description = observe.config.temporaryDirectory.description +key = temporary.directory +type = file +defaultValue = ${data.directory}/tmp +transient = true +final = true + [option tmpDirectory] -description = observe.config.defaultTmpDirectory.description +description = observe.config.temporaryDirectory.description key = tmp.directory type = file defaultValue = ${data.directory}/tmp @@ -717,6 +725,12 @@ key = ui.seineBycatchObservedSystem type = fr.ird.observe.validation.SeineBycatchObservedSystemConfig defaultValue = {\"fr.ird.referential.common.Species#1239832684290#0.04680507324710936\": [\"fr.ird.referential.ps.observation.ObservedSystem#0#1.0\",\"fr.ird.referential.ps.observation.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 ===================================== @@ -33,7 +33,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.h2.can.editReferential.description observe.config.h2.can.migrate.description @@ -91,6 +90,8 @@ observe.config.speciesList.seine.observation.schoolEstimate observe.config.speciesList.seine.observation.targetCatch observe.config.swingSessionFile.description observe.config.temperature.format +observe.config.temporaryDirectory.description +observe.config.temporaryFilesTimeout.description observe.config.ui.autoPopupNumberEditor observe.config.ui.blockStateColor observe.config.ui.busyStateColor ===================================== client-configuration/src/main/java/fr/ird/observe/client/configuration/ClientConfig.java ===================================== @@ -35,6 +35,7 @@ import fr.ird.observe.dto.referential.ReferentialLocale; import fr.ird.observe.gson.ObserveDtoGsonSupplier; import fr.ird.observe.navigation.model.edit.ObserveEditModel; import fr.ird.observe.navigation.model.select.ObserveSelectModel; +import fr.ird.observe.services.service.CleanTemporaryFilesTaskConfiguration; import io.ultreia.java4all.application.context.spi.ApplicationComponentInstantiateStrategy; import io.ultreia.java4all.application.context.spi.GenerateApplicationComponent; import io.ultreia.java4all.application.template.TemplateGeneratorConfig; @@ -92,12 +93,13 @@ import static io.ultreia.java4all.i18n.I18n.t; hints = { TemplateGeneratorConfig.class, ObServeSwingSessionConfig.class, - ReferentialLocaleConfig.class}, + ReferentialLocaleConfig.class, + CleanTemporaryFilesTaskConfiguration.class}, instantiateStrategy = ApplicationComponentInstantiateStrategy.SUPPLIER, instantiateSupplier = ClientConfigFinder.class ) @GenerateTemplate(template = "about.ftl") -public class ClientConfig extends GeneratedClientConfig implements TemplateGeneratorConfig, ObServeSwingSessionConfig, ReferentialLocaleConfig, NavigationTreeConfig { +public class ClientConfig extends GeneratedClientConfig implements TemplateGeneratorConfig, ObServeSwingSessionConfig, ReferentialLocaleConfig, NavigationTreeConfig, CleanTemporaryFilesTaskConfiguration { public static final String DB_NAME = "obstuna"; public static final List<ClientConfigOption> MAP_LAYERS = ImmutableList.of( @@ -266,7 +268,7 @@ public class ClientConfig extends GeneratedClientConfig implements TemplateGener resourceManager.createDirectory(this, ClientConfigOption.TMP_DIRECTORY); // suppression du contenu du répertoire temporaire - FileUtils.cleanDirectory(this.getTmpDirectory()); + FileUtils.cleanDirectory(this.getTemporaryDirectory()); // 3 - backup directory ===================================== client-core/src/main/java/fr/ird/observe/client/ClientUIContext.java ===================================== @@ -34,6 +34,7 @@ import fr.ird.observe.dto.IdDto; import fr.ird.observe.dto.decoration.DecoratorService; import fr.ird.observe.dto.decoration.DecoratorServiceApplicationComponent; import fr.ird.observe.dto.decoration.ObserveI18nDecoratorHelper; +import fr.ird.observe.services.service.CleanTemporaryFilesTask; import io.ultreia.java4all.application.context.ApplicationContext; import io.ultreia.java4all.application.context.spi.GenerateApplicationComponent; import io.ultreia.java4all.i18n.I18n; @@ -57,9 +58,11 @@ import java.awt.event.ComponentEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeListener; +import java.io.Closeable; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Timer; import static io.ultreia.java4all.i18n.I18n.t; import static javax.swing.JOptionPane.CLOSED_OPTION; @@ -71,7 +74,7 @@ import static javax.swing.JOptionPane.VALUE_PROPERTY; ObserveSwingSessionHelper.class, ActionExecutor.class }) -public class ClientUIContext { +public class ClientUIContext implements Closeable { private static final Logger log = LogManager.getLogger(ClientUIContext.class); @@ -81,7 +84,9 @@ public class ClientUIContext { private final ActionExecutor actionExecutor; private ObserveMainUI mainUI; private ObserveUICallbackManager uiCallbackManager; + private Timer deleteTemporaryFilesTimer; private final BusyModel busyModel; + public ClientUIContext(DecoratorService decoratorService, ClientConfig clientConfig, ObserveSwingSessionHelper observeSwingSessionHelper, ActionExecutor actionExecutor) { this.decoratorService = decoratorService; this.clientConfig = clientConfig; @@ -90,6 +95,13 @@ public class ClientUIContext { this.busyModel = new BusyModel(); } + public void initDeleteTemporaryFilesTimer() { + if (deleteTemporaryFilesTimer != null) { + closeDeleteTemporaryFilesTimer(); + } + deleteTemporaryFilesTimer = CleanTemporaryFilesTask.create(getClientConfig()); + } + public static void displayInfo(String text) { JFrame ui = ClientUIContextApplicationComponent.value().getMainUI(); if (ui == null) { @@ -365,7 +377,9 @@ public class ClientUIContext { return observeSwingSessionHelper; } + @Override public void close() { + closeDeleteTemporaryFilesTimer(); mainUI = null; } @@ -464,4 +478,16 @@ public class ClientUIContext { public BusyModel getBusyModel() { return busyModel; } + + + void closeDeleteTemporaryFilesTimer() { + if (deleteTemporaryFilesTimer != null) { + try { + deleteTemporaryFilesTimer.cancel(); + } catch (Exception e) { + log.error("Could not terminates delete temporary files timer...", e); + } + } + } + } ===================================== client-core/src/main/java/fr/ird/observe/client/ObserveSwingApplicationContext.java ===================================== @@ -22,6 +22,7 @@ package fr.ird.observe.client; import fr.ird.observe.client.configuration.ClientConfig; +import fr.ird.observe.client.configuration.ClientConfigApplicationComponent; import fr.ird.observe.services.ObserveServiceMainFactory; import fr.ird.observe.services.ObserveServiceMainFactoryApplicationComponent; import fr.ird.observe.spi.DtoModelHelper; @@ -53,9 +54,12 @@ public class ObserveSwingApplicationContext extends ApplicationContext { //FIXME Je ne comprends pas pourquoi cela ne fonctionne plus. // config.get().setOption("user.home", SystemUtils.USER_HOME); - log.debug("Init model helper: " + DtoModelHelper.class); + log.debug(String.format("Init model helper: %s", DtoModelHelper.class)); ObserveServiceMainFactory serviceMainFactory = ObserveServiceMainFactoryApplicationComponent.value(); - log.info("Initialize services factory: " + serviceMainFactory); + log.info(String.format("Initialize services factory: %s", serviceMainFactory)); + ClientUIContext clientUIContext = ClientUIContextApplicationComponent.value(); + log.info("Initialize delete temporary files task."); + clientUIContext.initDeleteTemporaryFilesTimer(); } // We put here the i18n keys from the client-runner module, otherwise we need yet another module before observe-i18n ===================================== client-core/src/main/java/fr/ird/observe/client/datasource/api/ObserveDataSourcesManager.java ===================================== @@ -126,7 +126,7 @@ public class ObserveDataSourcesManager implements Closeable { public ObserveSwingDataSource newTemporaryH2DataSource(String label) { - 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/datasource/api/ObserveSwingDataSource.java ===================================== @@ -482,7 +482,7 @@ public class ObserveSwingDataSource extends ObserveServicesProviderSupport { Locale locale = config.getLocale(); - File tmpDirectory = config.getTmpDirectory(); + File tmpDirectory = config.getTemporaryDirectory(); ReferentialLocale referentialLocale = ReferentialLocale.valueOf(locale); ===================================== observe-i18n/src/main/i18n/translations/observe_en_GB.properties ===================================== @@ -482,7 +482,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 @@ -542,6 +541,8 @@ observe.config.speciesList.seine.observation.schoolEstimate=Species for school e observe.config.speciesList.seine.observation.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.blockStateColor=Color of block state observe.config.ui.busyStateColor=Color of busy state @@ -3519,7 +3520,7 @@ observeweb.devMode.description=Dev mode observeweb.host.description=Application host observeweb.httpTimeout.description=Http timeout in milli seconds observeweb.log4jConfigurationFile.description=Path to log configuration file -observeweb.sessionExpirationDelay.description=Session expiration deplay (in minutes) +observeweb.sessionExpirationDelay.description=Session expiration delay (in minutes) observeweb.sessionMaximumSize.description=Session maximum size observeweb.temporaryDirectory.description=Path to temporary directory observeweb.usersConfigurationFile.description=Path to users configuration file ===================================== observe-i18n/src/main/i18n/translations/observe_es_ES.properties ===================================== @@ -482,7 +482,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 @@ -542,6 +541,8 @@ observe.config.speciesList.seine.observation.schoolEstimate=Especies para las es observe.config.speciesList.seine.observation.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.blockStateColor=Color of block state \#TODO observe.config.ui.busyStateColor=Color of busy state \#TODO ===================================== observe-i18n/src/main/i18n/translations/observe_fr_FR.properties ===================================== @@ -482,7 +482,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 @@ -542,6 +541,8 @@ observe.config.speciesList.seine.observation.schoolEstimate=Espèces pour les es observe.config.speciesList.seine.observation.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.blockStateColor=Couleur lorsque l'on bloque une partie de l'application observe.config.ui.busyStateColor=Couleur lorsque l'application est occupée ===================================== persistence/src/main/java/fr/ird/observe/entities/AbstractObserveTopiaDao.java deleted ===================================== @@ -1,76 +0,0 @@ -package fr.ird.observe.entities; - -/* - * #%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.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 Entity> 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(" + Entity.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/entities/ObserveTopiaConfiguration.java deleted ===================================== @@ -1,84 +0,0 @@ -package fr.ird.observe.entities; - -/* - * #%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/entities/ObserveTopiaConfigurationFactory.java deleted ===================================== @@ -1,143 +0,0 @@ -package fr.ird.observe.entities; - -/* - * #%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/test/java/fr/ird/observe/persistence/ObserveTopiaApplicationContextTest.java → persistence/src/test/java/fr/ird/observe/entities/ObserveTopiaApplicationContextTest.java ===================================== @@ -1,4 +1,4 @@ -package fr.ird.observe.persistence; +package fr.ird.observe.entities; /*- * #%L @@ -22,9 +22,6 @@ package fr.ird.observe.persistence; * #L% */ -import fr.ird.observe.entities.ObserveTopiaApplicationContext; -import fr.ird.observe.entities.ObserveTopiaConfiguration; -import fr.ird.observe.entities.ObserveTopiaConfigurationFactory; import fr.ird.observe.test.TestHelper; import fr.ird.observe.test.TestSupportWithConfig; import org.junit.Assert; @@ -46,7 +43,7 @@ public class ObserveTopiaApplicationContextTest extends TestSupportWithConfig { File testBasedir = TestHelper.getTestBasedir(getClass()); - ObserveTopiaConfiguration observeTopiaConfiguration = ObserveTopiaConfigurationFactory.forH2Database(testBasedir, "testReplicateModel", "sa", "sa", true, false); + ObserveTopiaConfiguration observeTopiaConfiguration = ObserveTopiaConfigurationFactory.forH2Database(testBasedir, "testReplicateModel", "sa", "sa", testBasedir.toPath().resolve("temporary"), true, false); try (ObserveTopiaApplicationContext applicationContext = new ObserveTopiaApplicationContext(observeTopiaConfiguration)) { TopiaSqlTables tripLonglineTables = applicationContext.getTripLonglineTables(); Assert.assertNotNull(tripLonglineTables); ===================================== pom.xml ===================================== @@ -24,7 +24,7 @@ <parent> <groupId>io.ultreia.maven</groupId> <artifactId>pom</artifactId> - <version>2020.15</version> + <version>2020.17</version> </parent> <groupId>fr.ird.observe</groupId> @@ -162,7 +162,7 @@ <maven.build.timestamp.format>dd/MM/yyyy HH:mm z</maven.build.timestamp.format> <buildDate>${maven.build.timestamp}</buildDate> - <lib.version.toolkit>4.27</lib.version.toolkit> + <lib.version.toolkit>4.28</lib.version.toolkit> <lib.version.nuiton.validation>3.1</lib.version.nuiton.validation> <!--can't use 1.4.197 (date has changed + blob also)--> <lib.version.h2>1.4.196</lib.version.h2> @@ -176,7 +176,7 @@ <!--<lib.version.java4all.i18n>4.0-beta-3-SNAPSHOT</lib.version.java4all.i18n>--> <!--<lib.version.java4all.config>1.0.8-SNAPSHOT</lib.version.java4all.config>--> <!--<lib.version.nuiton.topia>3.4.2-SNAPSHOT</lib.version.nuiton.topia>--> - <!--<lib.version.java4all.topia>1.14</lib.version.java4all.topia>--> +<!-- <lib.version.java4all.topia>1.19-SNAPSHOT</lib.version.java4all.topia>--> <!--<lib.version.java4all.http>1.0.17-SNAPSHOT</lib.version.java4all.http>--> <!-- license header configuration --> ===================================== server-configuration/pom.xml ===================================== @@ -48,7 +48,11 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> - + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>services</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>io.ultreia.java4all</groupId> <artifactId>application-context</artifactId> ===================================== server-configuration/src/main/config/Server.ini ===================================== @@ -103,3 +103,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.baseDirectory.description ===================================== server-configuration/src/main/java/fr/ird/observe/server/configuration/ServerConfig.java ===================================== @@ -24,6 +24,7 @@ package fr.ird.observe.server.configuration; import fr.ird.observe.dto.ObserveUtil; import fr.ird.observe.dto.decoration.ReferentialLocaleConfig; +import fr.ird.observe.services.service.CleanTemporaryFilesTaskConfiguration; import io.ultreia.java4all.application.context.spi.GenerateApplicationComponent; import io.ultreia.java4all.application.template.TemplateGeneratorConfig; import io.ultreia.java4all.config.ApplicationConfig; @@ -46,8 +47,8 @@ import java.nio.file.Paths; * @author Tony Chemit - dev@tchemit.fr */ @GenerateApplicationComponent(name = "ObServe Web configuration", - hints = {TemplateGeneratorConfig.class, ReferentialLocaleConfig.class}) -public class ServerConfig extends GeneratedServerConfig { + hints = {TemplateGeneratorConfig.class, ReferentialLocaleConfig.class, CleanTemporaryFilesTaskConfiguration.class}) +public class ServerConfig extends GeneratedServerConfig implements CleanTemporaryFilesTaskConfiguration { private static Logger log = LogManager.getLogger(ServerConfig.class); ===================================== server-core/src/main/java/fr/ird/observe/server/ObserveWebApplicationContext.java ===================================== @@ -43,6 +43,7 @@ import fr.ird.observe.server.configuration.user.ObserveWebUsersHelperApplication import fr.ird.observe.server.configuration.user.impl.ObserveWebUsersImmutable; import fr.ird.observe.server.security.ObserveWebSecurityApplicationContext; import fr.ird.observe.server.security.ObserveWebSecurityApplicationContextApplicationComponent; +import fr.ird.observe.services.service.CleanTemporaryFilesTask; import fr.ird.observe.services.ObserveServiceFactory; import fr.ird.observe.services.ObserveServiceInitializer; import fr.ird.observe.services.ObserveServiceMainFactoryApplicationComponent; @@ -51,11 +52,14 @@ import fr.ird.observe.services.service.ObserveService; import fr.ird.observe.services.service.actions.consolidate.dcp.FloatingObjectModification; import io.ultreia.java4all.application.context.ApplicationComponent; import io.ultreia.java4all.application.context.ApplicationContext; +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.util.Map; +import java.util.Timer; /** * @author Tony Chemit - dev@tchemit.fr @@ -67,6 +71,8 @@ public class ObserveWebApplicationContext extends ApplicationContext { private static final String MISSING_APPLICATION_CONTEXT = String.format("%s not found. You probably forgot to register %s in your web.xml", ObserveWebApplicationContext.class.getSimpleName(), ObserveWebApplicationListener.class.getName()); + private static final Logger log = LogManager.getLogger(ObserveWebApplicationContext.class); + private ObserveDtoGsonSupplier gsonSupplier; private ServerConfig applicationConfiguration; private ObserveServiceFactory mainServiceFactory; @@ -75,6 +81,7 @@ public class ObserveWebApplicationContext extends ApplicationContext { private ObserveWebSecurityApplicationContext securityApplicationContext; private static ServerConfig applicationConfiguration1; + private Timer deleteTemporaryFilesTimer; static ObserveWebApplicationContext getApplicationContext(HttpContext context) { @@ -153,18 +160,26 @@ public class ObserveWebApplicationContext extends ApplicationContext { } }; } + if (deleteTemporaryFilesTimer != null) { + closeDeleteTemporaryFilesTimer(); + } + deleteTemporaryFilesTimer = CleanTemporaryFilesTask.create(getApplicationConfiguration()); + } + + @Override + public void close() { + + closeDeleteTemporaryFilesTimer(); + super.close(); } -// @Override -// public void close() { -// -// // Supprimer le cache des sessions -// securityApplicationContext.close(); -// -// // Fermer l'usine de services -// 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,13 +27,13 @@ import fr.ird.observe.dto.ObserveDbRole; import fr.ird.observe.dto.db.ObserveDbUserDto; import fr.ird.observe.entities.Entities; import fr.ird.observe.entities.ObserveTopiaApplicationContext; +import fr.ird.observe.entities.ObserveTopiaConfiguration; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.nuiton.topia.migration.mappings.TMSVersionHibernateDao; import org.nuiton.topia.persistence.TopiaEntityEnum; import org.nuiton.topia.persistence.TopiaException; -import org.nuiton.topia.persistence.jdbc.JdbcConfiguration; import org.nuiton.topia.persistence.jdbc.JdbcPostgresHelper; import org.nuiton.topia.persistence.script.SqlScriptConsumer; import org.nuiton.topia.persistence.script.SqlScriptWriter; @@ -81,10 +81,12 @@ public class ObserveSecurityHelper { private static final String SCHEMA_PUBLIC = "public"; 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) { @@ -93,7 +95,7 @@ public class ObserveSecurityHelper { } 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 ===================================== @@ -150,6 +150,7 @@ public class ObserveTopiaApplicationContextFactory { configuration.getJdbcUrl(), configuration.getUsername(), String.valueOf(configuration.getPassword()), + configuration.getTemporaryDirectory(), initSchema, configuration.isTraceSql() ); @@ -175,6 +176,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 ===================================== @@ -69,6 +69,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; @@ -108,6 +109,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS public ObserveDataSourceInformation checkCanConnectOrBeEmpty(ObserveDataSourceConfiguration dataSourceConfiguration) throws DatabaseNotFoundException, DatabaseConnexionNotAuthorizedException { ObserveDataSourceConfigurationTopiaSupport dataSourceConfigurationTopiaSupport = (ObserveDataSourceConfigurationTopiaSupport) dataSourceConfiguration; + Path temporaryDirectory = serviceContext.getTemporaryDirectoryRoot().toPath(); ObserveDataSourceInformation dataSourceInformation; if (dataSourceConfigurationTopiaSupport.isH2Database()) { @@ -141,7 +143,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS h2DataSourceConfiguration.getDbName(), h2DataSourceConfiguration.getUsername(), new String(h2DataSourceConfiguration.getPassword()), - false, + temporaryDirectory, false, false); @@ -165,7 +167,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 { @@ -188,6 +190,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS @Override public ObserveDataSourceInformation checkCanConnect(ObserveDataSourceConfiguration dataSourceConfiguration) throws DatabaseNotFoundException, DatabaseConnexionNotAuthorizedException { + Path temporaryDirectory = getTemporaryDirectory(dataSourceConfiguration); ObserveDataSourceConfigurationTopiaSupport dataSourceConfigurationTopiaSupport = (ObserveDataSourceConfigurationTopiaSupport) dataSourceConfiguration; ObserveDataSourceInformation dataSourceInformation; @@ -223,6 +226,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS h2DataSourceConfiguration.getDbName(), h2DataSourceConfiguration.getUsername(), new String(h2DataSourceConfiguration.getPassword()), + temporaryDirectory, false, false); @@ -247,6 +251,7 @@ public class DataSourceServiceLocal extends ObserveServiceLocal implements DataS ObserveTopiaConfiguration topiaConfiguration = ObserveTopiaConfigurationFactory.forPostgresqlDatabase(pgDataSourceConfiguration.getJdbcUrl(), pgDataSourceConfiguration.getUsername(), new String(pgDataSourceConfiguration.getPassword()), + temporaryDirectory, false, false); @@ -266,13 +271,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); @@ -291,10 +305,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); } @@ -455,7 +468,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(); @@ -557,6 +571,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) { @@ -575,6 +592,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 ===================================== @@ -90,7 +90,6 @@ public class LocalTestClassResource extends TestClassResourceSupport { public ObserveDataSourceConfigurationTopiaH2 createDataSourceConfiguration(Version dbVersion, String dbName, File targetPath, String login, char[] password) throws DataSourceCreateWithNoReferentialImportException, IOException, IncompatibleDataSourceCreateConfigurationException, DatabaseNotFoundException, DatabaseConnexionNotAuthorizedException, BabModelVersionException { ObserveDataSourceConfigurationTopiaH2 sharedDatabaseConfiguration = dataSourcesForTestManager.createSharedDataSourceConfigurationH2(dbVersion, dbName, login, password); - File sharedDatabaseFile = sharedDatabaseConfiguration.getDatabaseFile(); ObserveDataSourceConfigurationTopiaH2 dataSourceConfiguration; @@ -101,6 +100,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(); @@ -135,12 +135,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,120 @@ +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 io.ultreia.java4all.util.Dates; +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); + } + } +} ===================================== persistence/src/main/java/fr/ird/observe/entities/ObserveTopiaIdFactory.java → services/src/main/java/fr/ird/observe/services/service/CleanTemporaryFilesTaskConfiguration.java ===================================== @@ -1,8 +1,8 @@ -package fr.ird.observe.entities; +package fr.ird.observe.services.service; -/* +/*- * #%L - * ObServe :: Persistence + * ObServe :: Services API * %% * Copyright (C) 2008 - 2020 IRD, Code Lutin, Ultreia.io * %% @@ -22,17 +22,19 @@ package fr.ird.observe.entities; * #L% */ +import java.io.File; + /** - * Created on 21/08/15. - * * @author Tony Chemit - dev@tchemit.fr + * @since 8.0 */ -public class ObserveTopiaIdFactory extends ObserveTopiaIdFactorySupport { +public interface CleanTemporaryFilesTaskConfiguration { + + File getTemporaryDirectory(); - private static final long serialVersionUID = 1L; + void setTemporaryDirectory(File temporaryDirectory); - public ObserveTopiaIdFactory() { - super("fr.ird.observe.entities."); - } + int getTemporaryFilesTimeout(); + void setTemporaryFilesTimeout(int temporaryFilesTimeout); } View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/31be83c4c1554f685caa5ee47c... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/31be83c4c1554f685caa5ee47c... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT