FINERACT-1724: Making global configuration caching transaction bound
This commit is contained in:
committed by
Arnold Gálovics
parent
651052c44b
commit
e9e31a8190
Vendored
+1
-1
@@ -25,6 +25,6 @@ public final class CacheApiConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final String RESOURCE_NAME = "CACHE";
|
public static final String RESOURCE_NAME = "CACHE";
|
||||||
public static final String cacheTypeParameter = "cacheType";
|
public static final String CACHE_TYPE_PARAMETER = "cacheType";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -48,7 +48,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
public class UpdateCacheCommandHandler implements NewCommandSourceHandler {
|
public class UpdateCacheCommandHandler implements NewCommandSourceHandler {
|
||||||
|
|
||||||
private final CacheWritePlatformService cacheService;
|
private final CacheWritePlatformService cacheService;
|
||||||
private static final Set<String> REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(CacheApiConstants.cacheTypeParameter));
|
private static final Set<String> REQUEST_DATA_PARAMETERS = new HashSet<>(Arrays.asList(CacheApiConstants.CACHE_TYPE_PARAMETER));
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public UpdateCacheCommandHandler(final CacheWritePlatformService cacheService) {
|
public UpdateCacheCommandHandler(final CacheWritePlatformService cacheService) {
|
||||||
@@ -72,8 +72,8 @@ public class UpdateCacheCommandHandler implements NewCommandSourceHandler {
|
|||||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||||
.resource(CacheApiConstants.RESOURCE_NAME.toLowerCase());
|
.resource(CacheApiConstants.RESOURCE_NAME.toLowerCase());
|
||||||
|
|
||||||
final int cacheTypeEnum = command.integerValueSansLocaleOfParameterNamed(CacheApiConstants.cacheTypeParameter);
|
final int cacheTypeEnum = command.integerValueSansLocaleOfParameterNamed(CacheApiConstants.CACHE_TYPE_PARAMETER);
|
||||||
baseDataValidator.reset().parameter(CacheApiConstants.cacheTypeParameter).value(Integer.valueOf(cacheTypeEnum)).notNull()
|
baseDataValidator.reset().parameter(CacheApiConstants.CACHE_TYPE_PARAMETER).value(Integer.valueOf(cacheTypeEnum)).notNull()
|
||||||
.isOneOfTheseValues(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3));
|
.isOneOfTheseValues(Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3));
|
||||||
|
|
||||||
if (!dataValidationErrors.isEmpty()) {
|
if (!dataValidationErrors.isEmpty()) {
|
||||||
|
|||||||
+36
-46
@@ -22,17 +22,17 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.infrastructure.cache.CacheApiConstants;
|
import org.apache.fineract.infrastructure.cache.CacheApiConstants;
|
||||||
import org.apache.fineract.infrastructure.cache.CacheEnumerations;
|
import org.apache.fineract.infrastructure.cache.CacheEnumerations;
|
||||||
import org.apache.fineract.infrastructure.cache.data.CacheData;
|
import org.apache.fineract.infrastructure.cache.data.CacheData;
|
||||||
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
||||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||||
import org.slf4j.Logger;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.jcache.JCacheCacheManager;
|
|
||||||
import org.springframework.cache.support.NoOpCacheManager;
|
import org.springframework.cache.support.NoOpCacheManager;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -43,49 +43,43 @@ import org.springframework.stereotype.Component;
|
|||||||
* database on startup and allow user to switch implementation through UI/API
|
* database on startup and allow user to switch implementation through UI/API
|
||||||
*/
|
*/
|
||||||
@Component(value = "runtimeDelegatingCacheManager")
|
@Component(value = "runtimeDelegatingCacheManager")
|
||||||
public class RuntimeDelegatingCacheManager implements CacheManager {
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class RuntimeDelegatingCacheManager implements CacheManager, InitializingBean {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(RuntimeDelegatingCacheManager.class);
|
@Qualifier("ehCacheManager")
|
||||||
|
private final CacheManager ehCacheManager;
|
||||||
private final CacheManager cacheManager;
|
@Qualifier("defaultCacheManager")
|
||||||
private final CacheManager noOpCacheManager = new NoOpCacheManager();
|
private final CacheManager defaultCacheManager;
|
||||||
private CacheManager currentCacheManager;
|
private CacheManager currentCacheManager;
|
||||||
|
|
||||||
@Autowired
|
@Override
|
||||||
public RuntimeDelegatingCacheManager(final JCacheCacheManager cacheManager) {
|
public void afterPropertiesSet() throws Exception {
|
||||||
this.cacheManager = cacheManager;
|
currentCacheManager = defaultCacheManager;
|
||||||
this.currentCacheManager = this.noOpCacheManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cache getCache(final String name) {
|
public Cache getCache(final String name) {
|
||||||
return this.currentCacheManager.getCache(name);
|
return currentCacheManager.getCache(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getCacheNames() {
|
public Collection<String> getCacheNames() {
|
||||||
return this.currentCacheManager.getCacheNames();
|
return currentCacheManager.getCacheNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<CacheData> retrieveAll() {
|
public Collection<CacheData> retrieveAll() {
|
||||||
|
|
||||||
final boolean noCacheEnabled = this.currentCacheManager instanceof NoOpCacheManager;
|
final boolean noCacheEnabled = currentCacheManager == defaultCacheManager;
|
||||||
final boolean ehcacheEnabled = this.currentCacheManager instanceof JCacheCacheManager;
|
final boolean ehCacheEnabled = currentCacheManager == ehCacheManager;
|
||||||
|
|
||||||
// final boolean distributedCacheEnabled = false;
|
|
||||||
|
|
||||||
final EnumOptionData noCacheType = CacheEnumerations.cacheType(CacheType.NO_CACHE);
|
final EnumOptionData noCacheType = CacheEnumerations.cacheType(CacheType.NO_CACHE);
|
||||||
final EnumOptionData singleNodeCacheType = CacheEnumerations.cacheType(CacheType.SINGLE_NODE);
|
final EnumOptionData singleNodeCacheType = CacheEnumerations.cacheType(CacheType.SINGLE_NODE);
|
||||||
// final EnumOptionData multiNodeCacheType =
|
|
||||||
// CacheEnumerations.cacheType(CacheType.MULTI_NODE);
|
|
||||||
|
|
||||||
final CacheData noCache = CacheData.instance(noCacheType, noCacheEnabled);
|
final CacheData noCache = CacheData.instance(noCacheType, noCacheEnabled);
|
||||||
final CacheData singleNodeCache = CacheData.instance(singleNodeCacheType, ehcacheEnabled);
|
final CacheData singleNodeCache = CacheData.instance(singleNodeCacheType, ehCacheEnabled);
|
||||||
// final CacheData distributedCache =
|
|
||||||
// CacheData.instance(multiNodeCacheType, distributedCacheEnabled);
|
|
||||||
|
|
||||||
final Collection<CacheData> caches = Arrays.asList(noCache, singleNodeCache);
|
return Arrays.asList(noCache, singleNodeCache);
|
||||||
return caches;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> switchToCache(final boolean ehcacheEnabled, final CacheType toCacheType) {
|
public Map<String, Object> switchToCache(final boolean ehcacheEnabled, final CacheType toCacheType) {
|
||||||
@@ -93,42 +87,38 @@ public class RuntimeDelegatingCacheManager implements CacheManager {
|
|||||||
final Map<String, Object> changes = new HashMap<>();
|
final Map<String, Object> changes = new HashMap<>();
|
||||||
|
|
||||||
final boolean noCacheEnabled = !ehcacheEnabled;
|
final boolean noCacheEnabled = !ehcacheEnabled;
|
||||||
final boolean distributedCacheEnabled = !ehcacheEnabled;
|
|
||||||
|
|
||||||
switch (toCacheType) {
|
switch (toCacheType) {
|
||||||
case INVALID:
|
case INVALID -> {
|
||||||
break;
|
log.warn("Invalid cache type used");
|
||||||
case NO_CACHE:
|
}
|
||||||
|
case NO_CACHE -> {
|
||||||
if (!noCacheEnabled) {
|
if (!noCacheEnabled) {
|
||||||
changes.put(CacheApiConstants.cacheTypeParameter, toCacheType.getValue());
|
changes.put(CacheApiConstants.CACHE_TYPE_PARAMETER, toCacheType.getValue());
|
||||||
}
|
}
|
||||||
this.currentCacheManager = this.noOpCacheManager;
|
currentCacheManager = defaultCacheManager;
|
||||||
break;
|
}
|
||||||
case SINGLE_NODE:
|
case SINGLE_NODE -> {
|
||||||
if (!ehcacheEnabled) {
|
if (!ehcacheEnabled) {
|
||||||
changes.put(CacheApiConstants.cacheTypeParameter, toCacheType.getValue());
|
changes.put(CacheApiConstants.CACHE_TYPE_PARAMETER, toCacheType.getValue());
|
||||||
clearEhCache();
|
clearEhCache();
|
||||||
}
|
}
|
||||||
this.currentCacheManager = this.cacheManager;
|
currentCacheManager = ehCacheManager;
|
||||||
|
|
||||||
if (this.currentCacheManager.getCacheNames().size() == 0) {
|
if (currentCacheManager.getCacheNames().size() == 0) {
|
||||||
LOG.error("No caches configured for activated CacheManager {}", this.currentCacheManager);
|
log.error("No caches configured for activated CacheManager {}", currentCacheManager);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case MULTI_NODE:
|
case MULTI_NODE -> throw new UnsupportedOperationException("Multi node cache is not supported");
|
||||||
if (!distributedCacheEnabled) {
|
|
||||||
changes.put(CacheApiConstants.cacheTypeParameter, toCacheType.getValue());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearEhCache() {
|
private void clearEhCache() {
|
||||||
Iterable<String> cacheNames = cacheManager.getCacheNames();
|
Iterable<String> cacheNames = ehCacheManager.getCacheNames();
|
||||||
for (String cacheName : cacheNames) {
|
for (String cacheName : cacheNames) {
|
||||||
cacheManager.getCache(cacheName).clear();
|
ehCacheManager.getCache(cacheName).clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-26
@@ -19,23 +19,22 @@
|
|||||||
package org.apache.fineract.infrastructure.configuration.domain;
|
package org.apache.fineract.infrastructure.configuration.domain;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.HashMap;
|
import lombok.RequiredArgsConstructor;
|
||||||
import java.util.Map;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
import org.apache.fineract.infrastructure.cache.domain.CacheType;
|
||||||
import org.apache.fineract.infrastructure.cache.domain.PlatformCache;
|
import org.apache.fineract.infrastructure.cache.domain.PlatformCache;
|
||||||
import org.apache.fineract.infrastructure.cache.domain.PlatformCacheRepository;
|
import org.apache.fineract.infrastructure.cache.domain.PlatformCacheRepository;
|
||||||
import org.apache.fineract.infrastructure.configuration.data.GlobalConfigurationPropertyData;
|
import org.apache.fineract.infrastructure.configuration.data.GlobalConfigurationPropertyData;
|
||||||
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
|
|
||||||
import org.apache.fineract.useradministration.domain.Permission;
|
import org.apache.fineract.useradministration.domain.Permission;
|
||||||
import org.apache.fineract.useradministration.domain.PermissionRepository;
|
import org.apache.fineract.useradministration.domain.PermissionRepository;
|
||||||
import org.apache.fineract.useradministration.exception.PermissionNotFoundException;
|
import org.apache.fineract.useradministration.exception.PermissionNotFoundException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ConfigurationDomainServiceJpa implements ConfigurationDomainService {
|
public class ConfigurationDomainServiceJpa implements ConfigurationDomainService {
|
||||||
|
|
||||||
public static final String ENABLE_BUSINESS_DATE = "enable_business_date";
|
public static final String ENABLE_BUSINESS_DATE = "enable_business_date";
|
||||||
@@ -55,15 +54,6 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
|||||||
private final PermissionRepository permissionRepository;
|
private final PermissionRepository permissionRepository;
|
||||||
private final GlobalConfigurationRepositoryWrapper globalConfigurationRepository;
|
private final GlobalConfigurationRepositoryWrapper globalConfigurationRepository;
|
||||||
private final PlatformCacheRepository cacheTypeRepository;
|
private final PlatformCacheRepository cacheTypeRepository;
|
||||||
private static Map<String, GlobalConfigurationPropertyData> configurations = new HashMap<>();
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ConfigurationDomainServiceJpa(final PermissionRepository permissionRepository,
|
|
||||||
final GlobalConfigurationRepositoryWrapper globalConfigurationRepository, final PlatformCacheRepository cacheTypeRepository) {
|
|
||||||
this.permissionRepository = permissionRepository;
|
|
||||||
this.globalConfigurationRepository = globalConfigurationRepository;
|
|
||||||
this.cacheTypeRepository = cacheTypeRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMakerCheckerEnabledForTask(final String taskPermissionCode) {
|
public boolean isMakerCheckerEnabledForTask(final String taskPermissionCode) {
|
||||||
@@ -321,9 +311,7 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeGlobalConfigurationPropertyDataFromCache(final String propertyName) {
|
public void removeGlobalConfigurationPropertyDataFromCache(final String propertyName) {
|
||||||
String identifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
globalConfigurationRepository.removeFromCache(propertyName);
|
||||||
String key = identifier + "_" + propertyName;
|
|
||||||
configurations.remove(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -389,15 +377,8 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
|||||||
return property.getValue();
|
return property.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "configByName", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#propertyName)")
|
private GlobalConfigurationPropertyData getGlobalConfigurationPropertyData(final String propertyName) {
|
||||||
public GlobalConfigurationPropertyData getGlobalConfigurationPropertyData(final String propertyName) {
|
return globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName).toData();
|
||||||
String identifier = ThreadLocalContextUtil.getTenant().getTenantIdentifier();
|
|
||||||
String key = identifier + "_" + propertyName;
|
|
||||||
if (!configurations.containsKey(key)) {
|
|
||||||
GlobalConfigurationProperty configuration = this.globalConfigurationRepository.findOneByNameWithNotFoundDetection(propertyName);
|
|
||||||
configurations.put(key, configuration.toData());
|
|
||||||
}
|
|
||||||
return configurations.get(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+9
@@ -18,8 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.configuration.domain;
|
package org.apache.fineract.infrastructure.configuration.domain;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.infrastructure.configuration.exception.GlobalConfigurationPropertyNotFoundException;
|
import org.apache.fineract.infrastructure.configuration.exception.GlobalConfigurationPropertyNotFoundException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,6 +31,7 @@ import org.springframework.stereotype.Service;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class GlobalConfigurationRepositoryWrapper {
|
public class GlobalConfigurationRepositoryWrapper {
|
||||||
|
|
||||||
private final GlobalConfigurationRepository repository;
|
private final GlobalConfigurationRepository repository;
|
||||||
@@ -37,6 +41,7 @@ public class GlobalConfigurationRepositoryWrapper {
|
|||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Cacheable(value = "configByName", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#propertyName)")
|
||||||
public GlobalConfigurationProperty findOneByNameWithNotFoundDetection(final String propertyName) {
|
public GlobalConfigurationProperty findOneByNameWithNotFoundDetection(final String propertyName) {
|
||||||
final GlobalConfigurationProperty property = this.repository.findOneByName(propertyName);
|
final GlobalConfigurationProperty property = this.repository.findOneByName(propertyName);
|
||||||
if (property == null) {
|
if (property == null) {
|
||||||
@@ -61,4 +66,8 @@ public class GlobalConfigurationRepositoryWrapper {
|
|||||||
this.repository.delete(globalConfigurationProperty);
|
this.repository.delete(globalConfigurationProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CacheEvict(value = "configByName", key = "T(org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#propertyName)")
|
||||||
|
public void removeFromCache(String propertyName) {
|
||||||
|
log.debug("Cache entry evicted {}", propertyName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -53,6 +53,7 @@ public class FineractProperties {
|
|||||||
private FineractJobProperties job;
|
private FineractJobProperties job;
|
||||||
|
|
||||||
private FineractTemplateProperties template;
|
private FineractTemplateProperties template;
|
||||||
|
private FineractJpaProperties jpa;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@@ -248,4 +249,10 @@ public class FineractProperties {
|
|||||||
private List<String> regexWhitelist;
|
private List<String> regexWhitelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public static class FineractJpaProperties {
|
||||||
|
|
||||||
|
private boolean statementLoggingEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -17,7 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.fineract.infrastructure.core.config;
|
package org.apache.fineract.infrastructure.core.config.cache;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import javax.cache.CacheManager;
|
import javax.cache.CacheManager;
|
||||||
@@ -28,20 +28,32 @@ import org.ehcache.config.builders.ExpiryPolicyBuilder;
|
|||||||
import org.ehcache.config.builders.ResourcePoolsBuilder;
|
import org.ehcache.config.builders.ResourcePoolsBuilder;
|
||||||
import org.ehcache.jsr107.Eh107Configuration;
|
import org.ehcache.jsr107.Eh107Configuration;
|
||||||
import org.springframework.cache.jcache.JCacheCacheManager;
|
import org.springframework.cache.jcache.JCacheCacheManager;
|
||||||
|
import org.springframework.cache.support.NoOpCacheManager;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class CacheConfig {
|
public class CacheConfig {
|
||||||
|
|
||||||
|
public static final String CONFIG_BY_NAME_CACHE_NAME = "configByName";
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TransactionBoundCacheManager defaultCacheManager(JCacheCacheManager ehCacheManager) {
|
||||||
|
SpecifiedCacheSupportingCacheManager cacheManager = new SpecifiedCacheSupportingCacheManager();
|
||||||
|
cacheManager.setNoOpCacheManager(new NoOpCacheManager());
|
||||||
|
cacheManager.setDelegateCacheManager(ehCacheManager);
|
||||||
|
cacheManager.setSupportedCaches(CONFIG_BY_NAME_CACHE_NAME);
|
||||||
|
return new TransactionBoundCacheManager(cacheManager);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public JCacheCacheManager ehCacheManager() {
|
public JCacheCacheManager ehCacheManager() {
|
||||||
JCacheCacheManager jCacheCacheManager = new JCacheCacheManager();
|
JCacheCacheManager jCacheCacheManager = new JCacheCacheManager();
|
||||||
jCacheCacheManager.setCacheManager(getCustomCacheManager());
|
jCacheCacheManager.setCacheManager(getInternalEhCacheManager());
|
||||||
return jCacheCacheManager;
|
return jCacheCacheManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CacheManager getCustomCacheManager() {
|
private CacheManager getInternalEhCacheManager() {
|
||||||
CachingProvider provider = Caching.getCachingProvider();
|
CachingProvider provider = Caching.getCachingProvider();
|
||||||
CacheManager cacheManager = provider.getCacheManager();
|
CacheManager cacheManager = provider.getCacheManager();
|
||||||
|
|
||||||
@@ -61,6 +73,7 @@ public class CacheConfig {
|
|||||||
cacheManager.createCache("codes", defaultTemplate);
|
cacheManager.createCache("codes", defaultTemplate);
|
||||||
cacheManager.createCache("hooks", defaultTemplate);
|
cacheManager.createCache("hooks", defaultTemplate);
|
||||||
cacheManager.createCache("tfConfig", defaultTemplate);
|
cacheManager.createCache("tfConfig", defaultTemplate);
|
||||||
|
cacheManager.createCache(CONFIG_BY_NAME_CACHE_NAME, defaultTemplate);
|
||||||
|
|
||||||
javax.cache.configuration.Configuration<Object, Object> accessTokenTemplate = Eh107Configuration.fromEhcacheCacheConfiguration(
|
javax.cache.configuration.Configuration<Object, Object> accessTokenTemplate = Eh107Configuration.fromEhcacheCacheConfiguration(
|
||||||
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
|
CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.heap(10000))
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* 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.cache;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.jcache.JCacheCacheManager;
|
||||||
|
import org.springframework.cache.support.NoOpCacheManager;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SpecifiedCacheSupportingCacheManager implements CacheManager, InitializingBean {
|
||||||
|
|
||||||
|
private JCacheCacheManager delegateCacheManager;
|
||||||
|
private NoOpCacheManager noOpCacheManager;
|
||||||
|
|
||||||
|
private final Set<String> supportedCacheNames = new LinkedHashSet<>(16);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
Assert.notNull(delegateCacheManager, "cacheManager cannot be null");
|
||||||
|
Assert.notNull(noOpCacheManager, "delegate cannot be null");
|
||||||
|
Assert.notEmpty(supportedCacheNames, "supportedCacheNames must not be empty");
|
||||||
|
delegateCacheManager.afterPropertiesSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cache getCache(String name) {
|
||||||
|
if (supportedCacheNames.contains(name)) {
|
||||||
|
Cache cache = delegateCacheManager.getCache(name);
|
||||||
|
if (cache != null) {
|
||||||
|
return cache;
|
||||||
|
} else {
|
||||||
|
return noOpCacheManager.getCache(name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return noOpCacheManager.getCache(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getCacheNames() {
|
||||||
|
synchronized (supportedCacheNames) {
|
||||||
|
return Collections.unmodifiableSet(supportedCacheNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelegateCacheManager(JCacheCacheManager delegateCacheManager) {
|
||||||
|
this.delegateCacheManager = delegateCacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNoOpCacheManager(NoOpCacheManager noOpCacheManager) {
|
||||||
|
this.noOpCacheManager = noOpCacheManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupportedCaches(String... cacheNames) {
|
||||||
|
supportedCacheNames.addAll(Arrays.asList(cacheNames));
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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.cache;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.fineract.infrastructure.core.persistence.TransactionLifecycleCallback;
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TransactionBoundCacheManager implements TransactionLifecycleCallback, CacheManager {
|
||||||
|
|
||||||
|
private final CacheManager delegate;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion() {
|
||||||
|
Collection<String> cacheNames = delegate.getCacheNames();
|
||||||
|
cacheNames.forEach(c -> {
|
||||||
|
Cache cache = delegate.getCache(c);
|
||||||
|
if (cache != null) {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cache getCache(String name) {
|
||||||
|
return delegate.getCache(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getCacheNames() {
|
||||||
|
return delegate.getCacheNames();
|
||||||
|
}
|
||||||
|
}
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* 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.diagnostics.jpa;
|
||||||
|
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
|
||||||
|
import org.eclipse.persistence.sessions.changesets.UnitOfWorkChangeSet;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class can be used for IntelliJ debugging purposes to access the current transaction bound EntityManager
|
||||||
|
* instance. <br>
|
||||||
|
* <br>
|
||||||
|
* With Alt + F8 you can run evaluations in IntelliJ and this class makes it easier to access the EntityManager and to
|
||||||
|
* see what kind of changes are pending within the Persistence Context. <br>
|
||||||
|
* <br>
|
||||||
|
* To enable this, run Fineract with the <b>diagnostics</b> profile.
|
||||||
|
*/
|
||||||
|
@Profile("diagnostics")
|
||||||
|
@Component
|
||||||
|
public class DiagnosticsEntityManager implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private static ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
public static EntityManagerImpl getCurrentEntityManager() {
|
||||||
|
EntityManagerFactory emf = applicationContext.getBean(EntityManagerFactory.class);
|
||||||
|
return (EntityManagerImpl) EntityManagerFactoryUtils.getTransactionalEntityManager(emf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnitOfWorkChangeSet getCurrentChanges() {
|
||||||
|
return DiagnosticsEntityManager.getCurrentEntityManager().getUnitOfWork().getCurrentChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
DiagnosticsEntityManager.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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.diagnostics.jpa;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.fineract.infrastructure.core.config.jpa.EntityManagerFactoryCustomizer;
|
||||||
|
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||||
|
import org.eclipse.persistence.logging.SessionLog;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Conditional(StatementLoggingCustomizerCondition.class)
|
||||||
|
public class StatementLoggingCustomizer implements EntityManagerFactoryCustomizer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> additionalVendorProperties() {
|
||||||
|
return Map.of("eclipselink.logging.level.sql", SessionLog.FINE_LABEL, PersistenceUnitProperties.LOGGING_PARAMETERS,
|
||||||
|
Boolean.TRUE.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.diagnostics.jpa;
|
||||||
|
|
||||||
|
import org.apache.fineract.infrastructure.core.condition.PropertiesCondition;
|
||||||
|
import org.apache.fineract.infrastructure.core.config.FineractProperties;
|
||||||
|
|
||||||
|
public class StatementLoggingCustomizerCondition extends PropertiesCondition {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean matches(FineractProperties properties) {
|
||||||
|
return properties.getJpa().isStatementLoggingEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-1
@@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.core.persistence;
|
package org.apache.fineract.infrastructure.core.persistence;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.FlushModeType;
|
import javax.persistence.FlushModeType;
|
||||||
import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport;
|
import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport;
|
||||||
@@ -29,6 +32,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
|||||||
|
|
||||||
public class ExtendedJpaTransactionManager extends JpaTransactionManager {
|
public class ExtendedJpaTransactionManager extends JpaTransactionManager {
|
||||||
|
|
||||||
|
private final List<TransactionLifecycleCallback> lifecycleCallbacks = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
public ExtendedJpaTransactionManager() {
|
public ExtendedJpaTransactionManager() {
|
||||||
setValidateExistingTransaction(true);
|
setValidateExistingTransaction(true);
|
||||||
}
|
}
|
||||||
@@ -42,7 +47,7 @@ public class ExtendedJpaTransactionManager extends JpaTransactionManager {
|
|||||||
entityManager.setFlushMode(FlushModeType.COMMIT);
|
entityManager.setFlushMode(FlushModeType.COMMIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
invokeLifecycleCallbacks(TransactionLifecycleCallback::afterBegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -54,6 +59,13 @@ public class ExtendedJpaTransactionManager extends JpaTransactionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.doCommit(status);
|
super.doCommit(status);
|
||||||
|
invokeLifecycleCallbacks(TransactionLifecycleCallback::afterCommit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doCleanupAfterCompletion(Object transaction) {
|
||||||
|
super.doCleanupAfterCompletion(transaction);
|
||||||
|
invokeLifecycleCallbacks(TransactionLifecycleCallback::afterCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isReadOnlyTx(Object transaction) {
|
private boolean isReadOnlyTx(Object transaction) {
|
||||||
@@ -68,4 +80,12 @@ public class ExtendedJpaTransactionManager extends JpaTransactionManager {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void invokeLifecycleCallbacks(Consumer<TransactionLifecycleCallback> f) {
|
||||||
|
lifecycleCallbacks.forEach(f::accept);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLifecycleCallbacks(List<TransactionLifecycleCallback> lifecycleCallbacks) {
|
||||||
|
this.lifecycleCallbacks.addAll(lifecycleCallbacks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.persistence;
|
||||||
|
|
||||||
|
public interface TransactionLifecycleCallback {
|
||||||
|
|
||||||
|
default void afterBegin() {}
|
||||||
|
|
||||||
|
default void afterCommit() {}
|
||||||
|
|
||||||
|
default void afterCompletion() {}
|
||||||
|
}
|
||||||
+5
-1
@@ -18,7 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.infrastructure.jobs;
|
package org.apache.fineract.infrastructure.jobs;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import org.apache.fineract.infrastructure.core.persistence.ExtendedJpaTransactionManager;
|
import org.apache.fineract.infrastructure.core.persistence.ExtendedJpaTransactionManager;
|
||||||
|
import org.apache.fineract.infrastructure.core.persistence.TransactionLifecycleCallback;
|
||||||
import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
|
import org.apache.fineract.infrastructure.core.service.database.RoutingDataSource;
|
||||||
import org.springframework.batch.core.configuration.JobRegistry;
|
import org.springframework.batch.core.configuration.JobRegistry;
|
||||||
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
|
import org.springframework.batch.core.configuration.annotation.BatchConfigurer;
|
||||||
@@ -39,8 +41,10 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||||||
public class ScheduledJobRunnerConfig {
|
public class ScheduledJobRunnerConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PlatformTransactionManager transactionManager(ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
|
public PlatformTransactionManager transactionManager(ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
|
||||||
|
List<TransactionLifecycleCallback> callbacks) {
|
||||||
ExtendedJpaTransactionManager transactionManager = new ExtendedJpaTransactionManager();
|
ExtendedJpaTransactionManager transactionManager = new ExtendedJpaTransactionManager();
|
||||||
|
transactionManager.setLifecycleCallbacks(callbacks);
|
||||||
transactionManager.setValidateExistingTransaction(true);
|
transactionManager.setValidateExistingTransaction(true);
|
||||||
transactionManagerCustomizers.ifAvailable(customizers -> customizers.customize(transactionManager));
|
transactionManagerCustomizers.ifAvailable(customizers -> customizers.customize(transactionManager));
|
||||||
return transactionManager;
|
return transactionManager;
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ fineract.template.regex-whitelist=${FINERACT_TEMPLATE_REGEX_WHITELIST:}
|
|||||||
fineract.report.export.s3.bucket=${FINERACT_REPORT_EXPORT_S3_BUCKET_NAME:}
|
fineract.report.export.s3.bucket=${FINERACT_REPORT_EXPORT_S3_BUCKET_NAME:}
|
||||||
fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
|
fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
|
||||||
|
|
||||||
|
fineract.jpa.statementLoggingEnabled=${FINERACT_STATEMENT_LOGGING_ENABLED:false}
|
||||||
|
|
||||||
# Logging pattern for the console
|
# Logging pattern for the console
|
||||||
logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
|
logging.pattern.console=${CONSOLE_LOG_PATTERN:%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(%replace([%X{correlationId}]){'\\[\\]', ''}) %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ fineract.content.s3.secretKey=
|
|||||||
fineract.report.export.s3.bucket=${FINERACT_REPORT_EXPORT_S3_BUCKET_NAME:}
|
fineract.report.export.s3.bucket=${FINERACT_REPORT_EXPORT_S3_BUCKET_NAME:}
|
||||||
fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
|
fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
|
||||||
|
|
||||||
|
fineract.jpa.statementLoggingEnabled=${FINERACT_STATEMENT_LOGGING_ENABLED:false}
|
||||||
|
|
||||||
management.health.jms.enabled=false
|
management.health.jms.enabled=false
|
||||||
|
|
||||||
# FINERACT 1296
|
# FINERACT 1296
|
||||||
|
|||||||
Reference in New Issue
Block a user