Commit 5b549d65 authored by LAVENIER's avatar LAVENIER
Browse files

[enh] Migrate to ehcache 3.8

[fix] Data: Add product frequencies in test DB
parent 01e0baa5
......@@ -113,21 +113,21 @@
<hibernate-search.version>5.11.8.Final</hibernate-search.version>
<hibernate-spatial.version>5.4.27.Final</hibernate-spatial.version>
<hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
<spring.version>5.2.13.RELEASE</spring.version>
<spring-web.version>5.2.13.RELEASE</spring-web.version>
<spring-data.version>2.3.7.RELEASE</spring-data.version>
<spring.version>5.3.6</spring.version>
<spring-web.version>5.3.6</spring-web.version>
<spring-data.version>2.5.0</spring-data.version>
<querydsl.version>4.2.2</querydsl.version>
<aspectj.version>1.9.6</aspectj.version>
<javassist.version>3.27.0-GA</javassist.version>
<cglib.version>3.3.0</cglib.version>
<ehcache.version>2.10.6</ehcache.version>
<ehcache.version>3.8.1</ehcache.version>
<ehcache-monitor.version>2.7.11</ehcache-monitor.version>
<lombok.version>1.18.20</lombok.version>
<xmlquery.version>1.2</xmlquery.version>
<jdom2.version>2.0.6</jdom2.version>
<jaxen.version>1.2.0</jaxen.version>
<spring-boot.version>2.3.9.RELEASE</spring-boot.version>
<spring-boot-plugin.version>2.3.9.RELEASE</spring-boot-plugin.version>
<spring-boot.version>2.4.5</spring-boot.version>
<spring-boot-plugin.version>2.4.5</spring-boot-plugin.version>
<ozimov-email.version>0.6.3</ozimov-email.version>
<reflections.version>0.9.12</reflections.version>
<rxjava2.version>2.2.21</rxjava2.version>
......@@ -138,10 +138,10 @@
<!--<kalium.version>0.8.1-SNAPSHOT</kalium.version>-->
<scrypt.version>1.4.0</scrypt.version>
<geojson-jackson.version>1.14</geojson-jackson.version>
<graphql-java.version>13.0</graphql-java.version>
<graphql-java-tools.version>6.1.0</graphql-java-tools.version>
<graphql-java-servlet.version>9.2.0</graphql-java-servlet.version>
<spqr.version>0.10.1</spqr.version>
<graphql-java.version>16.2</graphql-java.version>
<graphql-java-tools.version>11.0.1</graphql-java-tools.version>
<graphql-java-servlet.version>11.1.0</graphql-java-servlet.version>
<spqr.version>0.11.2</spqr.version>
<kotlin.version>1.3.70</kotlin.version>
<!-- database version management -->
......@@ -368,7 +368,7 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
......@@ -618,22 +618,8 @@
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<artifactId>hibernate-jcache</artifactId>
<version>${hibernate.version}</version>
<exclusions>
<exclusion>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</exclusion>
<exclusion>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
......@@ -675,11 +661,18 @@
<artifactId>hibernate-envers</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- EhCache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.1</version>
</dependency>
<!-- XML Query -->
<dependency>
......
......@@ -51,8 +51,7 @@ logging.level.net.sumaris.core.extraction=debug
logging.level.org.springframework=warn
logging.level.org.nuiton=warn
logging.level.org.nuiton.i18n=error
logging.level.net.sf.ehcache=warn
logging.level.net.sf.ehcache.hibernate=info
logging.level.org.ehcache=warn
logging.level.org.apache.commons.beanutils=warn
logging.level.org.apache.jena=warn
logging.level.org.hibernate=warn
......
......@@ -78,7 +78,6 @@ public class AgggregationAction {
log.info("Starting {} aggregation {{}}...",
StringUtils.capitalize(type.getCategory().name().toLowerCase()),
type.getLabel());
ActionUtils.logConnectionProperties();
}
}
......@@ -35,6 +35,7 @@ import net.sumaris.core.model.technical.extraction.IExtractionFormat;
import net.sumaris.core.service.ServiceLocator;
import net.sumaris.core.util.Files;
import net.sumaris.core.util.StringUtils;
import net.sumaris.core.util.TimeUtils;
import java.io.File;
import java.io.IOException;
......@@ -65,13 +66,12 @@ public class ExtractionAction {
log.info("Starting {} extraction {{}}...",
StringUtils.capitalize(format.getCategory().name().toLowerCase()),
format.getLabel());
ActionUtils.logConnectionProperties();
// Check output file
File outputFile = ActionUtils.checkAndGetOutputFile(false, ExtractionAction.class);
// Execute the extraction
long now = System.currentTimeMillis();
long startTime = System.currentTimeMillis();
File tempFile;
try {
ExtractionTypeVO type = service.getByFormat(format);
......@@ -88,15 +88,18 @@ public class ExtractionAction {
// Move temp file to expected output file
try {
Files.moveFile(tempFile, outputFile);
log.info("{} extraction {{}} finished, in {}s - output file: {}",
StringUtils.capitalize(format.getCategory().name().toLowerCase()),
format.getLabel(),
(System.currentTimeMillis() - now) / 1000,
outputFile.getAbsolutePath());
}
catch (IOException e) {
log.error("Error while creating output file: " + e.getMessage(), e);
return;
}
// Success log
log.info("{} extraction {{}} finished, in {} - output: {}",
StringUtils.capitalize(format.getCategory().name().toLowerCase()),
format.getLabel(),
TimeUtils.printDurationFrom(startTime),
outputFile.getAbsolutePath());
}
}
......@@ -68,7 +68,6 @@ public class ProductAction {
long now = System.currentTimeMillis();
log.info("Updating products... {frequency: '{}'}", frequency);
ActionUtils.logConnectionProperties();
// Get products to refresh
List<ExtractionProductVO> products = productService.findByFilter(ExtractionProductFilterVO.builder()
......
......@@ -19,43 +19,36 @@
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
package net.sumaris.core.extraction.cache;
package net.sumaris.core.extraction.config;
import net.sf.ehcache.CacheManager;
import net.sumaris.core.dao.cache.CacheConfiguration;
import net.sumaris.core.dao.technical.ehcache.Caches;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
import net.sumaris.core.config.CacheConfiguration;
import net.sumaris.core.dao.technical.cache.CacheDurations;
import net.sumaris.core.dao.technical.cache.Caches;
import net.sumaris.core.extraction.vo.AggregationTypeVO;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cache.ehcache.EhCacheFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnBean({CacheConfiguration.class})
@AutoConfigureAfter({CacheConfiguration.class})
@ConditionalOnBean({ExtractionAutoConfiguration.class})
@Slf4j
public class ExtractionCacheConfiguration {
/**
* Logger.
*/
protected static final Logger log =
LoggerFactory.getLogger(ExtractionCacheConfiguration.class);
protected CacheManager cacheManager;
@Autowired
protected ExtractionCacheConfiguration(CacheConfiguration cacheConfiguration) {
this.cacheManager = cacheConfiguration.getCacheManager();
log.info("Adding {Extraction} caches...");
}
@Bean
public EhCacheFactoryBean aggregationTypeById() {
return Caches.createHeapCache(cacheManager, ExtractionCacheNames.AGGREGATION_TYPE_BY_ID, 1500, 1500, 100);
public interface Names {
String AGGREGATION_TYPE_BY_ID = "net.sumaris.core.extraction.service.aggregationTypeById";
String AGGREGATION_TYPE_BY_FORMAT = "net.sumaris.core.extraction.service.aggregationTypeByFormat";
}
@Bean
public EhCacheFactoryBean aggregationTypeByFormat() {
return Caches.createHeapCache(cacheManager, ExtractionCacheNames.AGGREGATION_TYPE_BY_FORMAT, 60*10000, 60*1000, 100);
public JCacheManagerCustomizer extractionCacheCustomizer() {
return cacheManager -> {
log.info("Adding {Extraction} caches...");
Caches.createHeapCache(cacheManager, Names.AGGREGATION_TYPE_BY_ID, Integer.class, AggregationTypeVO.class, CacheDurations.DEFAULT, 100);
Caches.createHeapCache(cacheManager, Names.AGGREGATION_TYPE_BY_FORMAT, String.class, AggregationTypeVO.class, CacheDurations.DEFAULT, 100);
};
}
}
\ No newline at end of file
......@@ -34,6 +34,7 @@ import net.sumaris.core.extraction.vo.administration.ExtractionStrategyFilterVO;
import net.sumaris.core.util.Beans;
import net.sumaris.core.util.Dates;
import net.sumaris.core.util.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import java.util.Arrays;
......@@ -110,6 +111,12 @@ public interface ExtractionStrategyDao<C extends ExtractionStrategyContextVO, F
}
}
});
// Clean criteria, to avoid reapply on cleanRow
if (CollectionUtils.size(source.getCriteria()) == 1 && CollectionUtils.isNotEmpty(target.getStrategyIds())) {
source.getCriteria().clear();
}
return target;
}
......
......@@ -31,6 +31,7 @@ import net.sumaris.core.extraction.dao.technical.ExtractionBaseDaoImpl;
import net.sumaris.core.extraction.dao.technical.XMLQuery;
import net.sumaris.core.extraction.format.LiveFormatEnum;
import net.sumaris.core.extraction.specification.administration.StratSpecification;
import net.sumaris.core.extraction.vo.ExtractionFilterCriterionVO;
import net.sumaris.core.extraction.vo.ExtractionFilterVO;
import net.sumaris.core.extraction.vo.administration.ExtractionStrategyContextVO;
import net.sumaris.core.extraction.vo.administration.ExtractionStrategyFilterVO;
......
......@@ -208,7 +208,7 @@ public abstract class ExtractionBaseDaoImpl extends HibernateDaoSupport {
protected <F extends ExtractionFilterVO> int cleanRow(String tableName, F filter, String sheetName) {
Preconditions.checkNotNull(tableName);
if (filter == null) return 0;
if (filter == null || CollectionUtils.isEmpty(filter.getCriteria())) return 0;
SumarisTableMetadata table = databaseMetadata.getTable(tableName.toLowerCase());
Preconditions.checkNotNull(table);
......
......@@ -191,9 +191,11 @@ public class ExtractionPmfmTripDaoImpl<C extends ExtractionRdbTripContextVO, F e
xmlQuery.bind("pmfmId" + pmfm.getAlias(), String.valueOf(pmfm.getPmfmId()));
xmlQuery.bind("pmfmLabel" + pmfm.getAlias(), pmfm.getLabel());
// ForDisable groups of unused pmfm type
// Disable groups of unused pmfm type
for (PmfmValueType enumType: PmfmValueType.values()) {
xmlQuery.setGroup(enumType.name().toLowerCase() + pmfm.getAlias(), enumType == pmfm.getType());
if (enumType != pmfm.getType()) {
xmlQuery.setGroup(enumType.name().toLowerCase() + pmfm.getAlias(), false);
}
}
}
}
......@@ -31,7 +31,7 @@ import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import net.sumaris.core.dao.technical.SortDirection;
import net.sumaris.core.exception.SumarisTechnicalException;
import net.sumaris.core.extraction.cache.ExtractionCacheNames;
import net.sumaris.core.extraction.config.ExtractionCacheConfiguration;
import net.sumaris.core.extraction.dao.technical.table.ExtractionTableColumnOrder;
import net.sumaris.core.extraction.dao.technical.table.ExtractionTableDao;
import net.sumaris.core.extraction.dao.trip.rdb.AggregationRdbTripDao;
......@@ -115,14 +115,14 @@ public class AggregationServiceImpl implements AggregationService {
}
@Override
@Cacheable(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_ID)
@Cacheable(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_ID)
public AggregationTypeVO getTypeById(int id, ExtractionProductFetchOptions fetchOptions) {
ExtractionProductVO source = productService.get(id, fetchOptions);
return toAggregationType(source);
}
@Override
@Cacheable(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_FORMAT,
@Cacheable(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_FORMAT,
key = "#format.category + #format.label + #format.version",
condition = " #format != null", unless = "#result == null")
public AggregationTypeVO getTypeByFormat(IExtractionFormat format) {
......@@ -297,8 +297,8 @@ public class AggregationServiceImpl implements AggregationService {
@Override
@Caching(
evict = {
@CacheEvict(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_ID, allEntries = true),
@CacheEvict(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_FORMAT, allEntries = true)
@CacheEvict(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_ID, allEntries = true),
@CacheEvict(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_FORMAT, allEntries = true)
}
)
public CompletableFuture<AggregationTypeVO> asyncSave(AggregationTypeVO type, @Nullable ExtractionFilterVO filter) {
......@@ -348,8 +348,8 @@ public class AggregationServiceImpl implements AggregationService {
@Override
@Caching(
evict = {
@CacheEvict(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_ID, allEntries = true),
@CacheEvict(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_FORMAT, allEntries = true)
@CacheEvict(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_ID, allEntries = true),
@CacheEvict(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_FORMAT, allEntries = true)
}
)
public AggregationTypeVO save(AggregationTypeVO source, @Nullable ExtractionFilterVO filter) {
......
......@@ -22,23 +22,13 @@ package net.sumaris.core.extraction.service;
* #L%
*/
import net.sumaris.core.dao.technical.SortDirection;
import net.sumaris.core.extraction.cache.ExtractionCacheNames;
import net.sumaris.core.extraction.vo.*;
import net.sumaris.core.extraction.vo.filter.AggregationTypeFilterVO;
import net.sumaris.core.vo.data.DataFetchOptions;
import net.sumaris.core.extraction.config.ExtractionCacheConfiguration;
import net.sumaris.core.vo.technical.extraction.*;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
/**
......@@ -72,8 +62,8 @@ public interface ExtractionProductService {
@Transactional
@Caching(evict = {
@CacheEvict(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_ID, allEntries = true),
@CacheEvict(cacheNames = ExtractionCacheNames.AGGREGATION_TYPE_BY_FORMAT, allEntries = true)
@CacheEvict(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_ID, allEntries = true),
@CacheEvict(cacheNames = ExtractionCacheConfiguration.Names.AGGREGATION_TYPE_BY_FORMAT, allEntries = true)
})
void delete(int id);
......
......@@ -23,6 +23,7 @@
package net.sumaris.server.config;
import net.sumaris.server.http.ExtractionRestController;
import net.sumaris.server.http.ExtractionRestPaths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
......@@ -60,7 +61,7 @@ public class ExtractionWebAutoConfiguration {
havingValue = "servlet",
matchIfMissing = true
)
public WebMvcConfigurer configureExtractionStatics() {
public WebMvcConfigurer configureExtractionWebMvc() {
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
......@@ -80,8 +81,8 @@ public class ExtractionWebAutoConfiguration {
public void addCorsMappings(CorsRegistry registry) {
// Enable Global CORS support for the application
//See https://stackoverflow.com/questions/35315090/spring-boot-enable-global-cors-support-issue-only-get-is-working-post-put-and
registry.addMapping("/**")
.allowedOrigins("*") // TODO Spring update will need to change this to allowedOriginPattern()
registry.addMapping(ExtractionRestPaths.BASE_PATH + "/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
.allowedHeaders("accept", "access-control-allow-origin", "authorization", "content-type")
.allowCredentials(true);
......
......@@ -40,6 +40,7 @@ import net.sumaris.core.vo.data.PhysicalGearVO;
import net.sumaris.core.vo.data.TripVO;
import net.sumaris.server.config.ExtractionWebAutoConfiguration;
import net.sumaris.server.http.ExtractionRestController;
import net.sumaris.server.http.ExtractionRestPaths;
import net.sumaris.server.security.ExtractionSecurityService;
import net.sumaris.server.security.IDownloadController;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -79,7 +80,7 @@ public class ExtractionGraphQLService {
String serverUrl = event.getConfiguration().getApplicationConfig().getOption("server.url");
if (StringUtils.isNotBlank(serverUrl)) {
documentationUrl = serverUrl + ExtractionRestController.DOC_PATH;
documentationUrl = serverUrl + ExtractionRestPaths.DOC_PATH;
}
else {
documentationUrl = null;
......
......@@ -46,13 +46,7 @@ import java.text.ParseException;
@RestController
@ConditionalOnBean({ExtractionWebAutoConfiguration.class})
public class AggregationRestController {
protected static final String BASE_PATH = "/api/extraction/product";
protected static final String GEOJSON_LABEL_PATH = BASE_PATH + "/{label:[a-zA-Z0-9-_]+}";
protected static final String GEOJSON_LABEL_WITH_SPACE_PATH = GEOJSON_LABEL_PATH + "/{space}";
protected static final String GEOJSON_EXTENSION = ".geojson";
public class AggregationRestController implements ExtractionRestPaths {
@Autowired
private AggregationService aggregationService;
......@@ -97,8 +91,8 @@ public class AggregationRestController {
throw new SumarisTechnicalException(ErrorCodes.BAD_REQUEST, "Invalid query: " + queryString);
}
int offset = offsetParam != null ? offsetParam.intValue() : 0;
int size = sizeParam != null ? sizeParam.intValue() : 100;
int offset = offsetParam != null ? offsetParam : 0;
int size = sizeParam != null ? sizeParam : 100;
// Limit to 1000 rows
if (size > 1000) size = 1000;
......
......@@ -75,24 +75,8 @@ import java.util.*;
@RestController
@ConditionalOnBean({ExtractionWebAutoConfiguration.class})
public class ExtractionRestController {
public class ExtractionRestController implements ExtractionRestPaths {
public static final String BASE_PATH = "/api/extraction";
// Get types paths
public static final String TYPES_PATH = BASE_PATH + "/types";
// Download file paths
public static final String DOWNLOAD_BASE_PATH = BASE_PATH + "/download";
public static final String DOWNLOAD_PATH = DOWNLOAD_BASE_PATH + "/{category}/{label:[a-zA-Z0-9-_]+}";
public static final String DOWNLOAD_WITH_VERSION_PATH = DOWNLOAD_PATH + "/{category}/{label:[a-zA-Z0-9-_]+}/{version}";
// Get documentation paths
public static final String DOC_BASE_PATH = BASE_PATH + "/doc";
public static final String DOC_PATH = DOC_BASE_PATH + "/{category}/{label:[a-zA-Z0-9-_]+}";
public static final String DOC_WITH_VERSION_PATH = DOC_PATH + "/{version}";
protected static final String EXTENSION_PATH_PARAM = ".{extension:[a-z0-9-_]+}";
protected static final String HTML_PREVIEW_PATH = "classpath:static/doc/preview.html";
protected static final Collection<MediaType> HTML_MEDIA_TYPES = ImmutableList.of(
......@@ -119,7 +103,7 @@ public class ExtractionRestController {
@PostConstruct
public void init() {
log.info("Starting extraction endpoint {{}}...", BASE_PATH);
log.info("Starting extraction endpoint {{}}...", ExtractionRestPaths.BASE_PATH);
}
@GetMapping(
......
/*
* #%L
* SUMARiS
* %%
* Copyright (C) 2019 SUMARiS Consortium
* %%
* 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%
*/
package net.sumaris.server.http;
public interface ExtractionRestPaths {
// Extensions
String EXTENSION_PATH_PARAM = ".{extension:[a-z0-9-_]+}";
String GEOJSON_EXTENSION = ".geojson";
String BASE_PATH = "/api/extraction";
// Get types paths
String TYPES_PATH = BASE_PATH + "/types";
// Download file paths
String DOWNLOAD_BASE_PATH = BASE_PATH + "/download";
String DOWNLOAD_PATH = DOWNLOAD_BASE_PATH + "/{category}/{label:[a-zA-Z0-9-_]+}";
String DOWNLOAD_WITH_VERSION_PATH = DOWNLOAD_PATH + "/{category}/{label:[a-zA-Z0-9-_]+}/{version}";
// Get documentation paths
String DOC_BASE_PATH = BASE_PATH + "/doc";
String DOC_PATH = DOC_BASE_PATH + "/{category}/{label:[a-zA-Z0-9-_]+}";
String DOC_WITH_VERSION_PATH = DOC_PATH + "/{version}";
// Product paths
String PRODUCT_BASE_PATH = ExtractionRestPaths.BASE_PATH + "/product";
String GEOJSON_LABEL_PATH = PRODUCT_BASE_PATH + "/{label:[a-zA-Z0-9-_]+}";
String GEOJSON_LABEL_WITH_SPACE_PATH = GEOJSON_LABEL_PATH + "/{space}";
}
sumaris.config.option.auth.allExtractionTypeAccess.role.description=
sumaris.config.option.extraction.cli.frequency.description=
sumaris.config.option.extraction.cli.output.format.description=
sumaris.config.option.extraction.enabled.description=
sumaris.config.option.extraction.product.enable.description=
sumaris.config.option.server.url.description=
sumaris.extraction.COST.HH=Fishing Stations
sumaris.extraction.COST.SL=Species List
......@@ -12,6 +16,7 @@ sumaris.extraction.SURVIVAL_TEST.RL=Individual Releases
sumaris.extraction.SURVIVAL_TEST.SL=Species List
sumaris.extraction.SURVIVAL_TEST.ST=Survival Tests
sumaris.extraction.SURVIVAL_TEST.TR=Trips
sumaris.extraction.config=
sumaris.extraction.documentation.header.comments=Comments
sumaris.extraction.documentation.header.fieldName=Field name
sumaris.extraction.documentation.header.type=Type
......
sumaris.config.option.auth.allExtractionTypeAccess.role.description=
sumaris.config.option.extraction.cli.frequency.description=
sumaris.config.option.extraction.cli.output.format.description=
sumaris.config.option.extraction.enabled.description=
sumaris.config.option.extraction.product.enable.description=
sumaris.config.option.server.url.description=
sumaris.extraction.COST.HH=Opérations
sumaris.extraction.COST.HL=Mensurations
......@@ -14,6 +18,7 @@ sumaris.extraction.SURVIVAL_TEST.RL=Relachés
sumaris.extraction.SURVIVAL_TEST.SL=Espèces capturées
sumaris.extraction.SURVIVAL_TEST.ST=Tests de survie
sumaris.extraction.SURVIVAL_TEST.TR=Marée
sumaris.extraction.config=
sumaris.extraction.documentation.header.comments=Comments
sumaris.extraction.documentation.header.fieldName=Field name
sumaris.extraction.documentation.header.type=Type
......