From 10218db983786ee6ba6d51723b6b23865a6e994c Mon Sep 17 00:00:00 2001 From: Peter Hoffmann <954078+p-hoffmann@users.noreply.github.com> Date: Sun, 11 Jan 2026 23:37:44 +0800 Subject: [PATCH 1/2] fix login/auth problem --- .../org/ohdsi/webapi/ShiroConfiguration.java | 18 ++++++++-- .../org/ohdsi/webapi/shiro/TokenManager.java | 34 ++++++++++++++----- .../filters/auth/AtlasJwtAuthFilter.java | 6 ++++ .../management/AtlasRegularSecurity.java | 1 + .../shiro/management/DisabledSecurity.java | 1 + .../shiro/management/FilterChainBuilder.java | 6 ++++ 6 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/ohdsi/webapi/ShiroConfiguration.java b/src/main/java/org/ohdsi/webapi/ShiroConfiguration.java index adfffb16ea..d8167ccf9e 100644 --- a/src/main/java/org/ohdsi/webapi/ShiroConfiguration.java +++ b/src/main/java/org/ohdsi/webapi/ShiroConfiguration.java @@ -2,9 +2,11 @@ import java.util.Collection; import java.util.Set; +import org.apache.shiro.SecurityUtils; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.ohdsi.webapi.shiro.AtlasWebSecurityManager; import org.ohdsi.webapi.shiro.lockout.*; import org.ohdsi.webapi.shiro.management.DataSourceAccessBeanPostProcessor; @@ -13,14 +15,18 @@ import org.ohdsi.webapi.shiro.management.datasource.DataSourceAccessParameterResolver; import org.ohdsi.webapi.shiro.realms.JwtAuthRealm; import org.ohdsi.webapi.shiro.subject.WebDelegatingRunAsSubjectFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; import jakarta.servlet.Filter; import java.util.Map; @@ -33,6 +39,8 @@ @Configuration public class ShiroConfiguration { + private static final Logger log = LoggerFactory.getLogger(ShiroConfiguration.class); + @Value("${security.maxLoginAttempts}") private int maxLoginAttempts; @Value("${security.duration.initial}") @@ -44,7 +52,7 @@ public class ShiroConfiguration { @Autowired protected ApplicationEventPublisher eventPublisher; - @Bean + @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilter(Security security, LockoutPolicy lockoutPolicy) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); @@ -53,7 +61,10 @@ public ShiroFilterFactoryBean shiroFilter(Security security, LockoutPolicy locko Map filters = security.getFilters().entrySet().stream() .collect(Collectors.toMap(f -> f.getKey().getTemplateName(), Map.Entry::getValue)); shiroFilter.setFilters(filters); - shiroFilter.setFilterChainDefinitionMap(security.getFilterChain()); + + Map filterChain = security.getFilterChain(); + + shiroFilter.setFilterChainDefinitionMap(filterChain); return shiroFilter; } @@ -73,6 +84,9 @@ public DefaultWebSecurityManager securityManager(Security security, LockoutPolic securityManager.setSubjectFactory(new WebDelegatingRunAsSubjectFactory()); + // Initialize SecurityUtils for programmatic access throughout the application + SecurityUtils.setSecurityManager(securityManager); + return securityManager; } diff --git a/src/main/java/org/ohdsi/webapi/shiro/TokenManager.java b/src/main/java/org/ohdsi/webapi/shiro/TokenManager.java index 13850b9522..bb65257ff6 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/TokenManager.java +++ b/src/main/java/org/ohdsi/webapi/shiro/TokenManager.java @@ -55,14 +55,13 @@ public static String getSubject(String jwt) throws JwtException { } public static Claims getBody(String jwt) { - - // Get untrusted subject for secret key retrieval + // Extract subject without signature verification to retrieve signing key String untrustedSubject = getUntrustedSubject(jwt); if (untrustedSubject == null) { throw new UnsupportedJwtException("Cannot extract subject from the token"); } - // Pick all secret keys: latest one + previous keys, which were just invalidated (to overcome concurrency issue) + // Retrieve signing keys: current key + grace period keys for concurrency handling List keyOptions = gracePeriodInvalidTokens.get(untrustedSubject); if (userToKeyMap.containsKey(untrustedSubject)) { keyOptions.add(0, userToKeyMap.get(untrustedSubject)); @@ -86,12 +85,30 @@ public static Claims getBody(String jwt) { } protected static String getUntrustedSubject(String jws) { - int i = jws.lastIndexOf('.'); - if (i == -1) { + try { + // Split JWT into header.payload.signature components + String[] parts = jws.split("\\."); + if (parts.length != 3) { + return null; + } + + // Base64-decode payload to extract subject claim + String payload = new String(java.util.Base64.getUrlDecoder().decode(parts[1])); + + // Extract "sub" field from JSON payload + int subIndex = payload.indexOf("\"sub\""); + if (subIndex == -1) { return null; + } + + int colonIndex = payload.indexOf(":", subIndex); + int startQuote = payload.indexOf("\"", colonIndex); + int endQuote = payload.indexOf("\"", startQuote + 1); + + return payload.substring(startQuote + 1, endQuote); + } catch (Exception e) { + return null; } - String untrustedJwtString = jws.substring(0, i+1); - return Jwts.parser().unsecured().build().parseUnsecuredClaims(untrustedJwtString).getPayload().getSubject(); } public static Boolean invalidate(String jwt) { @@ -127,7 +144,6 @@ public static String extractToken(ServletRequest request) { if (headerParts.length != 2) return null; - String jwt = headerParts[1]; - return jwt; + return headerParts[1]; } } diff --git a/src/main/java/org/ohdsi/webapi/shiro/filters/auth/AtlasJwtAuthFilter.java b/src/main/java/org/ohdsi/webapi/shiro/filters/auth/AtlasJwtAuthFilter.java index 026f41a449..7a23d9bf6d 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/filters/auth/AtlasJwtAuthFilter.java +++ b/src/main/java/org/ohdsi/webapi/shiro/filters/auth/AtlasJwtAuthFilter.java @@ -10,9 +10,13 @@ import org.ohdsi.webapi.shiro.filters.AtlasAuthFilter; import org.ohdsi.webapi.shiro.tokens.JwtAuthToken; import org.ohdsi.webapi.shiro.TokenManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class AtlasJwtAuthFilter extends AtlasAuthFilter { + private static final Logger logger = LoggerFactory.getLogger(AtlasJwtAuthFilter.class); + @Override protected JwtAuthToken createToken(ServletRequest request, ServletResponse response) throws Exception { String jwt = TokenManager.extractToken(request); @@ -20,6 +24,7 @@ protected JwtAuthToken createToken(ServletRequest request, ServletResponse respo String subject = TokenManager.getSubject(jwt); return new JwtAuthToken(subject); } catch (JwtException e) { + logger.warn("JWT validation failed: {}", e.getMessage()); throw new AuthenticationException(e); } } @@ -33,6 +38,7 @@ protected boolean onAccessDenied(ServletRequest request, ServletResponse respons loggedIn = executeLogin(request, response); } catch(AuthenticationException ae) { + logger.debug("JWT authentication failed: {}", ae.getMessage()); loggedIn = false; } } diff --git a/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java b/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java index b0d66e1005..f786c45203 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java +++ b/src/main/java/org/ohdsi/webapi/shiro/management/AtlasRegularSecurity.java @@ -419,6 +419,7 @@ protected FilterChainBuilder getFilterChainBuilder() { // login/logout .addRestPath("/user/refresh", JWT_AUTHC, UPDATE_TOKEN, SEND_TOKEN_IN_HEADER) .addProtectedRestPath("/user/runas", RUN_AS, UPDATE_TOKEN, SEND_TOKEN_IN_HEADER) + .addProtectedRestPath("/user/me") .addRestPath("/user/logout", LOGOUT); // MUST be called before adding OAuth filters diff --git a/src/main/java/org/ohdsi/webapi/shiro/management/DisabledSecurity.java b/src/main/java/org/ohdsi/webapi/shiro/management/DisabledSecurity.java index ad3476a33e..249ad749f8 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/management/DisabledSecurity.java +++ b/src/main/java/org/ohdsi/webapi/shiro/management/DisabledSecurity.java @@ -16,6 +16,7 @@ import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; + import static org.ohdsi.webapi.shiro.management.FilterTemplates.*; /** * diff --git a/src/main/java/org/ohdsi/webapi/shiro/management/FilterChainBuilder.java b/src/main/java/org/ohdsi/webapi/shiro/management/FilterChainBuilder.java index 6bb2c96a19..45409af898 100644 --- a/src/main/java/org/ohdsi/webapi/shiro/management/FilterChainBuilder.java +++ b/src/main/java/org/ohdsi/webapi/shiro/management/FilterChainBuilder.java @@ -71,6 +71,12 @@ public FilterChainBuilder addPath(String path, FilterTemplates... filters) { public FilterChainBuilder addPath(String path, String filters) { path = path.replaceAll("/+$", ""); + + // Prepend /WebAPI to match JAX-RS @ApplicationPath("/WebAPI") + if (!path.startsWith("/WebAPI") && !path.equals("/**") && !path.equals("/*")) { + path = "/WebAPI" + path; + } + this.filterChain.put(path, filters); // If path ends with non wildcard character, need to add two paths - From 0162630fb3078035ff2853278850150f59f211e5 Mon Sep 17 00:00:00 2001 From: Peter Hoffmann <954078+p-hoffmann@users.noreply.github.com> Date: Tue, 13 Jan 2026 21:14:06 +0800 Subject: [PATCH 2/2] simplify configuration --- .../ohdsi/webapi/trexsql/TrexSQLConfig.java | 27 +- .../webapi/trexsql/TrexSQLSearchProvider.java | 5 - .../ohdsi/webapi/trexsql/TrexSQLService.java | 35 +- .../webapi/trexsql/TrexSQLSourceConfig.java | 27 - .../resources/application-broadsea.properties | 122 ---- src/main/resources/application-dev.properties | 114 ---- src/main/resources/application.properties | 616 ++++++++++-------- 7 files changed, 358 insertions(+), 588 deletions(-) delete mode 100644 src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSourceConfig.java delete mode 100644 src/main/resources/application-broadsea.properties delete mode 100644 src/main/resources/application-dev.properties diff --git a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLConfig.java b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLConfig.java index 2fb2b09511..2829256af5 100644 --- a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLConfig.java +++ b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLConfig.java @@ -2,12 +2,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; -import java.util.HashMap; -import java.util.Map; - /** - * Configuration properties for trexsql integration. - * Maps to trexsql.* in application properties. + * Global trexsql configuration. Per-source config is in the source table (is_cache_enabled). */ @ConfigurationProperties(prefix = "trexsql") public class TrexSQLConfig { @@ -15,7 +11,6 @@ public class TrexSQLConfig { private boolean enabled = false; private String cachePath = "./data/cache"; private String extensionsPath; - private Map sources = new HashMap<>(); public boolean isEnabled() { return enabled; @@ -40,24 +35,4 @@ public String getExtensionsPath() { public void setExtensionsPath(String extensionsPath) { this.extensionsPath = extensionsPath; } - - public Map getSources() { - return sources; - } - - public void setSources(Map sources) { - this.sources = sources; - } - - public TrexSQLSourceConfig getSourceConfig(String sourceKey) { - return sources.get(sourceKey); - } - - public boolean isEnabledForSource(String sourceKey) { - if (!enabled) { - return false; - } - TrexSQLSourceConfig sourceConfig = sources.get(sourceKey); - return sourceConfig != null && sourceConfig.isEnabled(); - } } diff --git a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSearchProvider.java b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSearchProvider.java index aa97a69edc..3dd6e3eed8 100644 --- a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSearchProvider.java +++ b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSearchProvider.java @@ -46,11 +46,6 @@ public int getPriority() { public Collection executeSearch(SearchProviderConfig searchConfig, String query, String rows) throws Exception { String sourceKey = searchConfig.getSourceKey(); - if (!trexsqlService.isEnabledForSource(sourceKey)) { - log.debug("TrexSQL not enabled for source {}", sourceKey); - throw new IllegalStateException("TrexSQL not enabled for source: " + sourceKey); - } - if (!trexsqlService.isCacheAvailable(sourceKey)) { log.debug("Cache not available for source {}", sourceKey); throw new IllegalStateException("TrexSQL cache not available for source: " + sourceKey); diff --git a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLService.java b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLService.java index 689e8f3d13..71698edb1b 100644 --- a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLService.java +++ b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLService.java @@ -12,7 +12,7 @@ import java.util.Map; /** - * Service for TrexSQL operations used by SearchProvider. + * Service for TrexSQL operations. Cache is available if file exists. */ @Service @ConditionalOnProperty(name = "trexsql.enabled", havingValue = "true", matchIfMissing = false) @@ -28,42 +28,25 @@ public TrexSQLService(TrexSQLConfig config, TrexSQLInstanceManager instanceManag this.instanceManager = instanceManager; } - public boolean isEnabledForSource(String sourceKey) { - return config.isEnabledForSource(sourceKey); - } - + /** + * Check if cache file exists for source. + */ public boolean isCacheAvailable(String sourceKey) { - TrexSQLSourceConfig sourceConfig = config.getSourceConfig(sourceKey); - if (sourceConfig == null) { - return false; - } - String databaseCode = sourceConfig.getDatabaseCode(); - if (databaseCode == null || databaseCode.isEmpty()) { - return false; - } - return Paths.get(config.getCachePath(), databaseCode + ".db") - .toFile().exists(); + return Paths.get(config.getCachePath(), sourceKey + ".db").toFile().exists(); } @SuppressWarnings("unchecked") public List> searchVocab(String sourceKey, String searchTerm, int maxRows) { log.debug("Searching vocabulary for source {} with term: {}", sourceKey, searchTerm); - TrexSQLSourceConfig sourceConfig = config.getSourceConfig(sourceKey); - if (sourceConfig == null) { - throw new IllegalStateException("TrexSQL source configuration not found for key: " + sourceKey); - } - - String databaseCode = sourceConfig.getDatabaseCode(); - if (databaseCode == null || databaseCode.isEmpty()) { - throw new IllegalStateException("TrexSQL database code not configured for source: " + sourceKey); + if (!isCacheAvailable(sourceKey)) { + throw new IllegalStateException("TrexSQL cache not available for source: " + sourceKey); } Map options = new HashMap<>(); - options.put("database-code", databaseCode); + options.put("database-code", sourceKey); options.put("max-rows", maxRows); - String cachePath = config.getCachePath(); - options.put("cache-path", cachePath != null ? cachePath : "/data/cache"); + options.put("cache-path", config.getCachePath()); try { Object db = instanceManager.getInstance(); diff --git a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSourceConfig.java b/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSourceConfig.java deleted file mode 100644 index f55ac5c734..0000000000 --- a/src/main/java/org/ohdsi/webapi/trexsql/TrexSQLSourceConfig.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.ohdsi.webapi.trexsql; - -/** - * Per-source configuration for TrexSQL integration. - * Maps to trexsql.sources.{sourceKey} in application properties. - */ -public class TrexSQLSourceConfig { - - private boolean enabled = false; - private String databaseCode; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getDatabaseCode() { - return databaseCode; - } - - public void setDatabaseCode(String databaseCode) { - this.databaseCode = databaseCode; - } -} diff --git a/src/main/resources/application-broadsea.properties b/src/main/resources/application-broadsea.properties deleted file mode 100644 index c3c66d0d7f..0000000000 --- a/src/main/resources/application-broadsea.properties +++ /dev/null @@ -1,122 +0,0 @@ -# Broadsea PostgreSQL Configuration (define once, reused below) -broadsea.db.driver=org.postgresql.Driver -broadsea.db.url=jdbc:postgresql://localhost:5433/postgres?currentSchema=webapi_test -broadsea.db.username=postgres -broadsea.db.password=mypass -broadsea.db.schema=webapi_test -broadsea.db.dialect=postgresql - -datasource.driverClassName=${broadsea.db.driver} -datasource.url=${broadsea.db.url} -datasource.username=${broadsea.db.username} -datasource.password=${broadsea.db.password} -datasource.dialect=${broadsea.db.dialect} -datasource.ohdsi.schema=${broadsea.db.schema} -datasource.dialect.source=${broadsea.db.dialect} - -# Flyway Configuration (reuse primary datasource) - keep literal values to avoid SQL Server defaults -spring.flyway.enabled=true -spring.flyway.driver-class-name=org.postgresql.Driver -spring.flyway.url=${broadsea.db.url} -spring.flyway.user=${broadsea.db.username} -spring.flyway.password=${broadsea.db.password} -spring.flyway.locations=classpath:db/migration/postgresql -spring.flyway.schemas=${broadsea.db.schema} -spring.flyway.placeholders.ohdsiSchema=${broadsea.db.schema} -spring.flyway.validate-on-migrate=false -spring.flyway.baseline-on-migrate=true -spring.flyway.baseline-version=0 -spring.flyway.out-of-order=true - -# Hibernate Configuration - -# JPA Configuration -spring.jpa.show-sql=false -spring.jpa.properties.hibernate.default_schema=${broadsea.db.schema} -spring.jpa.properties.hibernate.generate_statistics=false -spring.jpa.properties.hibernate.jdbc.batch_size=20 -spring.jpa.properties.hibernate.order_inserts=true - -# Spring Batch Configuration -spring.batch.repository.tableprefix=${broadsea.db.schema}.BATCH_ -spring.batch.repository.isolationLevelForCreate=ISOLATION_DEFAULT -spring.batch.taskExecutor.corePoolSize=5 -spring.batch.taskExecutor.maxPoolSize=10 -spring.batch.taskExecutor.queueCapacity=500 -spring.batch.taskExecutor.threadGroupName=batchGroup -spring.batch.taskExecutor.threadNamePrefix=batchExec - -# Server Configuration -server.port=8081 - -# Security Configuration -security.provider=DisabledSecurity -security.cors.enabled=true -security.origin=* -security.token.expiration=43200 -security.defaultGlobalReadPermissions=true -security.ssl.enabled=false - -# Security data source defaults to Postgres (matches primary) -security.db.datasource.driverClassName=${broadsea.db.driver} -security.db.datasource.url=${broadsea.db.url} -security.db.datasource.username=${broadsea.db.username} -security.db.datasource.password=${broadsea.db.password} -security.db.datasource.schema=${broadsea.db.schema} - -# Hikari Configuration -spring.datasource.hikari.connection-test-query=SELECT 1 -spring.datasource.hikari.connection-test-query-timeout=1000 -spring.datasource.hikari.maximum-pool-size=10 -spring.datasource.hikari.minimum-idle=0 -spring.datasource.hikari.connection-timeout=30000 - -# CDM Properties -source.name=SYNPUF5PCT -cdm.version=5 - -# Logging -logging.level.org.springframework.web=INFO -logging.level.org.hibernate=INFO -logging.level.root=INFO -logging.level.org.ohdsi=INFO -logging.level.org.springframework.jdbc=DEBUG - -# Spring Cache -spring.cache.type=simple - -# Disable LDAP auto-config for JDK module restrictions in this env -spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration - -# Person Settings -person.viewDates=false - -# Heracles Settings -heracles.smallcellcount=5 - -# Jasypt Configuration -jasypt.encryptor.enabled=false - -# Organization Settings -organization.name=OHDSI - -# Audit Trail Settings -audit.trail.enabled=false - -# Cache Settings -cdm.result.cache.warming.enable=false -cdm.cache.achilles.warming.enable=false -cdm.cache.cron.warming.enable=false - -# GIS Settings -atlasgis.enabled=false - -# I18n Settings -i18n.enabled=false -i18n.defaultLocale=en - -# Tag Settings -tag.enabled=false - -# Versioning Settings -versioning.maxAttempt=3 diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties deleted file mode 100644 index 8745c1e335..0000000000 --- a/src/main/resources/application-dev.properties +++ /dev/null @@ -1,114 +0,0 @@ -# Development Profile - Fresh Schema Configuration -# PostgreSQL Configuration with new schema -datasource.driverClassName=org.postgresql.Driver -datasource.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=webapi_dev -datasource.username=postgres -datasource.password=mypass -datasource.dialect=postgresql -datasource.ohdsi.schema=webapi_dev -datasource.dialect.source=postgresql - -# Flyway Configuration (Spring Boot 3.x properties) -spring.flyway.driver-class-name=org.postgresql.Driver -spring.flyway.url=${datasource.url} -spring.flyway.user=${datasource.username} -spring.flyway.password=${datasource.password} -spring.flyway.schemas=${datasource.ohdsi.schema} -spring.flyway.placeholders.ohdsiSchema=${datasource.ohdsi.schema} -spring.flyway.locations=classpath:db/migration/postgresql -spring.flyway.validate-on-migrate=false -spring.flyway.baseline-on-migrate=true -spring.flyway.baseline-version=0 -spring.flyway.out-of-order=true - -# Secondary DataSource Configuration (for Flyway) -secondary.datasource.driverClassName=org.postgresql.Driver -secondary.datasource.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=webapi_dev -secondary.datasource.username=postgres -secondary.datasource.password=mypass - -# Hibernate Configuration - -# JPA Configuration -spring.jpa.show-sql=false -spring.jpa.properties.hibernate.default_schema=webapi_dev -spring.jpa.properties.hibernate.generate_statistics=false -spring.jpa.properties.hibernate.jdbc.batch_size=20 -spring.jpa.properties.hibernate.order_inserts=true - -# Spring Batch Configuration -spring.batch.repository.tableprefix=webapi_dev.BATCH_ -spring.batch.repository.isolationLevelForCreate=ISOLATION_DEFAULT -spring.batch.taskExecutor.corePoolSize=5 -spring.batch.taskExecutor.maxPoolSize=10 -spring.batch.taskExecutor.queueCapacity=500 -spring.batch.taskExecutor.threadGroupName=batchGroup -spring.batch.taskExecutor.threadNamePrefix=batchExec - -# Server Configuration -server.port=8080 - -# Security Configuration -security.provider=DisabledSecurity -security.cors.enabled=true -security.origin=* -security.token.expiration=43200 -security.defaultGlobalReadPermissions=true -security.ssl.enabled=false - -# Hikari Configuration -spring.datasource.hikari.connection-test-query=SELECT 1 -spring.datasource.hikari.connection-test-query-timeout=1000 -spring.datasource.hikari.maximum-pool-size=10 -spring.datasource.hikari.minimum-idle=0 -spring.datasource.hikari.connection-timeout=30000 - -# CDM Properties -source.name=SYNPUF5PCT -cdm.version=5 - -# Logging -logging.level.org.springframework.web=INFO -logging.level.org.hibernate=INFO -logging.level.root=INFO -logging.level.org.ohdsi=INFO -logging.level.org.springframework.jdbc=INFO - -# Spring Cache -spring.cache.type=none - -# Person Settings -person.viewDates=false - -# Heracles Settings -heracles.smallcellcount=5 - -# Jasypt Configuration -jasypt.encryptor.enabled=false - -# Organization Settings -organization.name=OHDSI - -# Audit Trail Settings -audit.trail.enabled=false - -# Cache Settings -cdm.result.cache.warming.enable=false -cdm.cache.achilles.warming.enable=false -cdm.cache.cron.warming.enable=false - -# GIS Settings -atlasgis.enabled=false - -# I18n Settings -i18n.enabled=false -i18n.defaultLocale=en - -# Tag Settings -tag.enabled=false - -# Versioning Settings -versioning.maxAttempt=3 - -# Disable LDAP autoconfiguration -spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index a9179ce7cd..5554270c51 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,285 +1,365 @@ -#BuildNumber Version property stub until migration to spring boot 2 -build.number=NA - -spring.profiles.active=${spring.profiles.active} - -# Logging -logging.level.org.springframework.web=${logging.level.org.springframework.web} -logging.level.org.hibernate=${logging.level.org.hibernate} -logging.level.root=${logging.level.root} -logging.level.org.ohdsi=${logging.level.org.ohdsi} -logging.level.org.springframework.orm=${logging.level.org.springframework.orm} -logging.level.org.springframework.jdbc=${logging.level.org.springframework.jdbc} -logging.level.org.apache.shiro=${logging.level.org.apache.shiro} - -spring.jackson.serialization.write-dates-as-timestamps=true - -#Primary DataSource -datasource.driverClassName=${datasource.driverClassName} -datasource.url=${datasource.url} -datasource.username=${datasource.username} -datasource.password=${datasource.password} -datasource.dialect=${datasource.dialect} -datasource.ohdsi.schema=${datasource.ohdsi.schema} -datasource.dialect.source=${datasource.dialect.source} +# WebAPI Application Properties +# All properties have sensible defaults and can be overridden via environment variables +# Spring Boot relaxed binding: DATASOURCE_PASSWORD env var -> datasource.password property -#CDM properties -source.name=${source.name} -cdm.version=${cdm.version} - -#R Service Host -r.serviceHost=${r.serviceHost} +build.number=NA -#DataSource for Change Managment / Migration +# ============================================================================= +# DATABASE CONFIGURATION +# ============================================================================= +datasource.driverClassName=${DATASOURCE_DRIVERCLASSNAME:org.postgresql.Driver} +datasource.url=${DATASOURCE_URL:jdbc:postgresql://localhost:5432/postgres?currentSchema=webapi} +datasource.username=${DATASOURCE_USERNAME:postgres} +datasource.password=${DATASOURCE_PASSWORD:} +datasource.dialect=${DATASOURCE_DIALECT:postgresql} +datasource.ohdsi.schema=${DATASOURCE_OHDSI_SCHEMA:webapi} +datasource.dialect.source=${datasource.dialect} + +# CDM Properties +source.name=${SOURCE_NAME:SYNPUF5PCT} +cdm.version=${CDM_VERSION:5} + +# ============================================================================= +# FLYWAY MIGRATION (inherits from primary datasource) +# ============================================================================= spring.flyway.enabled=true -spring.flyway.driver-class-name=${datasource.driverClassName} -spring.flyway.url=${datasource.url} -spring.flyway.user=${datasource.username} -spring.flyway.password=${datasource.password} -# Flyway schema history table name +spring.flyway.driver-class-name=${DATASOURCE_DRIVERCLASSNAME:org.postgresql.Driver} +spring.flyway.url=${DATASOURCE_URL:jdbc:postgresql://localhost:5432/postgres?currentSchema=webapi} +spring.flyway.user=${DATASOURCE_USERNAME:postgres} +spring.flyway.password=${DATASOURCE_PASSWORD:} spring.flyway.table=flyway_schema_history -# check that migration scripts location exists spring.flyway.fail-on-missing-locations=true -spring.flyway.locations=${flyway.locations} -# locations of migrations scripts -# schemas to manage/update (e.g. ohdsi/results schema) -NOTE: CASE SENSITIVE! -spring.flyway.schemas=${datasource.ohdsi.schema} -#Baseline - start flyway managment with existing objects +spring.flyway.locations=${flyway.locations:classpath:db/migration/postgresql} +spring.flyway.schemas=${DATASOURCE_OHDSI_SCHEMA:webapi} spring.flyway.baseline-on-migrate=true -#Due to issue https://github.com/flyway/flyway/issues/752 use default baselineVersion=1 (Note equality to 1.0.0.0, so scripts with that version will be omitted) -#spring.flyway.baseline-version=1.0.0.0 -spring.flyway.validate-on-migrate=${flyway.validateOnMigrate} -# Enable out of order migrations due to distributed development nature of WebAPI -spring.flyway.out-of-order=false -# Flyway Placeholders: -spring.flyway.placeholders.ohdsiSchema=${datasource.ohdsi.schema} - -#Disable any auto init -#http://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html +spring.flyway.baseline-version=${flyway.baseline-version:0} +spring.flyway.validate-on-migrate=${flyway.validateOnMigrate:false} +spring.flyway.out-of-order=${flyway.out-of-order:true} +spring.flyway.placeholders.ohdsiSchema=${DATASOURCE_OHDSI_SCHEMA:webapi} + +# ============================================================================= +# JPA / HIBERNATE (inherits schema from datasource) +# ============================================================================= spring.datasource.initialize=false -#JPA / Spring Data -spring.jpa.show-sql=${spring.jpa.show-sql} -# JPA Default Schema -spring.jpa.properties.hibernate.default_schema=${datasource.ohdsi.schema} -spring.jpa.properties.hibernate.generate_statistics=${spring.jpa.properties.hibernate.generate_statistics} -spring.jpa.properties.hibernate.jdbc.batch_size=${spring.jpa.properties.hibernate.jdbc.batch_size} -spring.jpa.properties.hibernate.order_inserts=${spring.jpa.properties.hibernate.order_inserts} - -#Jersey WADL disabled to silence missing JAXBContext warning +spring.jpa.show-sql=false +spring.jpa.properties.hibernate.default_schema=${DATASOURCE_OHDSI_SCHEMA:webapi} +spring.jpa.properties.hibernate.generate_statistics=false +spring.jpa.properties.hibernate.jdbc.batch_size=20 +spring.jpa.properties.hibernate.order_inserts=true + +# ============================================================================= +# SPRING BATCH (inherits schema from datasource) +# ============================================================================= +spring.batch.job.enabled=false +spring.batch.initializer.enabled=false +spring.batch.repository.tableprefix=${DATASOURCE_OHDSI_SCHEMA:webapi}.batch_ +spring.batch.repository.isolationLevelForCreate=ISOLATION_DEFAULT +spring.batch.taskExecutor.corePoolSize=5 +spring.batch.taskExecutor.maxPoolSize=10 +spring.batch.taskExecutor.queueCapacity=500 +spring.batch.taskExecutor.threadGroupName=batchGroup +spring.batch.taskExecutor.threadNamePrefix=batchExec + +# ============================================================================= +# HIKARI CONNECTION POOL +# ============================================================================= +spring.datasource.hikari.connection-test-query=SELECT 1 +spring.datasource.hikari.connection-test-query-timeout=1000 +spring.datasource.hikari.maximum-pool-size=10 +spring.datasource.hikari.minimum-idle=0 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.register-mbeans=false +spring.datasource.hikari.mbean-name= + +# ============================================================================= +# SERVER CONFIGURATION +# ============================================================================= +server.port=8080 +server.context-path=/WebAPI +server.ssl.enabled=false +server.ssl.key-store= +server.ssl.key-store-password= +server.ssl.key-password= + +# ============================================================================= +# SECURITY - CORE +# ============================================================================= +security.provider=DisabledSecurity +security.cors.enabled=true +security.origin=* +security.token.expiration=43200 +security.ssl.enabled=false +security.defaultGlobalReadPermissions=true + +# Lockout policy +security.maxLoginAttempts=5 +security.duration.initial=30 +security.duration.increment=30 + +# ============================================================================= +# SECURITY - AUTH PROVIDERS (all disabled by default) +# ============================================================================= +security.auth.jdbc.enabled=false +security.auth.ldap.enabled=false +security.auth.ad.enabled=false +security.auth.windows.enabled=false +security.auth.kerberos.enabled=false +security.auth.openid.enabled=false +security.auth.google.enabled=false +security.auth.facebook.enabled=false +security.auth.github.enabled=false +security.auth.cas.enabled=false + +# ============================================================================= +# SECURITY - DATABASE (defaults to primary datasource) +# ============================================================================= +security.db.datasource.driverClassName=${DATASOURCE_DRIVERCLASSNAME:org.postgresql.Driver} +security.db.datasource.url=${SECURITY_DB_DATASOURCE_URL:${DATASOURCE_URL:jdbc:postgresql://localhost:5432/postgres?currentSchema=webapi}} +security.db.datasource.username=${SECURITY_DB_DATASOURCE_USERNAME:${DATASOURCE_USERNAME:postgres}} +security.db.datasource.password=${SECURITY_DB_DATASOURCE_PASSWORD:${DATASOURCE_PASSWORD:}} +security.db.datasource.schema=webapi_security +security.db.datasource.authenticationQuery=SELECT password, first_name AS firstname, middle_name AS middlename, last_name AS lastname FROM ${security.db.datasource.schema}.sec_user WHERE login = ? + +# ============================================================================= +# SECURITY - OAUTH +# ============================================================================= +security.oauth.callback.ui= +security.oauth.callback.api= +security.oauth.callback.urlResolver=query +security.oauth.google.apiKey= +security.oauth.google.apiSecret= +security.oauth.facebook.apiKey= +security.oauth.facebook.apiSecret= +security.oauth.github.apiKey= +security.oauth.github.apiSecret= + +# ============================================================================= +# SECURITY - OPENID +# ============================================================================= +security.oid.clientId= +security.oid.apiSecret= +security.oid.url= +security.oid.redirectUrl= +security.oid.logoutUrl= +security.oid.extraScopes= +# security.oid.customParams - set via SECURITY_OID_CUSTOMPARAMS env var if needed + +# ============================================================================= +# SECURITY - LDAP +# ============================================================================= +security.ldap.dn= +security.ldap.url= +security.ldap.baseDn= +security.ldap.system.username= +security.ldap.system.password= +security.ldap.searchString= +security.ldap.searchBase= +security.ldap.userMapping.displaynameAttr= +security.ldap.userMapping.firstnameAttr= +security.ldap.userMapping.middlenameAttr= +security.ldap.userMapping.lastnameAttr= +security.ldap.userMapping.usernameAttr= +security.ldap.userImport.usernameAttr= +security.ldap.userImport.loginAttr= + +# ============================================================================= +# SECURITY - ACTIVE DIRECTORY +# ============================================================================= +security.ad.url= +security.ad.searchBase= +security.ad.principalSuffix= +security.ad.system.username= +security.ad.system.password= +security.ad.searchFilter= +security.ad.searchString= +security.ad.ignore.partial.result.exception=false +security.ad.result.count.limit=1000 +security.ad.default.import.group= +security.ad.userMapping.displaynameAttr= +security.ad.userMapping.firstnameAttr= +security.ad.userMapping.middlenameAttr= +security.ad.userMapping.lastnameAttr= +security.ad.userMapping.usernameAttr= +security.ad.userImport.usernameAttr= +security.ad.userImport.loginAttr= + +# ============================================================================= +# SECURITY - SAML +# ============================================================================= +security.saml.enabled=false +security.saml.entityId= +security.saml.idpMetadataLocation= +security.saml.keyManager.keyStoreFile= +security.saml.keyManager.storePassword= +security.saml.keyManager.defaultKey= +security.saml.keyManager.passwords.arachnenetwork= +security.saml.metadataLocation= +security.saml.callbackUrl= +security.saml.sloUrl= +security.saml.maximumAuthenticationLifetime=3600 + +# ============================================================================= +# SECURITY - CAS +# ============================================================================= +security.cas.loginUrl= +security.cas.callbackUrl= +security.cas.serverUrl= +security.cas.cassvcs= +security.cas.casticket= + +# ============================================================================= +# SECURITY - KERBEROS +# ============================================================================= +security.kerberos.spn= +security.kerberos.keytabPath= +kerberos.timeout=60000 +kerberos.configPath= +kerberos.kinitPath= + +# ============================================================================= +# SECURITY - GOOGLE IAP +# ============================================================================= +security.googleIap.cloudProjectId= +security.googleIap.backendServiceId= +security.google.accessToken.enabled=false + +# ============================================================================= +# LOGGING +# ============================================================================= +logging.level.root=INFO +logging.level.org.springframework.web=INFO +logging.level.org.springframework.orm=INFO +logging.level.org.springframework.jdbc=INFO +logging.level.org.hibernate=INFO +logging.level.org.ohdsi=INFO + +# ============================================================================= +# SPRING AUTOCONFIGURATION +# ============================================================================= +# Exclude LDAP auto-configuration by default (causes issues with Java 21+ module access) +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration + +# ============================================================================= +# JACKSON +# ============================================================================= +spring.jackson.serialization.write-dates-as-timestamps=true + +# ============================================================================= +# JERSEY / JAX-RS +# ============================================================================= jersey.config.server.wadl.disableWadl=true +jersey.resources.root.package=org.ohdsi.webapi -#Spring Cache +# ============================================================================= +# SPRING CACHE +# ============================================================================= spring.cache.jcache.config=classpath:appCache.xml -spring.cache.type=${spring.cache.type} - -#JAX-RS -jersey.resources.root.package=org.ohdsi.webapi +spring.cache.type=simple -#Spring boot auto starts jobs upon application start -spring.batch.job.enabled=false -#Disable auto init of spring batch tables -spring.batch.initializer.enabled=false -#Custom properties -spring.batch.repository.tableprefix=${spring.batch.repository.tableprefix} -spring.batch.repository.isolationLevelForCreate=${spring.batch.repository.isolationLevelForCreate} -spring.batch.taskExecutor.corePoolSize=${spring.batch.taskExecutor.corePoolSize} -spring.batch.taskExecutor.maxPoolSize=${spring.batch.taskExecutor.maxPoolSize} -spring.batch.taskExecutor.queueCapacity=${spring.batch.taskExecutor.queueCapacity} -spring.batch.taskExecutor.threadGroupName=${spring.batch.taskExecutor.threadGroupName} -spring.batch.taskExecutor.threadNamePrefix=${spring.batch.taskExecutor.threadNamePrefix} - -# EMBEDDED SERVER CONFIGURATION (ServerProperties) -server.port = ${server.port} -server.ssl.enabled = ${security.ssl.enabled} -server.ssl.key-store = ${server.ssl.key-store} -server.ssl.key-store-password = ${server.ssl.key-store-password} -server.ssl.key-password = ${server.ssl.key-password} -# the context path, defaults to '/' -server.context-path=/WebAPI -security.cas.loginUrl=${security.cas.loginUrl} -security.cas.callbackUrl=${security.cas.callbackUrl} -security.cas.serverUrl=${security.cas.serverUrl} -security.cas.cassvcs=${security.cas.cassvcs} -security.cas.casticket=${security.cas.casticket} -# Full Text Search settings -solr.endpoint = ${solr.endpoint} -solr.query.prefix = ${solr.query.prefix} -# Enabling Compression +# ============================================================================= +# COMPRESSION +# ============================================================================= compression=true compressableMimeType=application/json,application/xml,text/html,text/xml,text/plain - -#Disabled to support Basic Auth and RESTful interface -#http://docs.spring.io/spring-security/site/docs/3.2.x-SNAPSHOT/reference/html5/#when-to-use-csrf-protection +# ============================================================================= +# CSRF (disabled for REST API) +# ============================================================================= csrf.disable=true +# ============================================================================= +# SPARQL / SOLR +# ============================================================================= sparql.endpoint=http://virtuoso.ohdsi.org:8890/sparql?default-graph-uri=&query= - -security.defaultGlobalReadPermissions=${security.defaultGlobalReadPermissions} -security.provider=${security.provider} -security.cors.enabled=${security.cors.enabled} -security.token.expiration=${security.token.expiration} -security.origin=${security.origin} -security.ssl.enabled=${security.ssl.enabled} -security.oauth.callback.ui=${security.oauth.callback.ui} -security.oauth.callback.api=${security.oauth.callback.api} -security.oauth.callback.urlResolver=${security.oauth.callback.urlResolver} -security.oauth.google.apiKey=${security.oauth.google.apiKey} -security.oauth.google.apiSecret=${security.oauth.google.apiSecret} -security.oauth.facebook.apiKey=${security.oauth.facebook.apiKey} -security.oauth.facebook.apiSecret=${security.oauth.facebook.apiSecret} -security.oauth.github.apiKey=${security.oauth.github.apiKey} -security.oauth.github.apiSecret=${security.oauth.github.apiSecret} -security.oid.clientId=${security.oid.clientId} -security.oid.apiSecret=${security.oid.apiSecret} -security.oid.url=${security.oid.url} -security.oid.redirectUrl=${security.oid.redirectUrl} -security.oid.logoutUrl=${security.oid.logoutUrl} -security.oid.extraScopes=${security.oid.extraScopes} -security.oid.customParams=${security.oid.customParams} -security.db.datasource.driverClassName=${security.db.datasource.driverClassName} -security.db.datasource.url=${security.db.datasource.url} -security.db.datasource.username=${security.db.datasource.username} -security.db.datasource.password=${security.db.datasource.password} -security.db.datasource.schema=${security.db.datasource.schema} -security.db.datasource.authenticationQuery=${security.db.datasource.authenticationQuery} -security.ldap.dn=${security.ldap.dn} -security.ldap.url=${security.ldap.url} -security.ldap.baseDn=${security.ldap.baseDn} -security.ldap.system.username=${security.ldap.system.username} -security.ldap.system.password=${security.ldap.system.password} -security.ldap.searchString=${security.ldap.searchString} -security.ldap.searchBase=${security.ldap.searchBase} -security.ldap.userMapping.displaynameAttr=${security.ldap.userMapping.displaynameAttr} -security.ldap.userMapping.firstnameAttr=${security.ldap.userMapping.firstnameAttr} -security.ldap.userMapping.middlenameAttr=${security.ldap.userMapping.middlenameAttr} -security.ldap.userMapping.lastnameAttr=${security.ldap.userMapping.lastnameAttr} -security.ldap.userMapping.usernameAttr=${security.ldap.userMapping.usernameAttr} -security.ldap.userImport.usernameAttr=${security.ldap.userImport.usernameAttr} -security.ldap.userImport.loginAttr=${security.ldap.userImport.loginAttr} -security.ad.url=${security.ad.url} -security.ad.searchBase=${security.ad.searchBase} -security.ad.principalSuffix=${security.ad.principalSuffix} -security.ad.system.username=${security.ad.system.username} -security.ad.system.password=${security.ad.system.password} -security.ad.searchFilter=${security.ad.searchFilter} -security.ad.searchString=${security.ad.searchString} -security.ad.ignore.partial.result.exception=${security.ad.ignore.partial.result.exception} -security.ad.result.count.limit=${security.ad.result.count.limit} -security.ad.default.import.group=${security.ad.default.import.group} -security.ad.userMapping.displaynameAttr=${security.ad.userMapping.displaynameAttr} -security.ad.userMapping.firstnameAttr=${security.ad.userMapping.firstnameAttr} -security.ad.userMapping.middlenameAttr=${security.ad.userMapping.middlenameAttr} -security.ad.userMapping.lastnameAttr=${security.ad.userMapping.lastnameAttr} -security.ad.userMapping.usernameAttr=${security.ad.userMapping.usernameAttr} -security.ad.userImport.usernameAttr=${security.ad.userImport.usernameAttr} -security.ad.userImport.loginAttr=${security.ad.userImport.loginAttr} - -security.saml.enabled=${security.saml.enabled} -security.saml.entityId=${security.saml.entityId} -security.saml.idpMetadataLocation=${security.saml.idpMetadataLocation} -security.saml.keyManager.keyStoreFile=${security.saml.keyManager.keyStoreFile} -security.saml.keyManager.storePassword=${security.saml.keyManager.storePassword} -security.saml.keyManager.defaultKey=${security.saml.keyManager.defaultKey} -security.saml.keyManager.passwords.arachnenetwork=${security.saml.keyManager.passwords.arachnenetwork} -security.saml.metadataLocation=${security.saml.metadataLocation} -security.saml.callbackUrl=${security.saml.callbackUrl} -security.saml.sloUrl=${security.saml.sloUrl} -security.saml.maximumAuthenticationLifetime=${security.saml.maximumAuthenticationLifetime} - -security.googleIap.cloudProjectId=${security.googleIap.cloudProjectId} -security.googleIap.backendServiceId=${security.googleIap.backendServiceId} -security.google.accessToken.enabled=${security.google.accessToken.enabled} - -security.kerberos.spn=${security.kerberos.spn} -security.kerberos.keytabPath=${security.kerberos.keytabPath} - -security.maxLoginAttempts=${security.maxLoginAttempts} -security.duration.initial=${security.duration.initial} -security.duration.increment=${security.duration.increment} - -security.auth.windows.enabled=${security.auth.windows.enabled} -security.auth.kerberos.enabled=${security.auth.kerberos.enabled} -security.auth.openid.enabled=${security.auth.openid.enabled} -security.auth.facebook.enabled=${security.auth.facebook.enabled} -security.auth.github.enabled=${security.auth.github.enabled} -security.auth.google.enabled=${security.auth.google.enabled} -security.auth.jdbc.enabled=${security.auth.jdbc.enabled} -security.auth.ldap.enabled=${security.auth.ldap.enabled} -security.auth.ad.enabled=${security.auth.ad.enabled} -security.auth.cas.enabled=${security.auth.cas.enabled} - - -#Hikari -spring.datasource.hikari.connection-test-query=${spring.datasource.hikari.connection-test-query} -spring.datasource.hikari.connection-test-query-timeout=${spring.datasource.hikari.connection-test-query-timeout} -spring.datasource.hikari.maximum-pool-size=${spring.datasource.hikari.maximum-pool-size} -spring.datasource.hikari.minimum-idle=${spring.datasource.hikari.minimum-idle} -spring.datasource.hikari.connection-timeout=${spring.datasource.hikari.connection-timeout} -spring.datasource.hikari.register-mbeans=${spring.datasource.hikari.register-mbeans} -spring.datasource.hikari.mbean-name=${spring.datasource.hikari.mbean-name} - -person.viewDates=${person.viewDates} - -#Heracles settings -heracles.smallcellcount=${heracles.smallcellcount} - -jasypt.encryptor.enabled=${jasypt.encryptor.enabled} -jasypt.encryptor.password=${jasypt.encryptor.password} -jasypt.encryptor.algorithm=${jasypt.encryptor.algorithm} - -#Kerberos settings -kerberos.timeout=${kerberos.timeout} -kerberos.configPath=${kerberos.configPath} -kerberos.kinitPath=${kerberos.kinitPath} - -#Organization Settings -organization.name=${organization.name} - -#JdbcTemplate -jdbc.suppressInvalidApiException=${jdbc.suppressInvalidApiException} - -#Sensitive info settings -sensitiveinfo.admin.role=${sensitiveinfo.admin.role} -sensitiveinfo.moderator.role=${sensitiveinfo.moderator.role} -sensitiveinfo.analysis.extensions=${sensitiveinfo.analysis.extensions} -analysis.result.zipVolumeSizeMb=${analysis.result.zipVolumeSizeMb} - -#Cache Config -cdm.result.cache.warming.enable=${cdm.result.cache.warming.enable} -cdm.cache.achilles.warming.enable=${cdm.cache.achilles.warming.enable} -cdm.cache.cron.warming.enable=${cdm.cache.cron.warming.enable} -cdm.cache.cron.expression=${cdm.cache.cron.expression} - -cache.generation.invalidAfterDays=${cache.generation.invalidAfterDays} -cache.generation.cleanupInterval=${cache.generation.cleanupInterval} -cache.generation.useAsync=${cache.generation.useAsync} -cache.jobs.count=${cache.jobs.count} - -# Achilles cache -cache.achilles.usePersonCount=${cache.achilles.usePersonCount} - -#Atlas geo spatial -atlasgis.enabled=${gis.enabled} - -#I18n -i18n.enabled=${i18n.enabled} -i18n.defaultLocale=${i18n.defaultLocale} - -#Tags -tag.enabled=${tag.enabled} -tag.refreshStat.period=${tag.refreshStat.period} - -#Versioning -versioning.maxAttempt=${versioning.maxAttempt} - -#Audit trail -audit.trail.enabled=${audit.trail.enabled} -audit.trail.log.file=${audit.trail.log.file} -audit.trail.log.file.pattern=${audit.trail.log.file.pattern} -audit.trail.log.extraFile=${audit.trail.log.extraFile} - -# Trexsql configuration -trexsql.enabled=${trexsql.enabled} -trexsql.cache-path=${trexsql.cache-path} -trexsql.extensions-path=${trexsql.extensions-path} +solr.endpoint= +solr.query.prefix= + +# ============================================================================= +# R SERVICE +# ============================================================================= +r.serviceHost= + +# ============================================================================= +# PERSON SETTINGS +# ============================================================================= +person.viewDates=false + +# ============================================================================= +# HERACLES +# ============================================================================= +heracles.smallcellcount=5 + +# ============================================================================= +# JASYPT ENCRYPTION +# ============================================================================= +jasypt.encryptor.enabled=false +jasypt.encryptor.password= +jasypt.encryptor.algorithm=PBEWithMD5AndDES + +# ============================================================================= +# ORGANIZATION +# ============================================================================= +organization.name=OHDSI + +# ============================================================================= +# JDBC TEMPLATE +# ============================================================================= +jdbc.suppressInvalidApiException=false + +# ============================================================================= +# SENSITIVE INFO +# ============================================================================= +sensitiveinfo.admin.role= +sensitiveinfo.moderator.role= +sensitiveinfo.analysis.extensions= +analysis.result.zipVolumeSizeMb=100 + +# ============================================================================= +# CACHE CONFIGURATION +# ============================================================================= +cdm.result.cache.warming.enable=false +cdm.cache.achilles.warming.enable=false +cdm.cache.cron.warming.enable=false +cdm.cache.cron.expression=0 0 2 * * ? +cache.generation.invalidAfterDays=30 +cache.generation.cleanupInterval=86400000 +cache.generation.useAsync=true +cache.jobs.count=5 +cache.achilles.usePersonCount=true + +# ============================================================================= +# GIS +# ============================================================================= +atlasgis.enabled=${gis.enabled:false} + +# ============================================================================= +# I18N +# ============================================================================= +i18n.enabled=false +i18n.defaultLocale=en + +# ============================================================================= +# TAGS +# ============================================================================= +tag.enabled=false +tag.refreshStat.period=60000 + +# ============================================================================= +# VERSIONING +# ============================================================================= +versioning.maxAttempt=3 + +# ============================================================================= +# AUDIT TRAIL +# ============================================================================= +audit.trail.enabled=${AUDIT_TRAIL_ENABLED:false} +audit.trail.log.file=${AUDIT_TRAIL_LOG_FILE:} +audit.trail.log.file.pattern=${AUDIT_TRAIL_LOG_FILE_PATTERN:} +audit.trail.log.extraFile=${AUDIT_TRAIL_LOG_EXTRAFILE:} + +# ============================================================================= +# TREXSQL +# ============================================================================= +trexsql.enabled=false +trexsql.cache-path=/tmp/trexsql +trexsql.extensions-path=