keycloak-uncached
Changes
adapters/oidc/installed/pom.xml 2(+1 -1)
authz/policy/drools/pom.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml 4(+2 -2)
distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-clustered.cli 97(+95 -2)
distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-standalone.cli 61(+61 -0)
distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone.cli 61(+60 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone-ha.cli 98(+97 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-infinispan/main/module.xml 3(+2 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-subsystem/main/server-war/WEB-INF/web.xml 2(+1 -1)
distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-wildfly-adduser/main/module.xml 4(+2 -2)
distribution/server-dist/pom.xml 11(+0 -11)
distribution/server-provisioning.xml 3(+0 -3)
examples/providers/rest/pom.xml 2(+1 -1)
integration/admin-client/pom.xml 2(+1 -1)
model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java 8(+5 -3)
model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java 17(+5 -12)
model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java 88(+33 -55)
model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java 10(+2 -8)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java 8(+5 -3)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java 20(+5 -15)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/SessionData.java 5(+3 -2)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java 8(+4 -4)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java 2(+1 -1)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/UserSessionEntity.java 8(+4 -4)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/AbstractUserSessionClusterListener.java 6(+4 -2)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/SessionClusterEvent.java 6(+4 -2)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProvider.java 24(+7 -17)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProviderFactory.java 10(+1 -9)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java 1(+0 -1)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java 8(+5 -3)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/BaseCacheInitializer.java 33(+1 -32)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InfinispanCacheInitializer.java 45(+43 -2)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InitializerState.java 32(+8 -24)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoader.java 30(+25 -5)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoaderContext.java 66(+66 -0)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionInitializerWorker.java 11(+4 -7)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionLoader.java 29(+23 -6)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java 34(+21 -13)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java 51(+35 -16)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java 173(+100 -73)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoaderContext.java 99(+99 -0)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/InfinispanUtil.java 31(+3 -28)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/KeycloakMarshallUtil.java 1(+0 -1)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGCachePutTest.java 16(+14 -2)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGCacheReplaceTest.java 14(+8 -6)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGRemoteCacheClientListenersTest.java 23(+18 -5)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/RemoteCacheSessionsLoaderTest.java 160(+160 -0)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java 3(+3 -0)
model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java 5(+4 -1)
model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyLockingTest.java 4(+2 -2)
model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyVersioningTest.java 4(+2 -2)
model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/DistributedCacheWriteSkewTest.java 4(+2 -2)
model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/InitializerStateTest.java 49(+48 -1)
pom.xml 40(+26 -14)
services/pom.xml 2(+1 -1)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/org/keycloak/testsuite/integration-arquillian-testsuite-providers/main/module.xml 1(+1 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AuthenticationSessionClusterTest.java 2(+1 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ActionTokenCrossDCTest.java 10(+6 -4)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java 5(+5 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java 2(+0 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java 14(+12 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/error/UncaughtErrorPageTest.java 14(+12 -2)
testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json 2(+1 -1)
testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-3.4.3.Final-redhat-2.xml 1123(+1123 -0)
testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-3.4.3.Final-redhat-2.xml 185(+185 -0)
testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-3.4.3.Final-redhat-2.xml 573(+573 -0)
testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-3.4.3.Final-redhat-2.xml 631(+631 -0)
testsuite/jetty/jetty92/pom.xml 2(+1 -1)
testsuite/jetty/jetty93/pom.xml 2(+1 -1)
testsuite/jetty/jetty94/pom.xml 2(+1 -1)
testsuite/performance/tests/pom.xml 2(+1 -1)
testsuite/proxy/pom.xml 2(+1 -1)
testsuite/tomcat7/pom.xml 2(+1 -1)
testsuite/tomcat8/pom.xml 2(+1 -1)
testsuite/utils/pom.xml 2(+1 -1)
wildfly/adduser/pom.xml 6(+5 -1)
Details
adapters/oidc/installed/pom.xml 2(+1 -1)
diff --git a/adapters/oidc/installed/pom.xml b/adapters/oidc/installed/pom.xml
index 0e89e2b..e07cc0e 100755
--- a/adapters/oidc/installed/pom.xml
+++ b/adapters/oidc/installed/pom.xml
@@ -69,7 +69,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
</dependencies>
diff --git a/adapters/oidc/jaxrs-oauth-client/pom.xml b/adapters/oidc/jaxrs-oauth-client/pom.xml
index a8acfda..472e5c8 100755
--- a/adapters/oidc/jaxrs-oauth-client/pom.xml
+++ b/adapters/oidc/jaxrs-oauth-client/pom.xml
@@ -33,7 +33,7 @@
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
authz/policy/drools/pom.xml 2(+1 -1)
diff --git a/authz/policy/drools/pom.xml b/authz/policy/drools/pom.xml
index b633e22..a8b20e2 100644
--- a/authz/policy/drools/pom.xml
+++ b/authz/policy/drools/pom.xml
@@ -55,7 +55,7 @@
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
diff --git a/distribution/demo-dist/src/main/xslt/standalone.xsl b/distribution/demo-dist/src/main/xslt/standalone.xsl
index 7f18d0d..3754763 100755
--- a/distribution/demo-dist/src/main/xslt/standalone.xsl
+++ b/distribution/demo-dist/src/main/xslt/standalone.xsl
@@ -17,7 +17,7 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
- xmlns:j="urn:jboss:domain:5.0"
+ xmlns:j="urn:jboss:domain:7.0"
xmlns:ds="urn:jboss:domain:datasources:5.0"
xmlns:k="urn:jboss:domain:keycloak:1.1"
xmlns:sec="urn:jboss:domain:security:2.0"
@@ -81,12 +81,12 @@
<xsl:template match="//*[local-name()='subsystem' and starts-with(namespace-uri(), $inf)]">
<xsl:copy>
- <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <cache-container name="keycloak">
<local-cache name="realms">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="users">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
@@ -95,12 +95,12 @@
<local-cache name="offlineClientSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="authorization">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="actionTokens"/>
<local-cache name="work"/>
<local-cache name="keys">
- <eviction max-entries="1000" strategy="LRU"/>
+ <object-memory size="1000"/>
<expiration max-idle="3600000" />
</local-cache>
</cache-container>
@@ -114,4 +114,4 @@
</xsl:copy>
</xsl:template>
-</xsl:stylesheet>
\ No newline at end of file
+</xsl:stylesheet>
diff --git a/distribution/feature-packs/server-feature-pack/assembly.xml b/distribution/feature-packs/server-feature-pack/assembly.xml
index c933938..7c64b1a 100644
--- a/distribution/feature-packs/server-feature-pack/assembly.xml
+++ b/distribution/feature-packs/server-feature-pack/assembly.xml
@@ -34,6 +34,10 @@
<outputDirectory>content/themes</outputDirectory>
</fileSet>
<fileSet>
+ <directory>target/keycloak-client-tools/bin</directory>
+ <outputDirectory>content/bin</outputDirectory>
+ </fileSet>
+ <fileSet>
<directory>src/main/resources/identity/module</directory>
<includes>
<include>**/**</include>
diff --git a/distribution/feature-packs/server-feature-pack/pom.xml b/distribution/feature-packs/server-feature-pack/pom.xml
index cceef66..1d0ada9 100644
--- a/distribution/feature-packs/server-feature-pack/pom.xml
+++ b/distribution/feature-packs/server-feature-pack/pom.xml
@@ -613,6 +613,17 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-client-cli-dist</artifactId>
+ <type>zip</type>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<exclusions>
@@ -713,6 +724,16 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.aesh</groupId>
+ <artifactId>aesh</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
<build>
@@ -741,8 +762,33 @@
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack-cli</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-client-cli-dist</artifactId>
+ <type>zip</type>
+ <outputDirectory>target/</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.wildfly.build</groupId>
<artifactId>wildfly-feature-pack-build-maven-plugin</artifactId>
+ <version>${wildfly.build-tools.version}</version>
<executions>
<execution>
<id>feature-pack-build</id>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml
index 5774706..47f05e5 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/domain/template.xml
@@ -17,7 +17,7 @@
~ limitations under the License.
-->
-<domain xmlns="urn:jboss:domain:5.0">
+<domain xmlns="urn:jboss:domain:7.0">
<extensions>
<?EXTENSIONS?>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml
index 6a4dba4..07c65ad 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host.xml
@@ -23,7 +23,7 @@
via host-slave.xml
-->
-<host name="master" xmlns="urn:jboss:domain:5.0">
+<host name="master" xmlns="urn:jboss:domain:7.0">
<extensions>
<?EXTENSIONS?>
</extensions>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml
index 095fcc4..166e220 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-master.xml
@@ -22,7 +22,7 @@
is also started by this host controller file. The other instance must be started
via host-slave.xml
-->
-<host name="master" xmlns="urn:jboss:domain:5.0">
+<host name="master" xmlns="urn:jboss:domain:7.0">
<extensions>
<?EXTENSIONS?>
</extensions>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml
index 3b1812e..2cc9a3b 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/host/host-slave.xml
@@ -17,7 +17,7 @@
~ limitations under the License.
-->
-<host xmlns="urn:jboss:domain:5.0">
+<host xmlns="urn:jboss:domain:7.0">
<extensions>
<?EXTENSIONS?>
</extensions>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml
index 7b13afe..5c2cb0e 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/configuration/standalone/template.xml
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
-<server xmlns="urn:jboss:domain:5.0">
+<server xmlns="urn:jboss:domain:7.0">
<extensions>
<?EXTENSIONS?>
@@ -87,4 +87,4 @@
<?SOCKET-BINDINGS?>
</socket-binding-group>
-</server>
\ No newline at end of file
+</server>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-clustered.cli b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-clustered.cli
index 21fe61b..9b9729c 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-clustered.cli
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-clustered.cli
@@ -115,8 +115,7 @@ if (result == undefined) of /profile=$clusteredProfile/subsystem=infinispan/cach
/profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/component=expiration/:write-attribute(name=max-idle,value=3600000)
echo
end-if
-
-if (outcome == failed) of /profile=$clusteredProfile/subsystem=keycloak-server/spi=publicKeyStorage/:read-resource
+if (outcome == failed) of /profile=$clusteredProfile/subsystem=keycloak-server/spi=publicKeyStorage/:read-resource
echo Adding spi=publicKeyStorage...
/profile=$clusteredProfile/subsystem=keycloak-server/spi=publicKeyStorage/:add
/profile=$clusteredProfile/subsystem=keycloak-server/spi=publicKeyStorage/provider=infinispan/:add(properties={minTimeBetweenRequests => "10"},enabled=true)
@@ -447,4 +446,98 @@ if (outcome == failed) of /profile=$clusteredProfile/subsystem=keycloak-server/s
echo
end-if
+# Migrate from 4.3.0 to 4.4.0
+if (outcome == failed) of /profile=$clusteredProfile/subsystem=elytron/permission-set=login-permission/:read-resource
+ echo Adding permission-set=login-permission to elytron
+ /profile=$clusteredProfile/subsystem=elytron/permission-set=login-permission:add(permissions=[{class-name=org.wildfly.security.auth.permission.LoginPermission}])
+ /profile=$clusteredProfile/subsystem=elytron/permission-set=default-permissions/:add(permissions=[{class-name=org.wildfly.extension.batch.jberet.deployment.BatchPermission,module=org.wildfly.extension.batch.jberet,target-name=*},{class-name=org.wildfly.transaction.client.RemoteTransactionPermission,module=org.wildfly.transaction.client},{class-name=org.jboss.ejb.client.RemoteEJBPermission,module=org.jboss.ejb-client}])
+ /profile=$clusteredProfile/subsystem=elytron/simple-permission-mapper=default-permission-mapper/:undefine-attribute(name=permission-mappings)
+ /profile=$clusteredProfile/subsystem=elytron/simple-permission-mapper=default-permission-mapper:write-attribute(name=permission-mappings,value=[{permission-sets=[{permission-set=login-permission},{permission-set=default-permissions}],match-all=true},{permission-sets=[{permission-set=default-permissions}],principals=[anonymous]}])
+ echo
+end-if
+
+if (result == org.hibernate.infinispan) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate:read-attribute(name=module)
+ echo Update hibernate cache module
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate:write-attribute(name=module, value=org.infinispan.hibernate-cache)
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate:read-attribute(name=default-cache)
+ echo Remove default cache from hibernate cache
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate:undefine-attribute(name=default-cache)
+ echo
+end-if
+if (result == ASYNC) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/replicated-cache=timestamps:read-attribute(name=mode)
+ echo Switching mode for timestamps cache from ASYNC to SYNC
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/replicated-cache=timestamps:write-attribute(name=mode, value=SYNC)
+ echo
+end-if
+
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate entity cache and replacing with object-memory
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:remove
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/local-cache=entity/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/distributed-cache=local-query/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate local-query cache and replacing with object-memory
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/local-cache=local-query/eviction=EVICTION:remove
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=hibernate/local-cache=local-query/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak realms cache and replacing with object-memory
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:remove
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=realms/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak users cache and replacing with object-memory
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:remove
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=users/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak authorization cache and replacing with object-memory
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:remove
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak keys cache and replacing with object-memory
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:remove
+ /profile=$clusteredProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/memory=object:add(size=1000)
+ echo
+end-if
+
+if (outcome == success) of /profile=$clusteredProfile/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:read-resource
+ echo Changing JNDI reference in connectionsInfinispan SPI
+ /profile=$clusteredProfile/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:undefine-attribute(name=properties)
+ /profile=$clusteredProfile/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:write-attribute(name=properties,value={cacheContainer=java:jboss/infinispan/container/keycloak})
+ echo
+end-if
+
+if (outcome == success) of /profile=$clusteredProfile/subsystem=jgroups/stack=tcp/protocol=FRAG2:read-resource
+ echo Upgrade jgroups protocol from FRAG2 to FRAG3 for tcp stack
+ /profile=$clusteredProfile/subsystem=jgroups/stack=tcp/protocol=FRAG2:remove
+ /profile=$clusteredProfile/subsystem=jgroups/stack=tcp/protocol=FRAG3:add()
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=jgroups/stack=udp/protocol=FRAG2:read-resource
+ echo Upgrade jgroups protocol from FRAG2 to FRAG3 for udp stack
+ /profile=$clusteredProfile/subsystem=jgroups/stack=udp/protocol=FRAG2:remove
+ /profile=$clusteredProfile/subsystem=jgroups/stack=udp/protocol=FRAG3:add()
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/subsystem=remoting/configuration=endpoint:read-resource
+ echo Remove endpoint from remoting configuration
+ /profile=$clusteredProfile/subsystem=remoting/configuration=endpoint:remove
+ echo
+end-if
+if (outcome == success) of /profile=$clusteredProfile/socket-binding-group=$clusteredProfile-sockets/socket-binding=jgroups-mping:read-attribute(name=port)
+ /profile=$clusteredProfile/socket-binding-group=$clusteredProfile-sockets/socket-binding=jgroups-mping:undefine-attribute(name=port)
+end-if
+if (outcome == success) of /socket-binding-group=$clusteredProfile-sockets/socket-binding=modcluster:read-attribute(name=port)
+ /profile=$clusteredProfile/socket-binding-group=$clusteredProfile-sockets/socket-binding=modcluster:undefine-attribute(name=port)
+end-if
+
echo *** End Migration of /profile=$clusteredProfile ***
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-standalone.cli b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-standalone.cli
index 56b676c..49de7ae 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-standalone.cli
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-domain-standalone.cli
@@ -47,6 +47,7 @@ if (result == undefined) of /profile=$standaloneProfile/subsystem=infinispan/cac
echo Updating authorization cache container..
/profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/component=eviction/:write-attribute(name=strategy,value=LRU)
/profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/component=eviction/:write-attribute(name=max-entries,value=100)
+ echo
end-if
# Migrate from 2.0.0 to 2.1.0
@@ -347,6 +348,7 @@ if (outcome == success) of /profile=$standaloneProfile/subsystem=undertow/server
/profile=$standaloneProfile/subsystem=undertow/server=default-server/host=default-host/filter-ref=x-powered-by-header/:remove
/profile=$standaloneProfile/subsystem=undertow/configuration=filter/response-header=x-powered-by-header/:remove
/profile=$standaloneProfile/subsystem=undertow/configuration=filter/response-header=server-header/:remove
+ echo
end-if
if (outcome == success) of /profile=$standaloneProfile/subsystem=jdr/:read-resource
@@ -404,4 +406,63 @@ if (outcome == failed) of /profile=$standaloneProfile/subsystem=keycloak-server/
echo
end-if
+# Migrate from 4.3.0 to 4.4.0
+if (outcome == failed) of /profile=$standaloneProfile/subsystem=elytron/permission-set=login-permission/:read-resource
+ echo Adding permission-set=login-permission to elytron
+ /profile=$standaloneProfile/subsystem=elytron/permission-set=login-permission:add(permissions=[{class-name=org.wildfly.security.auth.permission.LoginPermission}])
+ /profile=$standaloneProfile/subsystem=elytron/permission-set=default-permissions/:add(permissions=[{class-name=org.wildfly.extension.batch.jberet.deployment.BatchPermission,module=org.wildfly.extension.batch.jberet,target-name=*},{class-name=org.wildfly.transaction.client.RemoteTransactionPermission,module=org.wildfly.transaction.client},{class-name=org.jboss.ejb.client.RemoteEJBPermission,module=org.jboss.ejb-client}])
+ /profile=$standaloneProfile/subsystem=elytron/simple-permission-mapper=default-permission-mapper/:undefine-attribute(name=permission-mappings)
+ /profile=$standaloneProfile/subsystem=elytron/simple-permission-mapper=default-permission-mapper:write-attribute(name=permission-mappings,value=[{permission-sets=[{permission-set=login-permission},{permission-set=default-permissions}],match-all=true},{permission-sets=[{permission-set=default-permissions}],principals=[anonymous]}])
+ echo
+end-if
+
+if (result == org.hibernate.infinispan) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate:read-attribute(name=module)
+ echo Update hibernate cache module
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate:write-attribute(name=module, value=org.infinispan.hibernate-cache)
+ echo
+end-if
+if (outcome == success) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate entity cache and replacing with object-memory
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:remove
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate/local-cache=entity/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate/local-cache=local-query/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate local-query cache and replacing with object-memory
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate/local-cache=local-query/eviction=EVICTION:remove
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=hibernate/local-cache=local-query/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak realms cache and replacing with object-memory
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:remove
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=realms/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak users cache and replacing with object-memory
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:remove
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=users/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak authorization cache and replacing with object-memory
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:remove
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak keys cache and replacing with object-memory
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:remove
+ /profile=$standaloneProfile/subsystem=infinispan/cache-container=keycloak/local-cache=keys/memory=object:add(size=1000)
+ echo
+end-if
+
+if (outcome == success) of /profile=$standaloneProfile/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:read-resource
+ echo Changing JNDI reference in connectionsInfinispan SPI
+ /profile=$standaloneProfile/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:undefine-attribute(name=properties)
+ /profile=$standaloneProfile/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:write-attribute(name=properties,value={cacheContainer=java:jboss/infinispan/container/keycloak})
+ echo
+end-if
+
echo *** End Migration of /profile=$standaloneProfile ***
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone.cli b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone.cli
index 5194c45..479fc1a 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone.cli
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone.cli
@@ -305,7 +305,7 @@ if (result == local-query) of /subsystem=infinispan/cache-container=hibernate/:r
/subsystem=infinispan/cache-container=hibernate/:undefine-attribute(name=default-cache)
echo
end-if
-
+
if (outcome == failed) of /subsystem=undertow/server=default-server/host=default-host/setting=http-invoker/:read-resource
echo Adding http-invoker to default-host
/subsystem=undertow/server=default-server/host=default-host/setting=http-invoker/:add(security-realm=ApplicationRealm)
@@ -375,4 +375,63 @@ if (outcome == failed) of /subsystem=keycloak-server/spi=hostname/:read-resource
echo
end-if
+# Migrate from 4.3.0 to 4.4.0
+if (outcome == failed) of /subsystem=elytron/permission-set=login-permission/:read-resource
+ echo Adding permission-set=login-permission to elytron
+ /subsystem=elytron/permission-set=login-permission:add(permissions=[{class-name=org.wildfly.security.auth.permission.LoginPermission}])
+ /subsystem=elytron/permission-set=default-permissions/:add(permissions=[{class-name=org.wildfly.extension.batch.jberet.deployment.BatchPermission,module=org.wildfly.extension.batch.jberet,target-name=*},{class-name=org.wildfly.transaction.client.RemoteTransactionPermission,module=org.wildfly.transaction.client},{class-name=org.jboss.ejb.client.RemoteEJBPermission,module=org.jboss.ejb-client}])
+ /subsystem=elytron/simple-permission-mapper=default-permission-mapper/:undefine-attribute(name=permission-mappings)
+ /subsystem=elytron/simple-permission-mapper=default-permission-mapper:write-attribute(name=permission-mappings,value=[{permission-sets=[{permission-set=login-permission},{permission-set=default-permissions}],match-all=true},{permission-sets=[{permission-set=default-permissions}],principals=[anonymous]}])
+ echo
+end-if
+
+if (result == org.hibernate.infinispan) of /subsystem=infinispan/cache-container=hibernate:read-attribute(name=module)
+ echo Update hibernate cache module
+ /subsystem=infinispan/cache-container=hibernate:write-attribute(name=module, value=org.infinispan.hibernate-cache)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate entity cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=hibernate/local-cache=entity/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=hibernate/local-cache=local-query/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate local-query cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=hibernate/local-cache=local-query/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=hibernate/local-cache=local-query/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak realms cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=realms/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak users cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=users/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak authorization cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=authorization/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak keys cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=keys/memory=object:add(size=1000)
+ echo
+end-if
+
+if (outcome == success) of /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:read-resource
+ echo Changing JNDI reference in connectionsInfinispan SPI
+ /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:undefine-attribute(name=properties)
+ /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:write-attribute(name=properties,value={cacheContainer=java:jboss/infinispan/container/keycloak})
+ echo
+end-if
+
echo *** End Migration ***
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone-ha.cli b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone-ha.cli
index 5b11647..e59194f 100644
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone-ha.cli
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/content/bin/migrate-standalone-ha.cli
@@ -137,7 +137,7 @@ if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/invali
echo
end-if
if (result == undefined) of /subsystem=infinispan/cache-container=keycloak/local-cache=users/component=eviction/:read-attribute(name=strategy,include-defaults=false)
- echo Updating eviction in local-cache=users...
+ echo Updating eviction in local-cache=users
/subsystem=infinispan/cache-container=keycloak/local-cache=users/component=eviction/:write-attribute(name=strategy,value=LRU)
/subsystem=infinispan/cache-container=keycloak/local-cache=users/component=eviction/:write-attribute(name=max-entries,value=10000)
echo
@@ -431,4 +431,100 @@ if (outcome == failed) of /subsystem=keycloak-server/spi=hostname/:read-resource
echo
end-if
+# Migrate from 4.3.0 to 4.4.0
+if (outcome == failed) of /subsystem=elytron/permission-set=login-permission/:read-resource
+ echo Adding permission-set=login-permission to elytron
+ /subsystem=elytron/permission-set=login-permission:add(permissions=[{class-name=org.wildfly.security.auth.permission.LoginPermission}])
+ /subsystem=elytron/permission-set=default-permissions/:add(permissions=[{class-name=org.wildfly.extension.batch.jberet.deployment.BatchPermission,module=org.wildfly.extension.batch.jberet,target-name=*},{class-name=org.wildfly.transaction.client.RemoteTransactionPermission,module=org.wildfly.transaction.client},{class-name=org.jboss.ejb.client.RemoteEJBPermission,module=org.jboss.ejb-client}])
+ /subsystem=elytron/simple-permission-mapper=default-permission-mapper/:undefine-attribute(name=permission-mappings)
+ /subsystem=elytron/simple-permission-mapper=default-permission-mapper:write-attribute(name=permission-mappings,value=[{permission-sets=[{permission-set=login-permission},{permission-set=default-permissions}],match-all=true},{permission-sets=[{permission-set=default-permissions}],principals=[anonymous]}])
+ echo
+end-if
+
+
+if (result == org.hibernate.infinispan) of /subsystem=infinispan/cache-container=hibernate:read-attribute(name=module)
+ echo Update hibernate cache module
+ /subsystem=infinispan/cache-container=hibernate:write-attribute(name=module, value=org.infinispan.hibernate-cache)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=hibernate:read-attribute(name=default-cache)
+ echo Remove default cache from hibernate cache
+ /subsystem=infinispan/cache-container=hibernate:undefine-attribute(name=default-cache)
+ echo
+end-if
+if (result == ASYNC) of /subsystem=infinispan/cache-container=hibernate/replicated-cache=timestamps:read-attribute(name=mode)
+ echo Switching mode for timestamps cache from ASYNC to SYNC
+ /subsystem=infinispan/cache-container=hibernate/replicated-cache=timestamps:write-attribute(name=mode, value=SYNC)
+ echo
+end-if
+
+if (outcome == success) of /subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate entity cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=hibernate/local-cache=entity/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=hibernate/local-cache=entity/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=hibernate/distributed-cache=local-query/eviction=EVICTION:read-resource
+ echo Removing eviction from hibernate local-query cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=hibernate/local-cache=local-query/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=hibernate/local-cache=local-query/memory=object:add(size=10000)
+ echo
+end-if
+
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak realms cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=realms/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak users cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=users/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak authorization cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=authorization/memory=object:add(size=10000)
+ echo
+end-if
+if (outcome == success) of /subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:read-resource
+ echo Removing eviction from keycloak keys cache and replacing with object-memory
+ /subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:remove
+ /subsystem=infinispan/cache-container=keycloak/local-cache=keys/memory=object:add(size=1000)
+ echo
+end-if
+
+if (outcome == success) of /subsystem=jgroups/stack=tcp/protocol=FRAG2:read-resource
+ echo Upgrade jgroups protocol from FRAG2 to FRAG3 for tcp stack
+ /subsystem=jgroups/stack=tcp/protocol=FRAG2:remove
+ /subsystem=jgroups/stack=tcp/protocol=FRAG3:add()
+ echo
+end-if
+if (outcome == success) of /subsystem=jgroups/stack=udp/protocol=FRAG2:read-resource
+ echo Upgrade jgroups protocol from FRAG2 to FRAG3 for udp stack
+ /subsystem=jgroups/stack=udp/protocol=FRAG2:remove
+ /subsystem=jgroups/stack=udp/protocol=FRAG3:add()
+ echo
+end-if
+if (outcome == success) of /subsystem=remoting/configuration=endpoint:read-resource
+ echo Remove endpoint from remoting configuration
+ /subsystem=remoting/configuration=endpoint:remove
+ echo
+end-if
+if (outcome == success) of /socket-binding-group=standard-sockets/socket-binding=jgroups-mping:read-attribute(name=port)
+ /socket-binding-group=standard-sockets/socket-binding=jgroups-mping:undefine-attribute(name=port)
+end-if
+if (outcome == success) of /socket-binding-group=standard-sockets/socket-binding=modcluster:read-attribute(name=port)
+ /socket-binding-group=standard-sockets/socket-binding=modcluster:undefine-attribute(name=port)
+end-if
+
+if (outcome == success) of /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:read-resource
+ echo Changing JNDI reference in connectionsInfinispan SPI
+ /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:undefine-attribute(name=properties)
+ /subsystem=keycloak-server/spi=connectionsInfinispan/provider=default:write-attribute(name=properties,value={cacheContainer=java:jboss/infinispan/container/keycloak})
+ echo
+end-if
+
echo *** End Migration ***
\ No newline at end of file
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-infinispan/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-infinispan/main/module.xml
index 4388f83..9d93415 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-infinispan/main/module.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-model-infinispan/main/module.xml
@@ -31,10 +31,11 @@
<module name="org.keycloak.keycloak-server-spi-private"/>
<module name="org.infinispan"/>
<module name="org.infinispan.commons"/>
- <module name="org.infinispan.cachestore.remote"/>
+ <module name="org.infinispan.persistence.remote"/>
<module name="org.infinispan.client.hotrod"/>
<module name="org.jgroups"/>
<module name="org.jboss.logging"/>
+ <module name="io.netty"/>
<module name="javax.api"/>
</dependencies>
</module>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-subsystem/main/server-war/WEB-INF/web.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-subsystem/main/server-war/WEB-INF/web.xml
index 6ad93e9..4a85d38 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-subsystem/main/server-war/WEB-INF/web.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-server-subsystem/main/server-war/WEB-INF/web.xml
@@ -61,6 +61,6 @@
<resource-env-ref>
<resource-env-ref-name>infinispan/Keycloak</resource-env-ref-name>
<resource-env-ref-type>org.infinispan.manager.EmbeddedCacheManager</resource-env-ref-type>
- <lookup-name>java:jboss/infinispan/Keycloak</lookup-name>
+ <lookup-name>java:jboss/infinispan/container/keycloak</lookup-name>
</resource-env-ref>
</web-app>
diff --git a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-wildfly-adduser/main/module.xml b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-wildfly-adduser/main/module.xml
index 88744ac..8854801 100755
--- a/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-wildfly-adduser/main/module.xml
+++ b/distribution/feature-packs/server-feature-pack/src/main/resources/modules/system/layers/keycloak/org/keycloak/keycloak-wildfly-adduser/main/module.xml
@@ -15,7 +15,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<module xmlns="urn:jboss:module:1.3" name="org.keycloak.keycloak-wildfly-adduser">
+<module xmlns="urn:jboss:module:1.6" name="org.keycloak.keycloak-wildfly-adduser">
<main-class name="org.keycloak.wildfly.adduser.AddUser"/>
<properties>
@@ -32,7 +32,7 @@
<module name="org.keycloak.keycloak-server-spi" services="import"/>
<module name="org.keycloak.keycloak-server-spi-private" services="import"/>
<module name="org.keycloak.keycloak-services" services="import"/>
- <module name="org.jboss.aesh"/>
+ <module name="org.aesh"/>
<module name="org.jboss.as.domain-management"/>
<module name="com.fasterxml.jackson.core.jackson-core"/>
<module name="com.fasterxml.jackson.core.jackson-annotations"/>
diff --git a/distribution/server-dist/assembly.xml b/distribution/server-dist/assembly.xml
index c73d5c1..0f8af6f 100755
--- a/distribution/server-dist/assembly.xml
+++ b/distribution/server-dist/assembly.xml
@@ -103,14 +103,6 @@
</includes>
</fileSet>
<fileSet>
- <directory>target/unpacked/keycloak-client-tools</directory>
- <outputDirectory/>
- <filtered>false</filtered>
- <includes>
- <include>**/*</include>
- </includes>
- </fileSet>
- <fileSet>
<directory>target/licenses/content/docs</directory>
<outputDirectory>docs</outputDirectory>
<includes>
distribution/server-dist/pom.xml 11(+0 -11)
diff --git a/distribution/server-dist/pom.xml b/distribution/server-dist/pom.xml
index 6a40e72..bbb589f 100755
--- a/distribution/server-dist/pom.xml
+++ b/distribution/server-dist/pom.xml
@@ -41,17 +41,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-client-cli-dist</artifactId>
- <type>zip</type>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
</dependencies>
<build>
diff --git a/distribution/server-overlay/src/main/cli/keycloak-install-base.cli b/distribution/server-overlay/src/main/cli/keycloak-install-base.cli
index 2ea58e0..8889156 100644
--- a/distribution/server-overlay/src/main/cli/keycloak-install-base.cli
+++ b/distribution/server-overlay/src/main/cli/keycloak-install-base.cli
@@ -1,10 +1,9 @@
embed-server --server-config=standalone.xml
/subsystem=datasources/data-source=KeycloakDS/:add(connection-url="jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE",enabled=true,driver-name=h2,jndi-name=java:jboss/datasources/KeycloakDS,password=sa,user-name=sa,use-java-context=true)
-/subsystem=infinispan/cache-container=keycloak:add(jndi-name="infinispan/Keycloak")
/subsystem=infinispan/cache-container=keycloak/local-cache=realms:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
+/subsystem=infinispan/cache-container=keycloak/local-cache=realms/memory=object:add(size=10000)
/subsystem=infinispan/cache-container=keycloak/local-cache=users:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
+/subsystem=infinispan/cache-container=keycloak/local-cache=users/memory=object:add(size=10000)
/subsystem=infinispan/cache-container=keycloak/local-cache=sessions:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=authenticationSessions:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=offlineSessions:add()
@@ -13,11 +12,11 @@ embed-server --server-config=standalone.xml
/subsystem=infinispan/cache-container=keycloak/local-cache=loginFailures:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=work:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=authorization:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:add(max-entries=100,strategy=LRU)
+/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/memory=object:add(size=10000)
/subsystem=infinispan/cache-container=keycloak/local-cache=keys:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:add(max-entries=1000,strategy=LRU)
+/subsystem=infinispan/cache-container=keycloak/local-cache=keys/memory=object:add(size=1000)
/subsystem=infinispan/cache-container=keycloak/local-cache=keys/expiration=EXPIRATION:add(max-idle=3600000)
/subsystem=infinispan/cache-container=keycloak/local-cache=actionTokens:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=actionTokens/eviction=EVICTION:add(max-entries=-1,strategy=NONE)
+/subsystem=infinispan/cache-container=keycloak/local-cache=actionTokens/memory=object:add(size=-1)
/subsystem=infinispan/cache-container=keycloak/local-cache=actionTokens/expiration=EXPIRATION:add(max-idle=-1,interval=300000)
/extension=org.keycloak.keycloak-server-subsystem/:add(module=org.keycloak.keycloak-server-subsystem)
diff --git a/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli b/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli
index d4b02f8..2c54880 100644
--- a/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli
+++ b/distribution/server-overlay/src/main/cli/keycloak-install-ha-base.cli
@@ -1,24 +1,23 @@
embed-server --server-config=standalone-ha.xml
/subsystem=datasources/data-source=KeycloakDS/:add(connection-url="jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE",enabled=true,driver-name=h2,jndi-name=java:jboss/datasources/KeycloakDS,password=sa,user-name=sa,use-java-context=true)
-/subsystem=infinispan/cache-container=keycloak:add(jndi-name="infinispan/Keycloak")
/subsystem=infinispan/cache-container=keycloak/transport=TRANSPORT:add(lock-timeout=60000)
/subsystem=infinispan/cache-container=keycloak/local-cache=realms:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=realms/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
+/subsystem=infinispan/cache-container=keycloak/local-cache=realms/memory=object:add(size=10000)
/subsystem=infinispan/cache-container=keycloak/local-cache=users:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=users/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:add(mode="SYNC",owners="1")
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:add(mode="SYNC",owners="1")
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(mode="SYNC",owners="1")
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=clientSessions:add(mode="SYNC",owners="1")
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineClientSessions:add(mode="SYNC",owners="1")
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(mode="SYNC",owners="1")
+/subsystem=infinispan/cache-container=keycloak/local-cache=users/memory=object:add(size=10000)
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:add(owners="1")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:add(owners="1")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(owners="1")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=clientSessions:add(owners="1")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineClientSessions:add(owners="1")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(owners="1")
/subsystem=infinispan/cache-container=keycloak/local-cache=authorization:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/eviction=EVICTION:add(max-entries=10000,strategy=LRU)
-/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:add(mode="SYNC")
+/subsystem=infinispan/cache-container=keycloak/local-cache=authorization/memory=object:add(size=10000)
+/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:add()
/subsystem=infinispan/cache-container=keycloak/local-cache=keys:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=keys/eviction=EVICTION:add(max-entries=1000,strategy=LRU)
+/subsystem=infinispan/cache-container=keycloak/local-cache=keys/memory=object:add(size=1000)
/subsystem=infinispan/cache-container=keycloak/local-cache=keys/expiration=EXPIRATION:add(max-idle=3600000)
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens:add(indexing="NONE",mode="SYNC",owners="2")
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/eviction=EVICTION:add(max-entries=-1,strategy=NONE)
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens:add(indexing="NONE",owners="2")
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/memory=object:add(size=-1)
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/expiration=EXPIRATION:add(max-idle=-1,interval=300000)
/extension=org.keycloak.keycloak-server-subsystem/:add(module=org.keycloak.keycloak-server-subsystem)
distribution/server-provisioning.xml 3(+0 -3)
diff --git a/distribution/server-provisioning.xml b/distribution/server-provisioning.xml
index 6d4c442..78b5a83 100644
--- a/distribution/server-provisioning.xml
+++ b/distribution/server-provisioning.xml
@@ -15,9 +15,6 @@
~ limitations under the License.
-->
<server-provisioning xmlns="urn:wildfly:server-provisioning:1.2" extract-schemas="true" copy-module-artifacts="true">
- <copy-artifacts>
- <copy-artifact artifact="org.keycloak:keycloak-client-cli-dist:zip" to-location="" from-location="keycloak-client-tools"/>
- </copy-artifacts>
<feature-packs>
<feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>
</feature-packs>
diff --git a/distribution/server-provisioning-devel.xml b/distribution/server-provisioning-devel.xml
index 4fe832c..2d6af4f 100644
--- a/distribution/server-provisioning-devel.xml
+++ b/distribution/server-provisioning-devel.xml
@@ -15,9 +15,6 @@
~ limitations under the License.
-->
<server-provisioning xmlns="urn:wildfly:server-provisioning:1.2" extract-schemas="true">
- <copy-artifacts>
- <copy-artifact artifact="org.keycloak:keycloak-client-cli-dist:zip" to-location="" from-location="keycloak-client-tools"/>
- </copy-artifacts>
<feature-packs>
<feature-pack groupId="org.keycloak" artifactId="keycloak-server-feature-pack" version="${project.version}"/>
</feature-packs>
diff --git a/examples/broker/twitter-authentication/pom.xml b/examples/broker/twitter-authentication/pom.xml
index 6e21b7b..0dfc072 100755
--- a/examples/broker/twitter-authentication/pom.xml
+++ b/examples/broker/twitter-authentication/pom.xml
@@ -66,7 +66,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
diff --git a/examples/providers/domain-extension/pom.xml b/examples/providers/domain-extension/pom.xml
index 6e16077..07ef60b 100755
--- a/examples/providers/domain-extension/pom.xml
+++ b/examples/providers/domain-extension/pom.xml
@@ -58,7 +58,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
</dependencies>
examples/providers/rest/pom.xml 2(+1 -1)
diff --git a/examples/providers/rest/pom.xml b/examples/providers/rest/pom.xml
index c3cc1b6..388a54b 100755
--- a/examples/providers/rest/pom.xml
+++ b/examples/providers/rest/pom.xml
@@ -48,7 +48,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
</dependencies>
integration/admin-client/pom.xml 2(+1 -1)
diff --git a/integration/admin-client/pom.xml b/integration/admin-client/pom.xml
index bbfd360..1939750 100755
--- a/integration/admin-client/pom.xml
+++ b/integration/admin-client/pom.xml
@@ -47,7 +47,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/integration/client-cli/admin-cli/pom.xml b/integration/client-cli/admin-cli/pom.xml
index 70a6e54..66aa372 100755
--- a/integration/client-cli/admin-cli/pom.xml
+++ b/integration/client-cli/admin-cli/pom.xml
@@ -145,7 +145,7 @@
</includes>
</filter>
<filter>
- <artifact>org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.0_spec</artifact>
+ <artifact>org.jboss.spec.javax.ws.rs:jboss-jaxrs-api_2.1_spec</artifact>
<includes>
<include>**/**</include>
</includes>
diff --git a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java
index 4334c29..73fbb5a 100644
--- a/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/cluster/infinispan/InfinispanClusterProviderFactory.java
@@ -33,6 +33,7 @@ import org.keycloak.cluster.ClusterProviderFactory;
import org.keycloak.common.util.Retry;
import org.keycloak.common.util.Time;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
@@ -77,7 +78,7 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
@Override
public ClusterProvider create(KeycloakSession session) {
lazyInit(session);
- String myAddress = InfinispanUtil.getMyAddress(session);
+ String myAddress = InfinispanUtil.getTopologyInfo(session).getMyNodeName();
return new InfinispanClusterProvider(clusterStartupTime, myAddress, crossDCAwareCacheFactory, notificationsManager, localExecutor);
}
@@ -96,8 +97,9 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
clusterStartupTime = initClusterStartupTime(session);
- String myAddress = InfinispanUtil.getMyAddress(session);
- String mySite = InfinispanUtil.getMySite(session);
+ TopologyInfo topologyInfo = InfinispanUtil.getTopologyInfo(session);
+ String myAddress = topologyInfo.getMyNodeName();
+ String mySite = topologyInfo.getMySiteName();
notificationsManager = InfinispanNotificationsManager.create(session, workCache, myAddress, mySite, remoteStores);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java
index c1f8914..f796dfb 100644
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java
@@ -28,14 +28,12 @@ public class DefaultInfinispanConnectionProvider implements InfinispanConnection
private final EmbeddedCacheManager cacheManager;
private final RemoteCacheProvider remoteCacheProvider;
- private final String siteName;
- private final String nodeName;
+ private final TopologyInfo topologyInfo;
- public DefaultInfinispanConnectionProvider(EmbeddedCacheManager cacheManager, RemoteCacheProvider remoteCacheProvider, String nodeName, String siteName) {
+ public DefaultInfinispanConnectionProvider(EmbeddedCacheManager cacheManager, RemoteCacheProvider remoteCacheProvider, TopologyInfo topologyInfo) {
this.cacheManager = cacheManager;
this.remoteCacheProvider = remoteCacheProvider;
- this.nodeName = nodeName;
- this.siteName = siteName;
+ this.topologyInfo = topologyInfo;
}
@Override
@@ -49,13 +47,8 @@ public class DefaultInfinispanConnectionProvider implements InfinispanConnection
}
@Override
- public String getNodeName() {
- return nodeName;
- }
-
- @Override
- public String getSiteName() {
- return siteName;
+ public TopologyInfo getTopologyInfo() {
+ return topologyInfo;
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
index 0053791..e3dfc36 100755
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
@@ -20,6 +20,7 @@ package org.keycloak.connections.infinispan;
import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;
+import org.infinispan.client.hotrod.ProtocolVersion;
import org.infinispan.commons.util.FileLookup;
import org.infinispan.commons.util.FileLookupFactory;
import org.infinispan.configuration.cache.CacheMode;
@@ -34,7 +35,7 @@ import org.infinispan.remoting.transport.Transport;
import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
import org.infinispan.transaction.LockingMode;
import org.infinispan.transaction.TransactionMode;
-import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.EmbeddedTransactionManagerLookup;
import org.jboss.logging.Logger;
import org.jgroups.JChannel;
import org.keycloak.Config;
@@ -60,15 +61,13 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
protected boolean containerManaged;
- private String nodeName;
-
- private String siteName;
+ private TopologyInfo topologyInfo;
@Override
public InfinispanConnectionProvider create(KeycloakSession session) {
lazyInit();
- return new DefaultInfinispanConnectionProvider(cacheManager, remoteCacheProvider, nodeName, siteName);
+ return new DefaultInfinispanConnectionProvider(cacheManager, remoteCacheProvider, topologyInfo);
}
@Override
@@ -108,7 +107,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
initEmbedded();
}
- logger.infof("Node name: %s, Site name: %s", nodeName, siteName);
+ logger.infof(topologyInfo.toString());
remoteCacheProvider = new RemoteCacheProvider(config, cacheManager);
}
@@ -121,7 +120,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
containerManaged = true;
- long realmRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+ long realmRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME).getCacheConfiguration().memory().size();
realmRevisionsMaxEntries = realmRevisionsMaxEntries > 0
? 2 * realmRevisionsMaxEntries
: InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX;
@@ -129,7 +128,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(realmRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, true);
- long userRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+ long userRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().memory().size();
userRevisionsMaxEntries = userRevisionsMaxEntries > 0
? 2 * userRevisionsMaxEntries
: InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
@@ -141,7 +140,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, true);
- long authzRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+ long authzRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME).getCacheConfiguration().memory().size();
authzRevisionsMaxEntries = authzRevisionsMaxEntries > 0
? 2 * authzRevisionsMaxEntries
: InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX;
@@ -149,20 +148,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, getRevisionCacheConfig(authzRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, true);
- Transport transport = cacheManager.getTransport();
- if (transport != null) {
- this.nodeName = transport.getAddress().toString();
- this.siteName = cacheManager.getCacheManagerConfiguration().transport().siteId();
- if (this.siteName == null) {
- this.siteName = System.getProperty(InfinispanConnectionProvider.JBOSS_SITE_NAME);
- }
- } else {
- this.nodeName = System.getProperty(InfinispanConnectionProvider.JBOSS_NODE_NAME);
- this.siteName = System.getProperty(InfinispanConnectionProvider.JBOSS_SITE_NAME);
- }
- if (this.nodeName == null || this.nodeName.equals("localhost")) {
- this.nodeName = generateNodeName();
- }
+ this.topologyInfo = new TopologyInfo(cacheManager, config, false);
logger.debugv("Using container managed Infinispan cache container, lookup={0}", cacheContainerLookup);
} catch (Exception e) {
@@ -180,25 +166,13 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
boolean async = config.getBoolean("async", false);
boolean allowDuplicateJMXDomains = config.getBoolean("allowDuplicateJMXDomains", true);
- this.nodeName = config.get("nodeName", System.getProperty(InfinispanConnectionProvider.JBOSS_NODE_NAME));
- if (this.nodeName != null && this.nodeName.isEmpty()) {
- this.nodeName = null;
- }
-
- this.siteName = config.get("siteName", System.getProperty(InfinispanConnectionProvider.JBOSS_SITE_NAME));
- if (this.siteName != null && this.siteName.isEmpty()) {
- this.siteName = null;
- }
+ this.topologyInfo = new TopologyInfo(cacheManager, config, true);
if (clustered) {
String jgroupsUdpMcastAddr = config.get("jgroupsUdpMcastAddr", System.getProperty(InfinispanConnectionProvider.JGROUPS_UDP_MCAST_ADDR));
- configureTransport(gcb, nodeName, siteName, jgroupsUdpMcastAddr);
+ configureTransport(gcb, topologyInfo.getMyNodeName(), topologyInfo.getMySiteName(), jgroupsUdpMcastAddr);
gcb.globalJmxStatistics()
- .jmxDomain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + nodeName);
- } else {
- if (nodeName == null) {
- nodeName = generateNodeName();
- }
+ .jmxDomain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + topologyInfo.getMyNodeName());
}
gcb.globalJmxStatistics()
@@ -208,10 +182,6 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager = new DefaultCacheManager(gcb.build());
containerManaged = false;
- if (cacheManager.getTransport() != null) {
- nodeName = cacheManager.getTransport().getAddress().toString();
- }
-
logger.debug("Started embedded Infinispan cache container");
ConfigurationBuilder modelCacheConfigBuilder = new ConfigurationBuilder();
@@ -311,7 +281,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
Configuration replicationEvictionCacheConfiguration = replicationConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.WORK_CACHE_NAME, replicationEvictionCacheConfiguration);
- long realmRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+ long realmRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME).getCacheConfiguration().memory().size();
realmRevisionsMaxEntries = realmRevisionsMaxEntries > 0
? 2 * realmRevisionsMaxEntries
: InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX;
@@ -319,7 +289,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(realmRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, true);
- long userRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+ long userRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().memory().size();
userRevisionsMaxEntries = userRevisionsMaxEntries > 0
? 2 * userRevisionsMaxEntries
: InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
@@ -340,7 +310,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.defineConfiguration(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, actionTokenCacheConfigBuilder.build());
cacheManager.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, true);
- long authzRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+ long authzRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME).getCacheConfiguration().memory().size();
authzRevisionsMaxEntries = authzRevisionsMaxEntries > 0
? 2 * authzRevisionsMaxEntries
: InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX;
@@ -349,20 +319,21 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, true);
}
- protected String generateNodeName() {
- return InfinispanConnectionProvider.NODE_PREFIX + new SecureRandom().nextInt(1000000);
- }
private Configuration getRevisionCacheConfig(long maxEntries) {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.invocationBatching().enable().transaction().transactionMode(TransactionMode.TRANSACTIONAL);
- // Use Dummy manager even in managed ( wildfly/eap ) environment. We don't want infinispan to participate in global transaction
- cb.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
+ // Use Embedded manager even in managed ( wildfly/eap ) environment. We don't want infinispan to participate in global transaction
+ cb.transaction().transactionManagerLookup(new EmbeddedTransactionManagerLookup());
cb.transaction().lockingMode(LockingMode.PESSIMISTIC);
- cb.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(maxEntries);
+ cb.memory()
+ .evictionStrategy(EvictionStrategy.REMOVE)
+ .evictionType(EvictionType.COUNT)
+ .size(maxEntries);
+
return cb.build();
}
@@ -383,6 +354,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
.rawValues(true)
.forceReturnValues(false)
.marshaller(KeycloakHotRodMarshallerFactory.class.getName())
+ //.protocolVersion(ProtocolVersion.PROTOCOL_VERSION_26)
.addServer()
.host(jdgServer)
.port(jdgPort)
@@ -410,6 +382,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
.rawValues(true)
.forceReturnValues(false)
.marshaller(KeycloakHotRodMarshallerFactory.class.getName())
+ //.protocolVersion(ProtocolVersion.PROTOCOL_VERSION_26)
.addServer()
.host(jdgServer)
.port(jdgPort)
@@ -420,7 +393,12 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
protected Configuration getKeysCacheConfig() {
ConfigurationBuilder cb = new ConfigurationBuilder();
- cb.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
+
+ cb.memory()
+ .evictionStrategy(EvictionStrategy.REMOVE)
+ .evictionType(EvictionType.COUNT)
+ .size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
+
cb.expiration().maxIdle(InfinispanConnectionProvider.KEYS_CACHE_MAX_IDLE_SECONDS, TimeUnit.SECONDS);
return cb.build();
}
@@ -428,9 +406,9 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
private ConfigurationBuilder getActionTokenCacheConfig() {
ConfigurationBuilder cb = new ConfigurationBuilder();
- cb.eviction()
- .strategy(EvictionStrategy.NONE)
- .type(EvictionType.COUNT)
+ cb.memory()
+ .evictionStrategy(EvictionStrategy.NONE)
+ .evictionType(EvictionType.COUNT)
.size(InfinispanConnectionProvider.ACTION_TOKEN_CACHE_DEFAULT_MAX);
cb.expiration()
.maxIdle(InfinispanConnectionProvider.ACTION_TOKEN_MAX_IDLE_SECONDS, TimeUnit.SECONDS)
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
index cb23b6f..03e51d0 100755
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
@@ -75,14 +75,8 @@ public interface InfinispanConnectionProvider extends Provider {
<K, V> RemoteCache<K, V> getRemoteCache(String name);
/**
- * @return Address of current node in cluster. In non-cluster environment, it returns some other non-null value (eg. hostname with some random value like "host-123456" )
+ * @return Information about cluster topology
*/
- String getNodeName();
-
- /**
- *
- * @return siteName or null if we're not in environment with multiple sites (data centers)
- */
- String getSiteName();
+ TopologyInfo getTopologyInfo();
}
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/TopologyInfo.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/TopologyInfo.java
new file mode 100644
index 0000000..25a6ad1
--- /dev/null
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/TopologyInfo.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.connections.infinispan;
+
+import java.net.InetSocketAddress;
+import java.security.SecureRandom;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.infinispan.Cache;
+import org.infinispan.distribution.DistributionManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.LocalModeAddress;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
+import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
+import org.jboss.logging.Logger;
+import org.jgroups.Event;
+import org.jgroups.JChannel;
+import org.jgroups.stack.IpAddress;
+import org.jgroups.util.NameCache;
+import org.keycloak.Config;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class TopologyInfo {
+
+ private static final Logger logger = Logger.getLogger(TopologyInfo.class);
+
+
+ // Node name used in clustered environment. This typically points to "jboss.node.name" . If "jboss.node.name" is not set, it is randomly generated
+ // name
+ private final String myNodeName;
+
+ // Used just if "site" is configured (typically in cross-dc environment). Otherwise null
+ private final String mySiteName;
+
+ private final boolean isGeneratedNodeName;
+
+
+ public TopologyInfo(EmbeddedCacheManager cacheManager, Config.Scope config, boolean embedded) {
+ String siteName;
+ String nodeName;
+ boolean isGeneratedNodeName = false;
+
+ if (!embedded) {
+ Transport transport = cacheManager.getTransport();
+ if (transport != null) {
+ nodeName = transport.getAddress().toString();
+ siteName = cacheManager.getCacheManagerConfiguration().transport().siteId();
+ if (siteName == null) {
+ siteName = System.getProperty(InfinispanConnectionProvider.JBOSS_SITE_NAME);
+ }
+ } else {
+ nodeName = System.getProperty(InfinispanConnectionProvider.JBOSS_NODE_NAME);
+ siteName = System.getProperty(InfinispanConnectionProvider.JBOSS_SITE_NAME);
+ }
+ if (nodeName == null || nodeName.equals("localhost")) {
+ isGeneratedNodeName = true;
+ nodeName = generateNodeName();
+ }
+ } else {
+ boolean clustered = config.getBoolean("clustered", false);
+
+ nodeName = config.get("nodeName", System.getProperty(InfinispanConnectionProvider.JBOSS_NODE_NAME));
+ if (nodeName != null && nodeName.isEmpty()) {
+ nodeName = null;
+ }
+
+ siteName = config.get("siteName", System.getProperty(InfinispanConnectionProvider.JBOSS_SITE_NAME));
+ if (siteName != null && siteName.isEmpty()) {
+ siteName = null;
+ }
+
+ if (nodeName == null) {
+ if (!clustered) {
+ isGeneratedNodeName = true;
+ nodeName = generateNodeName();
+ } else {
+ throw new IllegalStateException("You must set jboss.node.name if you use clustered mode for InfinispanConnectionProvider");
+ }
+ }
+ }
+
+ this.myNodeName = nodeName;
+ this.mySiteName = siteName;
+ this.isGeneratedNodeName = isGeneratedNodeName;
+ }
+
+
+ private String generateNodeName() {
+ return InfinispanConnectionProvider.NODE_PREFIX + new SecureRandom().nextInt(1000000);
+ }
+
+
+ public String getMyNodeName() {
+ return myNodeName;
+ }
+
+ public String getMySiteName() {
+ return mySiteName;
+ }
+
+
+ @Override
+ public String toString() {
+ return String.format("Node name: %s, Site name: %s", myNodeName, mySiteName);
+ }
+
+
+ /**
+ * True if I am primary owner of the key in case of distributed caches. In case of local caches, always return true
+ */
+ public boolean amIOwner(Cache cache, Object key) {
+ Address myAddress = cache.getCacheManager().getAddress();
+ Address objectOwnerAddress = getOwnerAddress(cache, key);
+
+ // NOTE: For scattered caches, this will always return true, which may not be correct. Need to review this if we add support for scattered caches
+ return Objects.equals(myAddress, objectOwnerAddress);
+ }
+
+
+ /**
+ * Get route to be used as the identifier for sticky session. Return null if I am not able to find the appropriate route (or in case of local mode)
+ */
+ public String getRouteName(Cache cache, Object key) {
+ if (cache.getCacheConfiguration().clustering().cacheMode().isClustered() && isGeneratedNodeName) {
+ logger.warn("Clustered configuration used, but node name is not properly set. Make sure to start server with jboss.node.name property identifying cluster node");
+ }
+
+ if (isGeneratedNodeName) {
+ return null;
+ }
+
+ // Impl based on Wildfly sticky session algorithm for generating routes ( org.wildfly.clustering.web.infinispan.session.InfinispanRouteLocator )
+ Address address = getOwnerAddress(cache, key);
+
+ // Local mode
+ if (address == null || (address == LocalModeAddress.INSTANCE)) {
+ return myNodeName;
+ }
+
+ org.jgroups.Address jgroupsAddress = toJGroupsAddress(address);
+ String name = NameCache.get(jgroupsAddress);
+
+ // If no logical name exists, create one using physical address
+ if (name == null) {
+
+ Transport transport = cache.getCacheManager().getTransport();
+ JChannel jgroupsChannel = ((JGroupsTransport) transport).getChannel();
+
+ IpAddress ipAddress = (IpAddress) jgroupsChannel.down(new Event(Event.GET_PHYSICAL_ADDRESS, jgroupsAddress));
+ // Physical address might be null if node is no longer a member of the cluster
+ InetSocketAddress socketAddress = (ipAddress != null) ? new InetSocketAddress(ipAddress.getIpAddress(), ipAddress.getPort()) : new InetSocketAddress(0);
+ name = String.format("%s:%s", socketAddress.getHostString(), socketAddress.getPort());
+
+ logger.debugf("Address not found in NameCache. Fallback to %s", name);
+ }
+
+ return name;
+ }
+
+
+ private Address getOwnerAddress(Cache cache, Object key) {
+ DistributionManager dist = cache.getAdvancedCache().getDistributionManager();
+ Address address = (dist != null) && !cache.getCacheConfiguration().clustering().cacheMode().isScattered() ?
+ dist.getCacheTopology().getDistribution(key).primary() :
+ cache.getCacheManager().getAddress();
+
+ return address;
+ }
+
+
+ // See org.wildfly.clustering.server.group.CacheGroup
+ private static org.jgroups.Address toJGroupsAddress(Address address) {
+ if ((address == null) || (address == LocalModeAddress.INSTANCE)) return null;
+ if (address instanceof JGroupsAddress) {
+ JGroupsAddress jgroupsAddress = (JGroupsAddress) address;
+ return jgroupsAddress.getJGroupsAddress();
+ }
+ throw new IllegalArgumentException(address.toString());
+ }
+
+
+}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java
index 3400782..fd6ebc0 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java
@@ -185,15 +185,17 @@ public class SessionEntityWrapper<S extends SessionEntity> {
if (forTransport) {
final SessionEntity entity = (SessionEntity) input.readObject();
final SessionEntityWrapper res = new SessionEntityWrapper(entity);
- if (log.isDebugEnabled()) {
- log.debugf("Loaded entity from remote store: %s, version=%s, metadata=%s", entity, res.version, res.localMetadata);
+ if (log.isTraceEnabled()) {
+ log.tracef("Loaded entity from remote store: %s, version=%s, metadata=%s", entity, res.version, res.localMetadata);
}
return res;
} else {
UUID sessionVersion = new UUID(input.readLong(), input.readLong());
HashMap<String, String> map = MarshallUtil.unmarshallMap(input, HashMap::new);
final SessionEntity entity = (SessionEntity) input.readObject();
- log.debugf("Found entity locally: entity=%s, version=%s, metadata=%s", entity, sessionVersion, map);
+ if (log.isTraceEnabled()) {
+ log.tracef("Found entity locally: entity=%s, version=%s, metadata=%s", entity, sessionVersion, map);
+ }
return new SessionEntityWrapper(sessionVersion, map, entity);
}
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java
index 00b499e..a184438 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java
@@ -23,6 +23,7 @@ import org.infinispan.Cache;
import org.jboss.logging.Logger;
import org.keycloak.cluster.ClusterEvent;
import org.keycloak.cluster.ClusterListener;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
@@ -45,20 +46,14 @@ public class LastSessionRefreshListener implements ClusterListener {
private final KeycloakSessionFactory sessionFactory;
private final Cache<String, SessionEntityWrapper<UserSessionEntity>> cache;
- private final boolean distributed;
- private final String myAddress;
+ private final TopologyInfo topologyInfo;
public LastSessionRefreshListener(KeycloakSession session, Cache<String, SessionEntityWrapper<UserSessionEntity>> cache, boolean offline) {
this.sessionFactory = session.getKeycloakSessionFactory();
this.cache = cache;
this.offline = offline;
- this.distributed = InfinispanUtil.isDistributedCache(cache);
- if (this.distributed) {
- this.myAddress = InfinispanUtil.getMyAddress(session);
- } else {
- this.myAddress = null;
- }
+ this.topologyInfo = InfinispanUtil.getTopologyInfo(session);
}
@Override
@@ -81,7 +76,7 @@ public class LastSessionRefreshListener implements ClusterListener {
RealmModel realm = kcSession.realms().getRealm(realmId);
UserSessionModel userSession = offline ? kcSession.sessions().getOfflineUserSession(realm, sessionId) : kcSession.sessions().getUserSession(realm, sessionId);
if (userSession == null) {
- logger.debugf("User session '%s' not available on node '%s' offline '%b'", sessionId, myAddress, offline);
+ logger.debugf("User session '%s' not available on node '%s' offline '%b'", sessionId, topologyInfo.getMyNodeName(), offline);
} else {
// Update just if lastSessionRefresh from event is bigger than ours
if (lastSessionRefresh > userSession.getLastSessionRefresh()) {
@@ -101,11 +96,6 @@ public class LastSessionRefreshListener implements ClusterListener {
// For distributed caches, ensure that local modification is executed just on owner
protected boolean shouldUpdateLocalCache(String key) {
- if (!distributed) {
- return true;
- } else {
- String keyAddress = InfinispanUtil.getKeyPrimaryOwnerAddress(cache, key);
- return myAddress.equals(keyAddress);
- }
+ return topologyInfo.amIOwner(cache, key);
}
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/SessionData.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/SessionData.java
index 5f78eda..c2e6c86 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/SessionData.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/SessionData.java
@@ -24,6 +24,7 @@ import java.io.ObjectOutput;
import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
+import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -58,14 +59,14 @@ public class SessionData {
@Override
public void writeObject(ObjectOutput output, SessionData obj) throws IOException {
MarshallUtil.marshallString(obj.realmId, output);
- MarshallUtil.marshallInt(output, obj.lastSessionRefresh);
+ KeycloakMarshallUtil.marshall(obj.lastSessionRefresh, output);
}
@Override
public SessionData readObject(ObjectInput input) throws IOException, ClassNotFoundException {
String realmId = MarshallUtil.unmarshallString(input);
- int lastSessionRefresh = MarshallUtil.unmarshallInt(input);
+ int lastSessionRefresh = KeycloakMarshallUtil.unmarshallInteger(input);
return new SessionData(realmId, lastSessionRefresh);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java
index 635f0e6..0e2e615 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticatedClientSessionEntity.java
@@ -174,14 +174,14 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
MarshallUtil.marshallString(session.getRealmId(), output);
MarshallUtil.marshallString(session.getAuthMethod(), output);
MarshallUtil.marshallString(session.getRedirectUri(), output);
- MarshallUtil.marshallInt(output, session.getTimestamp());
+ KeycloakMarshallUtil.marshall(session.getTimestamp(), output);
MarshallUtil.marshallString(session.getAction(), output);
Map<String, String> notes = session.getNotes();
KeycloakMarshallUtil.writeMap(notes, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT, output);
MarshallUtil.marshallString(session.getCurrentRefreshToken(), output);
- MarshallUtil.marshallInt(output, session.getCurrentRefreshTokenUseCount());
+ KeycloakMarshallUtil.marshall(session.getCurrentRefreshTokenUseCount(), output);
}
@@ -193,7 +193,7 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
sessionEntity.setAuthMethod(MarshallUtil.unmarshallString(input));
sessionEntity.setRedirectUri(MarshallUtil.unmarshallString(input));
- sessionEntity.setTimestamp(MarshallUtil.unmarshallInt(input));
+ sessionEntity.setTimestamp(KeycloakMarshallUtil.unmarshallInteger(input));
sessionEntity.setAction(MarshallUtil.unmarshallString(input));
Map<String, String> notes = KeycloakMarshallUtil.readMap(input, KeycloakMarshallUtil.STRING_EXT, KeycloakMarshallUtil.STRING_EXT,
@@ -201,7 +201,7 @@ public class AuthenticatedClientSessionEntity extends SessionEntity {
sessionEntity.setNotes(notes);
sessionEntity.setCurrentRefreshToken(MarshallUtil.unmarshallString(input));
- sessionEntity.setCurrentRefreshTokenUseCount(MarshallUtil.unmarshallInt(input));
+ sessionEntity.setCurrentRefreshTokenUseCount(KeycloakMarshallUtil.unmarshallInteger(input));
return sessionEntity;
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java
index cf51796..dfaa3aa 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/AuthenticationSessionEntity.java
@@ -23,7 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import org.infinispan.util.concurrent.ConcurrentHashSet;
+import org.infinispan.commons.util.concurrent.ConcurrentHashSet;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.sessions.CommonClientSessionModel.ExecutionStatus;
import java.io.IOException;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/UserSessionEntity.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/UserSessionEntity.java
index fafd156..40b1e10 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/UserSessionEntity.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/entities/UserSessionEntity.java
@@ -254,8 +254,8 @@ public class UserSessionEntity extends SessionEntity {
MarshallUtil.marshallString(session.getRealmId(), output);
MarshallUtil.marshallString(session.getUser(), output);
- MarshallUtil.marshallInt(output, session.getLastSessionRefresh());
- MarshallUtil.marshallInt(output, session.getStarted());
+ KeycloakMarshallUtil.marshall(session.getLastSessionRefresh(), output);
+ KeycloakMarshallUtil.marshall(session.getStarted(), output);
output.writeBoolean(session.isRememberMe());
int state = session.getState() == null ? 0 : STATE_TO_ID.get(session.getState());
@@ -291,8 +291,8 @@ public class UserSessionEntity extends SessionEntity {
sessionEntity.setRealmId(MarshallUtil.unmarshallString(input));
sessionEntity.setUser(MarshallUtil.unmarshallString(input));
- sessionEntity.setLastSessionRefresh(MarshallUtil.unmarshallInt(input));
- sessionEntity.setStarted(MarshallUtil.unmarshallInt(input));
+ sessionEntity.setLastSessionRefresh(KeycloakMarshallUtil.unmarshallInteger(input));
+ sessionEntity.setStarted(KeycloakMarshallUtil.unmarshallInteger(input));
sessionEntity.setRememberMe(input.readBoolean());
sessionEntity.setState(ID_TO_STATE.get(input.readInt()));
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/AbstractUserSessionClusterListener.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/AbstractUserSessionClusterListener.java
index 71d8268..1c83f0c 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/AbstractUserSessionClusterListener.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/AbstractUserSessionClusterListener.java
@@ -21,6 +21,7 @@ import org.jboss.logging.Logger;
import org.keycloak.cluster.ClusterEvent;
import org.keycloak.cluster.ClusterListener;
import org.keycloak.cluster.ClusterProvider;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.UserSessionProvider;
@@ -73,8 +74,9 @@ public abstract class AbstractUserSessionClusterListener<SE extends SessionClust
}
// Just the initiator will re-send the event after receiving it
- String myNode = InfinispanUtil.getMyAddress(session);
- String mySite = InfinispanUtil.getMySite(session);
+ TopologyInfo topology = InfinispanUtil.getTopologyInfo(session);
+ String myNode = topology.getMyNodeName();
+ String mySite = topology.getMySiteName();
return (event.getNodeId() != null && event.getNodeId().equals(myNode) && event.getSiteId() != null && event.getSiteId().equals(mySite));
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/SessionClusterEvent.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/SessionClusterEvent.java
index 3b8c4da..64048ac 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/SessionClusterEvent.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/events/SessionClusterEvent.java
@@ -18,6 +18,7 @@
package org.keycloak.models.sessions.infinispan.events;
import org.keycloak.cluster.ClusterEvent;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
import java.io.IOException;
@@ -52,8 +53,9 @@ public abstract class SessionClusterEvent implements ClusterEvent {
this.realmId = realmId;
this.eventKey = eventKey;
this.resendingEvent = resendingEvent;
- this.siteId = InfinispanUtil.getMySite(session);
- this.nodeId = InfinispanUtil.getMyAddress(session);
+ TopologyInfo topology = InfinispanUtil.getTopologyInfo(session);
+ this.siteId = topology.getMySiteName();
+ this.nodeId = topology.getMyNodeName();
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProvider.java
index 871525d..f908628 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProvider.java
@@ -22,6 +22,7 @@ import org.infinispan.distribution.DistributionManager;
import org.infinispan.remoting.transport.Address;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
import org.keycloak.sessions.StickySessionEncoderProvider;
/**
@@ -30,12 +31,10 @@ import org.keycloak.sessions.StickySessionEncoderProvider;
public class InfinispanStickySessionEncoderProvider implements StickySessionEncoderProvider {
private final KeycloakSession session;
- private final String myNodeName;
private final boolean shouldAttachRoute;
- public InfinispanStickySessionEncoderProvider(KeycloakSession session, String myNodeName, boolean shouldAttachRoute) {
+ public InfinispanStickySessionEncoderProvider(KeycloakSession session, boolean shouldAttachRoute) {
this.session = session;
- this.myNodeName = myNodeName;
this.shouldAttachRoute = shouldAttachRoute;
}
@@ -45,9 +44,9 @@ public class InfinispanStickySessionEncoderProvider implements StickySessionEnco
return sessionId;
}
- String nodeName = getNodeName(sessionId);
- if (nodeName != null) {
- return sessionId + '.' + nodeName;
+ String route = getRoute(sessionId);
+ if (route != null) {
+ return sessionId + '.' + route;
} else {
return sessionId;
}
@@ -71,19 +70,10 @@ public class InfinispanStickySessionEncoderProvider implements StickySessionEnco
}
- private String getNodeName(String sessionId) {
+ private String getRoute(String sessionId) {
InfinispanConnectionProvider ispnProvider = session.getProvider(InfinispanConnectionProvider.class);
Cache cache = ispnProvider.getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME);
- DistributionManager distManager = cache.getAdvancedCache().getDistributionManager();
-
- if (distManager != null) {
- // Sticky session to the node, who owns this authenticationSession
- Address address = distManager.getPrimaryLocation(sessionId);
- return address.toString();
- } else {
- // Fallback to jbossNodeName if authSession cache is local
- return myNodeName;
- }
+ return InfinispanUtil.getTopologyInfo(session).getRouteName(cache, sessionId);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProviderFactory.java
index 001e295..5e87395 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanStickySessionEncoderProviderFactory.java
@@ -38,15 +38,7 @@ public class InfinispanStickySessionEncoderProviderFactory implements StickySess
@Override
public StickySessionEncoderProvider create(KeycloakSession session) {
- String myNodeName = InfinispanUtil.getMyAddress(session);
-
- if (myNodeName != null && myNodeName.startsWith(InfinispanConnectionProvider.NODE_PREFIX)) {
-
- // Node name was randomly generated. We won't use anything for sticky sessions in this case
- myNodeName = null;
- }
-
- return new InfinispanStickySessionEncoderProvider(session, myNodeName, shouldAttachRoute);
+ return new InfinispanStickySessionEncoderProvider(session, shouldAttachRoute);
}
@Override
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
index 22ef5b7..1e1670d 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
@@ -21,7 +21,6 @@ import org.infinispan.Cache;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.context.Flag;
import org.infinispan.stream.CacheCollectors;
-import org.infinispan.stream.SerializableSupplier;
import org.jboss.logging.Logger;
import org.keycloak.cluster.ClusterProvider;
import org.keycloak.common.util.Time;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java
index 9e47c41..15d8c25 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java
@@ -141,7 +141,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
// Count of sessions to be computed in each segment
private int getSessionsPerSegment() {
- return config.getInt("sessionsPerSegment", 100);
+ return config.getInt("sessionsPerSegment", 64);
}
private int getTimeoutForPreloadingSessionsSeconds() {
@@ -161,7 +161,8 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
InfinispanConnectionProvider connections = session.getProvider(InfinispanConnectionProvider.class);
Cache<String, Serializable> workCache = connections.getCache(InfinispanConnectionProvider.WORK_CACHE_NAME);
- InfinispanCacheInitializer ispnInitializer = new InfinispanCacheInitializer(sessionFactory, workCache, new OfflinePersistentUserSessionLoader(), "offlineUserSessions", sessionsPerSegment, maxErrors);
+ InfinispanCacheInitializer ispnInitializer = new InfinispanCacheInitializer(sessionFactory, workCache,
+ new OfflinePersistentUserSessionLoader(sessionsPerSegment), "offlineUserSessions", sessionsPerSegment, maxErrors);
// DB-lock to ensure that persistent sessions are loaded from DB just on one DC. The other DCs will load them from remote cache.
CacheInitializer initializer = new DBLockBasedCacheInitializer(session, ispnInitializer);
@@ -302,7 +303,8 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
InfinispanConnectionProvider connections = session.getProvider(InfinispanConnectionProvider.class);
Cache<String, Serializable> workCache = connections.getCache(InfinispanConnectionProvider.WORK_CACHE_NAME);
- InfinispanCacheInitializer initializer = new InfinispanCacheInitializer(sessionFactory, workCache, new RemoteCacheSessionsLoader(cacheName), "remoteCacheLoad::" + cacheName, sessionsPerSegment, maxErrors);
+ InfinispanCacheInitializer initializer = new InfinispanCacheInitializer(sessionFactory, workCache,
+ new RemoteCacheSessionsLoader(cacheName, sessionsPerSegment), "remoteCacheLoad::" + cacheName, sessionsPerSegment, maxErrors);
initializer.initCache();
initializer.loadSessions();
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/BaseCacheInitializer.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/BaseCacheInitializer.java
index 40065d5..5241eb5 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/BaseCacheInitializer.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/BaseCacheInitializer.java
@@ -73,38 +73,7 @@ public abstract class BaseCacheInitializer extends CacheInitializer {
}
- protected InitializerState getOrCreateInitializerState() {
- InitializerState state = getStateFromCache();
- if (state == null) {
- final int[] count = new int[1];
-
- // Rather use separate transactions for update and counting
-
- KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
- @Override
- public void run(KeycloakSession session) {
- sessionLoader.init(session);
- }
-
- });
-
- KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
- @Override
- public void run(KeycloakSession session) {
- count[0] = sessionLoader.getSessionsCount(session);
- }
-
- });
-
- state = new InitializerState(count[0], sessionsPerSegment);
- saveStateToCache(state);
- }
- return state;
-
- }
-
-
- private InitializerState getStateFromCache() {
+ protected InitializerState getStateFromCache() {
// We ignore cacheStore for now, so that in Cross-DC scenario (with RemoteStore enabled) is the remoteStore ignored.
return (InitializerState) workCache.getAdvancedCache()
.withFlags(Flag.SKIP_CACHE_STORE, Flag.SKIP_CACHE_LOAD)
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InfinispanCacheInitializer.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InfinispanCacheInitializer.java
index 17dc54c..8dbcc20 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InfinispanCacheInitializer.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InfinispanCacheInitializer.java
@@ -21,7 +21,10 @@ import org.infinispan.Cache;
import org.infinispan.distexec.DefaultExecutorService;
import org.infinispan.remoting.transport.Transport;
import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.models.KeycloakSessionTask;
+import org.keycloak.models.utils.KeycloakModelUtils;
import java.io.Serializable;
import java.util.LinkedList;
@@ -60,8 +63,46 @@ public class InfinispanCacheInitializer extends BaseCacheInitializer {
// Just coordinator will run this
@Override
protected void startLoading() {
- InitializerState state = getOrCreateInitializerState();
+ InitializerState state = getStateFromCache();
+ SessionLoader.LoaderContext[] ctx = new SessionLoader.LoaderContext[1];
+ if (state == null) {
+ // Rather use separate transactions for update and counting
+ KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+ @Override
+ public void run(KeycloakSession session) {
+ sessionLoader.init(session);
+ }
+
+ });
+
+ KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+ @Override
+ public void run(KeycloakSession session) {
+ ctx[0] = sessionLoader.computeLoaderContext(session);
+ }
+
+ });
+
+ state = new InitializerState(ctx[0].getSegmentsCount());
+ saveStateToCache(state);
+ } else {
+ KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
+ @Override
+ public void run(KeycloakSession session) {
+ ctx[0] = sessionLoader.computeLoaderContext(session);
+ }
+
+ });
+ }
+
+ log.debugf("Start loading with loader: '%s', ctx: '%s' , state: %s",
+ sessionLoader.toString(), ctx[0].toString(), state.toString());
+
+ startLoadingImpl(state, ctx[0]);
+ }
+
+ protected void startLoadingImpl(InitializerState state, SessionLoader.LoaderContext ctx) {
// Assume each worker has same processor's count
int processors = Runtime.getRuntime().availableProcessors();
@@ -88,7 +129,7 @@ public class InfinispanCacheInitializer extends BaseCacheInitializer {
List<Future<WorkerResult>> futures = new LinkedList<>();
for (Integer segment : segments) {
SessionInitializerWorker worker = new SessionInitializerWorker();
- worker.setWorkerEnvironment(segment, sessionsPerSegment, sessionLoader);
+ worker.setWorkerEnvironment(segment, ctx, sessionLoader);
if (!distributed) {
worker.setEnvironment(workCache, null);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InitializerState.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InitializerState.java
index 930b24e..0fc9cfe 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InitializerState.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/InitializerState.java
@@ -42,33 +42,25 @@ public class InitializerState extends SessionEntity {
private static final Logger log = Logger.getLogger(InitializerState.class);
- private final int sessionsCount;
private final int segmentsCount;
private final BitSet segments;
private int lowestUnfinishedSegment = 0;
- public InitializerState(int sessionsCount, int sessionsPerSegment) {
- this.sessionsCount = sessionsCount;
-
- int segmentsCountLocal = sessionsCount / sessionsPerSegment;
- if (sessionsPerSegment * segmentsCountLocal < sessionsCount) {
- segmentsCountLocal = segmentsCountLocal + 1;
- }
- this.segmentsCount = segmentsCountLocal;
- this.segments = new BitSet(segmentsCountLocal);
+ public InitializerState(int segmentsCount) {
+ this.segmentsCount = segmentsCount;
+ this.segments = new BitSet(segmentsCount);
- log.debugf("sessionsCount: %d, sessionsPerSegment: %d, segmentsCount: %d", sessionsCount, sessionsPerSegment, segmentsCountLocal);
+ log.debugf("segmentsCount: %d", segmentsCount);
updateLowestUnfinishedSegment();
}
- private InitializerState(String realmId, int sessionsCount, int segmentsCount, BitSet segments) {
+ private InitializerState(String realmId, int segmentsCount, BitSet segments) {
super(realmId);
- this.sessionsCount = sessionsCount;
this.segmentsCount = segmentsCount;
this.segments = segments;
- log.debugf("sessionsCount: %d, segmentsCount: %d", sessionsCount, segmentsCount);
+ log.debugf("segmentsCount: %d", segmentsCount);
updateLowestUnfinishedSegment();
}
@@ -116,18 +108,15 @@ public class InitializerState extends SessionEntity {
@Override
public String toString() {
int finished = segments.cardinality();
- int nonFinished = this.segmentsCount;
+ int nonFinished = segmentsCount - finished;
- return "sessionsCount: "
- + sessionsCount
- + (", finished segments count: " + finished)
+ return "finished segments count: " + finished
+ (", non-finished segments count: " + nonFinished);
}
@Override
public int hashCode() {
int hash = 3;
- hash = 97 * hash + this.sessionsCount;
hash = 97 * hash + this.segmentsCount;
hash = 97 * hash + Objects.hashCode(this.segments);
hash = 97 * hash + this.lowestUnfinishedSegment;
@@ -146,9 +135,6 @@ public class InitializerState extends SessionEntity {
return false;
}
final InitializerState other = (InitializerState) obj;
- if (this.sessionsCount != other.sessionsCount) {
- return false;
- }
if (this.segmentsCount != other.segmentsCount) {
return false;
}
@@ -170,7 +156,6 @@ public class InitializerState extends SessionEntity {
output.writeByte(VERSION_1);
MarshallUtil.marshallString(value.getRealmId(), output);
- output.writeInt(value.sessionsCount);
output.writeInt(value.segmentsCount);
MarshallUtil.marshallByteArray(value.segments.toByteArray(), output);
}
@@ -189,7 +174,6 @@ public class InitializerState extends SessionEntity {
return new InitializerState(
MarshallUtil.unmarshallString(input),
input.readInt(),
- input.readInt(),
BitSet.valueOf(MarshallUtil.unmarshallByteArray(input))
);
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoader.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoader.java
index 7b60dcb..cf62230 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoader.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoader.java
@@ -29,12 +29,11 @@ import org.keycloak.models.session.UserSessionPersisterProvider;
import java.io.Serializable;
import java.util.List;
-import java.util.concurrent.TimeUnit;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
-public class OfflinePersistentUserSessionLoader implements SessionLoader, Serializable {
+public class OfflinePersistentUserSessionLoader implements SessionLoader<OfflinePersistentUserSessionLoaderContext>, Serializable {
private static final Logger log = Logger.getLogger(OfflinePersistentUserSessionLoader.class);
@@ -45,6 +44,13 @@ public class OfflinePersistentUserSessionLoader implements SessionLoader, Serial
public static final String PERSISTENT_SESSIONS_LOADED_IN_CURRENT_DC = "PERSISTENT_SESSIONS_LOADED_IN_CURRENT_DC";
+ private final int sessionsPerSegment;
+
+ public OfflinePersistentUserSessionLoader(int sessionsPerSegment) {
+ this.sessionsPerSegment = sessionsPerSegment;
+ }
+
+
@Override
public void init(KeycloakSession session) {
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
@@ -60,14 +66,19 @@ public class OfflinePersistentUserSessionLoader implements SessionLoader, Serial
@Override
- public int getSessionsCount(KeycloakSession session) {
+ public OfflinePersistentUserSessionLoaderContext computeLoaderContext(KeycloakSession session) {
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
- return persister.getUserSessionsCount(true);
+ int sessionsCount = persister.getUserSessionsCount(true);
+
+ return new OfflinePersistentUserSessionLoaderContext(sessionsCount, sessionsPerSegment);
}
@Override
- public boolean loadSessions(KeycloakSession session, int first, int max) {
+ public boolean loadSessions(KeycloakSession session, OfflinePersistentUserSessionLoaderContext ctx, int segment) {
+ int first = ctx.getSessionsPerSegment() * segment;
+ int max = sessionsPerSegment;
+
if (log.isTraceEnabled()) {
log.tracef("Loading sessions - first: %d, max: %d", first, max);
}
@@ -132,4 +143,13 @@ public class OfflinePersistentUserSessionLoader implements SessionLoader, Serial
log.debugf("Persistent sessions loaded successfully!");
}
+
+ @Override
+ public String toString() {
+ return new StringBuilder("OfflinePersistentUserSessionLoader [ ")
+ .append("sessionsPerSegment: ").append(sessionsPerSegment)
+ .append(" ]")
+ .toString();
+ }
+
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoaderContext.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoaderContext.java
new file mode 100644
index 0000000..491239b
--- /dev/null
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/OfflinePersistentUserSessionLoaderContext.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.models.sessions.infinispan.initializer;
+
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class OfflinePersistentUserSessionLoaderContext implements SessionLoader.LoaderContext, Serializable {
+
+ private final int sessionsTotal;
+ private final int segmentsCount;
+ private final int sessionsPerSegment;
+
+ public OfflinePersistentUserSessionLoaderContext(int sessionsTotal, int sessionsPerSegment) {
+ this.sessionsTotal = sessionsTotal;
+ this.sessionsPerSegment = sessionsPerSegment;
+
+ int segmentsCount = sessionsTotal / sessionsPerSegment;
+ if (sessionsTotal % sessionsPerSegment >= 1) {
+ segmentsCount = segmentsCount + 1;
+ }
+ this.segmentsCount = segmentsCount;
+ }
+
+
+ public int getSessionsTotal() {
+ return sessionsTotal;
+ }
+
+ @Override
+ public int getSegmentsCount() {
+ return segmentsCount;
+ }
+
+ public int getSessionsPerSegment() {
+ return sessionsPerSegment;
+ }
+
+
+ @Override
+ public String toString() {
+ return new StringBuilder("OfflinePersistentUserSessionLoaderContext [ ")
+ .append(" sessionsTotal: ").append(sessionsTotal)
+ .append(", sessionsPerSegment: ").append(sessionsPerSegment)
+ .append(", segmentsCount: ").append(segmentsCount)
+ .append(" ]")
+ .toString();
+ }
+}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionInitializerWorker.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionInitializerWorker.java
index ec647af..7df94bf 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionInitializerWorker.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionInitializerWorker.java
@@ -36,14 +36,14 @@ public class SessionInitializerWorker implements DistributedCallable<String, Ser
private static final Logger log = Logger.getLogger(SessionInitializerWorker.class);
private int segment;
- private int sessionsPerSegment;
+ private SessionLoader.LoaderContext ctx;
private SessionLoader sessionLoader;
private transient Cache<String, Serializable> workCache;
- public void setWorkerEnvironment(int segment, int sessionsPerSegment, SessionLoader sessionLoader) {
+ public void setWorkerEnvironment(int segment, SessionLoader.LoaderContext ctx, SessionLoader sessionLoader) {
this.segment = segment;
- this.sessionsPerSegment = sessionsPerSegment;
+ this.ctx = ctx;
this.sessionLoader = sessionLoader;
}
@@ -64,14 +64,11 @@ public class SessionInitializerWorker implements DistributedCallable<String, Ser
return InfinispanCacheInitializer.WorkerResult.create(segment, false);
}
- final int first = segment * sessionsPerSegment;
- final int max = sessionsPerSegment;
-
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
@Override
public void run(KeycloakSession session) {
- sessionLoader.loadSessions(session, first, max);
+ sessionLoader.loadSessions(session, ctx, segment);
}
});
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionLoader.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionLoader.java
index e4ec4d0..71b519e 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionLoader.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/initializer/SessionLoader.java
@@ -17,12 +17,14 @@
package org.keycloak.models.sessions.infinispan.initializer;
+import java.io.Serializable;
+
import org.keycloak.models.KeycloakSession;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
-public interface SessionLoader {
+public interface SessionLoader<LOADER_CONTEXT extends SessionLoader.LoaderContext> extends Serializable {
/**
* Will be triggered just once on cluster coordinator node to perform some generic initialization tasks (Eg. update DB before starting load).
@@ -35,23 +37,27 @@ public interface SessionLoader {
/**
- * Will be triggered just once on cluster coordinator node to count the number of sessions
+ *
+ * Will be triggered just once on cluster coordinator node to count the number of segments and other context data specific to the worker task.
+ * Each segment will be then later computed in one "worker" task
+ *
+ * This method could be expensive to call, so the "computed" loaderContext object is passed among workers/loaders and needs to be serializable
*
* @param session
* @return
*/
- int getSessionsCount(KeycloakSession session);
+ LOADER_CONTEXT computeLoaderContext(KeycloakSession session);
/**
* Will be called on all cluster nodes to load the specified page.
*
* @param session
- * @param first
- * @param max
+ * @param loaderContext loaderContext object, which was already computed before
+ * @param segment to be computed
* @return
*/
- boolean loadSessions(KeycloakSession session, int first, int max);
+ boolean loadSessions(KeycloakSession session, LOADER_CONTEXT loaderContext, int segment);
/**
@@ -69,4 +75,15 @@ public interface SessionLoader {
* @param initializer
*/
void afterAllSessionsLoaded(BaseCacheInitializer initializer);
+
+
+ /**
+ * Object, which contains some context data to be used by SessionLoader implementation. It's computed just once and then passed
+ * to each {@link SessionLoader}. It needs to be {@link Serializable}
+ */
+ interface LoaderContext extends Serializable {
+
+ int getSegmentsCount();
+
+ }
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java
index 15c9e4f..6dcfb70 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java
@@ -29,6 +29,7 @@ import org.infinispan.client.hotrod.Flag;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.VersionedValue;
import org.jboss.logging.Logger;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
@@ -83,10 +84,12 @@ public class RemoteCacheInvoker {
logger.tracef("Running task '%s' on remote cache '%s' . Key is '%s'", operation, cacheName, key);
}
+ TopologyInfo topology = InfinispanUtil.getTopologyInfo(kcSession);
+
Retry.executeWithBackoff((int iteration) -> {
try {
- runOnRemoteCache(context.remoteCache, maxIdleTimeMs, key, task, sessionWrapper);
+ runOnRemoteCache(topology, context.remoteCache, maxIdleTimeMs, key, task, sessionWrapper);
} catch (HotRodClientException re) {
if (logger.isDebugEnabled()) {
logger.debugf(re, "Failed running task '%s' on remote cache '%s' . Key: '%s', iteration '%s'. Will try to retry the task",
@@ -101,7 +104,7 @@ public class RemoteCacheInvoker {
}
- private <K, V extends SessionEntity> void runOnRemoteCache(RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long maxIdleMs, K key, SessionUpdateTask<V> task, SessionEntityWrapper<V> sessionWrapper) {
+ private <K, V extends SessionEntity> void runOnRemoteCache(TopologyInfo topology, RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long maxIdleMs, K key, SessionUpdateTask<V> task, SessionEntityWrapper<V> sessionWrapper) {
final V session = sessionWrapper.getEntity();
SessionUpdateTask.CacheOperation operation = task.getOperation(session);
@@ -119,11 +122,11 @@ public class RemoteCacheInvoker {
if (existing != null) {
logger.debugf("Existing entity in remote cache for key: %s . Will update it", key);
- replace(remoteCache, task.getLifespanMs(), maxIdleMs, key, task);
+ replace(topology, remoteCache, task.getLifespanMs(), maxIdleMs, key, task);
}
break;
case REPLACE:
- replace(remoteCache, task.getLifespanMs(), maxIdleMs, key, task);
+ replace(topology, remoteCache, task.getLifespanMs(), maxIdleMs, key, task);
break;
default:
throw new IllegalStateException("Unsupported state " + operation);
@@ -131,14 +134,13 @@ public class RemoteCacheInvoker {
}
- private <K, V extends SessionEntity> void replace(RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long lifespanMs, long maxIdleMs, K key, SessionUpdateTask<V> task) {
+ private <K, V extends SessionEntity> void replace(TopologyInfo topology, RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long lifespanMs, long maxIdleMs, K key, SessionUpdateTask<V> task) {
boolean replaced = false;
- int iteration = 0;
-
- while (!replaced && iteration < InfinispanUtil.MAXIMUM_REPLACE_RETRIES) {
- iteration++;
+ int replaceIteration = 0;
+ while (!replaced && replaceIteration < InfinispanUtil.MAXIMUM_REPLACE_RETRIES) {
+ replaceIteration++;
- VersionedValue<SessionEntityWrapper<V>> versioned = remoteCache.getVersioned(key);
+ VersionedValue<SessionEntityWrapper<V>> versioned = remoteCache.getWithMetadata(key);
if (versioned == null) {
logger.warnf("Not found entity to replace for key '%s'", key);
return;
@@ -151,16 +153,17 @@ public class RemoteCacheInvoker {
task.runUpdate(session);
if (logger.isTraceEnabled()) {
- logger.tracef("Before replaceWithVersion. Entity to write version %d: %s", versioned.getVersion(), session);
+ logger.tracef("%s: Before replaceWithVersion. Entity to write version %d: %s", logTopologyData(topology, replaceIteration),
+ versioned.getVersion(), session);
}
replaced = remoteCache.replaceWithVersion(key, SessionEntityWrapper.forTransport(session), versioned.getVersion(), lifespanMs, TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
if (!replaced) {
- logger.debugf("Failed to replace entity '%s' version %d. Will retry again", key, versioned.getVersion());
+ logger.debugf("%s: Failed to replace entity '%s' version %d. Will retry again", logTopologyData(topology, replaceIteration), key, versioned.getVersion());
} else {
if (logger.isTraceEnabled()) {
- logger.tracef("Replaced entity version %d in remote cache: %s", versioned.getVersion(), session);
+ logger.tracef("%s: Replaced entity version %d in remote cache: %s", logTopologyData(topology, replaceIteration), versioned.getVersion(), session);
}
}
}
@@ -171,6 +174,11 @@ public class RemoteCacheInvoker {
}
+ private String logTopologyData(TopologyInfo topology, int iteration) {
+ return topology.toString() + ", replaceIteration: " + iteration;
+ }
+
+
private class RemoteCacheContext {
private final RemoteCache remoteCache;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java
index 1639c78..477a01e 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java
@@ -29,6 +29,7 @@ import org.infinispan.client.hotrod.event.ClientCacheEntryRemovedEvent;
import org.infinispan.client.hotrod.event.ClientEvent;
import org.infinispan.context.Flag;
import org.jboss.logging.Logger;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.executors.ExecutorsProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
@@ -46,10 +47,11 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
protected static final Logger logger = Logger.getLogger(RemoteCacheSessionListener.class);
+ private static final int MAXIMUM_REPLACE_RETRIES = 10;
+
private Cache<K, SessionEntityWrapper<V>> cache;
private RemoteCache<K, SessionEntityWrapper<V>> remoteCache;
- private boolean distributed;
- private String myAddress;
+ private TopologyInfo topologyInfo;
private ClientListenerExecutorDecorator<K> executor;
@@ -61,12 +63,7 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
this.cache = cache;
this.remoteCache = remoteCache;
- this.distributed = InfinispanUtil.isDistributedCache(cache);
- if (this.distributed) {
- this.myAddress = InfinispanUtil.getMyAddress(session);
- } else {
- this.myAddress = null;
- }
+ this.topologyInfo = InfinispanUtil.getTopologyInfo(session);
ExecutorService executor = session.getProvider(ExecutorsProvider.class).getExecutor("client-listener-" + cache.getName());
this.executor = new ClientListenerExecutorDecorator<>(executor);
@@ -80,8 +77,10 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
if (shouldUpdateLocalCache(event.getType(), key, event.isCommandRetried())) {
this.executor.submit(event, () -> {
- // Should load it from remoteStore
- cache.get(key);
+ // Doesn't work due https://issues.jboss.org/browse/ISPN-9323. Needs to explicitly retrieve and create it
+ //cache.get(key);
+
+ createRemoteEntityInCache(key, event.getVersion());
});
}
@@ -102,9 +101,30 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
}
}
- private static final int MAXIMUM_REPLACE_RETRIES = 10;
- private void replaceRemoteEntityInCache(K key, long eventVersion) {
+ protected void createRemoteEntityInCache(K key, long eventVersion) {
+ VersionedValue<SessionEntityWrapper<V>> remoteSessionVersioned = remoteCache.getWithMetadata(key);
+
+ // Maybe can happen under some circumstances that remoteCache doesn't yet contain the value sent in the event (maybe just theoretically...)
+ if (remoteSessionVersioned == null || remoteSessionVersioned.getValue() == null) {
+ logger.debugf("Entity '%s' not present in remoteCache. Ignoring create",
+ key.toString());
+ return;
+ }
+
+
+ V remoteSession = remoteSessionVersioned.getValue().getEntity();
+ SessionEntityWrapper<V> newWrapper = new SessionEntityWrapper<>(remoteSession);
+
+ logger.debugf("Read session entity wrapper from the remote cache: %s", remoteSession.toString());
+
+ // Using putIfAbsent. Theoretic possibility that entity was already put to cache by someone else
+ cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_STORE, Flag.SKIP_CACHE_LOAD, Flag.IGNORE_RETURN_VALUES)
+ .putIfAbsent(key, newWrapper);
+ }
+
+
+ protected void replaceRemoteEntityInCache(K key, long eventVersion) {
// TODO can be optimized and remoteSession sent in the event itself?
boolean replaced = false;
int replaceRetries = 0;
@@ -113,7 +133,7 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
replaceRetries++;
SessionEntityWrapper<V> localEntityWrapper = cache.get(key);
- VersionedValue<SessionEntityWrapper<V>> remoteSessionVersioned = remoteCache.getVersioned(key);
+ VersionedValue<SessionEntityWrapper<V>> remoteSessionVersioned = remoteCache.getWithMetadata(key);
// Probably already removed
if (remoteSessionVersioned == null || remoteSessionVersioned.getValue() == null) {
@@ -177,11 +197,10 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
return false;
}
- if (!distributed || commandRetried) {
+ if (commandRetried) {
result = true;
} else {
- String keyAddress = InfinispanUtil.getKeyPrimaryOwnerAddress(cache, key);
- result = myAddress.equals(keyAddress);
+ result = topologyInfo.amIOwner(cache, key);
}
logger.debugf("Received event from remote store. Event '%s', key '%s', skip '%b'", type.toString(), key, !result);
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
index 53b294c..0ff1a90 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
@@ -19,127 +19,138 @@ package org.keycloak.models.sessions.infinispan.remotestore;
import java.io.Serializable;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.infinispan.Cache;
import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.impl.RemoteCacheImpl;
+import org.infinispan.client.hotrod.impl.operations.IterationStartOperation;
+import org.infinispan.client.hotrod.impl.operations.IterationStartResponse;
+import org.infinispan.client.hotrod.impl.operations.OperationsFactory;
import org.infinispan.commons.marshall.Marshaller;
+import org.infinispan.commons.util.CloseableIterator;
import org.infinispan.context.Flag;
import org.jboss.logging.Logger;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.connections.infinispan.RemoteCacheProvider;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.initializer.BaseCacheInitializer;
import org.keycloak.models.sessions.infinispan.initializer.OfflinePersistentUserSessionLoader;
import org.keycloak.models.sessions.infinispan.initializer.SessionLoader;
+import static org.infinispan.client.hotrod.impl.Util.await;
+
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
-public class RemoteCacheSessionsLoader implements SessionLoader {
+public class RemoteCacheSessionsLoader implements SessionLoader<RemoteCacheSessionsLoaderContext>, Serializable {
private static final Logger log = Logger.getLogger(RemoteCacheSessionsLoader.class);
-
- // Javascript to be executed on remote infinispan server.
- // Flag CACHE_MODE_LOCAL is optimization used just when remoteCache is replicated as all the entries are available locally. For distributed caches, it can't be used
- private static final String REMOTE_SCRIPT_FOR_LOAD_SESSIONS =
- "function loadSessions() {" +
- " var flagClazz = cache.getClass().getClassLoader().loadClass(\"org.infinispan.context.Flag\"); \n" +
- " var localFlag = java.lang.Enum.valueOf(flagClazz, \"CACHE_MODE_LOCAL\"); \n" +
- " var cacheMode = cache.getCacheConfiguration().clustering().cacheMode(); \n" +
- " var canUseLocalFlag = !cacheMode.isClustered() || cacheMode.isReplicated(); \n" +
-
- " var cacheStream; \n" +
- " if (canUseLocalFlag) { \n" +
- " cacheStream = cache.getAdvancedCache().withFlags([ localFlag ]).entrySet().stream();\n" +
- " } else { \n" +
- " cacheStream = cache.getAdvancedCache().withFlags([ ]).entrySet().stream();\n" +
- " }; \n" +
-
- " var result = cacheStream.skip(first).limit(max).collect(java.util.stream.Collectors.toMap(\n" +
- " new java.util.function.Function() {\n" +
- " apply: function(entry) {\n" +
- " return entry.getKey();\n" +
- " }\n" +
- " },\n" +
- " new java.util.function.Function() {\n" +
- " apply: function(entry) {\n" +
- " return entry.getValue();\n" +
- " }\n" +
- " }\n" +
- " ));\n" +
- "\n" +
- " cacheStream.close();\n" +
- " return result;\n" +
- "};\n" +
- "\n" +
- "loadSessions();";
-
-
-
private final String cacheName;
+ private final int sessionsPerSegment;
- public RemoteCacheSessionsLoader(String cacheName) {
+ public RemoteCacheSessionsLoader(String cacheName, int sessionsPerSegment) {
this.cacheName = cacheName;
+ this.sessionsPerSegment = sessionsPerSegment;
}
+
@Override
public void init(KeycloakSession session) {
+ }
+
+
+ @Override
+ public RemoteCacheSessionsLoaderContext computeLoaderContext(KeycloakSession session) {
RemoteCache remoteCache = getRemoteCache(session);
+ int sessionsTotal = remoteCache.size();
+ int ispnSegments = getIspnSegmentsCount(remoteCache);
- RemoteCache<String, String> scriptCache = remoteCache.getRemoteCacheManager().getCache(RemoteCacheProvider.SCRIPT_CACHE_NAME);
+ return new RemoteCacheSessionsLoaderContext(ispnSegments, sessionsPerSegment, sessionsTotal);
- if (!scriptCache.containsKey("load-sessions.js")) {
- scriptCache.put("load-sessions.js",
- "// mode=local,language=javascript\n" +
- REMOTE_SCRIPT_FOR_LOAD_SESSIONS);
- }
}
- @Override
- public int getSessionsCount(KeycloakSession session) {
- RemoteCache remoteCache = getRemoteCache(session);
- return remoteCache.size();
+
+ protected int getIspnSegmentsCount(RemoteCache remoteCache) {
+ OperationsFactory operationsFactory = ((RemoteCacheImpl) remoteCache).getOperationsFactory();
+
+ // Same like RemoteCloseableIterator.startInternal
+ IterationStartOperation iterationStartOperation = operationsFactory.newIterationStartOperation(null, null, null, sessionsPerSegment, false);
+ IterationStartResponse startResponse = await(iterationStartOperation.execute());
+
+ try {
+ // Could happen for non-clustered caches
+ if (startResponse.getSegmentConsistentHash() == null) {
+ return -1;
+ } else {
+ return startResponse.getSegmentConsistentHash().getNumSegments();
+ }
+ } finally {
+ startResponse.getChannel().close();
+ }
}
+
@Override
- public boolean loadSessions(KeycloakSession session, int first, int max) {
+ public boolean loadSessions(KeycloakSession session, RemoteCacheSessionsLoaderContext context, int segment) {
Cache cache = getCache(session);
Cache decoratedCache = cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_LOAD, Flag.SKIP_CACHE_STORE, Flag.IGNORE_RETURN_VALUES);
+ RemoteCache remoteCache = getRemoteCache(session);
+
+ Set<Integer> myIspnSegments = getMyIspnSegments(segment, context);
- RemoteCache<?, ?> remoteCache = getRemoteCache(session);
+ log.debugf("Will do bulk load of sessions from remote cache '%s' . Segment: %d", cache.getName(), segment);
- log.debugf("Will do bulk load of sessions from remote cache '%s' . First: %d, max: %d", cache.getName(), first, max);
+ CloseableIterator<Map.Entry> iterator = null;
+ int countLoaded = 0;
+ try {
+ iterator = remoteCache.retrieveEntries(null, myIspnSegments, context.getSessionsPerSegment());
+ while (iterator.hasNext()) {
+ countLoaded++;
+ Map.Entry entry = iterator.next();
+ decoratedCache.putAsync(entry.getKey(), entry.getValue());
+ }
+ } catch (RuntimeException e) {
+ log.warnf(e, "Error loading sessions from remote cache '%s' for segment '%d'", remoteCache.getName(), segment);
+ throw e;
+ } finally {
+ if (iterator != null) {
+ iterator.close();
+ }
+ }
- Map<String, Integer> remoteParams = new HashMap<>();
- remoteParams.put("first", first);
- remoteParams.put("max", max);
- Map<byte[], byte[]> remoteObjects = remoteCache.execute("load-sessions.js", remoteParams);
+ log.debugf("Successfully finished loading sessions from cache '%s' . Segment: %d, Count of sessions loaded: %d", cache.getName(), segment, countLoaded);
- log.debugf("Successfully finished loading sessions '%s' . First: %d, max: %d", cache.getName(), first, max);
+ return true;
+ }
- Marshaller marshaller = remoteCache.getRemoteCacheManager().getMarshaller();
- for (Map.Entry<byte[], byte[]> entry : remoteObjects.entrySet()) {
- try {
- Object key = marshaller.objectFromByteBuffer(entry.getKey());
- SessionEntityWrapper entityWrapper = (SessionEntityWrapper) marshaller.objectFromByteBuffer(entry.getValue());
+ // Compute set of ISPN segments into 1 "worker" segment
+ protected Set<Integer> getMyIspnSegments(int segment, RemoteCacheSessionsLoaderContext ctx) {
+ // Remote cache is non-clustered
+ if (ctx.getIspnSegmentsCount() < 0) {
+ return null;
+ }
- decoratedCache.putAsync(key, entityWrapper);
- } catch (Exception e) {
- log.warn("Error loading session from remote cache", e);
- }
+ if (ctx.getIspnSegmentsCount() % ctx.getSegmentsCount() > 0) {
+ throw new IllegalStateException("Illegal state. IspnSegmentsCount: " + ctx.getIspnSegmentsCount() + ", segmentsCount: " + ctx.getSegmentsCount());
}
- return true;
- }
+ int countPerSegment = ctx.getIspnSegmentsCount() / ctx.getSegmentsCount();
+ int first = segment * countPerSegment;
+ int last = first + countPerSegment - 1;
+ Set<Integer> myIspnSegments = new HashSet<>();
+ for (int i=first ; i<=last ; i++) {
+ myIspnSegments.add(i);
+ }
+ return myIspnSegments;
- private Cache getCache(KeycloakSession session) {
- InfinispanConnectionProvider ispn = session.getProvider(InfinispanConnectionProvider.class);
- return ispn.getCache(cacheName);
}
@@ -165,12 +176,28 @@ public class RemoteCacheSessionsLoader implements SessionLoader {
@Override
public void afterAllSessionsLoaded(BaseCacheInitializer initializer) {
+ }
+
+ protected Cache getCache(KeycloakSession session) {
+ InfinispanConnectionProvider ispn = session.getProvider(InfinispanConnectionProvider.class);
+ return ispn.getCache(cacheName);
}
+
// Get remoteCache, which may be secured
- private RemoteCache getRemoteCache(KeycloakSession session) {
+ protected RemoteCache getRemoteCache(KeycloakSession session) {
InfinispanConnectionProvider ispn = session.getProvider(InfinispanConnectionProvider.class);
return ispn.getRemoteCache(cacheName);
}
+
+
+ @Override
+ public String toString() {
+ return new StringBuilder("RemoteCacheSessionsLoader [ ")
+ .append("cacheName: ").append(cacheName)
+ .append(", sessionsPerSegment: ").append(sessionsPerSegment)
+ .append(" ]")
+ .toString();
+ }
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoaderContext.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoaderContext.java
new file mode 100644
index 0000000..ec74871
--- /dev/null
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoaderContext.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.models.sessions.infinispan.remotestore;
+
+import java.io.Serializable;
+
+import org.keycloak.models.sessions.infinispan.initializer.SessionLoader;
+
+/**
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class RemoteCacheSessionsLoaderContext implements SessionLoader.LoaderContext, Serializable {
+
+ // Count of hash segments for remote infinispan cache. It's by default 256 for distributed/replicated caches
+ private final int ispnSegmentsCount;
+
+ // Count of segments (worker iterations for distributedExecutionService executions on KC side). Each segment will be 1 worker iteration.
+ // Count of segments could be lower than "ispnSegmentsCount" and depends on the size of the cache. For example if we have cache with just 500 items,
+ // we don't need 256 segments and send 256 requests to remoteCache to preload thing. Instead, we will have lower number of segments (EG. 8)
+ // and we will map more ispnSegments into 1 worker segment (In this case 256 / 8 = 32. So 32 ISPN segments mapped to each worker segment)
+ private final int segmentsCount;
+
+ private final int sessionsPerSegment;
+ private final int sessionsTotal;
+
+
+ public RemoteCacheSessionsLoaderContext(int ispnSegmentsCount, int sessionsPerSegment, int sessionsTotal) {
+ this.ispnSegmentsCount = ispnSegmentsCount;
+ this.sessionsPerSegment = sessionsPerSegment;
+ this.sessionsTotal = sessionsTotal;
+ this.segmentsCount = computeSegmentsCount(sessionsTotal, sessionsPerSegment, ispnSegmentsCount);
+ }
+
+
+ private int computeSegmentsCount(int sessionsTotal, int sessionsPerSegment, int ispnSegments) {
+ // No support by remote ISPN cache for segments. This can happen if remoteCache is local (non-clustered)
+ if (ispnSegments < 0) {
+ return 1;
+ }
+
+ int seg = sessionsTotal / sessionsPerSegment;
+ if (sessionsTotal % sessionsPerSegment > 0) {
+ seg = seg + 1;
+ }
+
+ int seg2 = 1;
+ while (seg2<seg && seg2<ispnSegments) {
+ seg2 = seg2 << 1;
+ }
+
+ return seg2;
+ }
+
+
+ @Override
+ public int getSegmentsCount() {
+ return segmentsCount;
+ }
+
+ public int getIspnSegmentsCount() {
+ return ispnSegmentsCount;
+ }
+
+ public int getSessionsPerSegment() {
+ return sessionsPerSegment;
+ }
+
+ public int getSessionsTotal() {
+ return sessionsTotal;
+ }
+
+
+ @Override
+ public String toString() {
+ return new StringBuilder("RemoteCacheSessionsLoaderContext [ ")
+ .append("segmentsCount: ").append(segmentsCount)
+ .append(", ispnSegmentsCount: ").append(ispnSegmentsCount)
+ .append(", sessionsPerSegment: ").append(sessionsPerSegment)
+ .append(", sessionsTotal: ").append(sessionsTotal)
+ .append(" ]")
+ .toString();
+ }
+}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/stream/Mappers.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/stream/Mappers.java
index 50df448..29193dd 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/stream/Mappers.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/stream/Mappers.java
@@ -17,7 +17,6 @@
package org.keycloak.models.sessions.infinispan.stream;
-import org.infinispan.stream.SerializableSupplier;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionEntity;
import org.keycloak.models.sessions.infinispan.entities.LoginFailureEntity;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/InfinispanUtil.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/InfinispanUtil.java
index 0566b6b..33e4eb8 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/InfinispanUtil.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/InfinispanUtil.java
@@ -27,6 +27,7 @@ import org.infinispan.persistence.manager.PersistenceManager;
import org.infinispan.persistence.remote.RemoteStore;
import org.infinispan.remoting.transport.Transport;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
+import org.keycloak.connections.infinispan.TopologyInfo;
import org.keycloak.models.KeycloakSession;
/**
@@ -52,34 +53,8 @@ public class InfinispanUtil {
}
- public static boolean isDistributedCache(Cache ispnCache) {
- CacheMode cacheMode = ispnCache.getCacheConfiguration().clustering().cacheMode();
- return cacheMode.isDistributed();
- }
-
-
- public static String getMyAddress(KeycloakSession session) {
- return session.getProvider(InfinispanConnectionProvider.class).getNodeName();
- }
-
- public static String getMySite(KeycloakSession session) {
- return session.getProvider(InfinispanConnectionProvider.class).getSiteName();
- }
-
-
- /**
- *
- * @param ispnCache
- * @param key
- * @return address of the node, who is owner of the specified key in current cluster
- */
- public static String getKeyPrimaryOwnerAddress(Cache ispnCache, Object key) {
- DistributionManager distManager = ispnCache.getAdvancedCache().getDistributionManager();
- if (distManager == null) {
- throw new IllegalArgumentException("Cache '" + ispnCache.getName() + "' is not distributed cache");
- }
-
- return distManager.getPrimaryLocation(key).toString();
+ public static TopologyInfo getTopologyInfo(KeycloakSession session) {
+ return session.getProvider(InfinispanConnectionProvider.class).getTopologyInfo();
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/KeycloakMarshallUtil.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/KeycloakMarshallUtil.java
index a1d8366..ed94d3c 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/KeycloakMarshallUtil.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/util/KeycloakMarshallUtil.java
@@ -165,7 +165,6 @@ public class KeycloakMarshallUtil {
return isSet ? input.readInt() : null;
}
-
public static class ConcurrentHashMapBuilder<K, V> implements MarshallUtil.MapBuilder<K, V, ConcurrentHashMap<K, V>> {
@Override
diff --git a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGRemoteCacheClientListenersTest.java b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGRemoteCacheClientListenersTest.java
index 80894a7..b662578 100644
--- a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGRemoteCacheClientListenersTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGRemoteCacheClientListenersTest.java
@@ -19,6 +19,8 @@ package org.keycloak.cluster.infinispan;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import org.infinispan.Cache;
@@ -41,7 +43,7 @@ import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
* Test that hotrod ClientListeners are correctly executed as expected
*
* STEPS TO REPRODUCE:
- * - Unzip infinispan-server-8.2.6.Final to some locations ISPN1 and ISPN2
+ * - Unzip infinispan-server-9.2.4.Final to some locations ISPN1 and ISPN2
*
* - Edit both ISPN1/standalone/configuration/clustered.xml and ISPN2/standalone/configuration/clustered.xml . Configure cache in container "clustered"
*
@@ -55,7 +57,7 @@ import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
./standalone.sh -c clustered.xml -Djava.net.preferIPv4Stack=true -Djboss.socket.binding.port-offset=1010 -Djboss.default.multicast.address=234.56.78.99 -Djboss.node.name=cache-server
- Run server2
- ./standalone.sh -c clustered.xml -Djava.net.preferIPv4Stack=true -Djboss.socket.binding.port-offset=2010 -Djboss.default.multicast.address=234.56.78.99 -Djboss.node.name=cache-server-dc-2
+ ./standalone.sh -c clustered.xml -Djava.net.preferIPv4Stack=true -Djboss.socket.binding.port-offset=2010 -Djboss.default.multicast.address=234.56.78.100 -Djboss.node.name=cache-server-dc-2
- Run this test as main class from IDE
*
@@ -145,10 +147,12 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
private final RemoteCache<String, Integer> remoteCache;
private final int threadId;
+ private Executor executor;
public HotRodListener(Cache<String, Integer> cache, int threadId) {
this.remoteCache = InfinispanUtil.getRemoteCache(cache);
this.threadId = threadId;
+ this.executor = Executors.newCachedThreadPool();
}
//private AtomicInteger listenerCount = new AtomicInteger(0);
@@ -156,7 +160,12 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
@ClientCacheEntryCreated
public void created(ClientCacheEntryCreatedEvent event) {
String cacheKey = (String) event.getKey();
- event(cacheKey, event.getVersion(), true);
+
+ executor.execute(() -> {
+
+ event(cacheKey, event.getVersion(), true);
+
+ });
}
@@ -164,7 +173,11 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
@ClientCacheEntryModified
public void updated(ClientCacheEntryModifiedEvent event) {
String cacheKey = (String) event.getKey();
- event(cacheKey, event.getVersion(), false);
+ executor.execute(() -> {
+
+ event(cacheKey, event.getVersion(), false);
+
+ });
}
@@ -174,7 +187,7 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
totalListenerCalls.incrementAndGet();
- VersionedValue<Integer> versionedVal = remoteCache.getVersioned(cacheKey);
+ VersionedValue<Integer> versionedVal = remoteCache.getWithMetadata(cacheKey);
if (versionedVal.getVersion() < version) {
System.err.println("INCOMPATIBLE VERSION. event version: " + version + ", entity version: " + versionedVal.getVersion());
diff --git a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/RemoteCacheSessionsLoaderTest.java b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/RemoteCacheSessionsLoaderTest.java
new file mode 100644
index 0000000..950a4c0
--- /dev/null
+++ b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/RemoteCacheSessionsLoaderTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed 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.keycloak.cluster.infinispan;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.infinispan.Cache;
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationBuilder;
+import org.jboss.logging.Logger;
+import org.junit.Assert;
+import org.keycloak.common.util.Time;
+import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
+import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
+import org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheSessionsLoader;
+import org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheSessionsLoaderContext;
+import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class RemoteCacheSessionsLoaderTest {
+
+ protected static final Logger logger = Logger.getLogger(RemoteCacheSessionsLoaderTest.class);
+
+ private static final int COUNT = 10000;
+
+ public static void main(String[] args) throws Exception {
+ String cacheName = InfinispanConnectionProvider.USER_SESSION_CACHE_NAME;
+ Cache cache1 = createManager(1, cacheName).getCache(cacheName);
+ Cache cache2 = cache1.getCacheManager().getCache("local");
+ RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache1);
+ cache1.clear();
+ cache2.clear();
+ remoteCache.clear();
+
+ try {
+
+ for (int i=0 ; i<COUNT ; i++) {
+ // Create initial item
+ UserSessionEntity session = new UserSessionEntity();
+ session.setId("loader-key-" + i);
+ session.setRealmId("master");
+ session.setBrokerSessionId("!23123123");
+ session.setBrokerUserId(null);
+ session.setUser("admin");
+ session.setLoginUsername("admin");
+ session.setIpAddress("123.44.143.178");
+ session.setStarted(Time.currentTime());
+ session.setLastSessionRefresh(Time.currentTime());
+
+ SessionEntityWrapper<UserSessionEntity> wrappedSession = new SessionEntityWrapper<>(session);
+
+ // Create caches, listeners and finally worker threads
+ remoteCache.put("loader-key-" + i, wrappedSession);
+ Assert.assertFalse(cache2.containsKey("loader-key-" + i));
+
+ if (i % 1000 == 0) {
+ logger.infof("%d sessions added", i);
+ }
+ }
+
+
+// RemoteCacheSessionsLoader loader = new RemoteCacheSessionsLoader(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME, 64) {
+//
+// @Override
+// protected Cache getCache(KeycloakSession session) {
+// return cache2;
+// }
+//
+// @Override
+// protected RemoteCache getRemoteCache(KeycloakSession session) {
+// return remoteCache;
+// }
+//
+// };
+
+ // Just to be able to test serializability
+ RemoteCacheSessionsLoader loader = new CustomLoader(cacheName, 64, cache2, remoteCache);
+
+ loader.init(null);
+ RemoteCacheSessionsLoaderContext ctx = loader.computeLoaderContext(null);
+ Assert.assertEquals(ctx.getSessionsTotal(), COUNT);
+ Assert.assertEquals(ctx.getIspnSegmentsCount(), 256);
+ //Assert.assertEquals(ctx.getSegmentsCount(), 16);
+ Assert.assertEquals(ctx.getSessionsPerSegment(), 64);
+
+ int totalCount = 0;
+ logger.infof("segmentsCount: %d", ctx.getSegmentsCount());
+
+ Set<String> visitedKeys = new HashSet<>();
+ for (int currentSegment=0 ; currentSegment<ctx.getSegmentsCount() ; currentSegment++) {
+ logger.infof("Loading segment %d", currentSegment);
+ loader.loadSessions(null, ctx, currentSegment);
+
+ logger.infof("Loaded %d keys for segment %d", cache2.keySet().size(), currentSegment);
+ totalCount = totalCount + cache2.keySet().size();
+ visitedKeys.addAll(cache2.keySet());
+ cache2.clear();
+ }
+
+ Assert.assertEquals(totalCount, COUNT);
+ Assert.assertEquals(visitedKeys.size(), COUNT);
+ logger.infof("SUCCESS: Loaded %d sessions", totalCount);
+ } finally {
+ // Finish JVM
+ cache1.getCacheManager().stop();
+ }
+ }
+
+
+ private static EmbeddedCacheManager createManager(int threadId, String cacheName) {
+ return new TestCacheManagerFactory().createManager(threadId, cacheName, RemoteStoreConfigurationBuilder.class);
+ }
+
+
+ public static class CustomLoader extends RemoteCacheSessionsLoader {
+
+ private final transient Cache cache2;
+ private final transient RemoteCache remoteCache;
+
+ public CustomLoader(String cacheName, int sessionsPerSegment, Cache cache2, RemoteCache remoteCache) {
+ super(cacheName, sessionsPerSegment);
+ this.cache2 = cache2;
+ this.remoteCache = remoteCache;
+
+ }
+
+ @Override
+ protected Cache getCache(KeycloakSession session) {
+ return cache2;
+ }
+
+ @Override
+ protected RemoteCache getRemoteCache(KeycloakSession session) {
+ return remoteCache;
+ }
+
+ }
+
+}
diff --git a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java
index 0fc8d7e..82de12c 100644
--- a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java
+++ b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java
@@ -53,6 +53,7 @@ class TestCacheManagerFactory {
Configuration invalidationCacheConfiguration = getCacheBackedByRemoteStore(threadId, cacheName, builderClass);
cacheManager.defineConfiguration(cacheName, invalidationCacheConfiguration);
+ cacheManager.defineConfiguration("local", new ConfigurationBuilder().build());
return cacheManager;
}
@@ -75,6 +76,8 @@ class TestCacheManagerFactory {
.rawValues(true)
.forceReturnValues(false)
.marshaller(KeycloakHotRodMarshallerFactory.class.getName())
+ //.protocolVersion(ProtocolVersion.PROTOCOL_VERSION_26)
+ //.maxBatchSize(5)
.addServer()
.host(host)
.port(port)
diff --git a/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java b/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java
index a9da1d7..308d7b2 100644
--- a/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/keys/infinispan/InfinispanKeyStorageProviderTest.java
@@ -161,7 +161,10 @@ public class InfinispanKeyStorageProviderTest {
final DefaultCacheManager cacheManager = new DefaultCacheManager(gcb.build());
ConfigurationBuilder cb = new ConfigurationBuilder();
- cb.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
+ cb.memory()
+ .evictionStrategy(EvictionStrategy.REMOVE)
+ .evictionType(EvictionType.COUNT)
+ .size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
cb.jmxStatistics().enabled(true);
Configuration cfg = cb.build();
diff --git a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyLockingTest.java b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyLockingTest.java
index 21b9233..e439b66 100755
--- a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyLockingTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyLockingTest.java
@@ -6,7 +6,7 @@ import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.transaction.LockingMode;
-import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.EmbeddedTransactionManagerLookup;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
@@ -71,7 +71,7 @@ public class ConcurrencyLockingTest {
ConfigurationBuilder counterConfigBuilder = new ConfigurationBuilder();
counterConfigBuilder.invocationBatching().enable();
- counterConfigBuilder.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
+ counterConfigBuilder.transaction().transactionManagerLookup(new EmbeddedTransactionManagerLookup());
counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC);
Configuration counterCacheConfiguration = counterConfigBuilder.build();
diff --git a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyVersioningTest.java b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyVersioningTest.java
index 39276ab..3641d27 100755
--- a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyVersioningTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/ConcurrencyVersioningTest.java
@@ -9,7 +9,7 @@ import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.transaction.TransactionMode;
-import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.EmbeddedTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.junit.Assert;
import org.junit.Ignore;
@@ -251,7 +251,7 @@ public class ConcurrencyVersioningTest {
invalidationConfigBuilder
//.invocationBatching().enable()
.transaction().transactionMode(TransactionMode.TRANSACTIONAL)
- .transaction().transactionManagerLookup(new DummyTransactionManagerLookup())
+ .transaction().transactionManagerLookup(new EmbeddedTransactionManagerLookup())
.locking().isolationLevel(IsolationLevel.REPEATABLE_READ).writeSkewCheck(true).versioning().enable().scheme(VersioningScheme.SIMPLE);
diff --git a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/DistributedCacheWriteSkewTest.java b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/DistributedCacheWriteSkewTest.java
index b578ab3..eaa2d0b 100644
--- a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/DistributedCacheWriteSkewTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/DistributedCacheWriteSkewTest.java
@@ -30,7 +30,7 @@ import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
import org.infinispan.transaction.LockingMode;
-import org.infinispan.transaction.lookup.DummyTransactionManagerLookup;
+import org.infinispan.transaction.lookup.EmbeddedTransactionManagerLookup;
import org.infinispan.util.concurrent.IsolationLevel;
import org.jgroups.JChannel;
import org.keycloak.common.util.Time;
@@ -202,7 +202,7 @@ public class DistributedCacheWriteSkewTest {
// distConfigBuilder.invocationBatching().enable();
//distConfigBuilder.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
- distConfigBuilder.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
+ distConfigBuilder.transaction().transactionManagerLookup(new EmbeddedTransactionManagerLookup());
distConfigBuilder.transaction().lockingMode(LockingMode.OPTIMISTIC);
}
Configuration distConfig = distConfigBuilder.build();
diff --git a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/InitializerStateTest.java b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/InitializerStateTest.java
index d26f2b9..1e72aa8 100644
--- a/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/InitializerStateTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/models/sessions/infinispan/initializer/InitializerStateTest.java
@@ -20,6 +20,7 @@ package org.keycloak.models.sessions.infinispan.initializer;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.cache.infinispan.UserCacheSession;
+import org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheSessionsLoaderContext;
import org.keycloak.storage.CacheableStorageProviderModel;
import java.text.DateFormat;
@@ -33,8 +34,54 @@ import java.util.List;
public class InitializerStateTest {
@Test
+ public void testOfflineLoaderContext() {
+ OfflinePersistentUserSessionLoaderContext ctx = new OfflinePersistentUserSessionLoaderContext(28, 5);
+ Assert.assertEquals(ctx.getSegmentsCount(), 6);
+
+ ctx = new OfflinePersistentUserSessionLoaderContext(19, 5);
+ Assert.assertEquals(ctx.getSegmentsCount(), 4);
+
+ ctx = new OfflinePersistentUserSessionLoaderContext(20, 5);
+ Assert.assertEquals(ctx.getSegmentsCount(), 4);
+
+ ctx = new OfflinePersistentUserSessionLoaderContext(21, 5);
+ Assert.assertEquals(ctx.getSegmentsCount(), 5);
+ }
+
+
+ @Test
+ public void testRemoteLoaderContext() {
+ assertSegmentsForRemoteLoader(0, 64, -1, 1);
+ assertSegmentsForRemoteLoader(0, 64, 256, 1);
+ assertSegmentsForRemoteLoader(5, 64, 256, 1);
+ assertSegmentsForRemoteLoader(63, 64, 256, 1);
+ assertSegmentsForRemoteLoader(64, 64, 256, 1);
+ assertSegmentsForRemoteLoader(65, 64, 256, 2);
+ assertSegmentsForRemoteLoader(127, 64, 256, 2);
+ assertSegmentsForRemoteLoader(1000, 64, 256, 16);
+
+ assertSegmentsForRemoteLoader(2047, 64, 256, 32);
+ assertSegmentsForRemoteLoader(2048, 64, 256, 32);
+ assertSegmentsForRemoteLoader(2049, 64, 256, 64);
+
+ assertSegmentsForRemoteLoader(1000, 64, 256, 16);
+ assertSegmentsForRemoteLoader(10000, 64, 256, 256);
+ assertSegmentsForRemoteLoader(1000000, 64, 256, 256);
+ assertSegmentsForRemoteLoader(10000000, 64, 256, 256);
+ }
+
+ private void assertSegmentsForRemoteLoader(int sessionsTotal, int sessionsPerSegment, int ispnSegmentsCount, int expectedSegments) {
+ RemoteCacheSessionsLoaderContext ctx = new RemoteCacheSessionsLoaderContext(ispnSegmentsCount, sessionsPerSegment, sessionsTotal);
+ Assert.assertEquals(expectedSegments, ctx.getSegmentsCount());
+ }
+
+
+ @Test
public void testComputationState() {
- InitializerState state = new InitializerState(28, 5);
+ OfflinePersistentUserSessionLoaderContext ctx = new OfflinePersistentUserSessionLoaderContext(28, 5);
+ Assert.assertEquals(ctx.getSegmentsCount(), 6);
+
+ InitializerState state = new InitializerState(ctx.getSegmentsCount());
Assert.assertFalse(state.isFinished());
List<Integer> segments = state.getUnfinishedSegments(3);
pom.xml 40(+26 -14)
diff --git a/pom.xml b/pom.xml
index 7e64720..3ed606b 100755
--- a/pom.xml
+++ b/pom.xml
@@ -44,16 +44,18 @@
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
- <wildfly.version>11.0.0.Final</wildfly.version>
- <wildfly.build-tools.version>1.2.2.Final</wildfly.build-tools.version>
- <eap.version>7.1.4.GA-redhat-1</eap.version>
- <eap.build-tools.version>1.2.2.Final</eap.build-tools.version>
- <wildfly.core.version>3.0.10.Final</wildfly.core.version>
+ <wildfly.version>13.0.0.Final</wildfly.version>
+ <wildfly.build-tools.version>1.2.10.Final</wildfly.build-tools.version>
+ <eap.version>7.2.0.CD13-redhat-4</eap.version>
+ <eap.build-tools.version>1.2.10.Final</eap.build-tools.version>
+ <wildfly.core.version>5.0.0.Final</wildfly.core.version>
<wildfly10.core.version>2.0.10.Final</wildfly10.core.version>
<jboss.as.version>7.2.0.Final</jboss.as.version>
- <aesh.version>0.66.19</aesh.version>
+ <jboss.aesh.version>0.66.19</jboss.aesh.version>
+ <aesh.version>1.4</aesh.version>
+ <aesh.readline.version>1.7</aesh.readline.version>
<apache.httpcomponents.version>4.5.2</apache.httpcomponents.version>
<apache.httpcomponents.httpcore.version>4.4.4</apache.httpcomponents.httpcore.version>
<apache.mime4j.version>0.6</apache.mime4j.version>
@@ -65,30 +67,30 @@
<h2.version>1.4.193</h2.version>
<hibernate.entitymanager.version>5.1.15.Final</hibernate.entitymanager.version>
<hibernate.javax.persistence.version>1.0.0.Final</hibernate.javax.persistence.version>
- <infinispan.version>8.2.11.Final</infinispan.version>
+ <infinispan.version>9.2.4.Final</infinispan.version>
<jackson.version>2.8.11</jackson.version>
<jackson.databind.version>2.8.11.1</jackson.databind.version>
<javax.mail.version>1.5.6</javax.mail.version>
<jboss.logging.version>3.3.1.Final</jboss.logging.version>
<jboss.logging.tools.version>2.1.0.Final</jboss.logging.tools.version>
<jboss.logging.tools.wf8.version>1.2.0.Final</jboss.logging.tools.wf8.version>
- <jboss-jaxrs-api_2.0_spec>1.0.0.Final</jboss-jaxrs-api_2.0_spec>
+ <jboss-jaxrs-api_2.1_spec>1.0.0.Final</jboss-jaxrs-api_2.1_spec>
<jboss-transaction-api_1.2_spec>1.0.1.Final</jboss-transaction-api_1.2_spec>
<jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>1.0.4.Final</jboss.spec.javax.xml.bind.jboss-jaxb-api_2.2_spec.version>
<log4j.version>1.2.17</log4j.version>
- <resteasy.version>3.0.26.Final</resteasy.version>
+ <resteasy.version>3.5.1.Final</resteasy.version>
<owasp.html.sanitizer.version>20180219.1</owasp.html.sanitizer.version>
<slf4j.version>1.7.22</slf4j.version>
<sun.istack.version>2.21</sun.istack.version>
<sun.jaxb.version>2.2.11</sun.jaxb.version>
<sun.xsom.version>20140925</sun.xsom.version>
- <undertow.version>1.4.18.Final</undertow.version>
- <elytron.version>1.1.10.Final</elytron.version>
+ <undertow.version>2.0.9.Final</undertow.version>
+ <elytron.version>1.3.3.Final</elytron.version>
<elytron.undertow-server.version>1.0.1.Final</elytron.undertow-server.version>
<woodstox.version>5.0.3</woodstox.version>
<xmlsec.version>2.0.9</xmlsec.version>
<glassfish.json.version>1.0.4</glassfish.json.version>
- <wildfly.common.version>1.2.0.Final</wildfly.common.version>
+ <wildfly.common.version>1.4.0.Final</wildfly.common.version>
<!-- Authorization Drools Policy Provider -->
<version.org.drools>6.5.0.Final</version.org.drools>
@@ -261,8 +263,8 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
- <version>${jboss-jaxrs-api_2.0_spec}</version>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
+ <version>${jboss-jaxrs-api_2.1_spec}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
@@ -711,8 +713,18 @@
<dependency>
<groupId>org.jboss.aesh</groupId>
<artifactId>aesh</artifactId>
+ <version>${jboss.aesh.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.aesh</groupId>
+ <artifactId>aesh</artifactId>
<version>${aesh.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.aesh</groupId>
+ <artifactId>aesh-readline</artifactId>
+ <version>${aesh.readline.version}</version>
+ </dependency>
<!-- keycloak -->
<dependency>
services/pom.xml 2(+1 -1)
diff --git a/services/pom.xml b/services/pom.xml
index b26cb45..a5a6d8b 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -126,7 +126,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationSessionManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationSessionManager.java
index 6963153..6f6f5f0 100644
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationSessionManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationSessionManager.java
@@ -71,17 +71,18 @@ public class AuthenticationSessionManager {
return rootAuthSession;
}
+
public RootAuthenticationSessionModel getCurrentRootAuthenticationSession(RealmModel realm) {
- List<String> authSessionIds = getAuthSessionCookieIds(realm);
+ List<String> authSessionCookies = getAuthSessionCookies(realm);
- return authSessionIds.stream().map(id -> {
- SimpleEntry<String, String> entry = decodeAuthSessionId(id);
- String sessionId = entry.getKey();
+ return authSessionCookies.stream().map(oldEncodedId -> {
+ AuthSessionId authSessionId = decodeAuthSessionId(oldEncodedId);
+ String sessionId = authSessionId.getDecodedId();
RootAuthenticationSessionModel rootAuthSession = session.authenticationSessions().getRootAuthenticationSession(realm, sessionId);
if (rootAuthSession != null) {
- reencodeAuthSessionCookie(sessionId, entry.getValue(), realm);
+ reencodeAuthSessionCookie(oldEncodedId, authSessionId, realm);
return rootAuthSession;
}
@@ -89,17 +90,18 @@ public class AuthenticationSessionManager {
}).filter(authSession -> Objects.nonNull(authSession)).findFirst().orElse(null);
}
+
public UserSessionModel getUserSessionFromAuthCookie(RealmModel realm) {
- List<String> authSessionIds = getAuthSessionCookieIds(realm);
+ List<String> authSessionCookies = getAuthSessionCookies(realm);
- return authSessionIds.stream().map(id -> {
- SimpleEntry<String, String> entry = decodeAuthSessionId(id);
- String sessionId = entry.getKey();
+ return authSessionCookies.stream().map(oldEncodedId -> {
+ AuthSessionId authSessionId = decodeAuthSessionId(oldEncodedId);
+ String sessionId = authSessionId.getDecodedId();
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
if (userSession != null) {
- reencodeAuthSessionCookie(sessionId, entry.getValue(), realm);
+ reencodeAuthSessionCookie(oldEncodedId, authSessionId, realm);
return userSession;
}
@@ -114,16 +116,16 @@ public class AuthenticationSessionManager {
* @return
*/
public AuthenticationSessionModel getCurrentAuthenticationSession(RealmModel realm, ClientModel client, String tabId) {
- List<String> authSessionIds = getAuthSessionCookieIds(realm);
+ List<String> authSessionCookies = getAuthSessionCookies(realm);
- return authSessionIds.stream().map(id -> {
- SimpleEntry<String, String> entry = decodeAuthSessionId(id);
- String sessionId = entry.getKey();
+ return authSessionCookies.stream().map(oldEncodedId -> {
+ AuthSessionId authSessionId = decodeAuthSessionId(oldEncodedId);
+ String sessionId = authSessionId.getDecodedId();
AuthenticationSessionModel authSession = getAuthenticationSessionByIdAndClient(realm, sessionId, client, tabId);
if (authSession != null) {
- reencodeAuthSessionCookie(sessionId, entry.getValue(), realm);
+ reencodeAuthSessionCookie(oldEncodedId, authSessionId, realm);
return authSession;
}
@@ -132,6 +134,10 @@ public class AuthenticationSessionManager {
}
+ /**
+ * @param authSessionId decoded authSessionId (without route info attached)
+ * @param realm
+ */
public void setAuthSessionCookie(String authSessionId, RealmModel realm) {
UriInfo uriInfo = session.getContext().getUri();
String cookiePath = AuthenticationManager.getRealmCookiePath(realm, uriInfo);
@@ -146,23 +152,36 @@ public class AuthenticationSessionManager {
log.debugf("Set AUTH_SESSION_ID cookie with value %s", encodedAuthSessionId);
}
- public SimpleEntry<String, String> decodeAuthSessionId(String authSessionId) {
- log.debugf("Found AUTH_SESSION_ID cookie with value %s", authSessionId);
+
+ /**
+ *
+ * @param encodedAuthSessionId encoded ID with attached route in cluster environment (EG. "5e161e00-d426-4ea6-98e9-52eb9844e2d7.node1" )
+ * @return object with decoded and actually encoded authSessionId
+ */
+ AuthSessionId decodeAuthSessionId(String encodedAuthSessionId) {
+ log.debugf("Found AUTH_SESSION_ID cookie with value %s", encodedAuthSessionId);
StickySessionEncoderProvider encoder = session.getProvider(StickySessionEncoderProvider.class);
- String decodedAuthSessionId = encoder.decodeSessionId(authSessionId);
+ String decodedAuthSessionId = encoder.decodeSessionId(encodedAuthSessionId);
String reencoded = encoder.encodeSessionId(decodedAuthSessionId);
- return new SimpleEntry(decodedAuthSessionId, reencoded);
+ return new AuthSessionId(decodedAuthSessionId, reencoded);
}
- public void reencodeAuthSessionCookie(String decodedAuthSessionId, String reencodedAuthSessionId, RealmModel realm) {
- if (!decodedAuthSessionId.equals(reencodedAuthSessionId)) {
- log.debugf("Route changed. Will update authentication session cookie");
- setAuthSessionCookie(decodedAuthSessionId, realm);
+
+ void reencodeAuthSessionCookie(String oldEncodedAuthSessionId, AuthSessionId newAuthSessionId, RealmModel realm) {
+ if (!oldEncodedAuthSessionId.equals(newAuthSessionId.getEncodedId())) {
+ log.debugf("Route changed. Will update authentication session cookie. Old: '%s', New: '%s'", oldEncodedAuthSessionId,
+ newAuthSessionId.getEncodedId());
+ setAuthSessionCookie(newAuthSessionId.getDecodedId(), realm);
}
}
- public List<String> getAuthSessionCookieIds(RealmModel realm) {
+
+ /**
+ * @param realm
+ * @return list of the values of AUTH_SESSION_ID cookies. It is assumed that values could be encoded with route added (EG. "5e161e00-d426-4ea6-98e9-52eb9844e2d7.node1" )
+ */
+ List<String> getAuthSessionCookies(RealmModel realm) {
Set<String> cookiesVal = CookieHelper.getCookieValue(AUTH_SESSION_ID);
if (cookiesVal.size() > 1) {
diff --git a/services/src/main/java/org/keycloak/services/managers/UserSessionCrossDCManager.java b/services/src/main/java/org/keycloak/services/managers/UserSessionCrossDCManager.java
index bd56400..e8736b3 100644
--- a/services/src/main/java/org/keycloak/services/managers/UserSessionCrossDCManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/UserSessionCrossDCManager.java
@@ -62,11 +62,11 @@ public class UserSessionCrossDCManager {
// Just check if userSession also exists on remoteCache. It can happen that logout happened on 2nd DC and userSession is already removed on remoteCache and this DC wasn't yet notified
public UserSessionModel getUserSessionIfExistsRemotely(AuthenticationSessionManager asm, RealmModel realm) {
- List<String> sessionIds = asm.getAuthSessionCookieIds(realm);
+ List<String> sessionCookies = asm.getAuthSessionCookies(realm);
- return sessionIds.stream().map(id -> {
- SimpleEntry<String, String> entry = asm.decodeAuthSessionId(id);
- String sessionId = entry.getKey();
+ return sessionCookies.stream().map(oldEncodedId -> {
+ AuthSessionId authSessionId = asm.decodeAuthSessionId(oldEncodedId);
+ String sessionId = authSessionId.getDecodedId();
// This will remove userSession "locally" if it doesn't exists on remoteCache
kcSession.sessions().getUserSessionWithPredicate(realm, sessionId, false, (UserSessionModel userSession2) -> userSession2 == null);
@@ -74,7 +74,7 @@ public class UserSessionCrossDCManager {
UserSessionModel userSession = kcSession.sessions().getUserSession(realm, sessionId);
if (userSession != null) {
- asm.reencodeAuthSessionCookie(sessionId, entry.getValue(), realm);
+ asm.reencodeAuthSessionCookie(oldEncodedId, authSessionId, realm);
return userSession;
}
diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md
index 347ff20..81eb5cb 100644
--- a/testsuite/integration-arquillian/HOW-TO-RUN.md
+++ b/testsuite/integration-arquillian/HOW-TO-RUN.md
@@ -287,6 +287,17 @@ This will start latest Keycloak and import the realm JSON file, which was previo
-Dmigrated.auth.server.version=1.9.8.Final
+## Server configuration migration test
+This will compare if Wildfly configuration files (standalone.xml, standalone-ha.xml, domain.xml)
+are correctly migrated from previous version
+
+ mvn -f testsuite/integration-arquillian/tests/other/server-config-migration/pom.xml \
+ clean install \
+ -Dmigrated.version=1.9.8.Final-redhat-1
+
+For the available versions, take a look at the directory [tests/other/server-config-migration/src/test/resources/standalone](tests/other/server-config-migration/src/test/resources/standalone)
+
+
## Admin Console UI tests
The UI tests are real-life, UI focused integration tests. Hence they do not support the default HtmlUnit browser. Only the following real-life browsers are supported: Mozilla Firefox, Google Chrome and Internet Explorer. For details on how to run the tests with these browsers, please refer to [Different Browsers](#different-browsers) chapter.
diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/common/io.xsl b/testsuite/integration-arquillian/servers/app-server/jboss/common/io.xsl
index 03d518a..cceb8e2 100644
--- a/testsuite/integration-arquillian/servers/app-server/jboss/common/io.xsl
+++ b/testsuite/integration-arquillian/servers/app-server/jboss/common/io.xsl
@@ -25,7 +25,7 @@
<xsl:param name="worker.io-threads" select="'16'"/>
<xsl:param name="worker.task-max-threads" select="'128'"/>
-
+
<!--set worker threads-->
<xsl:template match="//*[local-name()='worker' and @name='default']">
<worker name="default" io-threads="{$worker.io-threads}" task-max-threads="{$worker.task-max-threads}" />
diff --git a/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml b/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml
index 40762db..d7cadd8 100644
--- a/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml
+++ b/testsuite/integration-arquillian/servers/app-server/tomcat/pom.xml
@@ -112,7 +112,7 @@
</artifactItem>
<artifactItem>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</artifactItem>
<artifactItem>
<groupId>org.jboss.resteasy</groupId>
diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/common/ispn-cache-owners.xsl b/testsuite/integration-arquillian/servers/auth-server/jboss/common/ispn-cache-owners.xsl
index 46c6f7c..bac1141 100644
--- a/testsuite/integration-arquillian/servers/auth-server/jboss/common/ispn-cache-owners.xsl
+++ b/testsuite/integration-arquillian/servers/auth-server/jboss/common/ispn-cache-owners.xsl
@@ -1,6 +1,6 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
- xmlns:i="urn:jboss:domain:infinispan:4.0"
+ xmlns:i="urn:jboss:domain:infinispan:6.0"
version="2.0"
exclude-result-prefixes="xalan i">
@@ -23,11 +23,21 @@
<xsl:value-of select="$sessionCacheOwners"/>
</xsl:attribute>
</xsl:template>
+ <xsl:template match="//i:cache-container/i:distributed-cache[@name='clientSessions']/@owners">
+ <xsl:attribute name="owners">
+ <xsl:value-of select="$sessionCacheOwners"/>
+ </xsl:attribute>
+ </xsl:template>
<xsl:template match="//i:cache-container/i:distributed-cache[@name='offlineSessions']/@owners">
<xsl:attribute name="owners">
<xsl:value-of select="$offlineSessionCacheOwners"/>
</xsl:attribute>
</xsl:template>
+ <xsl:template match="//i:cache-container/i:distributed-cache[@name='offlineClientSessions']/@owners">
+ <xsl:attribute name="owners">
+ <xsl:value-of select="$offlineSessionCacheOwners"/>
+ </xsl:attribute>
+ </xsl:template>
<xsl:template match="//i:cache-container/i:distributed-cache[@name='loginFailures']/@owners">
<xsl:attribute name="owners">
<xsl:value-of select="$loginFailureCacheOwners"/>
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/org/keycloak/testsuite/integration-arquillian-testsuite-providers/main/module.xml b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/org/keycloak/testsuite/integration-arquillian-testsuite-providers/main/module.xml
index 9d818c3..abf6fae 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/org/keycloak/testsuite/integration-arquillian-testsuite-providers/main/module.xml
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/org/keycloak/testsuite/integration-arquillian-testsuite-providers/main/module.xml
@@ -35,6 +35,7 @@
<module name="org.keycloak.keycloak-ldap-federation"/>
<module name="org.infinispan"/>
<module name="org.infinispan.client.hotrod"/>
+ <module name="org.jgroups"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
<module name="javax.persistence.api"/>
diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/common/add-keycloak-caches.xsl b/testsuite/integration-arquillian/servers/cache-server/jboss/common/add-keycloak-caches.xsl
index 7b48a96..0809003 100644
--- a/testsuite/integration-arquillian/servers/cache-server/jboss/common/add-keycloak-caches.xsl
+++ b/testsuite/integration-arquillian/servers/cache-server/jboss/common/add-keycloak-caches.xsl
@@ -25,6 +25,7 @@
<xsl:param name="local.site" />
<xsl:param name="remote.site" />
+ <xsl:param name="transactions.enabled" />
<xsl:variable name="nsCacheServer" select="'urn:infinispan:server:core:'"/>
<xsl:variable name="nsJGroups" select="'urn:infinispan:server:jgroups:'"/>
@@ -36,7 +37,9 @@
<xsl:apply-templates select="@* | node()" />
<replicated-cache-configuration name="sessions-cfg" mode="SYNC" start="EAGER" batching="false">
- <transaction mode="NON_DURABLE_XA" locking="PESSIMISTIC"/>
+ <xsl:if test="$transactions.enabled='true'">
+ <transaction mode="NON_DURABLE_XA" locking="PESSIMISTIC"/>
+ </xsl:if>
<locking acquire-timeout="0" />
<backups>
<backup site="{$remote.site}" failure-policy="FAIL" strategy="SYNC" enabled="true">
diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml b/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml
index 4eebe36..57aa4e3 100644
--- a/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml
+++ b/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml
@@ -35,6 +35,7 @@
<cache.server.home>${containers.home}/${cache.server.container}</cache.server.home>
<cache.server.jboss.cache-authorization-disabled>true</cache.server.jboss.cache-authorization-disabled>
+ <cache.server.jboss.jdg-transactions-enabled>false</cache.server.jboss.jdg-transactions-enabled>
<cache.server.jboss.groupId>org.infinispan.server</cache.server.jboss.groupId>
<cache.server.jboss.artifactId>infinispan-server</cache.server.jboss.artifactId>
<cache.server.jboss.version>${infinispan.version}</cache.server.jboss.version>
diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml b/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml
index c498e99..88f81d2 100644
--- a/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml
+++ b/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml
@@ -34,7 +34,8 @@
<cache.server.container>cache-server-${cache.server}</cache.server.container>
<cache.server.home>${containers.home}/${cache.server.container}</cache.server.home>
- <cache.server.jboss.cache-authorization-disabled>false</cache.server.jboss.cache-authorization-disabled>
+ <cache.server.jboss.cache-authorization-disabled>true</cache.server.jboss.cache-authorization-disabled>
+ <cache.server.jboss.jdg-transactions-enabled>true</cache.server.jboss.jdg-transactions-enabled>
<cache.server.jboss.groupId>org.infinispan.server</cache.server.jboss.groupId>
<cache.server.jboss.artifactId>infinispan-server</cache.server.jboss.artifactId>
<cache.server.jboss.version>${jdg.version}</cache.server.jboss.version>
diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml
index 7540bb0..f3474d8 100644
--- a/testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml
+++ b/testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml
@@ -34,6 +34,7 @@
<assembly.xml>${project.parent.basedir}/assembly.xml</assembly.xml>
<cache.server.jboss.home>${containers.home}/${cache.server.jboss.unpacked.folder.name}</cache.server.jboss.home>
<cache.server.jboss.cache-authorization-disabled>true</cache.server.jboss.cache-authorization-disabled>
+ <cache.server.jboss.jdg-transactions-enabled>true</cache.server.jboss.jdg-transactions-enabled>
<security.xslt>security.xsl</security.xslt>
</properties>
@@ -126,6 +127,10 @@
<name>remote.site</name>
<value>dc-1</value>
</parameter>
+ <parameter>
+ <name>transactions.enabled</name>
+ <value>${cache.server.jboss.jdg-transactions-enabled}</value>
+ </parameter>
</parameters>
<outputDir>${cache.server.jboss.home}/standalone/configuration</outputDir>
<fileMappers>
@@ -152,6 +157,10 @@
<name>remote.site</name>
<value>dc-0</value>
</parameter>
+ <parameter>
+ <name>transactions.enabled</name>
+ <value>${cache.server.jboss.jdg-transactions-enabled}</value>
+ </parameter>
</parameters>
<outputDir>${cache.server.jboss.home}/standalone/configuration</outputDir>
<fileMappers>
diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml
index 96588c8..fb63271 100644
--- a/testsuite/integration-arquillian/servers/pom.xml
+++ b/testsuite/integration-arquillian/servers/pom.xml
@@ -47,8 +47,8 @@
<fuse62.version>6.2.1.redhat-084</fuse62.version>
<!-- cache server versions -->
- <!--<infinispan.version>9.0.1.Final</infinispan.version>--> <!-- Use same version like our infinispan version for now -->
- <jdg.version>8.4.0.Final-redhat-2</jdg.version><!-- JDG 7.1.0 -->
+ <!--<infinispan.version>8.2.8.Final</infinispan.version>--><!-- Use same infinspan-server version as our version -->
+ <jdg.version>8.5.0.Final-redhat-9</jdg.version><!-- JDG 7.2.0 -->
<jboss.default.worker.io-threads>16</jboss.default.worker.io-threads>
<jboss.default.worker.task-max-threads>128</jboss.default.worker.task-max-threads>
diff --git a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml
index 47e31d2..bb0119f 100755
--- a/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml
+++ b/testsuite/integration-arquillian/test-apps/photoz/photoz-restful-api/pom.xml
@@ -19,7 +19,7 @@
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/testsuite/integration-arquillian/test-apps/servlets/pom.xml b/testsuite/integration-arquillian/test-apps/servlets/pom.xml
index ec91b9c..20cede5 100644
--- a/testsuite/integration-arquillian/test-apps/servlets/pom.xml
+++ b/testsuite/integration-arquillian/test-apps/servlets/pom.xml
@@ -32,7 +32,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AuthenticationSessionClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AuthenticationSessionClusterTest.java
index 684b13d..d54ca85 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AuthenticationSessionClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AuthenticationSessionClusterTest.java
@@ -146,7 +146,7 @@ public class AuthenticationSessionClusterTest extends AbstractClusterTest {
// Check that route owner is always node1
getTestingClientFor(backendNode(0)).server().run(session -> {
Cache authSessionCache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME);
- String keyOwner = InfinispanUtil.getKeyPrimaryOwnerAddress(authSessionCache, authSessionCookie);
+ String keyOwner = InfinispanUtil.getTopologyInfo(session).getRouteName(authSessionCache, authSessionCookie);
Assert.assertEquals("node1", keyOwner);
});
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ActionTokenCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ActionTokenCrossDCTest.java
index 5a86665..d88785b 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ActionTokenCrossDCTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ActionTokenCrossDCTest.java
@@ -92,7 +92,7 @@ public class ActionTokenCrossDCTest extends AbstractAdminCrossDCTest {
cacheDc0Node1Statistics.waitToBecomeAvailable(10, TimeUnit.SECONDS);
- Comparable originalNumberOfEntries = cacheDc0Node0Statistics.getSingleStatistics(Constants.STAT_CACHE_NUMBER_OF_ENTRIES);
+ Comparable originalNumberOfEntries = cacheDc0Node0Statistics.getSingleStatistics(Constants.STAT_CACHE_NUMBER_OF_ENTRIES_IN_MEMORY);
UserRepresentation userRep = new UserRepresentation();
userRep.setEnabled(true);
@@ -112,7 +112,7 @@ public class ActionTokenCrossDCTest extends AbstractAdminCrossDCTest {
String link = MailUtils.getPasswordResetEmailLink(message);
- assertSingleStatistics(cacheDc0Node0Statistics, Constants.STAT_CACHE_NUMBER_OF_ENTRIES,
+ assertSingleStatistics(cacheDc0Node0Statistics, Constants.STAT_CACHE_NUMBER_OF_ENTRIES_IN_MEMORY,
() -> driver.navigate().to(link),
Matchers::is
);
@@ -141,13 +141,15 @@ public class ActionTokenCrossDCTest extends AbstractAdminCrossDCTest {
assertThat(PageUtils.getPageTitle(driver), containsString("Your account has been updated."));
// Verify that there was an action token added in the node which was targetted by the link
- assertThat(cacheDc0Node0Statistics.getSingleStatistics(Constants.STAT_CACHE_NUMBER_OF_ENTRIES), greaterThan(originalNumberOfEntries));
+ assertThat(cacheDc0Node0Statistics.getSingleStatistics(Constants.STAT_CACHE_NUMBER_OF_ENTRIES_IN_MEMORY), greaterThan(originalNumberOfEntries));
disableDcOnLoadBalancer(DC.FIRST);
enableDcOnLoadBalancer(DC.SECOND);
// Make sure that after going to the link, the invalidated action token has been retrieved from Infinispan server cluster in the other DC
- assertSingleStatistics(cacheDc1Node0Statistics, Constants.STAT_CACHE_NUMBER_OF_ENTRIES,
+ // NOTE: Using STAT_CACHE_NUMBER_OF_ENTRIES_IN_MEMORY as it doesn't contain the items from cacheLoader (remoteCache) until they are really loaded into the cache memory. That's the
+ // statistic, which is actually increased on dc1-node0 once the used actionToken is loaded to the cache (memory) from remoteCache
+ assertSingleStatistics(cacheDc1Node0Statistics, Constants.STAT_CACHE_NUMBER_OF_ENTRIES_IN_MEMORY,
() -> driver.navigate().to(link),
Matchers::greaterThan
);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java
index aea8b2a..afcfe20 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java
@@ -168,6 +168,9 @@ public class BruteForceCrossDCTest extends AbstractAdminCrossDCTest {
enableDcOnLoadBalancer(DC.FIRST);
enableDcOnLoadBalancer(DC.SECOND);
+// log.infof("Sleeping");
+// Thread.sleep(3600000);
+
// Clear all
adminClient.realms().realm(REALM_NAME).attackDetection().clearAllBruteForce();
assertStatistics("After brute force cleared", 0, 0, 0);
@@ -222,6 +225,8 @@ public class BruteForceCrossDCTest extends AbstractAdminCrossDCTest {
@Test
public void testBruteForceConcurrentUpdate() throws Exception {
+ //Thread.sleep(120000);
+
// Enable 1st node on each DC only
enableDcOnLoadBalancer(DC.FIRST);
enableDcOnLoadBalancer(DC.SECOND);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java
index 33deb9b..ed87fcf 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/ConcurrentLoginCrossDCTest.java
@@ -20,12 +20,10 @@ package org.keycloak.testsuite.crossdc;
import java.util.ArrayList;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.RealmResource;
-import java.util.List;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.admin.concurrency.ConcurrentLoginTest;
-import org.keycloak.testsuite.arquillian.ContainerInfo;
import org.keycloak.testsuite.arquillian.LoadBalancerController;
import org.keycloak.testsuite.arquillian.annotation.LoadBalancer;
import java.util.Arrays;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java
index 643bb4b..95cdd49 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/SessionExpirationCrossDCTest.java
@@ -192,7 +192,8 @@ public class SessionExpirationCrossDCTest extends AbstractAdminCrossDCTest {
int clientSessions2 = getTestingClientForStartedNodeInDc(1).testing().cache(clientSessionsCacheName).size();
int remoteSessions1 = (Integer) cacheDc1Statistics.getSingleStatistics(InfinispanStatistics.Constants.STAT_CACHE_NUMBER_OF_ENTRIES);
int remoteSessions2 = (Integer) cacheDc2Statistics.getSingleStatistics(InfinispanStatistics.Constants.STAT_CACHE_NUMBER_OF_ENTRIES);
- long messagesCount = (Long) channelStatisticsCrossDc.getSingleStatistics(InfinispanStatistics.Constants.STAT_CHANNEL_SENT_MESSAGES);
+ // Needs to use "received_messages" on Infinispan 9.2.4.Final. Stats for "sent_messages" is always null
+ long messagesCount = (Long) channelStatisticsCrossDc.getSingleStatistics(InfinispanStatistics.Constants.STAT_CHANNEL_RECEIVED_MESSAGES);
log.infof(messagePrefix + ": sessions1: %d, sessions2: %d, remoteSessions1: %d, remoteSessions2: %d, sentMessages: %d", sessions1, sessions2, remoteSessions1, remoteSessions2, messagesCount);
Assert.assertEquals(sessions1, sessions1Expected);
@@ -432,6 +433,15 @@ public class SessionExpirationCrossDCTest extends AbstractAdminCrossDCTest {
// Kill node2 now. Around 10 sessions (half of SESSIONS_COUNT) will be lost on Keycloak side. But not on infinispan side
CrossDCTestEnricher.stopAuthServerBackendNode(DC.FIRST, 1);
+ // Assert it's still possible to refresh tokens. UserSessions, which were cleared from the Keycloak node, should be downloaded from remoteStore
+ int i1 = 0;
+ for (OAuthClient.AccessTokenResponse response : responses) {
+ i1++;
+ OAuthClient.AccessTokenResponse refreshTokenResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
+ Assert.assertNotNull("Failed in iteration " + i1, refreshTokenResponse.getRefreshToken());
+ Assert.assertNull("Failed in iteration " + i1, refreshTokenResponse.getError());
+ }
+
channelStatisticsCrossDc.reset();
// Increase offset a bit to ensure logout happens later then token issued time
@@ -662,7 +672,7 @@ public class SessionExpirationCrossDCTest extends AbstractAdminCrossDCTest {
Retry.execute(() -> {
int authSessions1 = getTestingClientForStartedNodeInDc(0).testing().cache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME).size();
int authSessions2 = getTestingClientForStartedNodeInDc(1).testing().cache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME).size();
- long messagesCount = (Long) channelStatisticsCrossDc.getSingleStatistics(InfinispanStatistics.Constants.STAT_CHANNEL_SENT_MESSAGES);
+ long messagesCount = (Long) channelStatisticsCrossDc.getSingleStatistics(InfinispanStatistics.Constants.STAT_CHANNEL_RECEIVED_MESSAGES);
log.infof(messagePrefix + ": authSessions1: %d, authSessions2: %d, sentMessages: %d", authSessions1, authSessions2, messagesCount);
int diff1 = authSessions1 - authSessions01;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/error/UncaughtErrorPageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/error/UncaughtErrorPageTest.java
index 4bdb9ec..2414599 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/error/UncaughtErrorPageTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/error/UncaughtErrorPageTest.java
@@ -1,16 +1,22 @@
package org.keycloak.testsuite.error;
import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Assert;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
+import org.keycloak.common.util.StreamUtil;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.pages.ErrorPage;
import javax.ws.rs.core.Response;
+
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URI;
+import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
@@ -43,10 +49,14 @@ public class UncaughtErrorPageTest extends AbstractKeycloakTest {
}
@Test
- public void uncaughtErrorJson() {
+ public void uncaughtErrorJson() throws IOException {
Response response = testingClient.testing().uncaughtError();
- assertNull(response.getEntity());
assertEquals(500, response.getStatus());
+
+ InputStream is = (InputStream) response.getEntity();
+ String responseString = StreamUtil.readString(is, Charset.forName("UTF-8"));
+
+ Assert.assertTrue(responseString.contains("An internal server error has occurred"));
}
@Test
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
index bc06479..e1e7dca 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
@@ -126,7 +126,7 @@
"sessionsOwners": "${keycloak.connectionsInfinispan.sessionsOwners:1}",
"l1Lifespan": "${keycloak.connectionsInfinispan.l1Lifespan:600000}",
"remoteStoreEnabled": "${keycloak.connectionsInfinispan.remoteStoreEnabled:false}",
- "remoteStoreServer": "${keycloak.connectionsInfinispan.remoteStoreServer:localhost}",
+ "remoteStoreHost": "${keycloak.connectionsInfinispan.remoteStoreServer:localhost}",
"remoteStorePort": "${keycloak.connectionsInfinispan.remoteStorePort:11222}"
}
},
diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/README.md b/testsuite/integration-arquillian/tests/other/server-config-migration/README.md
index 83b832b..921517c 100644
--- a/testsuite/integration-arquillian/tests/other/server-config-migration/README.md
+++ b/testsuite/integration-arquillian/tests/other/server-config-migration/README.md
@@ -27,7 +27,7 @@ Migration scripts are applied using **offline mode**. Temporary data are removed
`maven-exec-plugin` is used to read migrated configs and saves the output to `${project.build.directory}/migrated-${config.name}.txt`
### `default-test`
-`org.keycloak.test.config.migrationConfigMigrationTest` is executed. It compares generated outputs from ${project.build.directory}
+`org.keycloak.test.config.migration.ConfigMigrationTest` is executed. It compares generated outputs from ${project.build.directory}
If config outputs don't equal to each other, **by default** the test will compare outputs more deeply to get more readable output. It fails on first found difference.
diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-3.4.3.Final-redhat-2.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-3.4.3.Final-redhat-2.xml
new file mode 100644
index 0000000..3855f81
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/domain-3.4.3.Final-redhat-2.xml
@@ -0,0 +1,1123 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<domain xmlns="urn:jboss:domain:5.0">
+ <extensions>
+ <extension module="org.jboss.as.clustering.infinispan"/>
+ <extension module="org.jboss.as.clustering.jgroups"/>
+ <extension module="org.jboss.as.connector"/>
+ <extension module="org.jboss.as.ee"/>
+ <extension module="org.jboss.as.ejb3"/>
+ <extension module="org.jboss.as.jaxrs"/>
+ <extension module="org.jboss.as.jmx"/>
+ <extension module="org.jboss.as.jpa"/>
+ <extension module="org.jboss.as.logging"/>
+ <extension module="org.jboss.as.mail"/>
+ <extension module="org.jboss.as.modcluster"/>
+ <extension module="org.jboss.as.naming"/>
+ <extension module="org.jboss.as.remoting"/>
+ <extension module="org.jboss.as.security"/>
+ <extension module="org.jboss.as.transactions"/>
+ <extension module="org.keycloak.keycloak-server-subsystem"/>
+ <extension module="org.wildfly.extension.bean-validation"/>
+ <extension module="org.wildfly.extension.core-management"/>
+ <extension module="org.wildfly.extension.elytron"/>
+ <extension module="org.wildfly.extension.io"/>
+ <extension module="org.wildfly.extension.request-controller"/>
+ <extension module="org.wildfly.extension.security.manager"/>
+ <extension module="org.wildfly.extension.undertow"/>
+ </extensions>
+ <system-properties>
+ <!-- IPv4 is not required, but setting this helps avoid unintended use of IPv6 -->
+ <property name="java.net.preferIPv4Stack" value="true"/>
+ </system-properties>
+ <management>
+ <access-control provider="simple">
+ <role-mapping>
+ <role name="SuperUser">
+ <include>
+ <user name="$local"/>
+ </include>
+ </role>
+ </role-mapping>
+ </access-control>
+ </management>
+ <profiles>
+ <!-- Non clustered authentication server profile -->
+ <profile name="auth-server-standalone">
+ <subsystem xmlns="urn:jboss:domain:logging:3.0">
+ <console-handler name="CONSOLE">
+ <level name="INFO"/>
+ <formatter>
+ <named-formatter name="COLOR-PATTERN"/>
+ </formatter>
+ </console-handler>
+ <periodic-rotating-file-handler name="FILE" autoflush="true">
+ <formatter>
+ <named-formatter name="PATTERN"/>
+ </formatter>
+ <file relative-to="jboss.server.log.dir" path="server.log"/>
+ <suffix value=".yyyy-MM-dd"/>
+ <append value="true"/>
+ </periodic-rotating-file-handler>
+ <logger category="com.arjuna">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.jboss.as.config">
+ <level name="DEBUG"/>
+ </logger>
+ <logger category="sun.rmi">
+ <level name="WARN"/>
+ </logger>
+ <root-logger>
+ <level name="INFO"/>
+ <handlers>
+ <handler name="CONSOLE"/>
+ <handler name="FILE"/>
+ </handlers>
+ </root-logger>
+ <formatter name="PATTERN">
+ <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ <formatter name="COLOR-PATTERN">
+ <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:datasources:5.0">
+ <datasources>
+ <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <drivers>
+ <driver name="h2" module="com.h2database.h2">
+ <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+ </driver>
+ </drivers>
+ </datasources>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ee:4.0">
+ <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+ <concurrent>
+ <context-services>
+ <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
+ </context-services>
+ <managed-thread-factories>
+ <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
+ </managed-thread-factories>
+ <managed-executor-services>
+ <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
+ </managed-executor-services>
+ <managed-scheduled-executor-services>
+ <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
+ </managed-scheduled-executor-services>
+ </concurrent>
+ <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
+ <session-bean>
+ <stateless>
+ <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+ </stateless>
+ <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
+ <singleton default-access-timeout="5000"/>
+ </session-bean>
+ <pools>
+ <bean-instance-pools>
+ <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ </bean-instance-pools>
+ </pools>
+ <caches>
+ <cache name="simple"/>
+ <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
+ </caches>
+ <passivation-stores>
+ <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
+ </passivation-stores>
+ <async thread-pool-name="default"/>
+ <timer-service thread-pool-name="default" default-data-store="default-file-store">
+ <data-stores>
+ <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+ </data-stores>
+ </timer-service>
+ <remote connector-ref="http-remoting-connector" thread-pool-name="default">
+ <channel-creation-options>
+ <option name="READ_TIMEOUT" value="${prop.remoting-connector.read.timeout:20}" type="xnio"/>
+ <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
+ </channel-creation-options>
+ </remote>
+ <thread-pools>
+ <thread-pool name="default">
+ <max-threads count="10"/>
+ <keepalive-time time="100" unit="milliseconds"/>
+ </thread-pool>
+ </thread-pools>
+ <default-security-domain value="other"/>
+ <default-missing-method-permissions-deny-access value="true"/>
+ <log-system-exceptions value="true"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:io:2.0">
+ <worker name="default"/>
+ <buffer-pool name="default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:infinispan:4.0">
+ <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <local-cache name="realms">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="users">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="sessions"/>
+ <local-cache name="authenticationSessions"/>
+ <local-cache name="offlineSessions"/>
+ <local-cache name="clientSessions"/>
+ <local-cache name="offlineClientSessions"/>
+ <local-cache name="loginFailures"/>
+ <local-cache name="work"/>
+ <local-cache name="authorization">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="keys">
+ <eviction max-entries="1000" strategy="LRU"/>
+ <expiration max-idle="3600000"/>
+ </local-cache>
+ <local-cache name="actionTokens">
+ <eviction max-entries="-1" strategy="NONE"/>
+ <expiration max-idle="-1" interval="300000"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
+ <local-cache name="default">
+ <transaction mode="BATCH"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
+ <local-cache name="passivation">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store passivation="true" purge="false"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="ejb" aliases="sfsb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan">
+ <local-cache name="passivation">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store passivation="true" purge="false"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="hibernate" module="org.hibernate.infinispan">
+ <local-cache name="entity">
+ <transaction mode="NON_XA"/>
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <local-cache name="local-query">
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <local-cache name="timestamps"/>
+ </cache-container>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jca:5.0">
+ <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+ <bean-validation enabled="true"/>
+ <default-workmanager>
+ <short-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </short-running-threads>
+ <long-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </long-running-threads>
+ </default-workmanager>
+ <cached-connection-manager/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+ <expose-resolved-model/>
+ <expose-expression-model/>
+ <!--<remoting-connector use-management-endpoint="false"/>-->
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+ <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:mail:3.0">
+ <mail-session name="default" jndi-name="java:jboss/mail/Default">
+ <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+ </mail-session>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:naming:2.0">
+ <remote-naming/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:remoting:4.0">
+ <endpoint/>
+ <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
+ <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+ <providers>
+ <aggregate-providers name="combined-providers">
+ <providers name="elytron"/>
+ <providers name="openssl"/>
+ </aggregate-providers>
+ <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+ <provider-loader name="openssl" module="org.wildfly.openssl"/>
+ </providers>
+ <audit-logging>
+ <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
+ </audit-logging>
+ <security-domains>
+ <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
+ <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
+ </security-domain>
+ </security-domains>
+ <security-realms>
+ <identity-realm name="local" identity="$local"/>
+ <properties-realm name="ApplicationRealm">
+ <users-properties path="application-users.properties" relative-to="jboss.domain.config.dir" digest-realm-name="ApplicationRealm"/>
+ <groups-properties path="application-roles.properties" relative-to="jboss.domain.config.dir"/>
+ </properties-realm>
+ </security-realms>
+ <mappers>
+ <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+ <permission-mapping>
+ <principal name="anonymous"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ <permission-mapping match-all="true">
+ <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ </simple-permission-mapper>
+ <constant-realm-mapper name="local" realm-name="local"/>
+ <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+ <constant-role-mapper name="super-user-mapper">
+ <role name="SuperUser"/>
+ </constant-role-mapper>
+ </mappers>
+ <http>
+ <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="BASIC">
+ <mechanism-realm realm-name="Application Realm"/>
+ </mechanism>
+ <mechanism mechanism-name="FORM"/>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <provider-http-server-mechanism-factory name="global"/>
+ </http>
+ <sasl>
+ <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ApplicationRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+ <properties>
+ <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+ </properties>
+ </configurable-sasl-server-factory>
+ <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+ <filters>
+ <filter provider-name="WildFlyElytron"/>
+ </filters>
+ </mechanism-provider-filtering-sasl-server-factory>
+ <provider-sasl-server-factory name="global"/>
+ </sasl>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:security:2.0">
+ <security-domains>
+ <security-domain name="other" cache-type="default">
+ <authentication>
+ <login-module code="Remoting" flag="optional">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ <login-module code="RealmDirect" flag="required">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ </authentication>
+ </security-domain>
+ <security-domain name="jboss-web-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jboss-ejb-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jaspitest" cache-type="default">
+ <authentication-jaspi>
+ <login-module-stack name="dummy">
+ <login-module code="Dummy" flag="optional"/>
+ </login-module-stack>
+ <auth-module code="Dummy"/>
+ </authentication-jaspi>
+ </security-domain>
+ </security-domains>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:security-manager:1.0">
+ <deployment-permissions>
+ <maximum-set>
+ <permission class="java.security.AllPermission"/>
+ </maximum-set>
+ </deployment-permissions>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:transactions:4.0">
+ <core-environment>
+ <process-id>
+ <uuid/>
+ </process-id>
+ </core-environment>
+ <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+ <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:undertow:4.0">
+ <buffer-cache name="default"/>
+ <server name="default-server">
+ <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
+ <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
+ <host name="default-host" alias="localhost">
+ <location name="/" handler="welcome-content"/>
+ <http-invoker security-realm="ApplicationRealm"/>
+ </host>
+ </server>
+ <servlet-container name="default">
+ <jsp-config/>
+ <websockets/>
+ </servlet-container>
+ <handlers>
+ <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
+ </handlers>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+ <web-context>auth</web-context>
+ <providers>
+ <provider>classpath:${jboss.home.dir}/providers/*</provider>
+ </providers>
+ <master-realm-name>master</master-realm-name>
+ <scheduled-task-interval>900</scheduled-task-interval>
+ <theme>
+ <staticMaxAge>2592000</staticMaxAge>
+ <cacheThemes>true</cacheThemes>
+ <cacheTemplates>true</cacheTemplates>
+ <dir>${jboss.home.dir}/themes</dir>
+ </theme>
+ <spi name="eventsStore">
+ <provider name="jpa" enabled="true">
+ <properties>
+ <property name="exclude-events" value="["REFRESH_TOKEN"]"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="userCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="userSessionPersister">
+ <default-provider>jpa</default-provider>
+ </spi>
+ <spi name="timer">
+ <default-provider>basic</default-provider>
+ </spi>
+ <spi name="connectionsHttpClient">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsJpa">
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
+ <property name="initializeEmpty" value="true"/>
+ <property name="migrationStrategy" value="update"/>
+ <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="realmCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsInfinispan">
+ <default-provider>default</default-provider>
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="cacheContainer" value="java:comp/env/infinispan/Keycloak"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="jta-lookup">
+ <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
+ <provider name="jboss" enabled="true"/>
+ </spi>
+ <spi name="publicKeyStorage">
+ <provider name="infinispan" enabled="true">
+ <properties>
+ <property name="minTimeBetweenRequests" value="10"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="x509cert-lookup">
+ <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
+ <provider name="default" enabled="true"/>
+ </spi>
+ </subsystem>
+ </profile>
+ <!--
+ ~
+ ~ Clustering authentication server setup.
+ ~
+ ~ You must configure a remote shared external database like PostgreSQL or MySql if you want this to be
+ ~ able to work on multiple machines.
+ ~
+ -->
+ <profile name="auth-server-clustered">
+ <subsystem xmlns="urn:jboss:domain:logging:3.0">
+ <console-handler name="CONSOLE">
+ <level name="INFO"/>
+ <formatter>
+ <named-formatter name="COLOR-PATTERN"/>
+ </formatter>
+ </console-handler>
+ <periodic-rotating-file-handler name="FILE" autoflush="true">
+ <formatter>
+ <named-formatter name="PATTERN"/>
+ </formatter>
+ <file relative-to="jboss.server.log.dir" path="server.log"/>
+ <suffix value=".yyyy-MM-dd"/>
+ <append value="true"/>
+ </periodic-rotating-file-handler>
+ <logger category="com.arjuna">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.jboss.as.config">
+ <level name="DEBUG"/>
+ </logger>
+ <logger category="sun.rmi">
+ <level name="WARN"/>
+ </logger>
+ <root-logger>
+ <level name="INFO"/>
+ <handlers>
+ <handler name="CONSOLE"/>
+ <handler name="FILE"/>
+ </handlers>
+ </root-logger>
+ <formatter name="PATTERN">
+ <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ <formatter name="COLOR-PATTERN">
+ <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:datasources:5.0">
+ <datasources>
+ <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:${jboss.server.data.dir}/../../shared-database/keycloak;AUTO_SERVER=TRUE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <drivers>
+ <driver name="h2" module="com.h2database.h2">
+ <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+ </driver>
+ </drivers>
+ </datasources>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ee:4.0">
+ <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+ <concurrent>
+ <context-services>
+ <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
+ </context-services>
+ <managed-thread-factories>
+ <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
+ </managed-thread-factories>
+ <managed-executor-services>
+ <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
+ </managed-executor-services>
+ <managed-scheduled-executor-services>
+ <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
+ </managed-scheduled-executor-services>
+ </concurrent>
+ <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
+ <session-bean>
+ <stateless>
+ <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+ </stateless>
+ <stateful default-access-timeout="5000" cache-ref="distributable" passivation-disabled-cache-ref="simple"/>
+ <singleton default-access-timeout="5000"/>
+ </session-bean>
+ <pools>
+ <bean-instance-pools>
+ <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ </bean-instance-pools>
+ </pools>
+ <caches>
+ <cache name="simple"/>
+ <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
+ </caches>
+ <passivation-stores>
+ <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
+ </passivation-stores>
+ <async thread-pool-name="default"/>
+ <timer-service thread-pool-name="default" default-data-store="default-file-store">
+ <data-stores>
+ <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+ </data-stores>
+ </timer-service>
+ <remote connector-ref="http-remoting-connector" thread-pool-name="default">
+ <channel-creation-options>
+ <option name="READ_TIMEOUT" value="${prop.remoting-connector.read.timeout:20}" type="xnio"/>
+ <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
+ </channel-creation-options>
+ </remote>
+ <thread-pools>
+ <thread-pool name="default">
+ <max-threads count="10"/>
+ <keepalive-time time="100" unit="milliseconds"/>
+ </thread-pool>
+ </thread-pools>
+ <default-security-domain value="other"/>
+ <default-missing-method-permissions-deny-access value="true"/>
+ <log-system-exceptions value="true"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:io:2.0">
+ <worker name="default"/>
+ <buffer-pool name="default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:infinispan:4.0">
+ <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <transport lock-timeout="60000"/>
+ <local-cache name="realms">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="users">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <distributed-cache name="sessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="authenticationSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="clientSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="offlineClientSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
+ <local-cache name="authorization">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <replicated-cache name="work" mode="SYNC"/>
+ <local-cache name="keys">
+ <eviction max-entries="1000" strategy="LRU"/>
+ <expiration max-idle="3600000"/>
+ </local-cache>
+ <distributed-cache name="actionTokens" mode="SYNC" owners="2">
+ <eviction max-entries="-1" strategy="NONE"/>
+ <expiration max-idle="-1" interval="300000"/>
+ </distributed-cache>
+ </cache-container>
+ <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
+ <transport lock-timeout="60000"/>
+ <replicated-cache name="default">
+ <transaction mode="BATCH"/>
+ </replicated-cache>
+ </cache-container>
+ <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
+ <transport lock-timeout="60000"/>
+ <distributed-cache name="dist">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store/>
+ </distributed-cache>
+ </cache-container>
+ <cache-container name="ejb" aliases="sfsb" default-cache="dist" module="org.wildfly.clustering.ejb.infinispan">
+ <transport lock-timeout="60000"/>
+ <distributed-cache name="dist">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store/>
+ </distributed-cache>
+ </cache-container>
+ <cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan">
+ <transport lock-timeout="60000"/>
+ <local-cache name="local-query">
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <invalidation-cache name="entity">
+ <transaction mode="NON_XA"/>
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </invalidation-cache>
+ <replicated-cache name="timestamps" mode="ASYNC"/>
+ </cache-container>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jca:5.0">
+ <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+ <bean-validation enabled="true"/>
+ <default-workmanager>
+ <short-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </short-running-threads>
+ <long-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </long-running-threads>
+ </default-workmanager>
+ <cached-connection-manager/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jgroups:5.0">
+ <channels default="ee">
+ <channel name="ee" stack="udp" cluster="ejb"/>
+ </channels>
+ <stacks>
+ <stack name="udp">
+ <transport type="UDP" socket-binding="jgroups-udp"/>
+ <protocol type="PING"/>
+ <protocol type="MERGE3"/>
+ <protocol type="FD_SOCK"/>
+ <protocol type="FD_ALL"/>
+ <protocol type="VERIFY_SUSPECT"/>
+ <protocol type="pbcast.NAKACK2"/>
+ <protocol type="UNICAST3"/>
+ <protocol type="pbcast.STABLE"/>
+ <protocol type="pbcast.GMS"/>
+ <protocol type="UFC"/>
+ <protocol type="MFC"/>
+ <protocol type="FRAG2"/>
+ </stack>
+ <stack name="tcp">
+ <transport type="TCP" socket-binding="jgroups-tcp"/>
+ <socket-protocol type="MPING" socket-binding="jgroups-mping"/>
+ <protocol type="MERGE3"/>
+ <protocol type="FD_SOCK"/>
+ <protocol type="FD_ALL"/>
+ <protocol type="VERIFY_SUSPECT"/>
+ <protocol type="pbcast.NAKACK2"/>
+ <protocol type="UNICAST3"/>
+ <protocol type="pbcast.STABLE"/>
+ <protocol type="pbcast.GMS"/>
+ <protocol type="MFC"/>
+ <protocol type="FRAG2"/>
+ </stack>
+ </stacks>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+ <expose-resolved-model/>
+ <expose-expression-model/>
+ <!--<remoting-connector use-management-endpoint="false"/>-->
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+ <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:mail:3.0">
+ <mail-session name="default" jndi-name="java:jboss/mail/Default">
+ <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+ </mail-session>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:modcluster:3.0">
+ <mod-cluster-config advertise-socket="modcluster" connector="ajp">
+ <dynamic-load-provider>
+ <load-metric type="cpu"/>
+ </dynamic-load-provider>
+ </mod-cluster-config>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:naming:2.0">
+ <remote-naming/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:remoting:4.0">
+ <endpoint/>
+ <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
+ <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+ <providers>
+ <aggregate-providers name="combined-providers">
+ <providers name="elytron"/>
+ <providers name="openssl"/>
+ </aggregate-providers>
+ <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+ <provider-loader name="openssl" module="org.wildfly.openssl"/>
+ </providers>
+ <audit-logging>
+ <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
+ </audit-logging>
+ <security-domains>
+ <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
+ <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
+ </security-domain>
+ </security-domains>
+ <security-realms>
+ <identity-realm name="local" identity="$local"/>
+ <properties-realm name="ApplicationRealm">
+ <users-properties path="application-users.properties" relative-to="jboss.domain.config.dir" digest-realm-name="ApplicationRealm"/>
+ <groups-properties path="application-roles.properties" relative-to="jboss.domain.config.dir"/>
+ </properties-realm>
+ </security-realms>
+ <mappers>
+ <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+ <permission-mapping>
+ <principal name="anonymous"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ <permission-mapping match-all="true">
+ <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ </simple-permission-mapper>
+ <constant-realm-mapper name="local" realm-name="local"/>
+ <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+ <constant-role-mapper name="super-user-mapper">
+ <role name="SuperUser"/>
+ </constant-role-mapper>
+ </mappers>
+ <http>
+ <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="BASIC">
+ <mechanism-realm realm-name="Application Realm"/>
+ </mechanism>
+ <mechanism mechanism-name="FORM"/>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <provider-http-server-mechanism-factory name="global"/>
+ </http>
+ <sasl>
+ <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ApplicationRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+ <properties>
+ <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+ </properties>
+ </configurable-sasl-server-factory>
+ <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+ <filters>
+ <filter provider-name="WildFlyElytron"/>
+ </filters>
+ </mechanism-provider-filtering-sasl-server-factory>
+ <provider-sasl-server-factory name="global"/>
+ </sasl>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:security:2.0">
+ <security-domains>
+ <security-domain name="other" cache-type="default">
+ <authentication>
+ <login-module code="Remoting" flag="optional">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ <login-module code="RealmDirect" flag="required">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ </authentication>
+ </security-domain>
+ <security-domain name="jboss-web-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jboss-ejb-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jaspitest" cache-type="default">
+ <authentication-jaspi>
+ <login-module-stack name="dummy">
+ <login-module code="Dummy" flag="optional"/>
+ </login-module-stack>
+ <auth-module code="Dummy"/>
+ </authentication-jaspi>
+ </security-domain>
+ </security-domains>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:security-manager:1.0">
+ <deployment-permissions>
+ <maximum-set>
+ <permission class="java.security.AllPermission"/>
+ </maximum-set>
+ </deployment-permissions>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:transactions:4.0">
+ <core-environment>
+ <process-id>
+ <uuid/>
+ </process-id>
+ </core-environment>
+ <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+ <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:undertow:4.0">
+ <buffer-cache name="default"/>
+ <server name="default-server">
+ <ajp-listener name="ajp" socket-binding="ajp"/>
+ <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
+ <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
+ <host name="default-host" alias="localhost">
+ <location name="/" handler="welcome-content"/>
+ <http-invoker security-realm="ApplicationRealm"/>
+ </host>
+ </server>
+ <servlet-container name="default">
+ <jsp-config/>
+ <websockets/>
+ </servlet-container>
+ <handlers>
+ <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
+ </handlers>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+ <web-context>auth</web-context>
+ <providers>
+ <provider>classpath:${jboss.home.dir}/providers/*</provider>
+ </providers>
+ <master-realm-name>master</master-realm-name>
+ <scheduled-task-interval>900</scheduled-task-interval>
+ <theme>
+ <staticMaxAge>2592000</staticMaxAge>
+ <cacheThemes>true</cacheThemes>
+ <cacheTemplates>true</cacheTemplates>
+ <dir>${jboss.home.dir}/themes</dir>
+ </theme>
+ <spi name="eventsStore">
+ <provider name="jpa" enabled="true">
+ <properties>
+ <property name="exclude-events" value="["REFRESH_TOKEN"]"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="userCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="userSessionPersister">
+ <default-provider>jpa</default-provider>
+ </spi>
+ <spi name="timer">
+ <default-provider>basic</default-provider>
+ </spi>
+ <spi name="connectionsHttpClient">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsJpa">
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
+ <property name="initializeEmpty" value="true"/>
+ <property name="migrationStrategy" value="update"/>
+ <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="realmCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsInfinispan">
+ <default-provider>default</default-provider>
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="cacheContainer" value="java:comp/env/infinispan/Keycloak"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="jta-lookup">
+ <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
+ <provider name="jboss" enabled="true"/>
+ </spi>
+ <spi name="publicKeyStorage">
+ <provider name="infinispan" enabled="true">
+ <properties>
+ <property name="minTimeBetweenRequests" value="10"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="x509cert-lookup">
+ <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
+ <provider name="default" enabled="true"/>
+ </spi>
+ </subsystem>
+ </profile>
+ <!--
+ ~
+ ~ This is a profile for the built-in Underto Loadbalancer
+ ~ It should be removed in production systems and replaced with a better software or hardware based one
+ ~
+ -->
+ <profile name="load-balancer">
+ <subsystem xmlns="urn:jboss:domain:logging:3.0">
+ <console-handler name="CONSOLE">
+ <level name="INFO"/>
+ <formatter>
+ <named-formatter name="COLOR-PATTERN"/>
+ </formatter>
+ </console-handler>
+ <periodic-rotating-file-handler name="FILE" autoflush="true">
+ <formatter>
+ <named-formatter name="PATTERN"/>
+ </formatter>
+ <file relative-to="jboss.server.log.dir" path="server.log"/>
+ <suffix value=".yyyy-MM-dd"/>
+ <append value="true"/>
+ </periodic-rotating-file-handler>
+ <logger category="com.arjuna">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.jboss.as.config">
+ <level name="DEBUG"/>
+ </logger>
+ <logger category="sun.rmi">
+ <level name="WARN"/>
+ </logger>
+ <root-logger>
+ <level name="INFO"/>
+ <handlers>
+ <handler name="CONSOLE"/>
+ <handler name="FILE"/>
+ </handlers>
+ </root-logger>
+ <formatter name="PATTERN">
+ <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ <formatter name="COLOR-PATTERN">
+ <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:io:2.0">
+ <worker name="default"/>
+ <buffer-pool name="default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:undertow:4.0">
+ <buffer-cache name="default"/>
+ <server name="default-server">
+ <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
+ <http-listener name="management" socket-binding="mcmp-management" enable-http2="true"/>
+ <host name="default-host" alias="localhost">
+ <filter-ref name="load-balancer"/>
+ </host>
+ </server>
+ <servlet-container name="default"/>
+ <filters>
+ <mod-cluster name="load-balancer" management-socket-binding="mcmp-management" advertise-socket-binding="modcluster" enable-http2="true" max-retries="3"/>
+ </filters>
+ </subsystem>
+ </profile>
+ </profiles>
+ <!--
+ ~
+ ~ Named interfaces that can be referenced elsewhere in the configuration. The configuration
+ ~ for how to associate these logical names with an actual network interface can either
+ ~ be specified here or can be declared on a per-host basis in the equivalent element in host.xml.
+ ~
+ ~ These default configurations require the binding specification to be done in host.xml.
+ ~
+ -->
+ <interfaces>
+ <interface name="management"/>
+ <interface name="public"/>
+ <interface name="private">
+ <inet-address value="${jboss.bind.address.private:127.0.0.1}"/>
+ </interface>
+ </interfaces>
+ <socket-binding-groups>
+ <socket-binding-group name="standard-sockets" default-interface="public">
+ <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
+ <socket-binding name="http" port="${jboss.http.port:8080}"/>
+ <socket-binding name="https" port="${jboss.https.port:8443}"/>
+ <socket-binding name="txn-recovery-environment" port="4712"/>
+ <socket-binding name="txn-status-manager" port="4713"/>
+ <outbound-socket-binding name="mail-smtp">
+ <remote-destination host="localhost" port="25"/>
+ </outbound-socket-binding>
+ </socket-binding-group>
+ <socket-binding-group name="ha-sockets" default-interface="public">
+ <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
+ <socket-binding name="http" port="${jboss.http.port:8080}"/>
+ <socket-binding name="https" port="${jboss.https.port:8443}"/>
+ <socket-binding name="jgroups-mping" interface="private" port="0" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
+ <socket-binding name="jgroups-tcp" interface="private" port="7600"/>
+ <socket-binding name="jgroups-udp" interface="private" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
+ <socket-binding name="modcluster" port="0" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
+ <socket-binding name="txn-recovery-environment" port="4712"/>
+ <socket-binding name="txn-status-manager" port="4713"/>
+ <outbound-socket-binding name="mail-smtp">
+ <remote-destination host="localhost" port="25"/>
+ </outbound-socket-binding>
+ </socket-binding-group>
+ <!-- load-balancer-sockets should be removed in production systems and replaced with a better softare or hardare based one -->
+ <socket-binding-group name="load-balancer-sockets" default-interface="public">
+ <!-- Needed for server groups using the 'load-balancer' profile -->
+ <socket-binding name="http" port="${jboss.http.port:8080}"/>
+ <socket-binding name="https" port="${jboss.https.port:8443}"/>
+ <socket-binding name="mcmp-management" interface="private" port="${jboss.mcmp.port:8090}"/>
+ <socket-binding name="modcluster" interface="private" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
+ </socket-binding-group>
+ </socket-binding-groups>
+ <server-groups>
+ <server-group name="auth-server-group" profile="auth-server-clustered">
+ <jvm name="default">
+ <heap size="64m" max-size="512m"/>
+ </jvm>
+ <socket-binding-group ref="ha-sockets"/>
+ </server-group>
+ <!-- load-balancer-group should be removed in production systems and replaced with a better softare or hardare based one -->
+ <server-group name="load-balancer-group" profile="load-balancer">
+ <jvm name="default">
+ <heap size="64m" max-size="512m"/>
+ </jvm>
+ <socket-binding-group ref="load-balancer-sockets"/>
+ </server-group>
+ </server-groups>
+</domain>
diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-3.4.3.Final-redhat-2.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-3.4.3.Final-redhat-2.xml
new file mode 100644
index 0000000..7963f3d
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/domain/host-master-3.4.3.Final-redhat-2.xml
@@ -0,0 +1,185 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<host xmlns="urn:jboss:domain:5.0" name="master">
+ <extensions>
+ <extension module="org.jboss.as.jmx"/>
+ <extension module="org.wildfly.extension.core-management"/>
+ <extension module="org.wildfly.extension.elytron"/>
+ </extensions>
+ <management>
+ <security-realms>
+ <security-realm name="ManagementRealm">
+ <authentication>
+ <local default-user="$local" skip-group-loading="true"/>
+ <properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir"/>
+ </authentication>
+ <authorization map-groups-to-roles="false">
+ <properties path="mgmt-groups.properties" relative-to="jboss.domain.config.dir"/>
+ </authorization>
+ </security-realm>
+ <security-realm name="ApplicationRealm">
+ <server-identities>
+ <ssl>
+ <keystore path="application.keystore" relative-to="jboss.domain.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
+ </ssl>
+ </server-identities>
+ <authentication>
+ <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
+ <properties path="application-users.properties" relative-to="jboss.domain.config.dir"/>
+ </authentication>
+ <authorization>
+ <properties path="application-roles.properties" relative-to="jboss.domain.config.dir"/>
+ </authorization>
+ </security-realm>
+ </security-realms>
+ <audit-log>
+ <formatters>
+ <json-formatter name="json-formatter"/>
+ </formatters>
+ <handlers>
+ <file-handler name="host-file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.domain.data.dir"/>
+ <file-handler name="server-file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
+ </handlers>
+ <logger log-boot="true" log-read-only="false" enabled="false">
+ <handlers>
+ <handler name="host-file"/>
+ </handlers>
+ </logger>
+ <server-logger log-boot="true" log-read-only="false" enabled="false">
+ <handlers>
+ <handler name="server-file"/>
+ </handlers>
+ </server-logger>
+ </audit-log>
+ <management-interfaces>
+ <native-interface security-realm="ManagementRealm">
+ <socket interface="management" port="${jboss.management.native.port:9999}"/>
+ </native-interface>
+ <http-interface security-realm="ManagementRealm">
+ <http-upgrade enabled="true"/>
+ <socket interface="management" port="${jboss.management.http.port:9990}"/>
+ </http-interface>
+ </management-interfaces>
+ </management>
+ <domain-controller>
+ <local/>
+ </domain-controller>
+ <interfaces>
+ <interface name="management">
+ <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+ </interface>
+ <interface name="public">
+ <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+ </interface>
+ </interfaces>
+ <jvms>
+ <jvm name="default">
+ <heap size="64m" max-size="256m"/>
+ <jvm-options>
+ <option value="-server"/>
+ <option value="-XX:MetaspaceSize=96m"/>
+ <option value="-XX:MaxMetaspaceSize=256m"/>
+ </jvm-options>
+ </jvm>
+ </jvms>
+ <servers>
+ <!-- load-balancer should be removed in production systems and replaced with a better softare or hardare based one -->
+ <server name="load-balancer" group="load-balancer-group"/>
+ <server name="server-one" group="auth-server-group" auto-start="true">
+ <!--
+ ~ Remote JPDA debugging for a specific server
+ ~ <jvm name="default">
+ ~ <jvm-options>
+ ~ <option value="-agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n"/>
+ ~ </jvm-options>
+ ~ </jvm>
+ ~
+ -->
+ <!--
+ ~ server-two avoids port conflicts by incrementing the ports in
+ ~ the default socket-group declared in the server-group
+ -->
+ <socket-bindings port-offset="150"/>
+ </server>
+ </servers>
+ <profile>
+ <subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+ <expose-resolved-model/>
+ <expose-expression-model/>
+ <remoting-connector/>
+ </subsystem>
+ <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+ <providers>
+ <aggregate-providers name="combined-providers">
+ <providers name="elytron"/>
+ <providers name="openssl"/>
+ </aggregate-providers>
+ <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+ <provider-loader name="openssl" module="org.wildfly.openssl"/>
+ </providers>
+ <audit-logging>
+ <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.domain.log.dir" format="JSON"/>
+ </audit-logging>
+ <security-domains>
+ <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
+ <realm name="ManagementRealm" role-decoder="groups-to-roles"/>
+ <realm name="local" role-mapper="super-user-mapper"/>
+ </security-domain>
+ </security-domains>
+ <security-realms>
+ <identity-realm name="local" identity="$local"/>
+ <properties-realm name="ManagementRealm">
+ <users-properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir" digest-realm-name="ManagementRealm"/>
+ <groups-properties path="mgmt-groups.properties" relative-to="jboss.domain.config.dir"/>
+ </properties-realm>
+ </security-realms>
+ <mappers>
+ <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+ <permission-mapping>
+ <principal name="anonymous"/>
+ </permission-mapping>
+ <permission-mapping match-all="true">
+ <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+ </permission-mapping>
+ </simple-permission-mapper>
+ <constant-realm-mapper name="local" realm-name="local"/>
+ <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+ <constant-role-mapper name="super-user-mapper">
+ <role name="SuperUser"/>
+ </constant-role-mapper>
+ </mappers>
+ <http>
+ <http-authentication-factory name="management-http-authentication" http-server-mechanism-factory="global" security-domain="ManagementDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="BASIC">
+ <mechanism-realm realm-name="Management Realm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <provider-http-server-mechanism-factory name="global"/>
+ </http>
+ <sasl>
+ <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ManagementRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+ <properties>
+ <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+ </properties>
+ </configurable-sasl-server-factory>
+ <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+ <filters>
+ <filter provider-name="WildFlyElytron"/>
+ </filters>
+ </mechanism-provider-filtering-sasl-server-factory>
+ <provider-sasl-server-factory name="global"/>
+ </sasl>
+ </subsystem>
+ </profile>
+</host>
diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-3.4.3.Final-redhat-2.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-3.4.3.Final-redhat-2.xml
new file mode 100644
index 0000000..3f90433
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-3.4.3.Final-redhat-2.xml
@@ -0,0 +1,573 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:5.0">
+ <extensions>
+ <extension module="org.jboss.as.clustering.infinispan"/>
+ <extension module="org.jboss.as.connector"/>
+ <extension module="org.jboss.as.deployment-scanner"/>
+ <extension module="org.jboss.as.ee"/>
+ <extension module="org.jboss.as.ejb3"/>
+ <extension module="org.jboss.as.jaxrs"/>
+ <extension module="org.jboss.as.jmx"/>
+ <extension module="org.jboss.as.jpa"/>
+ <extension module="org.jboss.as.logging"/>
+ <extension module="org.jboss.as.mail"/>
+ <extension module="org.jboss.as.naming"/>
+ <extension module="org.jboss.as.remoting"/>
+ <extension module="org.jboss.as.security"/>
+ <extension module="org.jboss.as.transactions"/>
+ <extension module="org.keycloak.keycloak-server-subsystem"/>
+ <extension module="org.wildfly.extension.bean-validation"/>
+ <extension module="org.wildfly.extension.elytron"/>
+ <extension module="org.wildfly.extension.io"/>
+ <extension module="org.wildfly.extension.request-controller"/>
+ <extension module="org.wildfly.extension.security.manager"/>
+ <extension module="org.wildfly.extension.undertow"/>
+ </extensions>
+ <management>
+ <security-realms>
+ <security-realm name="ManagementRealm">
+ <authentication>
+ <local default-user="$local" skip-group-loading="true"/>
+ <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+ </authentication>
+ <authorization map-groups-to-roles="false">
+ <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+ </authorization>
+ </security-realm>
+ <security-realm name="ApplicationRealm">
+ <server-identities>
+ <ssl>
+ <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
+ </ssl>
+ </server-identities>
+ <authentication>
+ <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
+ <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+ </authentication>
+ <authorization>
+ <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+ </authorization>
+ </security-realm>
+ </security-realms>
+ <audit-log>
+ <formatters>
+ <json-formatter name="json-formatter"/>
+ </formatters>
+ <handlers>
+ <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
+ </handlers>
+ <logger log-boot="true" log-read-only="false" enabled="false">
+ <handlers>
+ <handler name="file"/>
+ </handlers>
+ </logger>
+ </audit-log>
+ <management-interfaces>
+ <http-interface security-realm="ManagementRealm">
+ <http-upgrade enabled="true"/>
+ <socket-binding http="management-http"/>
+ </http-interface>
+ </management-interfaces>
+ <access-control provider="simple">
+ <role-mapping>
+ <role name="SuperUser">
+ <include>
+ <user name="$local"/>
+ </include>
+ </role>
+ </role-mapping>
+ </access-control>
+ </management>
+ <profile>
+ <subsystem xmlns="urn:jboss:domain:logging:3.0">
+ <console-handler name="CONSOLE">
+ <level name="INFO"/>
+ <formatter>
+ <named-formatter name="COLOR-PATTERN"/>
+ </formatter>
+ </console-handler>
+ <periodic-rotating-file-handler name="FILE" autoflush="true">
+ <formatter>
+ <named-formatter name="PATTERN"/>
+ </formatter>
+ <file relative-to="jboss.server.log.dir" path="server.log"/>
+ <suffix value=".yyyy-MM-dd"/>
+ <append value="true"/>
+ </periodic-rotating-file-handler>
+ <logger category="com.arjuna">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.jboss.as.config">
+ <level name="DEBUG"/>
+ </logger>
+ <logger category="sun.rmi">
+ <level name="WARN"/>
+ </logger>
+ <root-logger>
+ <level name="INFO"/>
+ <handlers>
+ <handler name="CONSOLE"/>
+ <handler name="FILE"/>
+ </handlers>
+ </root-logger>
+ <formatter name="PATTERN">
+ <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ <formatter name="COLOR-PATTERN">
+ <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:datasources:5.0">
+ <datasources>
+ <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <drivers>
+ <driver name="h2" module="com.h2database.h2">
+ <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+ </driver>
+ </drivers>
+ </datasources>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
+ <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ee:4.0">
+ <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+ <concurrent>
+ <context-services>
+ <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
+ </context-services>
+ <managed-thread-factories>
+ <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
+ </managed-thread-factories>
+ <managed-executor-services>
+ <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
+ </managed-executor-services>
+ <managed-scheduled-executor-services>
+ <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
+ </managed-scheduled-executor-services>
+ </concurrent>
+ <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
+ <session-bean>
+ <stateless>
+ <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+ </stateless>
+ <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
+ <singleton default-access-timeout="5000"/>
+ </session-bean>
+ <pools>
+ <bean-instance-pools>
+ <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ </bean-instance-pools>
+ </pools>
+ <caches>
+ <cache name="simple"/>
+ <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
+ </caches>
+ <passivation-stores>
+ <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
+ </passivation-stores>
+ <async thread-pool-name="default"/>
+ <timer-service thread-pool-name="default" default-data-store="default-file-store">
+ <data-stores>
+ <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+ </data-stores>
+ </timer-service>
+ <remote connector-ref="http-remoting-connector" thread-pool-name="default">
+ <channel-creation-options>
+ <option name="READ_TIMEOUT" value="${prop.remoting-connector.read.timeout:20}" type="xnio"/>
+ <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
+ </channel-creation-options>
+ </remote>
+ <thread-pools>
+ <thread-pool name="default">
+ <max-threads count="10"/>
+ <keepalive-time time="100" unit="milliseconds"/>
+ </thread-pool>
+ </thread-pools>
+ <default-security-domain value="other"/>
+ <default-missing-method-permissions-deny-access value="true"/>
+ <log-system-exceptions value="true"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:io:2.0">
+ <worker name="default"/>
+ <buffer-pool name="default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:infinispan:4.0">
+ <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <local-cache name="realms">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="users">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="sessions"/>
+ <local-cache name="authenticationSessions"/>
+ <local-cache name="offlineSessions"/>
+ <local-cache name="clientSessions"/>
+ <local-cache name="offlineClientSessions"/>
+ <local-cache name="loginFailures"/>
+ <local-cache name="work"/>
+ <local-cache name="authorization">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="keys">
+ <eviction max-entries="1000" strategy="LRU"/>
+ <expiration max-idle="3600000"/>
+ </local-cache>
+ <local-cache name="actionTokens">
+ <eviction max-entries="-1" strategy="NONE"/>
+ <expiration max-idle="-1" interval="300000"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
+ <local-cache name="default">
+ <transaction mode="BATCH"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
+ <local-cache name="passivation">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store passivation="true" purge="false"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="ejb" aliases="sfsb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan">
+ <local-cache name="passivation">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store passivation="true" purge="false"/>
+ </local-cache>
+ </cache-container>
+ <cache-container name="hibernate" module="org.hibernate.infinispan">
+ <local-cache name="entity">
+ <transaction mode="NON_XA"/>
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <local-cache name="local-query">
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <local-cache name="timestamps"/>
+ </cache-container>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jca:5.0">
+ <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+ <bean-validation enabled="true"/>
+ <default-workmanager>
+ <short-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </short-running-threads>
+ <long-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </long-running-threads>
+ </default-workmanager>
+ <cached-connection-manager/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+ <expose-resolved-model/>
+ <expose-expression-model/>
+ <remoting-connector/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+ <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:mail:3.0">
+ <mail-session name="default" jndi-name="java:jboss/mail/Default">
+ <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+ </mail-session>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:naming:2.0">
+ <remote-naming/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:remoting:4.0">
+ <endpoint/>
+ <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:security-manager:1.0">
+ <deployment-permissions>
+ <maximum-set>
+ <permission class="java.security.AllPermission"/>
+ </maximum-set>
+ </deployment-permissions>
+ </subsystem>
+ <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+ <providers>
+ <aggregate-providers name="combined-providers">
+ <providers name="elytron"/>
+ <providers name="openssl"/>
+ </aggregate-providers>
+ <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+ <provider-loader name="openssl" module="org.wildfly.openssl"/>
+ </providers>
+ <audit-logging>
+ <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
+ </audit-logging>
+ <security-domains>
+ <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
+ <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
+ <realm name="local"/>
+ </security-domain>
+ <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
+ <realm name="ManagementRealm" role-decoder="groups-to-roles"/>
+ <realm name="local" role-mapper="super-user-mapper"/>
+ </security-domain>
+ </security-domains>
+ <security-realms>
+ <identity-realm name="local" identity="$local"/>
+ <properties-realm name="ApplicationRealm">
+ <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
+ <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+ </properties-realm>
+ <properties-realm name="ManagementRealm">
+ <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
+ <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+ </properties-realm>
+ </security-realms>
+ <mappers>
+ <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+ <permission-mapping>
+ <principal name="anonymous"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ <permission-mapping match-all="true">
+ <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ </simple-permission-mapper>
+ <constant-realm-mapper name="local" realm-name="local"/>
+ <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+ <constant-role-mapper name="super-user-mapper">
+ <role name="SuperUser"/>
+ </constant-role-mapper>
+ </mappers>
+ <http>
+ <http-authentication-factory name="management-http-authentication" http-server-mechanism-factory="global" security-domain="ManagementDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="DIGEST">
+ <mechanism-realm realm-name="ManagementRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="BASIC">
+ <mechanism-realm realm-name="Application Realm"/>
+ </mechanism>
+ <mechanism mechanism-name="FORM"/>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <provider-http-server-mechanism-factory name="global"/>
+ </http>
+ <sasl>
+ <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ManagementRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ApplicationRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+ <properties>
+ <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+ </properties>
+ </configurable-sasl-server-factory>
+ <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+ <filters>
+ <filter provider-name="WildFlyElytron"/>
+ </filters>
+ </mechanism-provider-filtering-sasl-server-factory>
+ <provider-sasl-server-factory name="global"/>
+ </sasl>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:security:2.0">
+ <security-domains>
+ <security-domain name="other" cache-type="default">
+ <authentication>
+ <login-module code="Remoting" flag="optional">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ <login-module code="RealmDirect" flag="required">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ </authentication>
+ </security-domain>
+ <security-domain name="jboss-web-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jboss-ejb-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jaspitest" cache-type="default">
+ <authentication-jaspi>
+ <login-module-stack name="dummy">
+ <login-module code="Dummy" flag="optional"/>
+ </login-module-stack>
+ <auth-module code="Dummy"/>
+ </authentication-jaspi>
+ </security-domain>
+ </security-domains>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:transactions:4.0">
+ <core-environment>
+ <process-id>
+ <uuid/>
+ </process-id>
+ </core-environment>
+ <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+ <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:undertow:4.0">
+ <buffer-cache name="default"/>
+ <server name="default-server">
+ <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
+ <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
+ <host name="default-host" alias="localhost">
+ <location name="/" handler="welcome-content"/>
+ <http-invoker security-realm="ApplicationRealm"/>
+ </host>
+ </server>
+ <servlet-container name="default">
+ <jsp-config/>
+ <websockets/>
+ </servlet-container>
+ <handlers>
+ <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
+ </handlers>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+ <web-context>auth</web-context>
+ <providers>
+ <provider>classpath:${jboss.home.dir}/providers/*</provider>
+ </providers>
+ <master-realm-name>master</master-realm-name>
+ <scheduled-task-interval>900</scheduled-task-interval>
+ <theme>
+ <staticMaxAge>2592000</staticMaxAge>
+ <cacheThemes>true</cacheThemes>
+ <cacheTemplates>true</cacheTemplates>
+ <dir>${jboss.home.dir}/themes</dir>
+ </theme>
+ <spi name="eventsStore">
+ <provider name="jpa" enabled="true">
+ <properties>
+ <property name="exclude-events" value="["REFRESH_TOKEN"]"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="userCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="userSessionPersister">
+ <default-provider>jpa</default-provider>
+ </spi>
+ <spi name="timer">
+ <default-provider>basic</default-provider>
+ </spi>
+ <spi name="connectionsHttpClient">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsJpa">
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
+ <property name="initializeEmpty" value="true"/>
+ <property name="migrationStrategy" value="update"/>
+ <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="realmCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsInfinispan">
+ <default-provider>default</default-provider>
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="cacheContainer" value="java:comp/env/infinispan/Keycloak"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="jta-lookup">
+ <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
+ <provider name="jboss" enabled="true"/>
+ </spi>
+ <spi name="publicKeyStorage">
+ <provider name="infinispan" enabled="true">
+ <properties>
+ <property name="minTimeBetweenRequests" value="10"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="x509cert-lookup">
+ <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
+ <provider name="default" enabled="true"/>
+ </spi>
+ </subsystem>
+ </profile>
+ <interfaces>
+ <interface name="management">
+ <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+ </interface>
+ <interface name="public">
+ <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+ </interface>
+ </interfaces>
+ <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+ <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+ <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
+ <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
+ <socket-binding name="http" port="${jboss.http.port:8080}"/>
+ <socket-binding name="https" port="${jboss.https.port:8443}"/>
+ <socket-binding name="txn-recovery-environment" port="4712"/>
+ <socket-binding name="txn-status-manager" port="4713"/>
+ <outbound-socket-binding name="mail-smtp">
+ <remote-destination host="localhost" port="25"/>
+ </outbound-socket-binding>
+ </socket-binding-group>
+</server>
diff --git a/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-3.4.3.Final-redhat-2.xml b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-3.4.3.Final-redhat-2.xml
new file mode 100644
index 0000000..d4c2884
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/server-config-migration/src/test/resources/standalone/standalone-ha-3.4.3.Final-redhat-2.xml
@@ -0,0 +1,631 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<server xmlns="urn:jboss:domain:5.0">
+ <extensions>
+ <extension module="org.jboss.as.clustering.infinispan"/>
+ <extension module="org.jboss.as.clustering.jgroups"/>
+ <extension module="org.jboss.as.connector"/>
+ <extension module="org.jboss.as.deployment-scanner"/>
+ <extension module="org.jboss.as.ee"/>
+ <extension module="org.jboss.as.ejb3"/>
+ <extension module="org.jboss.as.jaxrs"/>
+ <extension module="org.jboss.as.jmx"/>
+ <extension module="org.jboss.as.jpa"/>
+ <extension module="org.jboss.as.logging"/>
+ <extension module="org.jboss.as.mail"/>
+ <extension module="org.jboss.as.modcluster"/>
+ <extension module="org.jboss.as.naming"/>
+ <extension module="org.jboss.as.remoting"/>
+ <extension module="org.jboss.as.security"/>
+ <extension module="org.jboss.as.transactions"/>
+ <extension module="org.keycloak.keycloak-server-subsystem"/>
+ <extension module="org.wildfly.extension.bean-validation"/>
+ <extension module="org.wildfly.extension.elytron"/>
+ <extension module="org.wildfly.extension.io"/>
+ <extension module="org.wildfly.extension.request-controller"/>
+ <extension module="org.wildfly.extension.security.manager"/>
+ <extension module="org.wildfly.extension.undertow"/>
+ </extensions>
+ <management>
+ <security-realms>
+ <security-realm name="ManagementRealm">
+ <authentication>
+ <local default-user="$local" skip-group-loading="true"/>
+ <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
+ </authentication>
+ <authorization map-groups-to-roles="false">
+ <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+ </authorization>
+ </security-realm>
+ <security-realm name="ApplicationRealm">
+ <server-identities>
+ <ssl>
+ <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
+ </ssl>
+ </server-identities>
+ <authentication>
+ <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
+ <properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
+ </authentication>
+ <authorization>
+ <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+ </authorization>
+ </security-realm>
+ </security-realms>
+ <audit-log>
+ <formatters>
+ <json-formatter name="json-formatter"/>
+ </formatters>
+ <handlers>
+ <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
+ </handlers>
+ <logger log-boot="true" log-read-only="false" enabled="false">
+ <handlers>
+ <handler name="file"/>
+ </handlers>
+ </logger>
+ </audit-log>
+ <management-interfaces>
+ <http-interface security-realm="ManagementRealm">
+ <http-upgrade enabled="true"/>
+ <socket-binding http="management-http"/>
+ </http-interface>
+ </management-interfaces>
+ <access-control provider="simple">
+ <role-mapping>
+ <role name="SuperUser">
+ <include>
+ <user name="$local"/>
+ </include>
+ </role>
+ </role-mapping>
+ </access-control>
+ </management>
+ <profile>
+ <subsystem xmlns="urn:jboss:domain:logging:3.0">
+ <console-handler name="CONSOLE">
+ <level name="INFO"/>
+ <formatter>
+ <named-formatter name="COLOR-PATTERN"/>
+ </formatter>
+ </console-handler>
+ <periodic-rotating-file-handler name="FILE" autoflush="true">
+ <formatter>
+ <named-formatter name="PATTERN"/>
+ </formatter>
+ <file relative-to="jboss.server.log.dir" path="server.log"/>
+ <suffix value=".yyyy-MM-dd"/>
+ <append value="true"/>
+ </periodic-rotating-file-handler>
+ <logger category="com.arjuna">
+ <level name="WARN"/>
+ </logger>
+ <logger category="org.jboss.as.config">
+ <level name="DEBUG"/>
+ </logger>
+ <logger category="sun.rmi">
+ <level name="WARN"/>
+ </logger>
+ <root-logger>
+ <level name="INFO"/>
+ <handlers>
+ <handler name="CONSOLE"/>
+ <handler name="FILE"/>
+ </handlers>
+ </root-logger>
+ <formatter name="PATTERN">
+ <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ <formatter name="COLOR-PATTERN">
+ <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
+ </formatter>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:datasources:5.0">
+ <datasources>
+ <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
+ <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+ <driver>h2</driver>
+ <security>
+ <user-name>sa</user-name>
+ <password>sa</password>
+ </security>
+ </datasource>
+ <drivers>
+ <driver name="h2" module="com.h2database.h2">
+ <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
+ </driver>
+ </drivers>
+ </datasources>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
+ <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ee:4.0">
+ <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
+ <concurrent>
+ <context-services>
+ <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
+ </context-services>
+ <managed-thread-factories>
+ <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
+ </managed-thread-factories>
+ <managed-executor-services>
+ <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
+ </managed-executor-services>
+ <managed-scheduled-executor-services>
+ <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
+ </managed-scheduled-executor-services>
+ </concurrent>
+ <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:ejb3:5.0">
+ <session-bean>
+ <stateless>
+ <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
+ </stateless>
+ <stateful default-access-timeout="5000" cache-ref="distributable" passivation-disabled-cache-ref="simple"/>
+ <singleton default-access-timeout="5000"/>
+ </session-bean>
+ <pools>
+ <bean-instance-pools>
+ <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
+ </bean-instance-pools>
+ </pools>
+ <caches>
+ <cache name="simple"/>
+ <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
+ </caches>
+ <passivation-stores>
+ <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
+ </passivation-stores>
+ <async thread-pool-name="default"/>
+ <timer-service thread-pool-name="default" default-data-store="default-file-store">
+ <data-stores>
+ <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
+ </data-stores>
+ </timer-service>
+ <remote connector-ref="http-remoting-connector" thread-pool-name="default">
+ <channel-creation-options>
+ <option name="READ_TIMEOUT" value="${prop.remoting-connector.read.timeout:20}" type="xnio"/>
+ <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
+ </channel-creation-options>
+ </remote>
+ <thread-pools>
+ <thread-pool name="default">
+ <max-threads count="10"/>
+ <keepalive-time time="100" unit="milliseconds"/>
+ </thread-pool>
+ </thread-pools>
+ <default-security-domain value="other"/>
+ <default-missing-method-permissions-deny-access value="true"/>
+ <log-system-exceptions value="true"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:io:2.0">
+ <worker name="default"/>
+ <buffer-pool name="default"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:infinispan:4.0">
+ <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <transport lock-timeout="60000"/>
+ <local-cache name="realms">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <local-cache name="users">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <distributed-cache name="sessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="authenticationSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="clientSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="offlineClientSessions" mode="SYNC" owners="1"/>
+ <distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
+ <local-cache name="authorization">
+ <eviction max-entries="10000" strategy="LRU"/>
+ </local-cache>
+ <replicated-cache name="work" mode="SYNC"/>
+ <local-cache name="keys">
+ <eviction max-entries="1000" strategy="LRU"/>
+ <expiration max-idle="3600000"/>
+ </local-cache>
+ <distributed-cache name="actionTokens" mode="SYNC" owners="2">
+ <eviction max-entries="-1" strategy="NONE"/>
+ <expiration max-idle="-1" interval="300000"/>
+ </distributed-cache>
+ </cache-container>
+ <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
+ <transport lock-timeout="60000"/>
+ <replicated-cache name="default">
+ <transaction mode="BATCH"/>
+ </replicated-cache>
+ </cache-container>
+ <cache-container name="web" default-cache="dist" module="org.wildfly.clustering.web.infinispan">
+ <transport lock-timeout="60000"/>
+ <distributed-cache name="dist">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store/>
+ </distributed-cache>
+ </cache-container>
+ <cache-container name="ejb" aliases="sfsb" default-cache="dist" module="org.wildfly.clustering.ejb.infinispan">
+ <transport lock-timeout="60000"/>
+ <distributed-cache name="dist">
+ <locking isolation="REPEATABLE_READ"/>
+ <transaction mode="BATCH"/>
+ <file-store/>
+ </distributed-cache>
+ </cache-container>
+ <cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan">
+ <transport lock-timeout="60000"/>
+ <local-cache name="local-query">
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </local-cache>
+ <invalidation-cache name="entity">
+ <transaction mode="NON_XA"/>
+ <eviction strategy="LRU" max-entries="10000"/>
+ <expiration max-idle="100000"/>
+ </invalidation-cache>
+ <replicated-cache name="timestamps" mode="ASYNC"/>
+ </cache-container>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:jca:5.0">
+ <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
+ <bean-validation enabled="true"/>
+ <default-workmanager>
+ <short-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </short-running-threads>
+ <long-running-threads>
+ <core-threads count="50"/>
+ <queue-length count="50"/>
+ <max-threads count="50"/>
+ <keepalive-time time="10" unit="seconds"/>
+ </long-running-threads>
+ </default-workmanager>
+ <cached-connection-manager/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jgroups:5.0">
+ <channels default="ee">
+ <channel name="ee" stack="udp" cluster="ejb"/>
+ </channels>
+ <stacks>
+ <stack name="udp">
+ <transport type="UDP" socket-binding="jgroups-udp"/>
+ <protocol type="PING"/>
+ <protocol type="MERGE3"/>
+ <protocol type="FD_SOCK"/>
+ <protocol type="FD_ALL"/>
+ <protocol type="VERIFY_SUSPECT"/>
+ <protocol type="pbcast.NAKACK2"/>
+ <protocol type="UNICAST3"/>
+ <protocol type="pbcast.STABLE"/>
+ <protocol type="pbcast.GMS"/>
+ <protocol type="UFC"/>
+ <protocol type="MFC"/>
+ <protocol type="FRAG2"/>
+ </stack>
+ <stack name="tcp">
+ <transport type="TCP" socket-binding="jgroups-tcp"/>
+ <socket-protocol type="MPING" socket-binding="jgroups-mping"/>
+ <protocol type="MERGE3"/>
+ <protocol type="FD_SOCK"/>
+ <protocol type="FD_ALL"/>
+ <protocol type="VERIFY_SUSPECT"/>
+ <protocol type="pbcast.NAKACK2"/>
+ <protocol type="UNICAST3"/>
+ <protocol type="pbcast.STABLE"/>
+ <protocol type="pbcast.GMS"/>
+ <protocol type="MFC"/>
+ <protocol type="FRAG2"/>
+ </stack>
+ </stacks>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jmx:1.3">
+ <expose-resolved-model/>
+ <expose-expression-model/>
+ <remoting-connector/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:jpa:1.1">
+ <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:mail:3.0">
+ <mail-session name="default" jndi-name="java:jboss/mail/Default">
+ <smtp-server outbound-socket-binding-ref="mail-smtp"/>
+ </mail-session>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:modcluster:3.0">
+ <mod-cluster-config advertise-socket="modcluster" connector="ajp">
+ <dynamic-load-provider>
+ <load-metric type="cpu"/>
+ </dynamic-load-provider>
+ </mod-cluster-config>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:naming:2.0">
+ <remote-naming/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:remoting:4.0">
+ <endpoint/>
+ <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
+ <subsystem xmlns="urn:jboss:domain:security-manager:1.0">
+ <deployment-permissions>
+ <maximum-set>
+ <permission class="java.security.AllPermission"/>
+ </maximum-set>
+ </deployment-permissions>
+ </subsystem>
+ <subsystem xmlns="urn:wildfly:elytron:1.2" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
+ <providers>
+ <aggregate-providers name="combined-providers">
+ <providers name="elytron"/>
+ <providers name="openssl"/>
+ </aggregate-providers>
+ <provider-loader name="elytron" module="org.wildfly.security.elytron"/>
+ <provider-loader name="openssl" module="org.wildfly.openssl"/>
+ </providers>
+ <audit-logging>
+ <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
+ </audit-logging>
+ <security-domains>
+ <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
+ <realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
+ <realm name="local"/>
+ </security-domain>
+ <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
+ <realm name="ManagementRealm" role-decoder="groups-to-roles"/>
+ <realm name="local" role-mapper="super-user-mapper"/>
+ </security-domain>
+ </security-domains>
+ <security-realms>
+ <identity-realm name="local" identity="$local"/>
+ <properties-realm name="ApplicationRealm">
+ <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
+ <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
+ </properties-realm>
+ <properties-realm name="ManagementRealm">
+ <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
+ <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
+ </properties-realm>
+ </security-realms>
+ <mappers>
+ <simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
+ <permission-mapping>
+ <principal name="anonymous"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ <permission-mapping match-all="true">
+ <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
+ <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
+ <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
+ <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
+ </permission-mapping>
+ </simple-permission-mapper>
+ <constant-realm-mapper name="local" realm-name="local"/>
+ <simple-role-decoder name="groups-to-roles" attribute="groups"/>
+ <constant-role-mapper name="super-user-mapper">
+ <role name="SuperUser"/>
+ </constant-role-mapper>
+ </mappers>
+ <http>
+ <http-authentication-factory name="management-http-authentication" http-server-mechanism-factory="global" security-domain="ManagementDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="DIGEST">
+ <mechanism-realm realm-name="ManagementRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="BASIC">
+ <mechanism-realm realm-name="Application Realm"/>
+ </mechanism>
+ <mechanism mechanism-name="FORM"/>
+ </mechanism-configuration>
+ </http-authentication-factory>
+ <provider-http-server-mechanism-factory name="global"/>
+ </http>
+ <sasl>
+ <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ManagementRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
+ <mechanism-configuration>
+ <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
+ <mechanism mechanism-name="DIGEST-MD5">
+ <mechanism-realm realm-name="ApplicationRealm"/>
+ </mechanism>
+ </mechanism-configuration>
+ </sasl-authentication-factory>
+ <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
+ <properties>
+ <property name="wildfly.sasl.local-user.default-user" value="$local"/>
+ </properties>
+ </configurable-sasl-server-factory>
+ <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
+ <filters>
+ <filter provider-name="WildFlyElytron"/>
+ </filters>
+ </mechanism-provider-filtering-sasl-server-factory>
+ <provider-sasl-server-factory name="global"/>
+ </sasl>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:security:2.0">
+ <security-domains>
+ <security-domain name="other" cache-type="default">
+ <authentication>
+ <login-module code="Remoting" flag="optional">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ <login-module code="RealmDirect" flag="required">
+ <module-option name="password-stacking" value="useFirstPass"/>
+ </login-module>
+ </authentication>
+ </security-domain>
+ <security-domain name="jboss-web-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jboss-ejb-policy" cache-type="default">
+ <authorization>
+ <policy-module code="Delegating" flag="required"/>
+ </authorization>
+ </security-domain>
+ <security-domain name="jaspitest" cache-type="default">
+ <authentication-jaspi>
+ <login-module-stack name="dummy">
+ <login-module code="Dummy" flag="optional"/>
+ </login-module-stack>
+ <auth-module code="Dummy"/>
+ </authentication-jaspi>
+ </security-domain>
+ </security-domains>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:transactions:4.0">
+ <core-environment>
+ <process-id>
+ <uuid/>
+ </process-id>
+ </core-environment>
+ <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
+ <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:undertow:4.0">
+ <buffer-cache name="default"/>
+ <server name="default-server">
+ <ajp-listener name="ajp" socket-binding="ajp"/>
+ <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
+ <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
+ <host name="default-host" alias="localhost">
+ <location name="/" handler="welcome-content"/>
+ <http-invoker security-realm="ApplicationRealm"/>
+ </host>
+ </server>
+ <servlet-container name="default">
+ <jsp-config/>
+ <websockets/>
+ </servlet-container>
+ <handlers>
+ <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
+ </handlers>
+ </subsystem>
+ <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
+ <web-context>auth</web-context>
+ <providers>
+ <provider>classpath:${jboss.home.dir}/providers/*</provider>
+ </providers>
+ <master-realm-name>master</master-realm-name>
+ <scheduled-task-interval>900</scheduled-task-interval>
+ <theme>
+ <staticMaxAge>2592000</staticMaxAge>
+ <cacheThemes>true</cacheThemes>
+ <cacheTemplates>true</cacheTemplates>
+ <dir>${jboss.home.dir}/themes</dir>
+ </theme>
+ <spi name="eventsStore">
+ <provider name="jpa" enabled="true">
+ <properties>
+ <property name="exclude-events" value="["REFRESH_TOKEN"]"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="userCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="userSessionPersister">
+ <default-provider>jpa</default-provider>
+ </spi>
+ <spi name="timer">
+ <default-provider>basic</default-provider>
+ </spi>
+ <spi name="connectionsHttpClient">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsJpa">
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
+ <property name="initializeEmpty" value="true"/>
+ <property name="migrationStrategy" value="update"/>
+ <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="realmCache">
+ <provider name="default" enabled="true"/>
+ </spi>
+ <spi name="connectionsInfinispan">
+ <default-provider>default</default-provider>
+ <provider name="default" enabled="true">
+ <properties>
+ <property name="cacheContainer" value="java:comp/env/infinispan/Keycloak"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="jta-lookup">
+ <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
+ <provider name="jboss" enabled="true"/>
+ </spi>
+ <spi name="publicKeyStorage">
+ <provider name="infinispan" enabled="true">
+ <properties>
+ <property name="minTimeBetweenRequests" value="10"/>
+ </properties>
+ </provider>
+ </spi>
+ <spi name="x509cert-lookup">
+ <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
+ <provider name="default" enabled="true"/>
+ </spi>
+ </subsystem>
+ </profile>
+ <interfaces>
+ <interface name="management">
+ <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
+ </interface>
+ <interface name="public">
+ <inet-address value="${jboss.bind.address:127.0.0.1}"/>
+ </interface>
+ <interface name="private">
+ <inet-address value="${jboss.bind.address.private:127.0.0.1}"/>
+ </interface>
+ </interfaces>
+ <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+ <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
+ <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
+ <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
+ <socket-binding name="http" port="${jboss.http.port:8080}"/>
+ <socket-binding name="https" port="${jboss.https.port:8443}"/>
+ <socket-binding name="jgroups-mping" interface="private" port="0" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
+ <socket-binding name="jgroups-tcp" interface="private" port="7600"/>
+ <socket-binding name="jgroups-udp" interface="private" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
+ <socket-binding name="modcluster" port="0" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
+ <socket-binding name="txn-recovery-environment" port="4712"/>
+ <socket-binding name="txn-status-manager" port="4713"/>
+ <outbound-socket-binding name="mail-smtp">
+ <remote-destination host="localhost" port="25"/>
+ </outbound-socket-binding>
+ </socket-binding-group>
+</server>
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 8bfbce3..56fb882 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -950,7 +950,7 @@
<cache.server.jboss>true</cache.server.jboss>
<cache.server.config.dir>${cache.server.home}/standalone/configuration</cache.server.config.dir>
<keycloak.testsuite.logging.pattern>%d{HH:mm:ss,SSS} [%t] %-5p [%c{1.}] %m%n</keycloak.testsuite.logging.pattern>
- <keycloak.connectionsInfinispan.default.remoteStoreSecurityEnabled>true</keycloak.connectionsInfinispan.default.remoteStoreSecurityEnabled>
+ <keycloak.connectionsInfinispan.default.remoteStoreSecurityEnabled>false</keycloak.connectionsInfinispan.default.remoteStoreSecurityEnabled>
</properties>
<dependencies>
<dependency>
diff --git a/testsuite/integration-deprecated/pom.xml b/testsuite/integration-deprecated/pom.xml
index 20e7d18..0be943c 100755
--- a/testsuite/integration-deprecated/pom.xml
+++ b/testsuite/integration-deprecated/pom.xml
@@ -66,7 +66,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
testsuite/jetty/jetty92/pom.xml 2(+1 -1)
diff --git a/testsuite/jetty/jetty92/pom.xml b/testsuite/jetty/jetty92/pom.xml
index 7a37a58..a3a3cfe 100755
--- a/testsuite/jetty/jetty92/pom.xml
+++ b/testsuite/jetty/jetty92/pom.xml
@@ -67,7 +67,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
testsuite/jetty/jetty93/pom.xml 2(+1 -1)
diff --git a/testsuite/jetty/jetty93/pom.xml b/testsuite/jetty/jetty93/pom.xml
index 8e2cde0..5f5192d 100644
--- a/testsuite/jetty/jetty93/pom.xml
+++ b/testsuite/jetty/jetty93/pom.xml
@@ -67,7 +67,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
testsuite/jetty/jetty94/pom.xml 2(+1 -1)
diff --git a/testsuite/jetty/jetty94/pom.xml b/testsuite/jetty/jetty94/pom.xml
index d6a6aa6..d579071 100644
--- a/testsuite/jetty/jetty94/pom.xml
+++ b/testsuite/jetty/jetty94/pom.xml
@@ -67,7 +67,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
diff --git a/testsuite/performance/keycloak/src/main/scripts/jboss-cli/add-remote-cache-stores.cli b/testsuite/performance/keycloak/src/main/scripts/jboss-cli/add-remote-cache-stores.cli
index e4b707e..e9f6174 100644
--- a/testsuite/performance/keycloak/src/main/scripts/jboss-cli/add-remote-cache-stores.cli
+++ b/testsuite/performance/keycloak/src/main/scripts/jboss-cli/add-remote-cache-stores.cli
@@ -16,5 +16,5 @@ cd /subsystem=infinispan/cache-container=keycloak
./distributed-cache=loginFailures/store=remote:add(cache=loginFailures, fetch-state=false, passivation=false, preload=false, purge=false, remote-servers=["remote-cache"], shared=true, properties={rawValues=true, marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory})
./distributed-cache=actionTokens/store=remote:add(cache=actionTokens, fetch-state=false, passivation=false, preload=false, purge=false, remote-servers=["remote-cache"], shared=true, properties={rawValues=true, marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory})
-./distributed-cache=actionTokens/eviction=EVICTION:add(max-entries=-1, strategy=NONE)
+./distributed-cache=actionTokens/memory-object:add(size=-1)
./distributed-cache=actionTokens/expiration=EXPIRATION:add(max-idle=-1,interval=300000)
\ No newline at end of file
testsuite/performance/tests/pom.xml 2(+1 -1)
diff --git a/testsuite/performance/tests/pom.xml b/testsuite/performance/tests/pom.xml
index 8aff879..f43fe1c 100644
--- a/testsuite/performance/tests/pom.xml
+++ b/testsuite/performance/tests/pom.xml
@@ -129,7 +129,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
testsuite/proxy/pom.xml 2(+1 -1)
diff --git a/testsuite/proxy/pom.xml b/testsuite/proxy/pom.xml
index 64a29b9..fd78932 100755
--- a/testsuite/proxy/pom.xml
+++ b/testsuite/proxy/pom.xml
@@ -58,7 +58,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
testsuite/tomcat7/pom.xml 2(+1 -1)
diff --git a/testsuite/tomcat7/pom.xml b/testsuite/tomcat7/pom.xml
index f175e06..3173f2d 100755
--- a/testsuite/tomcat7/pom.xml
+++ b/testsuite/tomcat7/pom.xml
@@ -81,7 +81,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
testsuite/tomcat8/pom.xml 2(+1 -1)
diff --git a/testsuite/tomcat8/pom.xml b/testsuite/tomcat8/pom.xml
index 59424a9..2111bdc 100755
--- a/testsuite/tomcat8/pom.xml
+++ b/testsuite/tomcat8/pom.xml
@@ -53,7 +53,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
testsuite/utils/pom.xml 2(+1 -1)
diff --git a/testsuite/utils/pom.xml b/testsuite/utils/pom.xml
index 706c0cd..5017aee 100755
--- a/testsuite/utils/pom.xml
+++ b/testsuite/utils/pom.xml
@@ -79,7 +79,7 @@
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
- <artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
+ <artifactId>jboss-jaxrs-api_2.1_spec</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
diff --git a/testsuite/utils/src/main/resources/META-INF/keycloak-server.json b/testsuite/utils/src/main/resources/META-INF/keycloak-server.json
index d7aa39a..8da4160 100755
--- a/testsuite/utils/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/utils/src/main/resources/META-INF/keycloak-server.json
@@ -104,13 +104,7 @@
"l1Lifespan": "${keycloak.connectionsInfinispan.l1Lifespan:600000}",
"remoteStoreEnabled": "${keycloak.connectionsInfinispan.remoteStoreEnabled:false}",
"remoteStoreHost": "${keycloak.connectionsInfinispan.remoteStoreServer:localhost}",
- "remoteStorePort": "${keycloak.connectionsInfinispan.remoteStorePort:11222}",
- "remoteStoreSecurityEnabled": "${keycloak.connectionsInfinispan.remoteStoreSecurityEnabled:false}",
- "remoteStoreSecurityServerName": "${keycloak.connectionsInfinispan.remoteStoreSecurityServerName:keycloak-server}",
- "remoteStoreSecurityRealm": "${keycloak.connectionsInfinispan.remoteStoreSecurityRealm:ApplicationRealm}",
- "remoteStoreSecurityHotRodEndpoint": "${keycloak.connectionsInfinispan.remoteStoreSecurityHotRodEndpoint}",
- "remoteStoreSecurityUsername": "${keycloak.connectionsInfinispan.remoteStoreSecurityUsername}",
- "remoteStoreSecurityPassword": "${keycloak.connectionsInfinispan.remoteStoreSecurityPassword}"
+ "remoteStorePort": "${keycloak.connectionsInfinispan.remoteStorePort:11222}"
}
},
wildfly/adduser/pom.xml 6(+5 -1)
diff --git a/wildfly/adduser/pom.xml b/wildfly/adduser/pom.xml
index 981f7f2..b1fb823 100755
--- a/wildfly/adduser/pom.xml
+++ b/wildfly/adduser/pom.xml
@@ -52,8 +52,12 @@
<version>${wildfly.core.version}</version>
</dependency>
<dependency>
- <groupId>org.jboss.aesh</groupId>
+ <groupId>org.aesh</groupId>
<artifactId>aesh</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.aesh</groupId>
+ <artifactId>aesh-readline</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java b/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
index 4a7c9a1..6edb948 100644
--- a/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
+++ b/wildfly/adduser/src/main/java/org/keycloak/wildfly/adduser/AddUser.java
@@ -18,16 +18,28 @@
package org.keycloak.wildfly.adduser;
import com.fasterxml.jackson.core.type.TypeReference;
-import org.jboss.aesh.cl.CommandDefinition;
-import org.jboss.aesh.cl.Option;
-import org.jboss.aesh.cl.parser.ParserGenerator;
-import org.jboss.aesh.console.command.Command;
-import org.jboss.aesh.console.command.CommandNotFoundException;
-import org.jboss.aesh.console.command.CommandResult;
-import org.jboss.aesh.console.command.container.CommandContainer;
-import org.jboss.aesh.console.command.invocation.CommandInvocation;
-import org.jboss.aesh.console.command.registry.AeshCommandRegistryBuilder;
-import org.jboss.aesh.console.command.registry.CommandRegistry;
+import org.aesh.command.CommandDefinition;
+import org.aesh.command.impl.activator.AeshCommandActivatorProvider;
+import org.aesh.command.impl.activator.AeshOptionActivatorProvider;
+import org.aesh.command.impl.completer.AeshCompleterInvocationProvider;
+import org.aesh.command.impl.container.AeshCommandContainerBuilder;
+import org.aesh.command.impl.converter.AeshConverterInvocationProvider;
+import org.aesh.command.impl.invocation.AeshInvocationProviders;
+import org.aesh.command.impl.parser.CommandLineParser;
+import org.aesh.command.impl.validator.AeshValidatorInvocationProvider;
+import org.aesh.command.invocation.InvocationProviders;
+import org.aesh.command.option.Option;
+import org.aesh.command.Command;
+import org.aesh.command.CommandNotFoundException;
+import org.aesh.command.CommandResult;
+import org.aesh.command.container.CommandContainer;
+import org.aesh.command.invocation.CommandInvocation;
+import org.aesh.command.impl.registry.AeshCommandRegistryBuilder;
+import org.aesh.command.parser.CommandLineParserException;
+import org.aesh.command.registry.CommandRegistry;
+import org.aesh.command.settings.Settings;
+import org.aesh.command.settings.SettingsBuilder;
+import org.aesh.readline.AeshContext;
import org.keycloak.common.util.Base64;
import org.keycloak.credential.CredentialModel;
import org.keycloak.credential.hash.PasswordHashProvider;
@@ -57,34 +69,41 @@ public class AddUser {
private static final int DEFAULT_HASH_ITERATIONS = 100000;
private static final String DEFAULT_HASH_ALGORITH = PasswordPolicy.HASH_ALGORITHM_DEFAULT;
- public static void main(String[] args) throws Exception {
- AddUserCommand command = new AddUserCommand();
+ public static void main(String[] args) {
+ AddUserCommand command;
try {
- ParserGenerator.parseAndPopulate(command, COMMAND_NAME, args);
- } catch (Exception e) {
- System.err.println(e.getMessage());
- System.exit(1);
- }
+ Settings settings = SettingsBuilder.builder().build();
+ InvocationProviders invocationProviders = new AeshInvocationProviders(settings);
+ AeshContext aeshContext = settings.aeshContext();
+ CommandLineParser<AddUserCommand<CommandInvocation>> parser = new AeshCommandContainerBuilder<AddUserCommand<CommandInvocation>, CommandInvocation>().create(new AddUserCommand<>()).getParser();
+
+ StringBuilder sb = new StringBuilder(COMMAND_NAME);
+ for (String arg : args) {
+ sb.append(" " + arg);
+ }
+ parser.populateObject(sb.toString(), invocationProviders, aeshContext, CommandLineParser.Mode.VALIDATE);
+ command = parser.getCommand();
- if (command.isHelp()) {
- printHelp(command);
- } else {
- try {
+ if (command.isHelp()) {
+ printHelp(command);
+ } else {
String password = command.getPassword();
checkRequired(command, "user");
- if(isEmpty(command, "password")){
+ if (isEmpty(command, "password")) {
password = promptForInput();
}
File addUserFile = getAddUserFile(command);
createUser(addUserFile, command.getRealm(), command.getUser(), password, command.getRoles(), command.getIterations());
- } catch (Exception e) {
- System.err.println(e.getMessage());
- System.exit(1);
}
}
+ catch (Exception e){
+ System.err.println(e.getMessage());
+ System.exit(1);
+ }
+
}
private static File getAddUserFile(AddUserCommand command) throws Exception {
@@ -255,7 +274,7 @@ public class AddUser {
return new String(passwordArray);
}
- private static void printHelp(Command command) throws CommandNotFoundException {
+ private static void printHelp(Command command) throws CommandNotFoundException, CommandLineParserException {
CommandRegistry registry = new AeshCommandRegistryBuilder().command(command).create();
CommandContainer commandContainer = registry.getCommand(command.getClass().getAnnotation(CommandDefinition.class).name(), null);
String help = commandContainer.printHelp(null);
@@ -263,7 +282,7 @@ public class AddUser {
}
@CommandDefinition(name= COMMAND_NAME, description = "[options...]")
- public static class AddUserCommand implements Command {
+ public static class AddUserCommand<CI extends CommandInvocation> implements Command<CI> {
@Option(shortName = 'r', hasValue = true, description = "Name of realm to add user to")
private String realm;
diff --git a/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties b/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties
index aaecc2c..23f862b 100644
--- a/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties
+++ b/wildfly/server-subsystem/src/main/config/default-server-subsys-config.properties
@@ -58,7 +58,7 @@ keycloak.server.subsys.default.config=\
<default-provider>default</default-provider>\
<provider name="default" enabled="true">\
<properties>\
- <property name="cacheContainer" value="java:comp/env/infinispan/Keycloak"/>\
+ <property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>\
</properties>\
</provider>\
</spi>\
diff --git a/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli b/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli
index 26c6a8a..6e14be6 100644
--- a/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli
+++ b/wildfly/server-subsystem/src/main/resources/cli/default-keycloak-subsys-config.cli
@@ -15,7 +15,7 @@
/subsystem=keycloak-server/spi=realmCache/:add
/subsystem=keycloak-server/spi=realmCache/provider=default/:add(enabled=true)
/subsystem=keycloak-server/spi=connectionsInfinispan/:add(default-provider=default)
-/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default/:add(properties={cacheContainer => "java:comp/env/infinispan/Keycloak"},enabled=true)
+/subsystem=keycloak-server/spi=connectionsInfinispan/provider=default/:add(properties={cacheContainer => "java:jboss/infinispan/container/keycloak"},enabled=true)
/subsystem=keycloak-server/spi=jta-lookup/:add(default-provider=${keycloak.jta.lookup.provider:jboss})
/subsystem=keycloak-server/spi=jta-lookup/provider=jboss/:add(enabled=true)
/subsystem=keycloak-server/spi=publicKeyStorage/:add
diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
index b3ea2a9..f1edb80 100755
--- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
+++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
@@ -19,17 +19,17 @@
<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
<config default-supplement="default">
<extension-module>org.jboss.as.clustering.infinispan</extension-module>
- <subsystem xmlns="urn:jboss:domain:infinispan:4.0">
+ <subsystem xmlns="urn:jboss:domain:infinispan:6.0">
<?CACHE-CONTAINERS?>
</subsystem>
<supplement name="default">
<replacement placeholder="CACHE-CONTAINERS">
- <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <cache-container name="keycloak">
<local-cache name="realms">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="users">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
@@ -39,14 +39,14 @@
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="authorization">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="keys">
- <eviction max-entries="1000" strategy="LRU"/>
+ <object-memory size="1000"/>
<expiration max-idle="3600000" />
</local-cache>
<local-cache name="actionTokens">
- <eviction max-entries="-1" strategy="NONE"/>
+ <object-memory size="-1"/>
<expiration max-idle="-1" interval="300000"/>
</local-cache>
</cache-container>
@@ -69,14 +69,14 @@
<file-store passivation="true" purge="false"/>
</local-cache>
</cache-container>
- <cache-container name="hibernate" module="org.hibernate.infinispan">
+ <cache-container name="hibernate" module="org.infinispan.hibernate-cache">
<local-cache name="entity">
<transaction mode="NON_XA"/>
- <eviction strategy="LRU" max-entries="10000"/>
+ <object-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
- <eviction strategy="LRU" max-entries="10000"/>
+ <object-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps"/>
@@ -85,30 +85,30 @@
</supplement>
<supplement name="ha">
<replacement placeholder="CACHE-CONTAINERS">
- <cache-container name="keycloak" jndi-name="infinispan/Keycloak">
+ <cache-container name="keycloak">
<transport lock-timeout="60000"/>
<local-cache name="realms">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
<local-cache name="users">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
- <distributed-cache name="sessions" mode="SYNC" owners="1"/>
- <distributed-cache name="authenticationSessions" mode="SYNC" owners="1"/>
- <distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
- <distributed-cache name="clientSessions" mode="SYNC" owners="1"/>
- <distributed-cache name="offlineClientSessions" mode="SYNC" owners="1"/>
- <distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
+ <distributed-cache name="sessions" owners="1"/>
+ <distributed-cache name="authenticationSessions" owners="1"/>
+ <distributed-cache name="offlineSessions" owners="1"/>
+ <distributed-cache name="clientSessions" owners="1"/>
+ <distributed-cache name="offlineClientSessions" owners="1"/>
+ <distributed-cache name="loginFailures" owners="1"/>
<local-cache name="authorization">
- <eviction max-entries="10000" strategy="LRU"/>
+ <object-memory size="10000"/>
</local-cache>
- <replicated-cache name="work" mode="SYNC" />
+ <replicated-cache name="work" />
<local-cache name="keys">
- <eviction max-entries="1000" strategy="LRU"/>
+ <object-memory size="1000"/>
<expiration max-idle="3600000" />
</local-cache>
- <distributed-cache name="actionTokens" mode="SYNC" owners="2">
- <eviction max-entries="-1" strategy="NONE"/>
+ <distributed-cache name="actionTokens" owners="2">
+ <object-memory size="-1"/>
<expiration max-idle="-1" interval="300000"/>
</distributed-cache>
</cache-container>
@@ -134,18 +134,18 @@
<file-store/>
</distributed-cache>
</cache-container>
- <cache-container name="hibernate" default-cache="local-query" module="org.hibernate.infinispan">
+ <cache-container name="hibernate" module="org.infinispan.hibernate-cache">
<transport lock-timeout="60000"/>
<local-cache name="local-query">
- <eviction strategy="LRU" max-entries="10000"/>
+ <object-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<invalidation-cache name="entity">
<transaction mode="NON_XA"/>
- <eviction strategy="LRU" max-entries="10000"/>
+ <object-memory size="10000"/>
<expiration max-idle="100000"/>
</invalidation-cache>
- <replicated-cache name="timestamps" mode="ASYNC"/>
+ <replicated-cache name="timestamps"/>
</cache-container>
</replacement>
</supplement>
diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-undertow.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-undertow.xml
index db46210..715d136 100644
--- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-undertow.xml
+++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-undertow.xml
@@ -1,30 +1,37 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
- ~ Copyright 2016 Red Hat, Inc. and/or its affiliates
- ~ and other contributors as indicated by the @author tags.
+ ~ JBoss, Home of Professional Open Source.
+ ~ Copyright 2017, Red Hat, Inc., and individual contributors
+ ~ as indicated by the @author tags. See the copyright.txt file in the
+ ~ distribution for a full listing of individual contributors.
~
- ~ Licensed 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
+ ~ This is free software; you can redistribute it and/or modify it
+ ~ under the terms of the GNU Lesser General Public License as
+ ~ published by the Free Software Foundation; either version 2.1 of
+ ~ the License, or (at your option) any later version.
~
- ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~ This software is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ ~ Lesser General Public License for more details.
~
- ~ 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.
+ ~ You should have received a copy of the GNU Lesser General Public
+ ~ License along with this software; if not, write to the Free
+ ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->
+
+<!-- See src/resources/configuration/ReadMe.txt for how the configuration assembly works -->
<config>
<extension-module>org.wildfly.extension.undertow</extension-module>
- <subsystem xmlns="urn:jboss:domain:undertow:4.0">
- <buffer-cache name="default" />
+ <subsystem xmlns="urn:jboss:domain:undertow:6.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
+ <buffer-cache name="default"/>
<server name="default-server">
<?AJP?>
- <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" />
- <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true" />
+ <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
+ <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
- <location name="/" handler="welcome-content" />
+ <location name="/" handler="welcome-content"/>
<http-invoker security-realm="ApplicationRealm"/>
</host>
</server>
@@ -33,7 +40,7 @@
<websockets/>
</servlet-container>
<handlers>
- <file name="welcome-content" path="${jboss.home.dir}/welcome-content" />
+ <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
</subsystem>
<supplement name="ha">
@@ -45,3 +52,4 @@
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
</config>
+
diff --git a/wildfly/server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/JsonConfigConverterTestCase.java b/wildfly/server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/JsonConfigConverterTestCase.java
index 9931b4d..7752258 100644
--- a/wildfly/server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/JsonConfigConverterTestCase.java
+++ b/wildfly/server-subsystem/src/test/java/org/keycloak/subsystem/server/extension/JsonConfigConverterTestCase.java
@@ -166,7 +166,7 @@ public class JsonConfigConverterTestCase {
+ " \"connectionsInfinispan\": {\n"
+ " \"provider\": \"default\",\n"
+ " \"default\": {\n"
- + " \"cacheContainer\" : \"java:comp/env/infinispan/Keycloak\"\n"
+ + " \"cacheContainer\" : \"java:jboss/infinispan/container/keycloak\"\n"
+ " }\n"
+ " }\n"
+ "}";
@@ -429,7 +429,7 @@ public class JsonConfigConverterTestCase {
" (\"spi\" => \"connectionsInfinispan\"),\n" +
" (\"provider\" => \"default\")\n" +
" ],\n" +
- " \"properties\" => {\"cacheContainer\" => \"java:comp/env/infinispan/Keycloak\"},\n" +
+ " \"properties\" => {\"cacheContainer\" => \"java:jboss/infinispan/container/keycloak\"},\n" +
" \"enabled\" => true\n" +
"}"
));