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 871c7417b7..3eb35ada80 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
@@ -21,10 +21,7 @@ import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.concurrent.TimeUnit;
-import org.infinispan.Cache;
import org.infinispan.client.hotrod.ProtocolVersion;
-import org.infinispan.client.hotrod.RemoteCache;
-import org.infinispan.commons.configuration.Builder;
import org.infinispan.commons.util.FileLookup;
import org.infinispan.commons.util.FileLookupFactory;
import org.infinispan.configuration.cache.CacheMode;
@@ -465,8 +462,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
System.setProperty(InfinispanConnectionProvider.JGROUPS_UDP_MCAST_ADDR, jgroupsUdpMcastAddr);
}
try {
- // Compatibility with Wildfly
- JChannel channel = new JChannel(fileLookup.lookupFileLocation("default-configs/default-jgroups-udp.xml", this.getClass().getClassLoader()).openStream());
+ JChannel channel = new JChannel(fileLookup.lookupFileLocation("default-configs/default-keycloak-jgroups-udp.xml", this.getClass().getClassLoader()).openStream());
channel.setName(nodeName);
JGroupsTransport transport = new JGroupsTransport(channel);
@@ -482,7 +478,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
transportBuilder.jmx()
- .jmxDomain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + nodeName)
+ .domain(InfinispanConnectionProvider.JMX_DOMAIN + "-" + nodeName)
.enable();
logger.infof("Configured jgroups transport with the channel name: %s", nodeName);
diff --git a/model/infinispan/src/main/resources/default-configs/default-keycloak-jgroups-udp.xml b/model/infinispan/src/main/resources/default-configs/default-keycloak-jgroups-udp.xml
new file mode 100644
index 0000000000..0971e53c17
--- /dev/null
+++ b/model/infinispan/src/main/resources/default-configs/default-keycloak-jgroups-udp.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/services/src/main/java/org/keycloak/services/filters/AbstractRequestFilter.java b/services/src/main/java/org/keycloak/services/filters/AbstractRequestFilter.java
index edf00ed353..2672acd891 100644
--- a/services/src/main/java/org/keycloak/services/filters/AbstractRequestFilter.java
+++ b/services/src/main/java/org/keycloak/services/filters/AbstractRequestFilter.java
@@ -30,7 +30,7 @@ import org.keycloak.services.resources.KeycloakApplication;
public abstract class AbstractRequestFilter {
protected void filter(ClientConnection clientConnection, Consumer next) {
- KeycloakSessionFactory sessionFactory = KeycloakApplication.getSessionFactory();
+ KeycloakSessionFactory sessionFactory = getSessionFactory();
KeycloakSession session = sessionFactory.create();
KeycloakTransactionManager tx = session.getTransactionManager();
@@ -51,6 +51,10 @@ public abstract class AbstractRequestFilter {
}
}
+ protected KeycloakSessionFactory getSessionFactory() {
+ return KeycloakApplication.getSessionFactory();
+ }
+
protected void close(KeycloakSession session) {
KeycloakTransactionManager tx = session.getTransactionManager();
if (tx.isActive()) {
diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java
index 1432509ce2..92b3bb7b6a 100644
--- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java
+++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java
@@ -39,7 +39,6 @@ import org.jboss.logging.Logger;
import org.jboss.resteasy.plugins.server.servlet.ResteasyContextParameters;
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
import org.jboss.resteasy.spi.ResteasyDeployment;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
@@ -57,6 +56,7 @@ import org.keycloak.testsuite.utils.undertow.UndertowDeployerHelper;
import org.keycloak.testsuite.utils.undertow.UndertowWarClassLoader;
import org.keycloak.util.JsonSerialization;
+import io.undertow.servlet.api.InstanceHandle;
import javax.servlet.DispatcherType;
import javax.servlet.ServletException;
import java.io.IOException;
@@ -64,6 +64,7 @@ import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import javax.servlet.Filter;
import org.xnio.Options;
import org.xnio.SslClientAuthMode;
@@ -103,7 +104,20 @@ public class KeycloakOnUndertow implements DeployableContainer filterInstance = new InstanceHandle() {
+ @Override
+ public Filter getInstance() {
+ return new UndertowRequestFilter(sessionFactory);
+ }
+
+ @Override
+ public void release() {
+ }
+ };
+ FilterInfo filter = Servlets.filter("SessionFilter", UndertowRequestFilter.class, () -> filterInstance);
di.addFilter(filter);
di.addFilterUrlMapping("SessionFilter", "/*", DispatcherType.REQUEST);
filter.setAsyncSupported(true);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractInvalidationClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractInvalidationClusterTest.java
index 33d82970d3..960e6be485 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractInvalidationClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/AbstractInvalidationClusterTest.java
@@ -49,28 +49,37 @@ public abstract class AbstractInvalidationClusterTest extends AbstractClu
public void crud(boolean backendFailover) {
T testEntity = createTestEntityRepresentation();
- // CREATE
+ // CREATE
+ log.info("(1) createEntityOnCurrentFailNode");
testEntity = createEntityOnCurrentFailNode(testEntity);
if (backendFailover) {
+ log.info("(2) failure");
failure();
}
+ log.info("(3) assertEntityOnSurvivorNodesEqualsTo");
assertEntityOnSurvivorNodesEqualsTo(testEntity);
+ log.info("(4) failback");
failback();
+ log.info("(5) iterateCurrentFailNode");
iterateCurrentFailNode();
// UPDATE(s)
+ log.info("(6) testEntityUpdates");
testEntity = testEntityUpdates(testEntity, backendFailover);
// DELETE
+ log.info("(7) deleteEntityOnCurrentFailNode");
deleteEntityOnCurrentFailNode(testEntity);
if (backendFailover) {
+ log.info("(8) failure");
failure();
}
+ log.info("(9) assertEntityOnSurvivorNodesIsDeleted");
assertEntityOnSurvivorNodesIsDeleted(testEntity);
}
@@ -136,6 +145,7 @@ public abstract class AbstractInvalidationClusterTest extends AbstractClu
protected void assertEntityOnSurvivorNodesEqualsTo(T testEntityOnFailNode) {
boolean entityDiffers = false;
for (ContainerInfo survivorNode : getCurrentSurvivorNodes()) {
+ log.debug(String.format("Attempt to verify %s on survivor %s (%s)", getEntityType(testEntityOnFailNode), survivorNode, survivorNode.getContextRoot()));
T testEntityOnSurvivorNode = readEntity(testEntityOnFailNode, survivorNode);
if (EqualsBuilder.reflectionEquals(sortFields(testEntityOnSurvivorNode), sortFields(testEntityOnFailNode), excludedComparisonFields)) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/ClientInvalidationClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/ClientInvalidationClusterTest.java
index e4903dc26a..1344d77e8f 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/ClientInvalidationClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/ClientInvalidationClusterTest.java
@@ -4,7 +4,6 @@ import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientsResource;
-import org.keycloak.common.util.Retry;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.ContainerInfo;
@@ -59,38 +58,24 @@ public class ClientInvalidationClusterTest extends AbstractInvalidationClusterTe
@Override
protected ClientRepresentation readEntity(ClientRepresentation client, ContainerInfo node) {
- ClientRepresentation u = Retry.call(new Retry.Supplier() {
- @Override
- public ClientRepresentation get(int iteration) {
- try {
- return entityResource(client, node).toRepresentation();
- } catch (NotFoundException nfe) {
- return null;
- }
- }
- }, 3, 5000);
+ ClientRepresentation u = null;
+ try {
+ u = entityResource(client, node).toRepresentation();
+ } catch (NotFoundException nfe) {
+ // expected when client doesn't exist
+ }
return u;
}
@Override
protected ClientRepresentation updateEntity(ClientRepresentation client, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(client, node).update(client);
- }
- }, 3, 5000);
+ entityResource(client, node).update(client);
return readEntity(client, node);
}
@Override
protected void deleteEntity(ClientRepresentation client, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(client, node).remove();
- }
- }, 3, 5000);
+ entityResource(client, node).remove();
assertNull(readEntity(client, node));
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/GroupInvalidationClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/GroupInvalidationClusterTest.java
index d45bc5599f..b97d6e91e6 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/GroupInvalidationClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/GroupInvalidationClusterTest.java
@@ -4,7 +4,6 @@ import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
import org.keycloak.admin.client.resource.GroupResource;
import org.keycloak.admin.client.resource.GroupsResource;
-import org.keycloak.common.util.Retry;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.ContainerInfo;
@@ -67,38 +66,24 @@ public class GroupInvalidationClusterTest extends AbstractInvalidationClusterTes
@Override
protected GroupRepresentation readEntity(GroupRepresentation group, ContainerInfo node) {
- GroupRepresentation u = Retry.call(new Retry.Supplier() {
- @Override
- public GroupRepresentation get(int iteration) {
- try {
- return entityResource(group, node).toRepresentation();
- } catch (NotFoundException nfe) {
- return null;
- }
- }
- }, 3, 5000);
+ GroupRepresentation u = null;
+ try {
+ u = entityResource(group, node).toRepresentation();
+ } catch (NotFoundException nfe) {
+ // expected when group doesn't exist
+ }
return u;
}
@Override
protected GroupRepresentation updateEntity(GroupRepresentation group, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(group, node).update(group);
- }
- }, 3, 5000);
+ entityResource(group, node).update(group);
return readEntity(group, node);
}
@Override
protected void deleteEntity(GroupRepresentation group, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(group, node).remove();
- }
- }, 3, 5000);
+ entityResource(group, node).remove();
assertNull(readEntity(group, node));
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RealmInvalidationClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RealmInvalidationClusterTest.java
index ed7562bae0..a054e7efbb 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RealmInvalidationClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RealmInvalidationClusterTest.java
@@ -2,7 +2,6 @@ package org.keycloak.testsuite.cluster;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RealmsResource;
-import org.keycloak.common.util.Retry;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.arquillian.ContainerInfo;
@@ -44,16 +43,12 @@ public class RealmInvalidationClusterTest extends AbstractInvalidationClusterTes
@Override
protected RealmRepresentation readEntity(RealmRepresentation realm, ContainerInfo node) {
- RealmRepresentation realmOnNode = Retry.call(new Retry.Supplier() {
- @Override
- public RealmRepresentation get(int iteration) {
- try {
- return entityResource(realm, node).toRepresentation();
- } catch (NotFoundException nfe) {
- return null;
- }
- }
- }, 3, 5000);
+ RealmRepresentation realmOnNode = null;
+ try {
+ realmOnNode = entityResource(realm, node).toRepresentation();
+ } catch (NotFoundException nfe) {
+ // expected if realm not found
+ }
return realmOnNode;
}
@@ -63,12 +58,7 @@ public class RealmInvalidationClusterTest extends AbstractInvalidationClusterTes
}
private RealmRepresentation updateEntity(String realmName, RealmRepresentation realm, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(realmName, node).update(realm);
- }
- }, 3, 5000);
+ entityResource(realmName, node).update(realm);
return readEntity(realm, node);
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RoleInvalidationClusterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RoleInvalidationClusterTest.java
index d776568843..c3ae0ea9dd 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RoleInvalidationClusterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cluster/RoleInvalidationClusterTest.java
@@ -3,7 +3,6 @@ package org.keycloak.testsuite.cluster;
import org.apache.commons.lang.RandomStringUtils;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RolesResource;
-import org.keycloak.common.util.Retry;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.testsuite.arquillian.ContainerInfo;
@@ -49,16 +48,11 @@ public class RoleInvalidationClusterTest extends AbstractInvalidationClusterTest
@Override
protected RoleRepresentation readEntity(RoleRepresentation role, ContainerInfo node) {
RoleRepresentation u = null;
- u = Retry.call(new Retry.Supplier() {
- @Override
- public RoleRepresentation get(int iteration) {
- try {
- return entityResource(role, node).toRepresentation();
- } catch (NotFoundException nfe) {
- return null;
- }
- }
- }, 3, 5000);
+ try {
+ u = entityResource(role, node).toRepresentation();
+ } catch (NotFoundException nfe) {
+ // expected when role doesn't exist
+ }
return u;
}
@@ -68,23 +62,13 @@ public class RoleInvalidationClusterTest extends AbstractInvalidationClusterTest
}
private RoleRepresentation updateEntity(String roleName, RoleRepresentation role, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(roleName, node).update(role);
- }
- }, 3, 5000);
+ entityResource(roleName, node).update(role);
return readEntity(role, node);
}
@Override
protected void deleteEntity(RoleRepresentation role, ContainerInfo node) {
- Retry.execute(new Runnable() {
- @Override
- public void run() {
- entityResource(role, node).remove();
- }
- }, 3, 5000);
+ entityResource(role, node).remove();
assertNull(readEntity(role, node));
}
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index d20a8dc107..a506ee104e 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -641,6 +641,7 @@
${keycloak.connectionsInfinispan.remoteStorePort}
${keycloak.connectionsInfinispan.remoteStorePort.2}
${keycloak.connectionsInfinispan.remoteStoreServer}
+ ${keycloak.connectionsInfinispan.sessionsOwners}
${keycloak.testsuite.logging.pattern}
${keycloak.connectionsJpa.url.crossdc}
@@ -771,6 +772,7 @@
false
true
true
+ 2
@@ -1246,6 +1248,7 @@
true
+ 2
diff --git a/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java
index e4bf8c9412..10509d8210 100755
--- a/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java
+++ b/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java
@@ -37,6 +37,7 @@ import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.KeycloakApplication;
import org.keycloak.testsuite.util.cli.TestsuiteCLI;
import org.keycloak.util.JsonSerialization;
+import io.undertow.servlet.api.InstanceHandle;
import org.xnio.Options;
import org.xnio.SslClientAuthMode;
@@ -58,6 +59,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
+import javax.servlet.Filter;
/**
* @author Stian Thorgersen
@@ -406,7 +408,17 @@ public class KeycloakServer {
// KEYCLOAK-14178
deployment.setProperty(ResteasyContextParameters.RESTEASY_DISABLE_HTML_SANITIZER, true);
- FilterInfo filter = Servlets.filter("SessionFilter", UndertowRequestFilter.class);
+ InstanceHandle filterInstance = new InstanceHandle() {
+ @Override
+ public Filter getInstance() {
+ return new UndertowRequestFilter(sessionFactory);
+ }
+
+ @Override
+ public void release() {
+ }
+ };
+ FilterInfo filter = Servlets.filter("SessionFilter", UndertowRequestFilter.class, () -> filterInstance);
filter.setAsyncSupported(true);
di.addFilter(filter);
diff --git a/testsuite/utils/src/main/java/org/keycloak/testsuite/UndertowRequestFilter.java b/testsuite/utils/src/main/java/org/keycloak/testsuite/UndertowRequestFilter.java
index 320762c617..979241d0a5 100755
--- a/testsuite/utils/src/main/java/org/keycloak/testsuite/UndertowRequestFilter.java
+++ b/testsuite/utils/src/main/java/org/keycloak/testsuite/UndertowRequestFilter.java
@@ -27,10 +27,17 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.keycloak.common.ClientConnection;
+import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.services.filters.AbstractRequestFilter;
public class UndertowRequestFilter extends AbstractRequestFilter implements Filter {
+ private final KeycloakSessionFactory factory;
+
+ public UndertowRequestFilter(KeycloakSessionFactory factory) {
+ this.factory = factory;
+ }
+
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws UnsupportedEncodingException {
@@ -81,6 +88,11 @@ public class UndertowRequestFilter extends AbstractRequestFilter implements Filt
};
}
+ @Override
+ protected KeycloakSessionFactory getSessionFactory() {
+ return this.factory;
+ }
+
@Override
public void init(FilterConfig filterConfig) {
}