FINERACT-1433: Switch to Java based config for Spring

This commit is contained in:
Petri Tuomola
2021-11-21 04:21:10 +01:00
committed by Aleksandar Vidakovic
parent 2513ee4837
commit 2b57bf379e
31 changed files with 454 additions and 712 deletions
+1 -1
View File
@@ -100,7 +100,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_if_empty"/>
+1 -1
View File
@@ -106,7 +106,7 @@ dependencies {
exclude group: 'javax.activation'
}
runtimeOnly('org.ehcache:ehcache') {
implementation ('org.ehcache:ehcache') {
exclude group: 'com.sun.activation'
}
@@ -21,6 +21,11 @@ spring.profiles.default=basicauth
spring.profiles.active=basicauth,twofactor
management.health.jms.enabled=false
# FINERACT 1296
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
# FINERACT-883
management.info.git.mode=FULL
@@ -21,9 +21,13 @@ spring.profiles.default=basicauth
spring.profiles.active=oauth
management.health.jms.enabled=false
# FINERACT 1296
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
# FINERACT-883
management.info.git.mode=FULL
# FINERACT-914
server.forward-headers-strategy=framework
spring.cache.jcache.config=classpath:/META-INF/spring/ehcache.xml
@@ -21,9 +21,13 @@ spring.profiles.default=basicauth
spring.profiles.active=oauth,twofactor
management.health.jms.enabled=false
# FINERACT 1296
management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true
# FINERACT-883
management.info.git.mode=FULL
# FINERACT-914
server.forward-headers-strategy=framework
spring.cache.jcache.config=classpath:/META-INF/spring/ehcache.xml
@@ -26,7 +26,6 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
/**
* Fineract main() application which launches Fineract in an embedded Tomcat HTTP (using Spring Boot).
@@ -39,13 +38,11 @@ import org.springframework.context.annotation.ImportResource;
*
* It's the old/classic Mifos (non-X) Workspace 2.0 reborn for Fineract! ;-)
*
* @see ServerWithMariaDB4jApplication for an alternative with an embedded DB
*/
public class ServerApplication extends SpringBootServletInitializer {
@Import({ EmbeddedTomcatWithSSLConfiguration.class })
@ImportResource({ "classpath*:META-INF/spring/hikariDataSource.xml" })
private static class Configuration extends AbstractApplicationConfiguration {}
@Override
@@ -1,105 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import org.apache.fineract.infrastructure.core.boot.AbstractApplicationConfiguration;
import org.apache.fineract.infrastructure.core.boot.ApplicationExitUtil;
import org.apache.fineract.infrastructure.core.boot.EmbeddedTomcatWithSSLConfiguration;
import org.apache.fineract.infrastructure.core.boot.db.MariaDB4jDataSourceConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource;
/**
* Fineract main() application which launches Fineract in an embedded Tomcat HTTP
* server (using Spring Boot), as well as an embedded database (using
* MariaDB4j).
*
* You can easily launch this via Debug as Java Application in your IDE -
* without needing command line Gradle stuff, no need to build and deploy a WAR,
* remote attachment etc.
*
* It's the old/classic Mifos (non-X) Workspace 2.0 reborn for Fineract! ;-)
*
* @see ServerApplication for the same without the embedded MariaDB4j database
*/
public class ServerWithMariaDB4jApplication {
private final static Logger LOG = LoggerFactory.getLogger(ServerWithMariaDB4jApplication.class);
@Import({ MariaDB4jDataSourceConfiguration.class, EmbeddedTomcatWithSSLConfiguration.class })
public static class Configuration extends AbstractApplicationConfiguration { }
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = SpringApplication.run(Configuration.class, args);
if (!Desktop.isDesktopSupported()) {
LOG.info("Not going to open UI homepage in local web browser, because !Desktop.isDesktopSupported()");
} else {
// apps/community-app/dist/community-app/index.html
Resource distResource = ctx.getResource("file:" + System.getProperty("user.dir") +
System.getProperty("file.separator") + "apps" +
System.getProperty("file.separator") + "community-app" +
System.getProperty("file.separator") + "dist" +
System.getProperty("file.separator") + "community-app" +
System.getProperty("file.separator") + "index.html");
URI distURI = URI.create("https://localhost:8443/fineract-provider" +
"/apps/community-app/index.html?baseApiUrl=https://localhost:8443" +
"&tenantIdentifier=default#/");
// apps/community-app/app/index.html
Resource devResource = ctx.getResource("file:" + System.getProperty("user.dir") +
System.getProperty("file.separator") + "apps" +
System.getProperty("file.separator") + "community-app" +
System.getProperty("file.separator") + "app" +
System.getProperty("file.separator") + "index.html");
URI devURI = URI.create("https://localhost:8443/fineract-provider" +
"/apps/community-app/app/index.html?baseApiUrl=https://localhost:8443" +
"&tenantIdentifier=default#/");
if (distResource.exists()) {
openWebBrowser(distURI);
} else if (devResource.exists()) {
openWebBrowser(devURI);
} else {
LOG.error("Cannot open Fineract UI in browser; not found: " + distResource.toString());
}
}
// TODO Tray Icon stuff; dig out my very own old @see https://github.com/mifos/head/tree/hudsonBuild-MIFOS-5157_Launch4j-EXE_NewDist-squash1/server-jetty/src/main/java/org/mifos/server/tray
ApplicationExitUtil.waitForKeyPressToCleanlyExit(ctx);
}
private static void openWebBrowser(URI uri) {
try {
LOG.info("Opening Fineract UI in browser: " + uri.toString());
Desktop.getDesktop().browse(uri);
} catch (IOException e) {
LOG.error("IOException when opening Fineract UI in browser: " + uri.toString(), e);
}
}
}
@@ -22,18 +22,14 @@ import org.apache.fineract.infrastructure.cache.service.RuntimeDelegatingCacheMa
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SuppressWarnings("deprecation")
@Configuration
@EnableCaching
public class PlatformCacheConfiguration implements CachingConfigurer {
public class PlatformCacheConfiguration extends CachingConfigurerSupport implements CachingConfigurer {
@Autowired
private RuntimeDelegatingCacheManager delegatingCacheManager;
@@ -43,21 +39,4 @@ public class PlatformCacheConfiguration implements CachingConfigurer {
public CacheManager cacheManager() {
return this.delegatingCacheManager;
}
@Override
public CacheResolver cacheResolver() {
// TODO https://issues.apache.org/jira/browse/FINERACT-705
return null;
}
@Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
}
@Override
public CacheErrorHandler errorHandler() {
// TODO https://issues.apache.org/jira/browse/FINERACT-705
return null;
}
}
@@ -47,13 +47,13 @@ public class RuntimeDelegatingCacheManager implements CacheManager {
private static final Logger LOG = LoggerFactory.getLogger(RuntimeDelegatingCacheManager.class);
private final JCacheCacheManager jcacheCacheManager;
private final CacheManager cacheManager;
private final CacheManager noOpCacheManager = new NoOpCacheManager();
private CacheManager currentCacheManager;
@Autowired
public RuntimeDelegatingCacheManager(final JCacheCacheManager jcacheCacheManager) {
this.jcacheCacheManager = jcacheCacheManager;
public RuntimeDelegatingCacheManager(final JCacheCacheManager cacheManager) {
this.cacheManager = cacheManager;
this.currentCacheManager = this.noOpCacheManager;
}
@@ -109,7 +109,7 @@ public class RuntimeDelegatingCacheManager implements CacheManager {
changes.put(CacheApiConstants.cacheTypeParameter, toCacheType.getValue());
clearEhCache();
}
this.currentCacheManager = this.jcacheCacheManager;
this.currentCacheManager = this.cacheManager;
if (this.currentCacheManager.getCacheNames().size() == 0) {
LOG.error("No caches configured for activated CacheManager {}", this.currentCacheManager);
@@ -126,7 +126,6 @@ public class RuntimeDelegatingCacheManager implements CacheManager {
}
private void clearEhCache() {
javax.cache.CacheManager cacheManager = this.jcacheCacheManager.getCacheManager();
Iterable<String> cacheNames = cacheManager.getCacheNames();
for (String cacheName : cacheNames) {
cacheManager.getCache(cacheName).clear();
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.infrastructure.core.boot;
import org.apache.fineract.notification.config.MessagingConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
@@ -26,33 +25,24 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* Base Spring Configuration with what's common to all Configuration subclasses.
*
* Notably the EnableAutoConfiguration excludes relevant for (and often adjusted when upgrading versions of) Spring
* Boot, the "old" (pre. Spring Boot &amp; MariaDB4j) fineract appContext.xml which all configurations need, and the
* web.xml successor WebXmlConfiguration.
*
* Should NOT include Configuration related to embedded Tomcat, data sources, and MariaDB4j (because those differ in the
* subclasses).
* Base Spring Configuration. Excludes autoconfiguration for those things we want to manually configure.
*/
@Configuration
@Import({ WebXmlConfiguration.class, WebXmlOauthConfiguration.class, WebFrontEndConfiguration.class, MessagingConfiguration.class,
WebTwoFactorXmlConfiguration.class, JerseyConfig.class })
@ImportResource({ "classpath*:META-INF/spring/appContext.xml" })
@PropertySource(value = "classpath:META-INF/spring/jdbc.properties")
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, FlywayAutoConfiguration.class, GsonAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class })
@EnableWebSecurity
@EnableTransactionManagement
@EnableWebSecurity
@ComponentScan(basePackages = "org.apache.fineract.**")
public abstract class AbstractApplicationConfiguration {
}
@@ -1,36 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot;
import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebTwoFactorXmlConfiguration {
@Bean
public FilterRegistrationBean twoFactorFilterBean(TwoFactorAuthenticationFilter filter) {
FilterRegistrationBean<TwoFactorAuthenticationFilter> registrationBean = new FilterRegistrationBean<TwoFactorAuthenticationFilter>(
filter);
registrationBean.setEnabled(false);
return registrationBean;
}
}
@@ -1,49 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot;
import org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/**
* This Configuration replaces what formerly was in web.xml.
*
* @see <a href=
* "http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-convert-an-existing-application-to-spring-boot">#howto-convert-an-existing-application-to-spring-boot</a>
*/
@Configuration
@Profile("basicauth")
public class WebXmlConfiguration {
@Autowired
private TenantAwareBasicAuthenticationFilter basicAuthenticationProcessingFilter;
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean<TenantAwareBasicAuthenticationFilter> filterRegistrationBean = new FilterRegistrationBean<TenantAwareBasicAuthenticationFilter>();
filterRegistrationBean.setFilter(basicAuthenticationProcessingFilter);
filterRegistrationBean.setEnabled(false);
return filterRegistrationBean;
}
}
@@ -1,62 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.db;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ch.vorburger.mariadb4j.springframework.MariaDB4jSpringService;
@Configuration
public class MariaDB4jDataSourceConfiguration extends DataSourceConfiguration {
@Bean
public MariaDB4jSetupService mariaDB4jSetUp() {
return new MariaDB4jSetupService(mariaDB4j().getDB());
}
@Bean
public MariaDB4jSpringService mariaDB4j() {
MariaDB4jSpringService mariaDB4jSpringService = new MariaDB4jSpringService();
mariaDB4jSpringService.setDefaultBaseDir("build/db/bin");
mariaDB4jSpringService.setDefaultDataDir("build/db/data");
return mariaDB4jSpringService;
}
@Override
// NOT @Bean @Override dataSourceProperties() - doesn't work :(
protected DataSourceProperties getProperties() {
DataSourceProperties p = super.getProperties();
String dbName = mariaDB4jSetUp().getTenantDBName();
// Do not use p.setUrl(mariaDB4j().getConfiguration().getURL(dbName));
// Because TenantDataSourcePortFixService needs separate
// host/port/db/uid/pwd:
// (DataSourceProperties getUrl() creates the correct JDBC URL from it)
// This intentionally overrides any fineract.datasource.* settings, because
// in this configuration, logically the mariaDB4j settings take
// precedence:
p.setHost("localhost");
p.setPort(mariaDB4j().getConfiguration().getPort());
p.setDBName(dbName);
// TODO p.setUsername(mariaDB4j().getConfiguration().getUsername());
// TODO p.setPassword(mariaDB4j().getConfiguration().getPassword());
return p;
}
}
@@ -1,54 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot.db;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import ch.vorburger.exec.ManagedProcessException;
import ch.vorburger.mariadb4j.DB;
public class MariaDB4jSetupService {
private DB db;
@Autowired
public MariaDB4jSetupService(DB db) {
this.db = db;
}
@PostConstruct
protected void setUpDBs() throws ManagedProcessException {
db.createDB(getTenantDBName());
db.createDB("fineract_default");
// Note that we don't need to initialize the DBs, because
// the TenantDatabaseUpgradeService will do this in just a moment.
}
public String getTenantDBName() {
return "fineract_tenants";
}
@PreDestroy
protected void stop() throws ManagedProcessException {
db = null;
}
}
@@ -0,0 +1,73 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.config;
import java.time.Duration;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.spi.CachingProvider;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.jsr107.Eh107Configuration;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CacheConfig {
@Bean
public JCacheCacheManager ehCacheManager() {
JCacheCacheManager jCacheCacheManager = new JCacheCacheManager();
jCacheCacheManager.setCacheManager(getCustomCacheManager());
return jCacheCacheManager;
}
private CacheManager getCustomCacheManager() {
CachingProvider provider = Caching.getCachingProvider();
CacheManager cacheManager = provider.getCacheManager();
javax.cache.configuration.Configuration<Object, Object> defaultTemplate = Eh107Configuration.fromEhcacheCacheConfiguration(
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
.withExpiry(ExpiryPolicyBuilder.noExpiration()).build());
cacheManager.createCache("users", defaultTemplate);
cacheManager.createCache("usersByUsername", defaultTemplate);
cacheManager.createCache("tenantsById", defaultTemplate);
cacheManager.createCache("offices", defaultTemplate);
cacheManager.createCache("officesForDropdown", defaultTemplate);
cacheManager.createCache("officesById", defaultTemplate);
cacheManager.createCache("charges", defaultTemplate);
cacheManager.createCache("funds", defaultTemplate);
cacheManager.createCache("code_values", defaultTemplate);
cacheManager.createCache("codes", defaultTemplate);
cacheManager.createCache("hooks", defaultTemplate);
cacheManager.createCache("tfConfig", defaultTemplate);
javax.cache.configuration.Configuration<Object, Object> accessTokenTemplate = Eh107Configuration.fromEhcacheCacheConfiguration(
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
.withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofHours(2))).build());
cacheManager.createCache("userTFAccessToken", accessTokenTemplate);
return cacheManager;
}
}
@@ -0,0 +1,83 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.config;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@Configuration
public class HikariCpConfig {
@Autowired
ApplicationContext context;
@Bean(destroyMethod = "close")
public HikariDataSource hikariTenantDataSource(HikariConfig hc) {
return new HikariDataSource(hc);
}
@Bean
public HikariConfig hikariConfig() {
Environment environment = context.getEnvironment();
HikariConfig hc = new HikariConfig();
hc.setDriverClassName(environment.getProperty("fineract_tenants_driver"));
hc.setJdbcUrl(environment.getProperty("fineract_tenants_url"));
hc.setUsername(environment.getProperty("fineract_tenants_uid"));
hc.setPassword(environment.getProperty("fineract_tenants_pwd"));
hc.setMinimumIdle(3);
hc.setMaximumPoolSize(10);
hc.setIdleTimeout(60000);
hc.setConnectionTestQuery("SELECT 1");
hc.setDataSourceProperties(dataSourceProperties());
return hc;
}
// These are the properties for the all Tenants DB; the same configuration is also (hard-coded) in the
// TomcatJdbcDataSourcePerTenantService class -->
private Properties dataSourceProperties() {
Properties props = new Properties();
props.setProperty("cachePrepStmts", "true");
props.setProperty("prepStmtCacheSize", "250");
props.setProperty("prepStmtCacheSqlLimit", "2048");
props.setProperty("useServerPrepStmts", "true");
props.setProperty("useLocalSessionState", "true");
props.setProperty("rewriteBatchedStatements", "true");
props.setProperty("cacheResultSetMetadata", "true");
props.setProperty("cacheServerConfiguration", "true");
props.setProperty("elideSetAutoCommits", "true");
props.setProperty("maintainTimeStats", "false");
// https://github.com/brettwooldridge/HikariCP/wiki/JDBC-Logging#mysql-connectorj
// TODO FINERACT-890: <prop key="logger">com.mysql.cj.log.Slf4JLogger</prop>
props.setProperty("logSlowQueries", "true");
props.setProperty("dumpQueriesOnException", "true");
return props;
}
}
@@ -17,7 +17,7 @@
* under the License.
*/
package org.apache.fineract.infrastructure.core.boot;
package org.apache.fineract.infrastructure.core.config;
import javax.annotation.PostConstruct;
import javax.ws.rs.ApplicationPath;
@@ -0,0 +1,76 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.config;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.apache.fineract.infrastructure.core.domain.AuditorAwareImpl;
import org.apache.fineract.infrastructure.openjpa.OpenJpaVendorAdapter;
import org.apache.fineract.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.support.TransactionTemplate;
@Configuration
@EnableJpaAuditing
@EnableJpaRepositories(basePackages = "org.apache.fineract.**.domain")
public class PersistenceConfig {
@Autowired
DataSource routingDataSource;
@Bean
@DependsOn("tenantDatabaseUpgradeService")
public EntityManagerFactory entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(routingDataSource);
em.setJpaVendorAdapter(new OpenJpaVendorAdapter());
em.setPersistenceUnitName("jpa-pu");
em.afterPropertiesSet();
return em.getObject();
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager jtm = new JpaTransactionManager();
jtm.setEntityManagerFactory(emf);
return jtm;
}
@Bean
public TransactionTemplate txTemplate(JpaTransactionManager jtm) {
TransactionTemplate tt = new TransactionTemplate();
tt.setTransactionManager(jtm);
return tt;
}
@Bean
public AuditorAware<AppUser> auditorAware() {
return new AuditorAwareImpl();
}
}
@@ -0,0 +1,140 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.config;
import org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthenticationFilter;
import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter;
import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
@Configuration
@Profile("basicauth")
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private TenantAwareJpaPlatformUserDetailsService userDetailsService;
@Autowired
private TenantAwareBasicAuthenticationFilter tenantAwareBasicAuthenticationFilter;
@Autowired
private TwoFactorAuthenticationFilter twoFactorAuthenticationFilter;
/**
* The purpose of this method is to exclude the URL's specific to Login, Swagger UI and static files. Any URL that
* should be excluded from the Spring security chain should be added to the ignore list in this method only
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui/**", "/actuator/**", "/api-docs/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**").csrf().disable() //
.authorizeRequests() //
.antMatchers(HttpMethod.POST, "/api/*/echo").permitAll() //
.antMatchers(HttpMethod.POST, "/api/*/authentication").permitAll() //
.antMatchers(HttpMethod.POST, "/api/*/self/authentication").permitAll() //
.antMatchers(HttpMethod.POST, "/api/*/self/registration").permitAll() //
.antMatchers(HttpMethod.POST, "/api/*/self/registration/user").permitAll() //
.antMatchers(HttpMethod.POST, "/api/*/twofactor/validate").fullyAuthenticated() //
.antMatchers("/api/*/twofactor").fullyAuthenticated() //
.antMatchers("/api/**").access("isFullyAuthenticated() and hasAuthority('TWOFACTOR_AUTHENTICATED')").and() //
.httpBasic() //
.authenticationEntryPoint(basicAuthenticationEntryPoint()) //
.and() //
.sessionManagement() //
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) //
.and() //
.addFilterAfter(tenantAwareBasicAuthenticationFilter, SecurityContextPersistenceFilter.class) //
.addFilterAfter(twoFactorAuthenticationFilter, BasicAuthenticationFilter.class) //
.requiresChannel(channel -> channel.antMatchers("/api/**").requiresSecure());
}
@Bean
public BasicAuthenticationEntryPoint basicAuthenticationEntryPoint() {
BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
basicAuthenticationEntryPoint.setRealmName("Fineract Platform API");
return basicAuthenticationEntryPoint;
}
@Bean(name = "customAuthenticationProvider")
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
auth.eraseCredentials(false);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public FilterRegistrationBean<TenantAwareBasicAuthenticationFilter> tenantAwareBasicAuthenticationFilterRegistration() {
FilterRegistrationBean<TenantAwareBasicAuthenticationFilter> registration = new FilterRegistrationBean<TenantAwareBasicAuthenticationFilter>(
tenantAwareBasicAuthenticationFilter);
registration.setEnabled(false);
return registration;
}
@Bean
public FilterRegistrationBean<TwoFactorAuthenticationFilter> twoFactorAuthenticationFilterRegistration() {
FilterRegistrationBean<TwoFactorAuthenticationFilter> registration = new FilterRegistrationBean<TwoFactorAuthenticationFilter>(
twoFactorAuthenticationFilter);
registration.setEnabled(false);
return registration;
}
}
@@ -0,0 +1,49 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.core.config;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.security.core.context.SecurityContextHolder;
@Configuration
public class SpringConfig {
@Bean
public SimpleApplicationEventMulticaster applicationEventMulticaster() {
SimpleApplicationEventMulticaster saem = new SimpleApplicationEventMulticaster();
saem.setTaskExecutor(new SimpleAsyncTaskExecutor());
return saem;
}
// The application events (for importing) rely on the inheritable thread local security context strategy
// This is NOT compatible with threadpools so if we use threadpools the below will need to be reworked
@Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean() {
MethodInvokingFactoryBean mifb = new MethodInvokingFactoryBean();
mifb.setTargetClass(SecurityContextHolder.class);
mifb.setTargetMethod("setStrategyName");
mifb.setArguments("MODE_INHERITABLETHREADLOCAL");
return mifb;
}
}
@@ -25,7 +25,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@SuppressWarnings("deprecation")
@Service(value = "applicationPasswordEncoder")
@Scope("singleton")
public class DefaultPlatformPasswordEncoder implements PlatformPasswordEncoder {
@@ -40,7 +40,7 @@ import org.springframework.stereotype.Service;
*
* This filter adds 'TWOFACTOR_AUTHENTICATED' authority to every authenticated platform user.
*/
@Service(value = "twoFactorAuthFilter")
@Service
@Profile("!twofactor")
public class InsecureTwoFactorAuthenticationFilter extends TwoFactorAuthenticationFilter {
@@ -59,7 +59,7 @@ import org.springframework.stereotype.Service;
*
* If multi-tenant and basic auth credentials are invalid, a http error response is returned.
*/
@Service(value = "basicAuthenticationProcessingFilter")
@Service
@Profile("basicauth")
public class TenantAwareBasicAuthenticationFilter extends BasicAuthenticationFilter {
@@ -54,7 +54,7 @@ import org.springframework.web.filter.GenericFilterBean;
* An authenticated platform user with permission 'BYPASS_TWOFACTOR' will always be granted 'TWOFACTOR_AUTHENTICATED'
* authority regardless of the value of the 'Fineract-Platform-TFA-Token' header.
*/
@Service(value = "twoFactorAuthFilter")
@Service
@Profile("twofactor")
public class TwoFactorAuthenticationFilter extends GenericFilterBean {
@@ -31,7 +31,7 @@ import org.springframework.stereotype.Service;
/**
* Used in securityContext.xml as implementation of spring security's {@link UserDetailsService}.
*/
@Service(value = "userDetailsService")
@Service("userDetailsService")
public class TenantAwareJpaPlatformUserDetailsService implements PlatformUserDetailsService {
@Autowired
@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:sec="http://www.springframework.org/schema/security"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<sec:global-method-security
pre-post-annotations="enabled" />
<context:component-scan base-package="org.apache.fineract.**">
<context:exclude-filter expression="org.springframework.stereotype.Controller"
type="annotation" />
<!-- We do NOT want all @Configuration "beans" to be auto-detected by ComponentScan,
but we want to use / import them explicitly in Tests & Spring Boot applications,
or other import in other @Configuration, so that we could have mutually exclusive ones.
-->
<context:exclude-filter expression="org.springframework.context.annotation.Configuration"
type="annotation" />
</context:component-scan>
<bean id="auditorAware"
class="org.apache.fineract.infrastructure.core.domain.AuditorAwareImpl" />
<jpa:auditing auditor-aware-ref="auditorAware" />
<jpa:repositories base-package="org.apache.fineract.**.domain" />
<import resource="infrastructure.xml" />
<import resource="securityContext.xml" />
<import resource="cache.xml" />
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor">
<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
</property>
</bean>
<!-- The application events (for importing) rely on the inheritable thread local security context strategy
This is NOT compatible with threadpools so if we use threadpools the below will need to be reworked -->
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"
value="org.springframework.security.core.context.SecurityContextHolder" />
<property name="targetMethod" value="setStrategyName" />
<property name="arguments" value="MODE_INHERITABLETHREADLOCAL" />
</bean>
</beans>
@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<bean id="ehcacheManager" class="org.springframework.cache.jcache.JCacheCacheManager"
p:cacheManager-ref="ehcacheInstance" />
<bean id="ehcacheInstance"
class="org.springframework.cache.jcache.JCacheManagerFactoryBean" p:cacheManagerUri="classpath:/META-INF/spring/ehcache.xml"/>
</beans>
@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.7.xsd">
<cache-template name="defaultTemplate">
<expiry>
<none/>
</expiry>
<heap unit="entries">
10000
</heap>
</cache-template>
<cache alias="users" uses-template="defaultTemplate"/>
<cache alias="usersByUsername" uses-template="defaultTemplate"/>
<cache alias="tenantsById" uses-template="defaultTemplate"/>
<cache alias="offices" uses-template="defaultTemplate"/>
<cache alias="officesForDropdown" uses-template="defaultTemplate"/>
<cache alias="officesById" uses-template="defaultTemplate"/>
<cache alias="charges" uses-template="defaultTemplate"/>
<cache alias="funds" uses-template="defaultTemplate"/>
<cache alias="code_values" uses-template="defaultTemplate"/>
<cache alias="codes" uses-template="defaultTemplate"/>
<cache alias="hooks" uses-template="defaultTemplate"/>
<cache alias="tfConfig" uses-template="defaultTemplate"/>
<cache alias="userTFAccessToken" uses-template="defaultTemplate">
<expiry>
<tti unit="seconds">7200</tti>
</expiry>
</cache>
</config>
@@ -1,69 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- HikariCP Database bean -->
<bean id="hikariTenantDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<!-- HikariConfig config that is fed to above dataSource -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="driverClassName" value="${fineract_tenants_driver}" />
<property name="jdbcUrl" value="${fineract_tenants_url}" />
<property name="username" value="${fineract_tenants_uid}" />
<property name="password" value="${fineract_tenants_pwd}" />
<property name="minimumIdle" value="3" />
<property name="maximumPoolSize" value="10" />
<property name="idleTimeout" value="60000" />
<property name="ConnectionTestQuery" value="SELECT 1" />
<!-- These are the properties for the all Tenants DB; the same configuration is also (hard-coded) in the TomcatJdbcDataSourcePerTenantService class -->
<property name="dataSourceProperties">
<props>
<!-- https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration -->
<prop key="cachePrepStmts">true</prop>
<prop key="prepStmtCacheSize">250</prop>
<prop key="prepStmtCacheSqlLimit">2048</prop>
<prop key="useServerPrepStmts">true</prop>
<prop key="useLocalSessionState">true</prop>
<prop key="rewriteBatchedStatements">true</prop>
<prop key="cacheResultSetMetadata">true</prop>
<prop key="cacheServerConfiguration">true</prop>
<prop key="elideSetAutoCommits">true</prop>
<prop key="maintainTimeStats">false</prop>
<!-- https://github.com/brettwooldridge/HikariCP/wiki/JDBC-Logging#mysql-connectorj -->
<!-- TODO FINERACT-890: <prop key="logger">com.mysql.cj.log.Slf4JLogger</prop> -->
<prop key="logSlowQueries">true</prop>
<prop key="dumpQueriesOnException">true</prop>
</props>
</property>
</bean>
</beans>
@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
depends-on="tenantDatabaseUpgradeService">
<property name="dataSource" ref="routingDataSource" />
<property name="persistenceUnitName" value="jpa-pu" />
<property name="jpaVendorAdapter">
<bean class="org.apache.fineract.infrastructure.openjpa.OpenJpaVendorAdapter"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Create instance of transaction template for programmatic transaction manipulation -->
<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
</beans>
@@ -31,60 +31,6 @@
http://www.springframework.org/schema/security
https://www.springframework.org/schema/security/spring-security.xsd">
<beans:beans profile="basicauth">
<http create-session="stateless" use-expressions="true" pattern="/api/**"
entry-point-ref="basicAuthenticationEntryPoint">
<csrf disabled="true"/>
<intercept-url pattern="/api/*/echo" access="permitAll" />
<intercept-url pattern="/api/*/authentication" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/self/authentication" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/self/registration" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/self/registration/user" access="permitAll"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/twofactor" access="isFullyAuthenticated()"
method="GET" requires-channel="https" />
<intercept-url pattern="/api/*/twofactor" access="isFullyAuthenticated()"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/*/twofactor/validate" access="isFullyAuthenticated()"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated() and hasAuthority('TWOFACTOR_AUTHENTICATED')"
method="GET" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated() and hasAuthority('TWOFACTOR_AUTHENTICATED')"
method="POST" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated() and hasAuthority('TWOFACTOR_AUTHENTICATED')"
method="PUT" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated() and hasAuthority('TWOFACTOR_AUTHENTICATED')"
method="DELETE" requires-channel="https" />
<intercept-url pattern="/api/**" access="isFullyAuthenticated() and hasAuthority('TWOFACTOR_AUTHENTICATED')"
method="HEAD" requires-channel="https" />
<custom-filter after="SECURITY_CONTEXT_FILTER" ref="basicAuthenticationProcessingFilter" />
<custom-filter ref="twoFactorAuthFilter" after="BASIC_AUTH_FILTER" />
</http>
<beans:bean id="basicAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<beans:property name="realmName" value="Fineract Platform API" />
</beans:bean>
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.factory.PasswordEncoderFactories"
factory-method="createDelegatingPasswordEncoder">
</beans:bean>
<beans:bean id="customAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
</beans:bean>
<authentication-manager alias="authenticationManager"
erase-credentials="false">
<authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>
</beans:beans>
<beans:beans profile="oauth">
<http create-session="stateless" use-expressions="true" pattern="/api/v1/**"
entry-point-ref="oauthAuthenticationEntryPoint"
@@ -133,10 +79,6 @@
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<beans:bean id="passwordEncoder" class="org.springframework.security.crypto.factory.PasswordEncoderFactories"
factory-method="createDelegatingPasswordEncoder">
</beans:bean>
<beans:bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<beans:property name="realmName" value="Fineract Platform API" />
@@ -178,12 +120,6 @@
<beans:constructor-arg ref="clientDetailsService" />
</beans:bean>
<beans:bean id="customAuthenticationProvider"
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="passwordEncoder" ref="passwordEncoder" />
</beans:bean>
<beans:bean id="clientDetailsService"
class="org.springframework.security.oauth2.provider.client.JdbcClientDetailsService">
<beans:constructor-arg ref="routingDataSource" />