diff --git a/.github/workflows/crosschecks.yml b/.github/workflows/crosschecks.yml
index d0deecd39b9..2038b8a3754 100644
--- a/.github/workflows/crosschecks.yml
+++ b/.github/workflows/crosschecks.yml
@@ -31,7 +31,7 @@ jobs:
fail-fast: false
matrix:
language: ['java']
- java: [ '25', '27-ea' ]
+ java: [ '25', '28-ea' ]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
diff --git a/archetype/src/main/resources/archetype-resources/core/pom.xml b/archetype/src/main/resources/archetype-resources/core/pom.xml
index 39282e92af6..6d0b2de0e32 100644
--- a/archetype/src/main/resources/archetype-resources/core/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/core/pom.xml
@@ -47,6 +47,10 @@ under the License.
org.apache.syncope.core
syncope-core-starter
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+
org.apache.syncope.core.idm
syncope-core-idm-rest-cxf
diff --git a/archetype/src/main/resources/archetype-resources/pom.xml b/archetype/src/main/resources/archetype-resources/pom.xml
index 25a71bc0e92..ae9d094b4ef 100644
--- a/archetype/src/main/resources/archetype-resources/pom.xml
+++ b/archetype/src/main/resources/archetype-resources/pom.xml
@@ -67,6 +67,11 @@ under the License.
syncope-core-starter
${syncope.version}
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ ${syncope.version}
+
org.apache.syncope.core.idm
syncope-core-idm-rest-cxf
diff --git a/core/cache/caffeine/pom.xml b/core/cache/caffeine/pom.xml
new file mode 100644
index 00000000000..ceeb6d677ad
--- /dev/null
+++ b/core/cache/caffeine/pom.xml
@@ -0,0 +1,55 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.syncope.core
+ syncope-core-cache
+ 5.0.0-SNAPSHOT
+
+
+ Apache Syncope Core Cache Caffeine
+ Apache Syncope Core Cache Caffeine
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ jar
+
+
+ ${basedir}/../../..
+
+
+
+
+ com.github.ben-manes.caffeine
+ jcache
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+
+
diff --git a/core/cache/ehcache/pom.xml b/core/cache/ehcache/pom.xml
new file mode 100644
index 00000000000..d2d9e3a2c04
--- /dev/null
+++ b/core/cache/ehcache/pom.xml
@@ -0,0 +1,55 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.syncope.core
+ syncope-core-cache
+ 5.0.0-SNAPSHOT
+
+
+ Apache Syncope Core Cache Ehcache
+ Apache Syncope Core Cache Ehcache
+ org.apache.syncope.core.cache
+ syncope-core-cache-ehcache
+ jar
+
+
+ ${basedir}/../../..
+
+
+
+
+ org.ehcache
+ ehcache
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+
+
diff --git a/core/cache/hazelcast/pom.xml b/core/cache/hazelcast/pom.xml
new file mode 100644
index 00000000000..d6873a57b01
--- /dev/null
+++ b/core/cache/hazelcast/pom.xml
@@ -0,0 +1,55 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.syncope.core
+ syncope-core-cache
+ 5.0.0-SNAPSHOT
+
+
+ Apache Syncope Core Cache Hazelcast
+ Apache Syncope Core Cache Hazelcast
+ org.apache.syncope.core.cache
+ syncope-core-cache-hazelcast
+ jar
+
+
+ ${basedir}/../../..
+
+
+
+
+ com.hazelcast
+ hazelcast
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+
+
diff --git a/core/cache/infinispan/pom.xml b/core/cache/infinispan/pom.xml
new file mode 100644
index 00000000000..c6906fea850
--- /dev/null
+++ b/core/cache/infinispan/pom.xml
@@ -0,0 +1,55 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.syncope.core
+ syncope-core-cache
+ 5.0.0-SNAPSHOT
+
+
+ Apache Syncope Core Cache Infinispan
+ Apache Syncope Core Cache Infinispan
+ org.apache.syncope.core.cache
+ syncope-core-cache-infinispan
+ jar
+
+
+ ${basedir}/../../..
+
+
+
+
+ org.infinispan
+ infinispan-jcache
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+
+
diff --git a/core/cache/pom.xml b/core/cache/pom.xml
new file mode 100644
index 00000000000..10c81c82286
--- /dev/null
+++ b/core/cache/pom.xml
@@ -0,0 +1,94 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.syncope
+ syncope-core
+ 5.0.0-SNAPSHOT
+
+
+ Apache Syncope Core Cache
+ Apache Syncope Core Cache
+ org.apache.syncope.core
+ syncope-core-cache
+ pom
+
+
+ ${basedir}/../..
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ package
+
+ single
+
+
+
+
+ wrap
+
+ zip
+
+ false
+
+
+ /
+ false
+ false
+ runtime
+
+
+
+
+ ${rootpom.basedir}/LICENSE
+ META-INF
+
+
+ ${rootpom.basedir}/NOTICE
+ META-INF
+
+
+
+
+
+
+
+
+
+
+
+
+
+ caffeine
+ hazelcast
+ ehcache
+ infinispan
+
+
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPADomainRegistry.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPADomainRegistry.java
index e9dbe5dac13..df1fa5e3d53 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPADomainRegistry.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/JPADomainRegistry.java
@@ -21,6 +21,7 @@
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.io.ByteArrayInputStream;
+import javax.cache.CacheManager;
import javax.sql.DataSource;
import org.apache.syncope.common.keymaster.client.api.model.JPADomain;
import org.apache.syncope.core.persistence.api.DomainHolder;
@@ -33,9 +34,12 @@
public class JPADomainRegistry implements DomainRegistry {
+ protected final CacheManager cacheManager;
+
protected final ConfigurableApplicationContext ctx;
- public JPADomainRegistry(final ConfigurableApplicationContext ctx) {
+ public JPADomainRegistry(final CacheManager cacheManager, final ConfigurableApplicationContext ctx) {
+ this.cacheManager = cacheManager;
this.ctx = ctx;
}
@@ -78,12 +82,12 @@ public void register(final JPADomain domain) {
addPropertyValue("jndiName", "java:comp/env/jdbc/syncope" + domain.getKey() + "DataSource").
addPropertyValue("defaultObject", new HikariDataSource(hikariConfig)).
getBeanDefinition());
- DataSource initedDataSource = beanFactory().getBean(domain.getKey() + "DataSource", DataSource.class);
+ DataSource initedDataSource = ctx.getBean(domain.getKey() + "DataSource", DataSource.class);
domainHolder().getDomains().put(domain.getKey(), initedDataSource);
// DomainRoutingEntityManagerFactory#domain
- beanFactory().getBean(DomainRoutingEntityManagerFactory.class).domain(domain, initedDataSource);
+ ctx.getBean(DomainRoutingEntityManagerFactory.class).domain(domain, initedDataSource, cacheManager);
// domainContentXML
beanFactory().registerBeanDefinition(domain.getKey() + "ContentXML",
@@ -109,7 +113,7 @@ public void unregister(final String domain) {
beanFactory().removeBeanDefinition(domain + "ContentXML");
// DomainRoutingEntityManagerFactory#remove
- beanFactory().getBean(DomainRoutingEntityManagerFactory.class).remove(domain);
+ ctx.getBean(DomainRoutingEntityManagerFactory.class).remove(domain);
// domainDataSourceInitializer
unregisterSingleton(domain.toLowerCase() + "DataSourceInitializer");
@@ -121,6 +125,6 @@ public void unregister(final String domain) {
unregisterSingleton(domain + "DataSource");
beanFactory().removeBeanDefinition(domain + "DataSource");
- beanFactory().getBean(DomainHolder.class).getDomains().remove(domain);
+ ctx.getBean(DomainHolder.class).getDomains().remove(domain);
}
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
index 8a8f871f70c..374ad73776c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceContext.java
@@ -20,10 +20,11 @@
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
+import jakarta.persistence.PersistenceConfiguration;
import jakarta.persistence.ValidationMode;
import java.util.HashMap;
import java.util.Map;
-import java.util.Optional;
+import javax.cache.CacheManager;
import javax.sql.DataSource;
import org.apache.syncope.common.keymaster.client.api.DomainOps;
import org.apache.syncope.common.keymaster.client.api.model.JPADomain;
@@ -188,6 +189,8 @@
import org.apache.syncope.core.persistence.jpa.spring.SyncopeJPARepository;
import org.apache.syncope.core.provisioning.api.ConnectorManager;
import org.apache.syncope.core.spring.security.SecurityProperties;
+import org.hibernate.cache.jcache.ConfigSettings;
+import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -217,7 +220,8 @@ public class PersistenceContext {
public CommonEntityManagerFactoryConf commonEMFConf(
final PersistenceProperties props,
@Qualifier("MasterDataSource")
- final JndiObjectFactoryBean masterDataSource) {
+ final JndiObjectFactoryBean masterDataSource,
+ final CacheManager cacheManager) {
CommonEntityManagerFactoryConf commonEMFConf = new CommonEntityManagerFactoryConf();
commonEMFConf.setPackagesToScan("org.apache.syncope.core.persistence.jpa.entity");
@@ -225,15 +229,14 @@ public CommonEntityManagerFactoryConf commonEMFConf(
commonEMFConf.setPersistenceUnitPostProcessors(new MultiJarAwarePersistenceUnitPostProcessor());
Map jpaPropertyMap = new HashMap<>();
- jpaPropertyMap.put("jakarta.persistence.schema-generation.database.action", "create");
+ jpaPropertyMap.put(PersistenceConfiguration.SCHEMAGEN_DATABASE_ACTION, "update");
+
+ jpaPropertyMap.put(AvailableSettings.USE_SECOND_LEVEL_CACHE, "true");
+ jpaPropertyMap.put(AvailableSettings.USE_QUERY_CACHE, "true");
+ jpaPropertyMap.put(AvailableSettings.CACHE_REGION_FACTORY, DomainJCacheRegionFactory.class.getName());
+ jpaPropertyMap.put(ConfigSettings.CACHE_MANAGER, cacheManager);
- jpaPropertyMap.put("hibernate.cache.use_second_level_cache", "true");
- jpaPropertyMap.put("hibernate.cache.use_query_cache", "true");
- jpaPropertyMap.put("hibernate.cache.region.factory_class", "jcache");
- jpaPropertyMap.put("hibernate.javax.cache.provider", props.getCacheProvider());
- Optional.ofNullable(props.getCacheURI()).
- ifPresent(cacheURI -> jpaPropertyMap.put("hibernate.javax.cache.uri", cacheURI));
- jpaPropertyMap.put("hibernate.cache.region.factory_class", DomainJCacheRegionFactory.class.getName());
+ jpaPropertyMap.putAll(props.getAdditionalJPAProperties());
commonEMFConf.setJpaPropertyMap(jpaPropertyMap);
@@ -250,11 +253,12 @@ public DomainRoutingEntityManagerFactory entityManagerFactory(
final JndiObjectFactoryBean masterDataSource,
final CommonEntityManagerFactoryConf commonEMFConf,
final @Lazy ConnectorManager connectorManager,
- final @Lazy ExternalResourceDAO resourceDAO) {
+ final @Lazy ExternalResourceDAO resourceDAO,
+ final CacheManager cacheManager) {
DomainRoutingEntityManagerFactory emf = new DomainRoutingEntityManagerFactory(
commonEMFConf, connectorManager, resourceDAO);
- emf.master(props, masterDataSource);
+ emf.master(props, masterDataSource, cacheManager);
return emf;
}
@@ -299,8 +303,11 @@ public XMLContentExporter xmlContentExporter(
@ConditionalOnMissingBean
@Bean
- public DomainRegistry domainRegistry(final ConfigurableApplicationContext ctx) {
- return new JPADomainRegistry(ctx);
+ public DomainRegistry domainRegistry(
+ final CacheManager cacheManager,
+ final ConfigurableApplicationContext ctx) {
+
+ return new JPADomainRegistry(cacheManager, ctx);
}
@ConditionalOnMissingBean
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java
index adc5c4e3c31..5c20252192d 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/PersistenceProperties.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.core.persistence.jpa;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.syncope.core.persistence.common.AbstractPersistenceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -28,27 +30,9 @@ public class PersistenceProperties extends AbstractPersistenceProperties additionalJPAProperties = new HashMap<>();
public String getViewsXML() {
return viewsXML;
@@ -57,4 +41,12 @@ public String getViewsXML() {
public void setViewsXML(final String viewsXML) {
this.viewsXML = viewsXML;
}
+
+ public Map getAdditionalJPAProperties() {
+ return additionalJPAProperties;
+ }
+
+ public void setAdditionalJPAProperties(final Map additionalJPAProperties) {
+ this.additionalJPAProperties = additionalJPAProperties;
+ }
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
index 5d89e319a36..9c9a02c3723 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARole.java
@@ -60,8 +60,7 @@ public class JPARole extends AbstractProvidedKeyEntity implements Role {
@JoinColumn(name = "realm_id"),
uniqueConstraints =
@UniqueConstraint(columnNames = { "role_id", "realm_id" }))
- @Valid
- private List realms = new ArrayList<>();
+ private List<@Valid JPARealm> realms = new ArrayList<>();
@Override
public Set getEntitlements() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
index bc931c30aa8..7814485e4ac 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
@@ -91,12 +91,10 @@ public class JPAAnyObject
private List auxClasses = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd")
- @Valid
- private List relationships = new ArrayList<>();
+ private List<@Valid JPAARelationship> relationships = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd")
- @Valid
- private List memberships = new ArrayList<>();
+ private List<@Valid JPAAMembership> memberships = new ArrayList<>();
@Override
public String getName() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
index d934f052168..99effe74f55 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/group/JPAGroup.java
@@ -93,8 +93,7 @@ public class JPAGroup
private List typeExtensions = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd")
- @Valid
- private List relationships = new ArrayList<>();
+ private List<@Valid JPAGRelationship> relationships = new ArrayList<>();
@Override
public String getName() {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java
index 31ad23b78b5..e46a7d2ee6f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAMacroTask.java
@@ -65,8 +65,7 @@ public class JPAMacroTask extends AbstractSchedTask implements MacroTask {
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "macroTask")
@OrderBy("idx")
- @Valid
- private List formPropertyDefs = new ArrayList<>();
+ private List<@Valid JPAFormPropertyDef> formPropertyDefs = new ArrayList<>();
@ManyToOne(fetch = FetchType.EAGER)
private JPAImplementation macroActions;
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
index aa4fb93a9f1..a0a40775d7a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUser.java
@@ -158,12 +158,10 @@ public class JPAUser
protected List auxClasses = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd")
- @Valid
- protected List relationships = new ArrayList<>();
+ protected List<@Valid JPAURelationship> relationships = new ArrayList<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "leftEnd")
- @Valid
- protected List memberships = new ArrayList<>();
+ protected List<@Valid JPAUMembership> memberships = new ArrayList<>();
@ManyToOne(fetch = FetchType.EAGER)
protected JPASecurityQuestion securityQuestion;
@@ -175,8 +173,7 @@ public class JPAUser
protected String mfa;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "owner")
- @Valid
- protected List linkedAccounts = new ArrayList<>();
+ protected List<@Valid JPALinkedAccount> linkedAccounts = new ArrayList<>();
protected Encryptor encryptor() {
return ApplicationContextProvider.getApplicationContext().getBean(EncryptorManager.class).getInstance();
@@ -231,11 +228,11 @@ protected String encode(final String value) throws Exception {
value,
Optional.ofNullable(cipherAlgorithm).
orElseGet(() -> CipherAlgorithm.valueOf(
- ApplicationContextProvider.getBeanFactory().getBean(ConfParamOps.class).get(
- AuthContextUtils.getDomain(),
- StandardConfParams.PASSWORD_CIPHER_ALGORITHM,
- CipherAlgorithm.AES.name(),
- String.class))));
+ ApplicationContextProvider.getBeanFactory().getBean(ConfParamOps.class).get(
+ AuthContextUtils.getDomain(),
+ StandardConfParams.PASSWORD_CIPHER_ALGORITHM,
+ CipherAlgorithm.AES.name(),
+ String.class))));
}
@Override
@@ -519,7 +516,7 @@ public boolean add(final LinkedAccount account) {
public Optional extends LinkedAccount> getLinkedAccount(final String resource, final String connObjectKeyValue) {
return linkedAccounts.stream().
filter(account -> account.getResource().getKey().equals(resource)
- && account.getConnObjectKeyValue().equals(connObjectKeyValue)).
+ && account.getConnObjectKeyValue().equals(connObjectKeyValue)).
findFirst();
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
index 1cd004a735a..d5fe7b8c455 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/CommonEntityManagerFactoryConf.java
@@ -33,7 +33,7 @@
/**
* Container for common configuration options among all EntityManagerFactory entities (one for each domain).
- * Acts as a commodity place for fetching each domain's {@link DataSource}..
+ * Acts as a commodity place for fetching each domain's {@link DataSource}.
*/
public class CommonEntityManagerFactoryConf implements DomainHolder {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
index e1789bf58a1..2f6549796cf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/spring/DomainEntityManagerFactoryBean.java
@@ -18,15 +18,10 @@
*/
package org.apache.syncope.core.persistence.jpa.spring;
-import jakarta.persistence.EntityManagerFactory;
-import jakarta.persistence.spi.PersistenceUnitInfo;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Optional;
-import javax.cache.Caching;
+import javax.cache.CacheManager;
import javax.cache.configuration.FactoryBuilder;
import javax.cache.configuration.MutableCacheEntryListenerConfiguration;
-import javax.cache.event.CacheEntryListener;
import org.apache.syncope.core.persistence.jpa.ConnectorManagerCacheEntryListener;
import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
@@ -43,11 +38,11 @@ public class DomainEntityManagerFactoryBean extends LocalContainerEntityManagerF
private static final long serialVersionUID = 49152547930966545L;
- protected final List> cacheEntryListeners = new ArrayList<>();
+ protected final CacheManager cacheManager;
- protected ConnectorManagerCacheEntryListener connectorManagerCacheEntryListener;
-
- protected ImplementationManagerCacheEntryListener implementationManagerCacheEntryListener;
+ public DomainEntityManagerFactoryBean(final CacheManager cacheManager) {
+ this.cacheManager = cacheManager;
+ }
public void setCommonEntityManagerFactoryConf(final CommonEntityManagerFactoryConf commonEMFConf) {
super.setJpaPropertyMap(commonEMFConf.getJpaPropertyMap());
@@ -62,42 +57,32 @@ public void setCommonEntityManagerFactoryConf(final CommonEntityManagerFactoryCo
}
public void setConnectorManagerCacheEntryListener(
+ final String domain,
final ConnectorManagerCacheEntryListener connectorManagerCacheEntryListener) {
- this.connectorManagerCacheEntryListener = connectorManagerCacheEntryListener;
+ Optional.ofNullable(cacheManager.getCache(
+ RegionNameQualifier.INSTANCE.qualify(domain, JPAConnInstance.class.getName()))).
+ ifPresent(cache -> cache.registerCacheEntryListener(
+ new MutableCacheEntryListenerConfiguration
-
- com.github.ben-manes.caffeine
- jcache
-
org.springframework.boot
diff --git a/core/starter/src/main/resources/core.properties b/core/starter/src/main/resources/core.properties
index 27c75d568ed..55b64fe55a6 100644
--- a/core/starter/src/main/resources/core.properties
+++ b/core/starter/src/main/resources/core.properties
@@ -45,8 +45,6 @@ service.discovery.address=http://localhost:8080/syncope/rest/
# acceptable values: POSTGRESQL | MYSQL | MARIADB | ORACLE
persistence.db-type=POSTGRESQL
-persistence.cacheProvider=com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
-
persistence.domain[0].key=Master
persistence.domain[0].jdbcDriver=org.postgresql.Driver
persistence.domain[0].jdbcURL=jdbc:postgresql://localhost:5432/syncope?stringtype=unspecified
diff --git a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java
index 664db44d1d2..678bf5c6c01 100644
--- a/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java
+++ b/core/workflow-java/src/test/java/org/apache/syncope/core/workflow/java/WorkflowTestContext.java
@@ -23,6 +23,8 @@
import static org.mockito.Mockito.mock;
import java.time.OffsetDateTime;
+import javax.cache.CacheManager;
+import javax.cache.Caching;
import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
import org.apache.syncope.common.keymaster.client.api.DomainOps;
import org.apache.syncope.common.keymaster.client.api.model.JPADomain;
@@ -128,4 +130,9 @@ public NotificationManager notificationManager() {
public ConnectorManager connectorManager() {
return mock(ConnectorManager.class);
}
+
+ @Bean
+ public CacheManager cacheManager() {
+ return Caching.getCachingProvider().getCacheManager();
+ }
}
diff --git a/docker/core/pom.xml b/docker/core/pom.xml
index 8d61db9d166..77d4e3e9050 100644
--- a/docker/core/pom.xml
+++ b/docker/core/pom.xml
@@ -111,6 +111,40 @@ under the License.
${project.version}
+
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ ${project.version}
+ wrap
+ zip
+ test
+
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-hazelcast
+ ${project.version}
+ wrap
+ zip
+ test
+
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-ehcache
+ ${project.version}
+ wrap
+ zip
+ test
+
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-infinispan
+ ${project.version}
+ wrap
+ zip
+ test
+
+
org.postgresql
@@ -172,6 +206,11 @@ under the License.
+
+
+
+
+
diff --git a/docker/core/src/main/resources/Dockerfile b/docker/core/src/main/resources/Dockerfile
index 62c065d62fe..e99b9a6e461 100644
--- a/docker/core/src/main/resources/Dockerfile
+++ b/docker/core/src/main/resources/Dockerfile
@@ -20,13 +20,14 @@ LABEL org.opencontainers.image.authors="dev@syncope.apache.org"
RUN apk update && apk add bash
-RUN mkdir /opt/syncope /opt/syncope/bin /opt/syncope/bundles /opt/syncope/conf /opt/syncope/lib /opt/syncope/log
+RUN mkdir /opt/syncope /opt/syncope/bin /opt/syncope/bundles /opt/syncope/conf /opt/syncope/lib /opt/syncope/log /opt/syncope/cache
COPY *.properties *.xml saml.keystore.jks /opt/syncope/conf/
COPY bundles/*.jar /opt/syncope/bundles/
COPY lib/mariadb*.jar lib/mysql*jar lib/ojdbc*jar lib/postgresql*jar /opt/syncope/lib/
+COPY lib/syncope-core-cache-*zip /opt/syncope/cache
COPY lib/syncope-docker-core-*jar /opt/syncope/lib/syncope.jar
ENV SPRING_PROFILES_ACTIVE=docker
diff --git a/docker/core/src/main/resources/core-docker.properties b/docker/core/src/main/resources/core-docker.properties
index 2749e0994c5..cbadd111aeb 100644
--- a/docker/core/src/main/resources/core-docker.properties
+++ b/docker/core/src/main/resources/core-docker.properties
@@ -24,8 +24,6 @@ security.productionMode=${PRODUCTION_MODE:true}
security.anonymousUser=${ANONYMOUS_USER:anonymous}
security.anonymousKey=${ANONYMOUS_KEY:anonymousKey}
-persistence.cacheProvider=${HIBERNATE_JCACHE_PROVIDER}
-
spring.lifecycle.timeout-per-shutdown-phase=30s
spring.threads.virtual.enabled=true
diff --git a/docker/core/src/main/resources/startup.sh b/docker/core/src/main/resources/startup.sh
index 3a552db7b06..09191582b60 100755
--- a/docker/core/src/main/resources/startup.sh
+++ b/docker/core/src/main/resources/startup.sh
@@ -17,4 +17,26 @@
# specific language governing permissions and limitations
# under the License.
+cd /opt/syncope/cache
+if [ $JCACHE = "ehcache" ]; then
+ mkdir ehcache && cd ehcache && unzip ../syncope-core-cache-ehcache-wrap.zip
+ LOADER_PATH="$LOADER_PATH,/opt/syncope/cache/ehcache"
+elif [[ $JCACHE == hazelcast* ]]; then
+ mkdir hazelcast && cd hazelcast && unzip ../syncope-core-cache-hazelcast-wrap.zip
+ LOADER_PATH="$LOADER_PATH,/opt/syncope/cache/hazelcast"
+
+ PROVIDER_TYPE="member"
+ if [ $JCACHE = "hazelcast_client" ]; then
+ PROVIDER_TYPE="client"
+ fi
+ JAVA_OPTS="$JAVA_OPTS -Dhazelcast.jcache.provider.type=$PROVIDER_TYPE -Dhazelcast.logging.type=slf4j --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED"
+elif [ $JCACHE = "infinispan" ]; then
+ mkdir infinispan && cd infinispan && unzip ../syncope-core-cache-infinispan-wrap.zip
+ LOADER_PATH="$LOADER_PATH,/opt/syncope/cache/infinispan"
+else
+ mkdir caffeine && cd caffeine && unzip ../syncope-core-cache-caffeine-wrap.zip
+ LOADER_PATH="$LOADER_PATH,/opt/syncope/cache/caffeine"
+fi
+cd -
+
exec java $JAVA_OPTS -jar /opt/syncope/lib/syncope.jar
diff --git a/docker/src/main/resources/docker-compose/docker-compose-all.yml b/docker/src/main/resources/docker-compose/docker-compose-all.yml
index 75f0feef1b6..a69b11424f9 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-all.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-all.yml
@@ -48,7 +48,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: keymaster:2181
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME:-}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD:-}
diff --git a/docker/src/main/resources/docker-compose/docker-compose-ha.yml b/docker/src/main/resources/docker-compose/docker-compose-ha.yml
index 1897c0723d9..840b412d72e 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-ha.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-ha.yml
@@ -35,13 +35,13 @@ services:
- "18080:8080"
restart: always
environment:
+ JCACHE: hazelcast_member
SPRING_PROFILES_ACTIVE: docker,postgresql,saml2
DB_URL: jdbc:postgresql://db:5432/syncope?stringtype=unspecified
DB_USER: syncope
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: tcp(Addresses=syncope1;syncope2)
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD}
@@ -57,13 +57,13 @@ services:
- "18081:8080"
restart: always
environment:
+ JCACHE: hazelcast_member
SPRING_PROFILES_ACTIVE: docker,postgresql
DB_URL: jdbc:postgresql://db:5432/syncope?stringtype=unspecified
DB_USER: syncope
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: tcp(Addresses=syncope1;syncope2)
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD}
diff --git a/docker/src/main/resources/docker-compose/docker-compose-mariadb.yml b/docker/src/main/resources/docker-compose/docker-compose-mariadb.yml
index cc2e5df6c26..866a91ea0e3 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-mariadb.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-mariadb.yml
@@ -43,7 +43,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD}
diff --git a/docker/src/main/resources/docker-compose/docker-compose-mysql.yml b/docker/src/main/resources/docker-compose/docker-compose-mysql.yml
index eee9de85bee..d464753b632 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-mysql.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-mysql.yml
@@ -43,7 +43,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD}
diff --git a/docker/src/main/resources/docker-compose/docker-compose-oracle.yml b/docker/src/main/resources/docker-compose/docker-compose-oracle.yml
index 00d72705bd4..4255ae77462 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-oracle.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-oracle.yml
@@ -42,7 +42,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD}
diff --git a/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml b/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml
index 4fbaf7e1ad3..3329f76dc5b 100644
--- a/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml
+++ b/docker/src/main/resources/docker-compose/docker-compose-postgresql.yml
@@ -40,7 +40,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD}
diff --git a/docker/src/main/resources/kubernetes/syncope/templates/syncope-deployment.yaml b/docker/src/main/resources/kubernetes/syncope/templates/syncope-deployment.yaml
index 74efb05717f..ebde7fd2fdd 100644
--- a/docker/src/main/resources/kubernetes/syncope/templates/syncope-deployment.yaml
+++ b/docker/src/main/resources/kubernetes/syncope/templates/syncope-deployment.yaml
@@ -25,7 +25,7 @@ data:
DB_PASSWORD: {{.Values.syncopeEnvironment.userCreds}}
DB_POOL_MAX: "{{.Values.syncopeEnvironment.dbPoolMax}}"
DB_POOL_MIN: "{{.Values.syncopeEnvironment.dbPoolMin}}"
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
---
apiVersion: extensions/v1beta1
kind: Deployment
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 3650a0e83ae..6525cf5be89 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -64,6 +64,12 @@ under the License.
${project.version}
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ ${project.version}
+
+
org.apache.syncope.core
syncope-core-self-keymaster-starter
@@ -1223,10 +1229,6 @@ under the License.
payara-it
-
- embedded,payara
-
-
org.apache.syncope.core
@@ -1241,13 +1243,16 @@ under the License.
org.apache.tomcat.embed
tomcat-embed-el
-
- com.github.ben-manes.caffeine
- jcache
-
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ ${project.version}
+ provided
+
+
org.glassfish
jakarta.faces
diff --git a/fit/core-reference/src/main/resources/core-payara.properties b/fit/core-reference/src/main/resources/core-payara.properties
deleted file mode 100644
index db449da9333..00000000000
--- a/fit/core-reference/src/main/resources/core-payara.properties
+++ /dev/null
@@ -1,18 +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.
-
-persistence.cacheProvider=com.hazelcast.cache.HazelcastCachingProvider
diff --git a/src/main/asciidoc/getting-started/obtain.adoc b/src/main/asciidoc/getting-started/obtain.adoc
index 69e109a68de..8f286193538 100644
--- a/src/main/asciidoc/getting-started/obtain.adoc
+++ b/src/main/asciidoc/getting-started/obtain.adoc
@@ -102,10 +102,9 @@ Environment variables:
* `DB_PASSWORD`: password for internal storage authentication
* `DB_POOL_MAX`: internal storage connection pool: ceiling
* `DB_POOL_MIN`: internal storage connection pool: floor
-* `HIBERNATE_JCACHE_PROVIDER`: configure multiple instances, with high availability; valid values are the ones accepted by
-Hibernate for
-https://docs.hibernate.org/orm/7.3/userguide/html_single/#caching-provider-jcache-cache-manager[JCache CacheManager^]
-including the default value `com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider` (single instance)
+* `JCACHE`: configure https://docs.hibernate.org/orm/7.4/userguide/html_single/#caching-provider-jcache-cache-manager[JCache provider^]
+for Hibernate, defaults to https://github.com/ben-manes/caffeine[Caffeine^] if no value is provided; allowed values:
+`caffeine|ehcache|hazelcast_client|hazelcast_member|infinispan`
===== Console
@@ -180,7 +179,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: http://localhost:8080/syncope/rest/keymaster
KEYMASTER_USERNAME: ${ANONYMOUS_USER}
KEYMASTER_PASSWORD: ${ANONYMOUS_KEY}
@@ -265,7 +264,7 @@ services:
DB_PASSWORD: syncope
DB_POOL_MAX: 20
DB_POOL_MIN: 5
- HIBERNATE_JCACHE_PROVIDER: com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
+ JCACHE: caffeine
KEYMASTER_ADDRESS: keymaster:2181
KEYMASTER_USERNAME: ${KEYMASTER_USERNAME:-}
KEYMASTER_PASSWORD: ${KEYMASTER_PASSWORD:-}
diff --git a/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc b/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc
index 328ce57ac72..65679d6c031 100644
--- a/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/attributerepositories.adoc
@@ -23,12 +23,12 @@ certain <>.
Some attribute repositories are provided:
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution-JDBC.html[Database^]
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution-LDAP.html[LDAP^]
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution-Stub.html[Stub^]
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution-Syncope.html[Syncope^]
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution-AzureAD.html[Azure Active Directory^]
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution-Okta.html[Okta^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution-JDBC.html[Database^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution-LDAP.html[LDAP^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution-Stub.html[Stub^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution-Syncope.html[Syncope^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution-AzureAD.html[Azure Active Directory^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution-Okta.html[Okta^]
[TIP]
====
@@ -51,4 +51,4 @@ class.
[NOTE]
Attribute Repositories are dynamically translated into
-https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution.html[CAS Attribute Resolution^] configuration.
+https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution.html[CAS Attribute Resolution^] configuration.
diff --git a/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc b/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc
index 4623370f6c3..880826b3a3f 100644
--- a/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/authenticationmodules.adoc
@@ -24,24 +24,24 @@ technology or repository, in the context of a certain <> integrated with <>, the following
information is tracked for <> and <>:
-* https://apereo.github.io/cas/7.3.x/authentication/Surrogate-Authentication.html[Surrogate Authentication^]
-* https://apereo.github.io/cas/7.3.x/mfa/GoogleAuthenticator-Authentication.html[Google Authenticator Authentication^]
-* https://apereo.github.io/cas/7.3.x/mfa/Multifactor-TrustedDevice-Authentication.html[Multifactor Authentication Trusted Devices^]
-* https://apereo.github.io/cas/7.3.x/mfa/FIDO2-WebAuthn-Authentication.html[FIDO2 WebAuthn (Passkey) Multifactor Authentication^]
-* https://apereo.github.io/cas/7.3.x/integration/Attribute-Release-Consent.html[Attribute Consent^]
+* https://apereo.github.io/cas/8.0.x/authentication/Surrogate-Authentication.html[Surrogate Authentication^]
+* https://apereo.github.io/cas/8.0.x/mfa/GoogleAuthenticator-Authentication.html[Google Authenticator Authentication^]
+* https://apereo.github.io/cas/8.0.x/mfa/Multifactor-TrustedDevice-Authentication.html[Multifactor Authentication Trusted Devices^]
+* https://apereo.github.io/cas/8.0.x/mfa/FIDO2-WebAuthn-Authentication.html[FIDO2 WebAuthn (Passkey) Multifactor Authentication^]
+* https://apereo.github.io/cas/8.0.x/integration/Attribute-Release-Consent.html[Attribute Consent^]
diff --git a/src/main/asciidoc/reference-guide/concepts/clientapplications.adoc b/src/main/asciidoc/reference-guide/concepts/clientapplications.adoc
index 4a1156f0773..f96f6265043 100644
--- a/src/main/asciidoc/reference-guide/concepts/clientapplications.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/clientapplications.adoc
@@ -34,17 +34,17 @@ When defining a client application, the following parameters shall be specified:
. name - regular expression to match requests
. description - optional textual description
. username attribute provider, mapping to
-https://apereo.github.io/cas/7.3.x/integration/Attribute-Release-PrincipalId-Attribute.html[CAS Attribute-based Principal Id^]
+https://apereo.github.io/cas/8.0.x/integration/Attribute-Release-PrincipalId-Attribute.html[CAS Attribute-based Principal Id^]
. <>
. <>
. <>
. <>
. additional properties
. logout type, mapping to
-https://apereo.github.io/cas/7.3.x/installation/Logout-Single-Signout.html#slo-requests[the equivalent CAS setting^]
+https://apereo.github.io/cas/8.0.x/installation/Logout-Single-Signout.html#slo-requests[the equivalent CAS setting^]
More parameters are required to be specified depending on the actual client application type.
[NOTE]
Client Applications are dynamically translated into
-https://apereo.github.io/cas/7.3.x/services/Service-Management.html[CAS Services^].
+https://apereo.github.io/cas/8.0.x/services/Service-Management.html[CAS Services^].
diff --git a/src/main/asciidoc/reference-guide/concepts/domains.adoc b/src/main/asciidoc/reference-guide/concepts/domains.adoc
index 3eea561038b..379cbe29641 100644
--- a/src/main/asciidoc/reference-guide/concepts/domains.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/domains.adoc
@@ -27,7 +27,7 @@ External Resources, Policies, Tasks, etc. from different domains (e.g. tenants)
By default, a single `Master` domain is defined, which also bears the configuration for additional domains.
Every domain besides `Master` is mapped one-to-one with a
-https://apereo.github.io/cas/7.3.x/multitenancy/Multitenancy-Overview.html[CAS tenant^] having the same identifier; this
+https://apereo.github.io/cas/8.0.x/multitenancy/Multitenancy-Overview.html[CAS tenant^] having the same identifier; this
allows for <> configuration to relate only to the given domain's database instance.
[.text-center]
diff --git a/src/main/asciidoc/reference-guide/concepts/passwordmanagement.adoc b/src/main/asciidoc/reference-guide/concepts/passwordmanagement.adoc
index 5807ed49caa..e44ef78fc6d 100644
--- a/src/main/asciidoc/reference-guide/concepts/passwordmanagement.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/passwordmanagement.adoc
@@ -23,10 +23,10 @@ according to rules defined by a single configured password management module (on
Some password management modules are provided:
-* https://apereo.github.io/cas/7.3.x/password_management/Password-Management-LDAP.html[LDAP^]
-* https://apereo.github.io/cas/7.3.x/password_management/Password-Management-JDBC.html[JDBC^]
-* https://apereo.github.io/cas/7.3.x/password_management/Password-Management-REST.html[REST^]
-* https://apereo.github.io/cas/7.3.x/password_management/Password-Management-ApacheSyncope.html[Syncope^]
+* https://apereo.github.io/cas/8.0.x/password_management/Password-Management-LDAP.html[LDAP^]
+* https://apereo.github.io/cas/8.0.x/password_management/Password-Management-JDBC.html[JDBC^]
+* https://apereo.github.io/cas/8.0.x/password_management/Password-Management-REST.html[REST^]
+* https://apereo.github.io/cas/8.0.x/password_management/Password-Management-ApacheSyncope.html[Syncope^]
[TIP]
====
@@ -49,4 +49,4 @@ class.
[NOTE]
Password Management is dynamically translated into
-https://apereo.github.io/cas/7.3.x/password_management/Password-Management.html[CAS Password Management^] configuration.
+https://apereo.github.io/cas/8.0.x/password_management/Password-Management.html[CAS Password Management^] configuration.
diff --git a/src/main/asciidoc/reference-guide/concepts/policies.adoc b/src/main/asciidoc/reference-guide/concepts/policies.adoc
index dd84c70dfbf..2d3ae151b21 100644
--- a/src/main/asciidoc/reference-guide/concepts/policies.adoc
+++ b/src/main/asciidoc/reference-guide/concepts/policies.adoc
@@ -329,7 +329,7 @@ endif::[]
[NOTE]
Access Policy instances are dynamically translated into
-https://apereo.github.io/cas/7.3.x/services/Configuring-Service-Access-Strategy.html#configure-service-access-strategy[CAS Service Access Strategy^].
+https://apereo.github.io/cas/8.0.x/services/Configuring-Service-Access-Strategy.html#configure-service-access-strategy[CAS Service Access Strategy^].
[[policies-attribute-release]]
==== Attribute Release
@@ -341,7 +341,7 @@ values.
[NOTE]
Attribute Release Policy instances are dynamically translated into
-https://apereo.github.io/cas/7.3.x/integration/Attribute-Release-Policies.html#attribute-release-policies[CAS Attribute Release Policy^].
+https://apereo.github.io/cas/8.0.x/integration/Attribute-Release-Policies.html#attribute-release-policies[CAS Attribute Release Policy^].
[[policies-authentication]]
==== Authentication
@@ -368,7 +368,7 @@ be considered successful.
[NOTE]
Authentication Policy instances are dynamically translated into
-https://apereo.github.io/cas/7.3.x/authentication/Configuring-Authentication-Policy.html#authentication-policy[CAS Authentication Policy^].
+https://apereo.github.io/cas/8.0.x/authentication/Configuring-Authentication-Policy.html#authentication-policy[CAS Authentication Policy^].
[[policies-propagation]]
==== Propagation
@@ -487,4 +487,4 @@ Ticket Expiration policies control the duration of various types of WA sessions.
[NOTE]
Ticket Expiration Policy instances are dynamically translated into
-https://apereo.github.io/cas/7.3.x/ticketing/Configuring-Ticket-Expiration-Policy.html[their CAS equivalent^].
+https://apereo.github.io/cas/8.0.x/ticketing/Configuring-Ticket-Expiration-Policy.html[their CAS equivalent^].
diff --git a/src/main/asciidoc/reference-guide/configuration/highavailability.adoc b/src/main/asciidoc/reference-guide/configuration/highavailability.adoc
index 101ff82ae80..5000cfc488a 100644
--- a/src/main/asciidoc/reference-guide/configuration/highavailability.adoc
+++ b/src/main/asciidoc/reference-guide/configuration/highavailability.adoc
@@ -21,31 +21,86 @@
==== Core HA
When deploying multiple Syncope <> instances with a single database or database cluster, it is of
-fundamental importance that the https://docs.hibernate.org/orm/7.3/userguide/html_single/#caching[second-level cache^]
+fundamental importance that the https://docs.hibernate.org/orm/7.4/userguide/html_single/#caching[second-level cache^]
is correctly configured for Hibernate ORM.
Such configuration, in fact, allows the Hibernate ORM cache to remain synchronized across multiple JVMs, thus
enforcing data consistency across all Syncope Core instances.
-The default configuration in `core.properties` is
+The supported https://github.com/jsr107/jsr107spec[JCache^] provider is configured according to the implementation found
+in the classpath.
-[source]
-....
-persistence.cacheProvider=com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider
-....
+[WARNING]
+Ensure to define only one of the following providers to avoid conflicts.
-which is suited for single JVM installations; with multiple instances, more options are available depending on the
-configured https://github.com/jsr107/jsr107spec[JCache^] implementation, such as, for example,
-https://docs.hazelcast.com/hazelcast/5.6/jcache/overview[Hazelcast^],
-https://www.ehcache.org/documentation/3.0/107.html[Ehcache],
-https://infinispan.org/docs/stable/titles/hibernate/hibernate.html[Infinispan^] or
-https://ignite.apache.org/[Apache Ignite^].
+[core-ha-caffeine]
+===== Caffeine
-Additional, implementation-specific configuration files can be set up via `persistence.cacheURI`.
+By default, the following dependency is set in `core/pom.xml`.
+
+[source,xml,subs="verbatim,attributes"]
+----
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ ${syncope.version}
+
+----
+
+[WARNING]
+https://github.com/ben-manes/caffeine[Caffeine^] does support only single JVM installations.
+
+[core-ha-ehcache]
+===== Ehcache
+
+Set the following dependency is in `core/pom.xml` to enable https://www.ehcache.org/documentation/3.11/107.html[Ehcache^]:
+
+[source,xml,subs="verbatim,attributes"]
+----
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-caffeine
+ ${syncope.version}
+
+----
+
+[TIP]
+Adding `ehcache.xml` in the classpath will allow to fine-tune Ehcache's https://www.ehcache.org/documentation/3.11/xml.html[configuration^].
+
+[core-ha-hazelcast]
+===== Hazelcast
+
+Set the following dependency is in `core/pom.xml` to enable https://docs.hazelcast.com/hazelcast/5.7/jcache/overview[Hazelcast^]:
+
+[source,xml,subs="verbatim,attributes"]
+----
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-hazelcast
+ ${syncope.version}
+
+----
+
+[TIP]
+Adding `hazelcast.xml` in the classpath will allow to fine-tune Hazelcast's https://docs.hazelcast.com/hazelcast/5.7/configuration/understanding-configuration[configuration^].
+
+[core-ha-infinispan]
+===== Infinispan
+
+Set the following dependency is in `core/pom.xml` to enable https://infinispan.org/docs/stable/titles/embedding/embedding.html[Infinispan^]:
+
+[source,xml,subs="verbatim,attributes"]
+----
+
+ org.apache.syncope.core.cache
+ syncope-core-cache-infinispan
+ ${syncope.version}
+
+----
==== WA HA
When multiple Syncope <> instances are needed to support authentication and authorization requirements,
-a distributed https://apereo.github.io/cas/7.3.x/ticketing/Configuring-Ticketing-Components.html#ticket-registry[Ticket Registry^]
+a distributed https://apereo.github.io/cas/8.0.x/ticketing/Configuring-Ticketing-Components.html#ticket-registry[Ticket Registry^]
is required, such has the ones based on
-https://apereo.github.io/cas/7.3.x/ticketing/Hazelcast-Ticket-Registry.html[Hazelcast^]
-or https://apereo.github.io/cas/7.3.x/ticketing/Ignite-Ticket-Registry.html[Apache Ignite^].
+https://apereo.github.io/cas/8.0.x/ticketing/Hazelcast-Ticket-Registry.html[Hazelcast^]
+or https://apereo.github.io/cas/8.0.x/ticketing/Ignite-Ticket-Registry.html[Apache Ignite^].
diff --git a/src/main/asciidoc/reference-guide/usage/actuator.adoc b/src/main/asciidoc/reference-guide/usage/actuator.adoc
index 478b348d1ef..10b8eeda8d3 100644
--- a/src/main/asciidoc/reference-guide/usage/actuator.adoc
+++ b/src/main/asciidoc/reference-guide/usage/actuator.adoc
@@ -40,7 +40,7 @@ The pre-defined `health` endpoint is typically used for liveness and readiness p
|===
| `entityCache`
-a| Allows to work with https://docs.hibernate.org/orm/7.3/userguide/html_single/#caching-statistics[JPA cache statistics^]
+a| Allows to work with https://docs.hibernate.org/orm/7.4/userguide/html_single/#caching-statistics[JPA cache statistics^]
* `GET` - shows JPA cache statistics
* `POST {ENABLE,DISABLE,RESET}` - performs the requested operation onto JPA cache
@@ -60,15 +60,15 @@ a| Allows to work with the various jobs defined after <> and <>.
|===
| `ssoSessions`
-| https://apereo.github.io/cas/7.3.x/authentication/Configuring-SSO.html#actuator-endpoints[More details^]
+| https://apereo.github.io/cas/8.0.x/authentication/Configuring-SSO.html#actuator-endpoints[More details^]
| `registeredServices`
-| https://apereo.github.io/cas/7.3.x/services/Service-Management.html#actuator-endpoints[More details^]
+| https://apereo.github.io/cas/8.0.x/services/Service-Management.html#actuator-endpoints[More details^]
| `authenticationHandlers`
-| https://apereo.github.io/cas/7.3.x/authentication/Configuring-Authentication-Components.html#actuator-endpoints[More details^]
+| https://apereo.github.io/cas/8.0.x/authentication/Configuring-Authentication-Components.html#actuator-endpoints[More details^]
| `authenticationPolicies`
-| https://apereo.github.io/cas/7.3.x/authentication/Configuring-Authentication-Policy.html#actuator-endpoints[More details^]
+| https://apereo.github.io/cas/8.0.x/authentication/Configuring-Authentication-Policy.html#actuator-endpoints[More details^]
| `resolveAttributes`
-| https://apereo.github.io/cas/7.3.x/integration/Attribute-Resolution.html#actuator-endpoints[More details^]
+| https://apereo.github.io/cas/8.0.x/integration/Attribute-Resolution.html#actuator-endpoints[More details^]
|===
diff --git a/src/main/asciidoc/reference-guide/usage/customization.adoc b/src/main/asciidoc/reference-guide/usage/customization.adoc
index f46742a1422..1280b54186a 100644
--- a/src/main/asciidoc/reference-guide/usage/customization.adoc
+++ b/src/main/asciidoc/reference-guide/usage/customization.adoc
@@ -275,7 +275,7 @@ components:
===== Customize Hibernate ORM settings
Hibernate ORM is at the core of the <> layer; its configuration can be tweaked under several
-aspects - including https://docs.hibernate.org/orm/7.3/userguide/html_single/#caching[caching^] for
+aspects - including https://docs.hibernate.org/orm/7.4/userguide/html_single/#caching[caching^] for
example, to best suit the various environments.
The main configuration classes are:
diff --git a/src/main/asciidoc/reference-guide/usage/metrics.adoc b/src/main/asciidoc/reference-guide/usage/metrics.adoc
index 01baccff3da..c3137f69456 100644
--- a/src/main/asciidoc/reference-guide/usage/metrics.adoc
+++ b/src/main/asciidoc/reference-guide/usage/metrics.adoc
@@ -52,4 +52,4 @@ This can be enabled by adding the following dependency to `wa/pom.xml`:
----
-For further options and configuration, refer to https://apereo.github.io/cas/7.3.x/monitoring/Configuring-Metrics.html[CAS documentation^].
+For further options and configuration, refer to https://apereo.github.io/cas/8.0.x/monitoring/Configuring-Metrics.html[CAS documentation^].