KEYCLOAK-5586 Add support for testing cross dc tests on jboss-based containers
This commit is contained in:
parent
da72968085
commit
f806d4a5d6
16 changed files with 779 additions and 188 deletions
|
@ -446,19 +446,19 @@ and argument: `-p 8181`
|
|||
|
||||
## Cross-DC tests
|
||||
|
||||
Cross-DC tests use 2 data centers, each with one automatically started and one manually controlled backend servers
|
||||
(currently only Keycloak on Undertow), and 1 frontend loadbalancer server node that sits in front of all servers.
|
||||
Cross-DC tests use 2 data centers, each with one automatically started and one manually controlled backend servers,
|
||||
and 1 frontend loadbalancer server node that sits in front of all servers.
|
||||
The browser usually communicates directly with the frontent node and the test controls where the HTTP requests
|
||||
land by adjusting load balancer configuration (e.g. to direct the traffic to only a single DC).
|
||||
|
||||
For an example of a test, see [org.keycloak.testsuite.crossdc.ActionTokenCrossDCTest](tests/base/src/test/java/org/keycloak/testsuite/crossdc/ActionTokenCrossDCTest.java).
|
||||
|
||||
The cross DC requires setting a profile specifying used cache server (currently only Infinispan) by specifying
|
||||
`cache-server-infinispan` profile in maven.
|
||||
The cross DC requires setting a profile specifying used cache server by specifying
|
||||
`cache-server-infinispan` or `cache-server-jdg` profile in maven.
|
||||
|
||||
#### Run Cross-DC Tests from Maven
|
||||
|
||||
First compile the Infinispan/JDG test server via the following command:
|
||||
a) First compile the Infinispan/JDG test server via the following command:
|
||||
|
||||
`mvn -Pcache-server-infinispan -f testsuite/integration-arquillian -DskipTests clean install`
|
||||
|
||||
|
@ -466,14 +466,30 @@ or
|
|||
|
||||
`mvn -Pcache-server-jdg -f testsuite/integration-arquillian -DskipTests clean install`
|
||||
|
||||
Then you can run the tests using the following command (adjust the test specification according to your needs):
|
||||
b) Then in case you want to use **JBoss-based** containers instead of containers on Embedded Undertow run following command:
|
||||
|
||||
`mvn -Pcache-server-infinispan -Dtest=*.crossdc.* -pl testsuite/integration-arquillian/tests/base test`
|
||||
`mvn -Pauth-servers-crossdc-jboss,auth-server-wildfly -f testsuite/integration-arquillian -DskipTests clean install`
|
||||
|
||||
*note: 'auth-server-wildfly' can be replaced by 'auth-server-eap'*
|
||||
|
||||
c1) Then you can run the tests using the following command (adjust the test specification according to your needs) for containers on **Undertow**:
|
||||
|
||||
`mvn -Pcache-server-infinispan,auth-servers-crossdc-undertow -Dtest=*.crossdc.* -pl testsuite/integration-arquillian/tests/base clean install`
|
||||
|
||||
or
|
||||
|
||||
`mvn -Pcache-server-jdg -Dtest=*.crossdc.* -pl testsuite/integration-arquillian/tests/base test`
|
||||
|
||||
`mvn -Pcache-server-jdg,auth-servers-crossdc-undertow -Dtest=*.crossdc.* -pl testsuite/integration-arquillian/tests/base clean install`
|
||||
|
||||
c2) For **JBoss-based** containers:
|
||||
|
||||
`mvn -Pcache-server-infinispan,auth-servers-crossdc-jboss,auth-server-wildfly -Dtest=*.crossdc.* -pl testsuite/integration-arquillian/tests/base clean install`
|
||||
|
||||
or
|
||||
|
||||
`mvn -Pcache-server-jdg,auth-servers-crossdc-jboss,auth-server-wildfly -Dtest=*.crossdc.* -pl testsuite/integration-arquillian/tests/base clean install`
|
||||
|
||||
*note: 'auth-server-wildfly can be replaced by auth-server-eap'*
|
||||
|
||||
It can be useful to add additional system property to enable logging:
|
||||
|
||||
-Dkeycloak.infinispan.logging.level=debug
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<selenium.version>3.5.3</selenium.version>
|
||||
<arquillian-drone.version>2.4.2</arquillian-drone.version>
|
||||
<arquillian-graphene.version>2.3.1</arquillian-graphene.version>
|
||||
<arquillian-wildfly-container.version>2.1.0.Beta1</arquillian-wildfly-container.version>
|
||||
<arquillian-wildfly-container.version>2.1.0.Final</arquillian-wildfly-container.version>
|
||||
<arquillian-wls-container.version>1.0.1.Final</arquillian-wls-container.version>
|
||||
<arquillian-infinispan-container.version>1.2.0.Beta2</arquillian-infinispan-container.version>
|
||||
<version.shrinkwrap.resolvers>2.2.6</version.shrinkwrap.resolvers>
|
||||
|
@ -56,7 +56,7 @@
|
|||
<migration.70.version>1.9.8.Final</migration.70.version>
|
||||
<migration.70.authz.version>2.2.1.Final</migration.70.authz.version>
|
||||
<migration.71.version>2.5.5.Final</migration.71.version>
|
||||
|
||||
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
</properties>
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
embed-server --server-config=standalone-ha.xml
|
||||
|
||||
echo **** Begin ****
|
||||
|
||||
echo *** Update jgoups subsystem ***
|
||||
/subsystem=jgroups/stack=udp/transport=UDP:write-attribute(name=site, value=${jboss.site.name})
|
||||
|
||||
echo *** Update infinispan subsystem ***
|
||||
/subsystem=infinispan/cache-container=keycloak:write-attribute(name=module, value=org.keycloak.keycloak-model-infinispan)
|
||||
|
||||
echo ** Update replicated-cache work element **
|
||||
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=custom:add( \
|
||||
class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
|
||||
passivation=false, \
|
||||
fetch-state=false, \
|
||||
purge=false, \
|
||||
preload=false, \
|
||||
shared=true \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=custom:write-attribute( \
|
||||
name=properties, value={ \
|
||||
rawValues=true, \
|
||||
marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \
|
||||
transportFactory=org.keycloak.models.sessions.infinispan.remotestore.KeycloakTcpTransportFactory, \
|
||||
remoteServers=localhost:${remote.cache.port}, \
|
||||
remoteCacheName=work, \
|
||||
sessionCache=false \
|
||||
} \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:write-attribute(name=statistics-enabled,value=true)
|
||||
|
||||
echo ** Update distributed-cache sessions element **
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=custom:add( \
|
||||
class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
|
||||
passivation=false, \
|
||||
fetch-state=false, \
|
||||
purge=false, \
|
||||
preload=false, \
|
||||
shared=true \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=custom:write-attribute( \
|
||||
name=properties, value={ \
|
||||
remoteCacheName=sessions, \
|
||||
useConfigTemplateFromCache=work, \
|
||||
sessionCache=true \
|
||||
} \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:write-attribute(name=statistics-enabled,value=true)
|
||||
|
||||
echo ** Update distributed-cache offlineSessions element **
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=custom:add( \
|
||||
class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
|
||||
passivation=false, \
|
||||
fetch-state=false, \
|
||||
purge=false, \
|
||||
preload=false, \
|
||||
shared=true \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=custom:write-attribute( \
|
||||
name=properties, value={ \
|
||||
remoteCacheName=offlineSessions, \
|
||||
useConfigTemplateFromCache=work, \
|
||||
sessionCache=true \
|
||||
} \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:write-attribute(name=statistics-enabled,value=true)
|
||||
|
||||
echo ** Update distributed-cache loginFailures element **
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=custom:add( \
|
||||
class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
|
||||
passivation=false, \
|
||||
fetch-state=false, \
|
||||
purge=false, \
|
||||
preload=false, \
|
||||
shared=true \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=custom:write-attribute( \
|
||||
name=properties, value={ \
|
||||
remoteCacheName=loginFailures, \
|
||||
useConfigTemplateFromCache=work, \
|
||||
sessionCache=true \
|
||||
} \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:write-attribute(name=statistics-enabled,value=true)
|
||||
|
||||
echo ** Update distributed-cache actionTokens element **
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=custom:add( \
|
||||
class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
|
||||
passivation=false, \
|
||||
fetch-state=false, \
|
||||
purge=false, \
|
||||
preload=true, \
|
||||
shared=true \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=custom:write-attribute( \
|
||||
name=properties, value={ \
|
||||
remoteCacheName=actionTokens, \
|
||||
useConfigTemplateFromCache=work, \
|
||||
sessionCache=false \
|
||||
} \
|
||||
)
|
||||
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens:write-attribute(name=statistics-enabled,value=true)
|
||||
|
||||
echo ** Update distributed-cache authenticationSessions element **
|
||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=authenticationSessions:write-attribute(name=statistics-enabled,value=true)
|
||||
|
||||
echo *** Enable debug logging ***
|
||||
/subsystem=logging/logger=org.keycloak.cluster.infinispan:add(level=DEBUG)
|
||||
|
||||
/subsystem=logging/logger=org.keycloak.connections.infinispan:add(level=DEBUG)
|
||||
|
||||
/subsystem=logging/logger=org.keycloak.models.cache.infinispan:add(level=DEBUG)
|
||||
|
||||
/subsystem=logging/logger=org.keycloak.models.sessions.infinispan:add(level=DEBUG)
|
||||
|
||||
echo *** Update undertow subsystem ***
|
||||
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)
|
||||
|
||||
echo **** End ****
|
|
@ -26,11 +26,11 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
<artifactId>integration-arquillian-servers-auth-server-eap</artifactId>
|
||||
|
||||
|
||||
<name>Auth Server - JBoss - EAP</name>
|
||||
|
||||
|
||||
<properties>
|
||||
<auth.server.jboss>eap</auth.server.jboss>
|
||||
<auth.server.home>${project.build.directory}/unpacked/${product.unpacked.folder.name}</auth.server.home>
|
||||
|
@ -57,6 +57,7 @@
|
|||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
<rules>
|
||||
<requireProperty>
|
||||
<property>product.version</property>
|
||||
|
@ -71,5 +72,5 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
|
@ -191,6 +191,7 @@
|
|||
<dir>${auth.server.home}/standalone/configuration</dir>
|
||||
<includes>
|
||||
<include>standalone.xml</include>
|
||||
<include>standalone-ha.xml</include>
|
||||
</includes>
|
||||
<stylesheet>${common.resources}/keycloak-server-subsystem.xsl</stylesheet>
|
||||
<outputDir>${auth.server.home}/standalone/configuration</outputDir>
|
||||
|
@ -575,6 +576,119 @@
|
|||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>auth-servers-crossdc-jboss</id>
|
||||
<properties>
|
||||
<crossdc.jboss.jdbc.url>jdbc:h2:tcp://localhost:9092/mem:keycloak-dc-shared;DB_CLOSE_DELAY=-1</crossdc.jboss.jdbc.url>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-profile-activation</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireProperty>
|
||||
<property>auth.server.jboss</property>
|
||||
<message>Profile "auth-servers-crossdc-jboss" requires activation of another profile: either "auth-server-wildfly" or "auth-server-eap".</message>
|
||||
<regex>(wildfly|eap)</regex>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>xml-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jpa-h2-tcp</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>transform</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformationSets>
|
||||
<transformationSet>
|
||||
<dir>${auth.server.home}/standalone/configuration</dir>
|
||||
<includes>
|
||||
<include>standalone-ha.xml</include>
|
||||
</includes>
|
||||
<stylesheet>${common.resources}/datasource-jdbc-url.xsl</stylesheet>
|
||||
<outputDir>${auth.server.home}/standalone/configuration</outputDir>
|
||||
<parameters>
|
||||
<parameter>
|
||||
<name>pool.name</name>
|
||||
<value>KeycloakDS</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>jdbc.url</name>
|
||||
<value>${crossdc.jboss.jdbc.url}</value>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</transformationSet>
|
||||
</transformationSets>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>crossdc-setup</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>${auth.server.home}/bin/jboss-cli.sh</executable>
|
||||
<arguments>
|
||||
<argument>--file=${common.resources}/crossdc/cross-dc-setup.cli</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>remove-temp-data-crossdc-setup</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<workingDirectory>${auth.server.home}/standalone/</workingDirectory>
|
||||
<executable>rm</executable>
|
||||
<arguments>
|
||||
<argument>-rf</argument>
|
||||
<argument>data</argument>
|
||||
<argument>log</argument>
|
||||
<argument>tmp</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>auth-server-cluster</id>
|
||||
<properties>
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
||||
<artifactId>integration-arquillian-servers-auth-server-wildfly</artifactId>
|
||||
|
||||
|
||||
<name>Auth Server - JBoss - Wildfly</name>
|
||||
|
||||
<dependencies>
|
||||
|
@ -38,9 +38,20 @@
|
|||
<type>zip</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<properties>
|
||||
<auth.server.jboss>wildfly</auth.server.jboss>
|
||||
</properties>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<module name="org.keycloak.keycloak-model-infinispan"/>
|
||||
<module name="org.keycloak.keycloak-model-jpa"/>
|
||||
<module name="org.infinispan"/>
|
||||
<module name="org.infinispan.client.hotrod"/>
|
||||
<module name="org.jboss.logging"/>
|
||||
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
|
||||
<module name="javax.persistence.api"/>
|
||||
|
|
|
@ -94,7 +94,7 @@ public class SimpleUndertowLoadBalancer {
|
|||
.build();
|
||||
undertow.start();
|
||||
|
||||
log.infof("Loadbalancer started and ready to serve requests on http://%s:%d", host, port);
|
||||
log.infof("#### Loadbalancer started and ready to serve requests on http://%s:%d ####", host, port);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -135,6 +135,11 @@ public class AuthServerTestEnricher {
|
|||
|
||||
return managementClient;
|
||||
}
|
||||
|
||||
public void distinguishContainersInConsoleOutput(@Observes(precedence = 5) StartContainer event) {
|
||||
log.info("*****************************************************************"
|
||||
+ "*****************************************************************************");
|
||||
}
|
||||
|
||||
public void initializeSuiteContext(@Observes(precedence = 2) BeforeSuite event) {
|
||||
Set<ContainerInfo> containers = containerRegistry.get().getContainers().stream()
|
||||
|
@ -165,15 +170,16 @@ public class AuthServerTestEnricher {
|
|||
}
|
||||
|
||||
containers.stream()
|
||||
.filter(c -> c.getQualifier().startsWith(AUTH_SERVER_CONTAINER + "-cross-dc-"))
|
||||
.sorted((a, b) -> a.getQualifier().compareTo(b.getQualifier()))
|
||||
.forEach(c -> {
|
||||
String portOffsetString = c.getArquillianContainer().getContainerConfiguration().getContainerProperties().getOrDefault("bindHttpPortOffset", "0");
|
||||
String dcString = c.getArquillianContainer().getContainerConfiguration().getContainerProperties().getOrDefault("dataCenter", "0");
|
||||
updateWithAuthServerInfo(c, Integer.valueOf(portOffsetString));
|
||||
suiteContext.addAuthServerBackendsInfo(Integer.valueOf(dcString), c);
|
||||
});
|
||||
.filter(c -> c.getQualifier().startsWith("auth-server-" + System.getProperty("node.name") + "-"))
|
||||
.sorted((a, b) -> a.getQualifier().compareTo(b.getQualifier()))
|
||||
.forEach(c -> {
|
||||
String portOffsetString = c.getArquillianContainer().getContainerConfiguration().getContainerProperties().getOrDefault("bindHttpPortOffset", "0");
|
||||
updateWithAuthServerInfo(c, Integer.valueOf(portOffsetString));
|
||||
|
||||
String dcString = c.getArquillianContainer().getContainerConfiguration().getContainerProperties().getOrDefault("dataCenter", "0");
|
||||
suiteContext.addAuthServerBackendsInfo(Integer.valueOf(dcString), c);
|
||||
});
|
||||
|
||||
containers.stream()
|
||||
.filter(c -> c.getQualifier().startsWith("cache-server-cross-dc-"))
|
||||
.sorted((a, b) -> a.getQualifier().compareTo(b.getQualifier()))
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
package org.keycloak.testsuite.arquillian;
|
||||
|
||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
import org.keycloak.testsuite.Retry;
|
||||
import java.util.Map;
|
||||
import org.jboss.arquillian.core.api.Instance;
|
||||
import org.jboss.arquillian.core.api.annotation.Inject;
|
||||
import java.io.IOException;
|
||||
import java.io.NotSerializableException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
import org.jboss.arquillian.container.spi.Container;
|
||||
import org.jboss.arquillian.container.spi.ContainerRegistry;
|
||||
import org.jboss.arquillian.test.spi.TestEnricher;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.management.Attribute;
|
||||
import javax.management.AttributeNotFoundException;
|
||||
|
@ -26,21 +21,26 @@ import javax.management.IntrospectionException;
|
|||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanException;
|
||||
import javax.management.MBeanInfo;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.jboss.arquillian.container.spi.Container;
|
||||
import org.jboss.arquillian.container.spi.ContainerRegistry;
|
||||
import org.jboss.arquillian.core.api.Instance;
|
||||
import org.jboss.arquillian.core.api.annotation.Inject;
|
||||
import org.jboss.arquillian.core.spi.Validate;
|
||||
import org.jboss.arquillian.test.spi.TestEnricher;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
import org.keycloak.testsuite.Retry;
|
||||
import org.keycloak.testsuite.arquillian.annotation.JmxInfinispanCacheStatistics;
|
||||
import java.util.Set;
|
||||
import org.keycloak.testsuite.arquillian.annotation.JmxInfinispanChannelStatistics;
|
||||
import org.keycloak.testsuite.arquillian.jmx.JmxConnectorRegistry;
|
||||
import org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow;
|
||||
import org.keycloak.testsuite.crossdc.DC;
|
||||
import java.io.NotSerializableException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.jboss.arquillian.core.spi.Validate;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -81,8 +81,6 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
}
|
||||
|
||||
private InfinispanStatistics getInfinispanCacheStatistics(JmxInfinispanCacheStatistics annotation) throws MalformedObjectNameException, IOException, MalformedURLException {
|
||||
MBeanServerConnection mbsc = getJmxServerConnection(annotation);
|
||||
|
||||
ObjectName mbeanName = new ObjectName(String.format(
|
||||
"%s:type=%s,name=\"%s(%s)\",manager=\"%s\",component=%s",
|
||||
annotation.domain().isEmpty() ? getDefaultDomain(annotation.dc().getDcIndex(), annotation.dcNodeIndex()) : InfinispanConnectionProvider.JMX_DOMAIN,
|
||||
|
@ -93,7 +91,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
annotation.component()
|
||||
));
|
||||
|
||||
InfinispanStatistics value = new InfinispanCacheStatisticsImpl(mbsc, mbeanName);
|
||||
InfinispanStatistics value = new InfinispanCacheStatisticsImpl(getJmxServerConnection(annotation), mbeanName);
|
||||
|
||||
if (annotation.domain().isEmpty()) {
|
||||
try {
|
||||
|
@ -101,7 +99,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
} catch (RuntimeException ex) {
|
||||
if (annotation.dc() != DC.UNDEFINED && annotation.dcNodeIndex() != -1
|
||||
&& suiteContext.get().getAuthServerBackendsInfo(annotation.dc().getDcIndex()).get(annotation.dcNodeIndex()).isStarted()) {
|
||||
LOG.warn("Could not reset statistics for " + mbeanName);
|
||||
LOG.warn("Could not reset statistics for " + mbeanName + ". The reason is: \"" + ex.getMessage() + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,8 +108,6 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
}
|
||||
|
||||
private InfinispanStatistics getJGroupsChannelStatistics(JmxInfinispanChannelStatistics annotation) throws MalformedObjectNameException, IOException, MalformedURLException {
|
||||
MBeanServerConnection mbsc = getJmxServerConnection(annotation);
|
||||
|
||||
ObjectName mbeanName = new ObjectName(String.format(
|
||||
"%s:type=%s,cluster=\"%s\"",
|
||||
annotation.domain().isEmpty() ? getDefaultDomain(annotation.dc().getDcIndex(), annotation.dcNodeIndex()) : InfinispanConnectionProvider.JMX_DOMAIN,
|
||||
|
@ -119,7 +115,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
annotation.cluster()
|
||||
));
|
||||
|
||||
InfinispanStatistics value = new InfinispanChannelStatisticsImpl(mbsc, mbeanName);
|
||||
InfinispanStatistics value = new InfinispanChannelStatisticsImpl(getJmxServerConnection(annotation), mbeanName);
|
||||
|
||||
if (annotation.domain().isEmpty()) {
|
||||
try {
|
||||
|
@ -127,7 +123,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
} catch (RuntimeException ex) {
|
||||
if (annotation.dc() != DC.UNDEFINED && annotation.dcNodeIndex() != -1
|
||||
&& suiteContext.get().getAuthServerBackendsInfo(annotation.dc().getDcIndex()).get(annotation.dcNodeIndex()).isStarted()) {
|
||||
LOG.warn("Could not reset statistics for " + mbeanName);
|
||||
LOG.warn("Could not reset statistics for " + mbeanName + ". The reason is: \"" + ex.getMessage() + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,12 +158,20 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
|
||||
private String getDefaultDomain(int dcIndex, int dcNodeIndex) {
|
||||
if (dcIndex != -1 && dcNodeIndex != -1) {
|
||||
if (Boolean.parseBoolean(System.getProperty("auth.server.jboss.crossdc"))) {
|
||||
//backend-jboss-server
|
||||
return "org.wildfly.clustering.infinispan";
|
||||
}
|
||||
|
||||
//backend-undertow-server
|
||||
return InfinispanConnectionProvider.JMX_DOMAIN + "-" + suiteContext.get().getAuthServerBackendsInfo(dcIndex).get(dcNodeIndex).getQualifier();
|
||||
}
|
||||
|
||||
//cache-server
|
||||
return InfinispanConnectionProvider.JMX_DOMAIN;
|
||||
}
|
||||
|
||||
private MBeanServerConnection getJmxServerConnection(JmxInfinispanCacheStatistics annotation) throws MalformedURLException, IOException {
|
||||
private Supplier<MBeanServerConnection> getJmxServerConnection(JmxInfinispanCacheStatistics annotation) throws MalformedURLException {
|
||||
final String host;
|
||||
final int port;
|
||||
|
||||
|
@ -175,7 +179,46 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
ContainerInfo node = suiteContext.get().getAuthServerBackendsInfo(annotation.dc().getDcIndex()).get(annotation.dcNodeIndex());
|
||||
Container container = node.getArquillianContainer();
|
||||
if (container.getDeployableContainer() instanceof KeycloakOnUndertow) {
|
||||
return ManagementFactory.getPlatformMBeanServer();
|
||||
return () -> ManagementFactory.getPlatformMBeanServer();
|
||||
}
|
||||
host = "localhost";
|
||||
port = container.getContainerConfiguration().getContainerProperties().containsKey("managementPort")
|
||||
? Integer.valueOf(container.getContainerConfiguration().getContainerProperties().get("managementPort"))
|
||||
: 9990;
|
||||
} else {
|
||||
host = annotation.host().isEmpty()
|
||||
? System.getProperty((annotation.hostProperty().isEmpty()
|
||||
? "keycloak.connectionsInfinispan.remoteStoreServer"
|
||||
: annotation.hostProperty()))
|
||||
: annotation.host();
|
||||
|
||||
port = annotation.managementPort() == -1
|
||||
? Integer.valueOf(System.getProperty((annotation.managementPortProperty().isEmpty()
|
||||
? "cache.server.management.port"
|
||||
: annotation.managementPortProperty())))
|
||||
: annotation.managementPort();
|
||||
}
|
||||
|
||||
|
||||
JMXServiceURL url = new JMXServiceURL("service:jmx:remote+http://" + host + ":" + port);
|
||||
return () -> {
|
||||
try {
|
||||
return jmxConnectorRegistry.get().getConnection(url).getMBeanServerConnection();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Supplier<MBeanServerConnection> getJmxServerConnection(JmxInfinispanChannelStatistics annotation) throws MalformedURLException {
|
||||
final String host;
|
||||
final int port;
|
||||
|
||||
if (annotation.dc() != DC.UNDEFINED && annotation.dcNodeIndex() != -1) {
|
||||
ContainerInfo node = suiteContext.get().getAuthServerBackendsInfo(annotation.dc().getDcIndex()).get(annotation.dcNodeIndex());
|
||||
Container container = node.getArquillianContainer();
|
||||
if (container.getDeployableContainer() instanceof KeycloakOnUndertow) {
|
||||
return () -> ManagementFactory.getPlatformMBeanServer();
|
||||
}
|
||||
host = "localhost";
|
||||
port = container.getContainerConfiguration().getContainerProperties().containsKey("managementPort")
|
||||
|
@ -196,79 +239,50 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
}
|
||||
|
||||
JMXServiceURL url = new JMXServiceURL("service:jmx:remote+http://" + host + ":" + port);
|
||||
JMXConnector jmxc = jmxConnectorRegistry.get().getConnection(url);
|
||||
|
||||
return jmxc.getMBeanServerConnection();
|
||||
}
|
||||
|
||||
private MBeanServerConnection getJmxServerConnection(JmxInfinispanChannelStatistics annotation) throws MalformedURLException, IOException {
|
||||
final String host;
|
||||
final int port;
|
||||
|
||||
if (annotation.dc() != DC.UNDEFINED && annotation.dcNodeIndex() != -1) {
|
||||
ContainerInfo node = suiteContext.get().getAuthServerBackendsInfo(annotation.dc().getDcIndex()).get(annotation.dcNodeIndex());
|
||||
Container container = node.getArquillianContainer();
|
||||
if (container.getDeployableContainer() instanceof KeycloakOnUndertow) {
|
||||
return ManagementFactory.getPlatformMBeanServer();
|
||||
return () -> {
|
||||
try {
|
||||
return jmxConnectorRegistry.get().getConnection(url).getMBeanServerConnection();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
host = "localhost";
|
||||
port = container.getContainerConfiguration().getContainerProperties().containsKey("managementPort")
|
||||
? Integer.valueOf(container.getContainerConfiguration().getContainerProperties().get("managementPort"))
|
||||
: 9990;
|
||||
} else {
|
||||
host = annotation.host().isEmpty()
|
||||
? System.getProperty((annotation.hostProperty().isEmpty()
|
||||
? "keycloak.connectionsInfinispan.remoteStoreServer"
|
||||
: annotation.hostProperty()))
|
||||
: annotation.host();
|
||||
|
||||
port = annotation.managementPort() == -1
|
||||
? Integer.valueOf(System.getProperty((annotation.managementPortProperty().isEmpty()
|
||||
? "cache.server.management.port"
|
||||
: annotation.managementPortProperty())))
|
||||
: annotation.managementPort();
|
||||
}
|
||||
|
||||
String jmxUrl = "service:jmx:remote+http://" + host + ":" + port;
|
||||
LOG.infof("JMX Service URL: %s", jmxUrl);
|
||||
|
||||
JMXServiceURL url = new JMXServiceURL(jmxUrl);
|
||||
JMXConnector jmxc = jmxConnectorRegistry.get().getConnection(url);
|
||||
|
||||
return jmxc.getMBeanServerConnection();
|
||||
};
|
||||
}
|
||||
|
||||
private static abstract class CacheStatisticsImpl implements InfinispanStatistics {
|
||||
|
||||
protected final MBeanServerConnection mbsc;
|
||||
private final Supplier<MBeanServerConnection> mbscCreateor;
|
||||
private final ObjectName mbeanNameTemplate;
|
||||
private ObjectName mbeanName;
|
||||
|
||||
public CacheStatisticsImpl(MBeanServerConnection mbsc, ObjectName mbeanNameTemplate) {
|
||||
this.mbsc = mbsc;
|
||||
public CacheStatisticsImpl(Supplier<MBeanServerConnection> mbscCreateor, ObjectName mbeanNameTemplate) {
|
||||
this.mbscCreateor = mbscCreateor;
|
||||
this.mbeanNameTemplate = mbeanNameTemplate;
|
||||
}
|
||||
|
||||
protected MBeanServerConnection getConnection() {
|
||||
return mbscCreateor.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
try {
|
||||
getMbeanName();
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
} catch (IOException | RuntimeException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getStatistics() {
|
||||
try {
|
||||
MBeanInfo mBeanInfo = mbsc.getMBeanInfo(getMbeanName());
|
||||
MBeanInfo mBeanInfo = getConnection().getMBeanInfo(getMbeanName());
|
||||
String[] statAttrs = Arrays.asList(mBeanInfo.getAttributes()).stream()
|
||||
.filter(MBeanAttributeInfo::isReadable)
|
||||
.map(MBeanAttributeInfo::getName)
|
||||
.collect(Collectors.toList())
|
||||
.toArray(new String[] {});
|
||||
return mbsc.getAttributes(getMbeanName(), statAttrs)
|
||||
return getConnection().getAttributes(getMbeanName(), statAttrs)
|
||||
.asList()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Attribute::getName, Attribute::getValue));
|
||||
|
@ -279,7 +293,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
|
||||
protected ObjectName getMbeanName() throws IOException, RuntimeException {
|
||||
if (this.mbeanName == null) {
|
||||
Set<ObjectName> queryNames = mbsc.queryNames(mbeanNameTemplate, null);
|
||||
Set<ObjectName> queryNames = getConnection().queryNames(mbeanNameTemplate, null);
|
||||
if (queryNames.isEmpty()) {
|
||||
throw new RuntimeException("No MBean of template " + mbeanNameTemplate + " found at JMX server");
|
||||
}
|
||||
|
@ -292,7 +306,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
@Override
|
||||
public Comparable getSingleStatistics(String statisticsName) {
|
||||
try {
|
||||
return (Comparable) mbsc.getAttribute(getMbeanName(), statisticsName);
|
||||
return (Comparable) getConnection().getAttribute(getMbeanName(), statisticsName);
|
||||
} catch (IOException | InstanceNotFoundException | MBeanException | ReflectionException | AttributeNotFoundException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
@ -305,7 +319,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
try {
|
||||
getMbeanName();
|
||||
if (! isAvailable()) throw new RuntimeException("Not available");
|
||||
} catch (Exception ex) {
|
||||
} catch (IOException | RuntimeException ex) {
|
||||
throw new RuntimeException("Timed out while waiting for " + mbeanNameTemplate + " to become available", ex);
|
||||
}
|
||||
}, 1 + (int) timeInMillis / 100, 100);
|
||||
|
@ -316,14 +330,14 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
|
||||
private static class InfinispanCacheStatisticsImpl extends CacheStatisticsImpl {
|
||||
|
||||
public InfinispanCacheStatisticsImpl(MBeanServerConnection mbsc, ObjectName mbeanName) {
|
||||
super(mbsc, mbeanName);
|
||||
public InfinispanCacheStatisticsImpl(Supplier<MBeanServerConnection> mbscCreator, ObjectName mbeanName) {
|
||||
super(mbscCreator, mbeanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
try {
|
||||
mbsc.invoke(getMbeanName(), "resetStatistics", new Object[] {}, new String[] {});
|
||||
getConnection().invoke(getMbeanName(), "resetStatistics", new Object[] {}, new String[] {});
|
||||
} catch (IOException | InstanceNotFoundException | MBeanException | ReflectionException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
@ -337,14 +351,14 @@ public class CacheStatisticsControllerEnricher implements TestEnricher {
|
|||
|
||||
private static class InfinispanChannelStatisticsImpl extends CacheStatisticsImpl {
|
||||
|
||||
public InfinispanChannelStatisticsImpl(MBeanServerConnection mbsc, ObjectName mbeanName) {
|
||||
super(mbsc, mbeanName);
|
||||
public InfinispanChannelStatisticsImpl(Supplier<MBeanServerConnection> mbscCreator, ObjectName mbeanName) {
|
||||
super(mbscCreator, mbeanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
try {
|
||||
mbsc.invoke(getMbeanName(), "resetStats", new Object[] {}, new String[] {});
|
||||
getConnection().invoke(getMbeanName(), "resetStats", new Object[] {}, new String[] {});
|
||||
} catch (NotSerializableException ex) {
|
||||
// Ignore return value not serializable, the invocation has already done its job
|
||||
} catch (IOException | InstanceNotFoundException | MBeanException | ReflectionException ex) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.jboss.arquillian.core.api.annotation.ApplicationScoped;
|
|||
import org.jboss.arquillian.core.api.annotation.Inject;
|
||||
import org.jboss.arquillian.core.api.annotation.Observes;
|
||||
import org.jboss.arquillian.test.spi.event.suite.BeforeSuite;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -34,6 +35,8 @@ import org.jboss.arquillian.test.spi.event.suite.BeforeSuite;
|
|||
*/
|
||||
public class JmxConnectorRegistryCreator {
|
||||
|
||||
private final Logger log = Logger.getLogger(JmxConnectorRegistryCreator.class);
|
||||
|
||||
@Inject
|
||||
@ApplicationScoped
|
||||
private InstanceProducer<JmxConnectorRegistry> connectorRegistry;
|
||||
|
@ -46,6 +49,7 @@ public class JmxConnectorRegistryCreator {
|
|||
|
||||
@Override
|
||||
public JMXConnector getConnection(JMXServiceURL url) {
|
||||
|
||||
JMXConnector res = connectors.get(url);
|
||||
if (res == null) {
|
||||
try {
|
||||
|
@ -55,7 +59,10 @@ public class JmxConnectorRegistryCreator {
|
|||
res = conn;
|
||||
}
|
||||
res.connect();
|
||||
log.infof("Connected to JMX Service URL: %s", url);
|
||||
} catch (IOException ex) {
|
||||
//remove conn from connectors in case something goes wrong. The connection will be established on-demand
|
||||
connectors.remove(url, res);
|
||||
throw new RuntimeException("Could not instantiate JMX connector for " + url, ex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ import java.io.IOException;
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -58,10 +58,12 @@ import java.util.Arrays;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.impl.client.BasicCookieStore;
|
||||
import org.hamcrest.Matchers;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -126,8 +128,7 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
CookieStore cookieStore = new BasicCookieStore();
|
||||
context.setCookieStore(cookieStore);
|
||||
HttpUriRequest request = handleLogin(getPageContent(oauth.getLoginFormUrl(), httpClient, context), userName, password);
|
||||
log.debug("Executing login request");
|
||||
Assert.assertTrue(parseAndCloseResponse(httpClient.execute(request, context)).contains("<title>AUTH_RESPONSE</title>"));
|
||||
Assert.assertThat(parseAndCloseResponse(httpClient.execute(request, context)), containsString("<title>AUTH_RESPONSE</title>"));
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -306,12 +307,8 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
}
|
||||
|
||||
private static Map<String, String> getQueryFromUrl(String url) throws URISyntaxException {
|
||||
Map<String, String> m = new HashMap<>();
|
||||
List<NameValuePair> pairs = URLEncodedUtils.parse(new URI(url), "UTF-8");
|
||||
for (NameValuePair p : pairs) {
|
||||
m.put(p.getName(), p.getValue());
|
||||
}
|
||||
return m;
|
||||
return URLEncodedUtils.parse(new URI(url), Charset.forName("UTF-8")).stream()
|
||||
.collect(Collectors.toMap(p -> p.getName(), p -> p.getValue()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -411,4 +408,4 @@ public class ConcurrentLoginTest extends AbstractConcurrencyTest {
|
|||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
// Keep the following constants in sync with arquillian
|
||||
public static final String QUALIFIER_NODE_BALANCER = "auth-server-balancer-cross-dc";
|
||||
public static final String QUALIFIER_JBOSS_DC_0_NODE_1 = "auth-server-jboss-cross-dc-0_1";
|
||||
public static final String QUALIFIER_JBOSS_DC_1_NODE_1 = "auth-server-jboss-cross-dc-1_1";
|
||||
|
||||
@ArquillianResource
|
||||
@LoadBalancer(value = QUALIFIER_NODE_BALANCER)
|
||||
|
@ -208,7 +210,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Disables routing requests to the given data center in the load balancer.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
*/
|
||||
public void disableDcOnLoadBalancer(DC dc) {
|
||||
int dcIndex = dc.ordinal();
|
||||
|
@ -218,7 +220,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Enables routing requests to all started nodes to the given data center in the load balancer.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
*/
|
||||
public void enableDcOnLoadBalancer(DC dc) {
|
||||
int dcIndex = dc.ordinal();
|
||||
|
@ -235,7 +237,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Disables routing requests to the given node within the given data center in the load balancer.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
* @param nodeIndex
|
||||
*/
|
||||
public void disableLoadBalancerNode(DC dc, int nodeIndex) {
|
||||
|
@ -246,7 +248,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Enables routing requests to the given node within the given data center in the load balancer.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
* @param nodeIndex
|
||||
*/
|
||||
public void enableLoadBalancerNode(DC dc, int nodeIndex) {
|
||||
|
@ -264,7 +266,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Starts a manually-controlled backend auth-server node in cross-DC scenario.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
* @param nodeIndex
|
||||
* @return Started instance descriptor.
|
||||
*/
|
||||
|
@ -275,6 +277,8 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
assertThat((Integer) nodeIndex, lessThan(dcNodes.size()));
|
||||
ContainerInfo dcNode = dcNodes.get(nodeIndex);
|
||||
assertTrue("Node " + dcNode.getQualifier() + " has to be controlled manually", dcNode.isManual());
|
||||
|
||||
log.infof("Starting backend node: %s (dcIndex: %d, nodeIndex: %d)", dcNode.getQualifier(), dcIndex, nodeIndex);
|
||||
containerController.start(dcNode.getQualifier());
|
||||
|
||||
createRESTClientsForNode(dcNode);
|
||||
|
@ -284,7 +288,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Stops a manually-controlled backend auth-server node in cross-DC scenario.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
* @param nodeIndex
|
||||
* @return Stopped instance descriptor.
|
||||
*/
|
||||
|
@ -298,13 +302,15 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
removeRESTClientsForNode(dcNode);
|
||||
|
||||
assertTrue("Node " + dcNode.getQualifier() + " has to be controlled manually", dcNode.isManual());
|
||||
|
||||
log.infof("Stopping backend node: %s (dcIndex: %d, nodeIndex: %d)", dcNode.getQualifier(), dcIndex, nodeIndex);
|
||||
containerController.stop(dcNode.getQualifier());
|
||||
return dcNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns stream of all nodes in the given dc that are started manually.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
* @return
|
||||
*/
|
||||
public Stream<ContainerInfo> getManuallyStartedBackendNodes(DC dc) {
|
||||
|
@ -315,7 +321,7 @@ public abstract class AbstractCrossDCTest extends AbstractTestRealmKeycloakTest
|
|||
|
||||
/**
|
||||
* Returns stream of all nodes in the given dc that are started automatically.
|
||||
* @param dcIndex
|
||||
* @param dc
|
||||
* @return
|
||||
*/
|
||||
public Stream<ContainerInfo> getAutomaticallyStartedBackendNodes(DC dc) {
|
||||
|
|
|
@ -21,6 +21,9 @@ import java.io.IOException;
|
|||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import org.jboss.arquillian.container.test.api.Deployment;
|
||||
import org.jboss.arquillian.container.test.api.TargetsContainer;
|
||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -31,9 +34,11 @@ import org.keycloak.models.UserLoginFailureModel;
|
|||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.Retry;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
|
||||
import org.keycloak.testsuite.util.ClientBuilder;
|
||||
import org.keycloak.testsuite.util.OAuthClient;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
|
@ -45,7 +50,31 @@ import org.keycloak.testsuite.util.UserBuilder;
|
|||
public class BruteForceCrossDCTest extends AbstractAdminCrossDCTest {
|
||||
|
||||
private static final String REALM_NAME = "brute-force-test";
|
||||
|
||||
|
||||
@Deployment(name = "dc0")
|
||||
@TargetsContainer(QUALIFIER_JBOSS_DC_0_NODE_1)
|
||||
public static WebArchive deployDC0() {
|
||||
return RunOnServerDeployment.create(
|
||||
BruteForceCrossDCTest.class,
|
||||
AbstractAdminCrossDCTest.class,
|
||||
AbstractCrossDCTest.class,
|
||||
AbstractTestRealmKeycloakTest.class,
|
||||
KeycloakTestingClient.class
|
||||
);
|
||||
}
|
||||
|
||||
@Deployment(name = "dc1")
|
||||
@TargetsContainer(QUALIFIER_JBOSS_DC_1_NODE_1)
|
||||
public static WebArchive deployDC1() {
|
||||
return RunOnServerDeployment.create(
|
||||
BruteForceCrossDCTest.class,
|
||||
AbstractAdminCrossDCTest.class,
|
||||
AbstractCrossDCTest.class,
|
||||
AbstractTestRealmKeycloakTest.class,
|
||||
KeycloakTestingClient.class
|
||||
);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void beforeTest() {
|
||||
try {
|
||||
|
@ -220,6 +249,7 @@ public class BruteForceCrossDCTest extends AbstractAdminCrossDCTest {
|
|||
|
||||
|
||||
// TODO Having this working on Wildfly might be a challenge. Maybe require @Deployment with @TargetsContainer descriptor generated at runtime as we don't know the container qualifier at compile time... Maybe workaround by add endpoint to TestingResourceProvider if needed..
|
||||
// resolution on Wildfly: make deployment available on both dc0_1 and dc1_1, see @Deployment methods
|
||||
private void addUserLoginFailure(KeycloakTestingClient testingClient) throws URISyntaxException, IOException {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName(REALM_NAME);
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
|
||||
<container qualifier="auth-server-undertow" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.undertow} && ! ${auth.server.undertow.crossdc}</property>
|
||||
<property name="enabled">${auth.server.undertow} && ! ${auth.server.crossdc}</property>
|
||||
<property name="bindAddress">0.0.0.0</property>
|
||||
<property name="adapterImplClass">org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow</property>
|
||||
<property name="bindHttpPort">${auth.server.http.port}</property>
|
||||
|
@ -74,7 +74,7 @@
|
|||
|
||||
<container qualifier="auth-server-${auth.server}" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.jboss}</property>
|
||||
<property name="enabled">${auth.server.jboss} && ! ${auth.server.crossdc}</property>
|
||||
<property name="adapterImplClass">${auth.server.adapter.impl.class}</property>
|
||||
<property name="jbossHome">${auth.server.home}</property>
|
||||
<property name="${auth.server.config.property.name}">${auth.server.config.property.value}</property>
|
||||
|
@ -186,18 +186,18 @@
|
|||
</group>
|
||||
|
||||
|
||||
<!-- Cross DC with embedded undertow. Node numbering is [centre #].[node #] -->
|
||||
<group qualifier="auth-server-undertow-cross-dc">
|
||||
<!-- Cross DC. Node numbering is [centre #].[node #] -->
|
||||
<group qualifier="auth-server-jboss-cross-dc">
|
||||
<container qualifier="cache-server-cross-dc-1" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.undertow.crossdc} && ! ${cache.server.lifecycle.skip}</property>
|
||||
<property name="enabled">${auth.server.crossdc} && ! ${cache.server.lifecycle.skip}</property>
|
||||
<property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
|
||||
<property name="jbossHome">${cache.server.home}</property>
|
||||
<property name="serverConfig">clustered.xml</property>
|
||||
<property name="jbossArguments">
|
||||
-Djboss.socket.binding.port-offset=${cache.server.port.offset}
|
||||
-Djboss.default.multicast.address=234.56.78.99
|
||||
-Djboss.node.name=cache-server
|
||||
-Djboss.node.name=cache-server-dc-1
|
||||
${adapter.test.props}
|
||||
${auth.server.profile}
|
||||
</property>
|
||||
|
@ -213,7 +213,7 @@
|
|||
|
||||
<container qualifier="cache-server-cross-dc-2" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.undertow.crossdc} && ! ${cache.server.lifecycle.skip}</property>
|
||||
<property name="enabled">${auth.server.crossdc} && ! ${cache.server.lifecycle.skip}</property>
|
||||
<property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
|
||||
<property name="jbossHome">${cache.server.home}</property>
|
||||
<property name="setupCleanServerBaseDir">true</property>
|
||||
|
@ -238,11 +238,11 @@
|
|||
|
||||
<container qualifier="auth-server-balancer-cross-dc" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.undertow.crossdc}</property>
|
||||
<property name="enabled">${auth.server.crossdc}</property>
|
||||
<property name="adapterImplClass">org.keycloak.testsuite.arquillian.undertow.lb.SimpleUndertowLoadBalancerContainer</property>
|
||||
<property name="bindAddress">localhost</property>
|
||||
<property name="bindHttpPort">${auth.server.http.port}</property>
|
||||
<property name="nodes">auth-server-undertow-cross-dc-0_1=http://localhost:8101,auth-server-undertow-cross-dc-0_2-manual=http://localhost:8102,auth-server-undertow-cross-dc-1_1=http://localhost:8111,auth-server-undertow-cross-dc-1_2-manual=http://localhost:8112</property>
|
||||
<property name="nodes">auth-server-${node.name}-cross-dc-0_1=http://localhost:8101,auth-server-${node.name}-cross-dc-0_2-manual=http://localhost:8102,auth-server-${node.name}-cross-dc-1_1=http://localhost:8111,auth-server-${node.name}-cross-dc-1_2-manual=http://localhost:8112</property>
|
||||
</configuration>
|
||||
</container>
|
||||
|
||||
|
@ -253,7 +253,6 @@
|
|||
<property name="bindAddress">localhost</property>
|
||||
<property name="bindHttpPort">${auth.server.http.port}</property>
|
||||
<property name="bindHttpPortOffset">-79</property>
|
||||
<property name="route">auth-server-undertow-cross-dc-0_1</property>
|
||||
<property name="remoteMode">${undertow.remote}</property>
|
||||
<property name="dataCenter">0</property>
|
||||
<property name="keycloakConfigPropertyOverrides">{
|
||||
|
@ -277,7 +276,6 @@
|
|||
<property name="bindAddress">localhost</property>
|
||||
<property name="bindHttpPort">${auth.server.http.port}</property>
|
||||
<property name="bindHttpPortOffset">-78</property>
|
||||
<property name="route">auth-server-undertow-cross-dc-0_2-manual</property>
|
||||
<property name="remoteMode">${undertow.remote}</property>
|
||||
<property name="dataCenter">0</property>
|
||||
<property name="keycloakConfigPropertyOverrides">{
|
||||
|
@ -302,7 +300,6 @@
|
|||
<property name="bindAddress">localhost</property>
|
||||
<property name="bindHttpPort">${auth.server.http.port}</property>
|
||||
<property name="bindHttpPortOffset">-69</property>
|
||||
<property name="route">auth-server-undertow-cross-dc-1_1</property>
|
||||
<property name="remoteMode">${undertow.remote}</property>
|
||||
<property name="dataCenter">1</property>
|
||||
<property name="keycloakConfigPropertyOverrides">{
|
||||
|
@ -326,7 +323,6 @@
|
|||
<property name="bindAddress">localhost</property>
|
||||
<property name="bindHttpPort">${auth.server.http.port}</property>
|
||||
<property name="bindHttpPortOffset">-68</property>
|
||||
<property name="route">auth-server-undertow-cross-dc-1_2-manual</property>
|
||||
<property name="remoteMode">${undertow.remote}</property>
|
||||
<property name="dataCenter">1</property>
|
||||
<property name="keycloakConfigPropertyOverrides">{
|
||||
|
@ -343,8 +339,97 @@
|
|||
}</property>
|
||||
</configuration>
|
||||
</container>
|
||||
</group>
|
||||
<container qualifier="auth-server-jboss-cross-dc-0_1" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.jboss.crossdc}</property>
|
||||
<property name="adapterImplClass">${auth.server.adapter.impl.class}</property>
|
||||
<property name="jbossHome">${auth.server.crossdc01.home}</property>
|
||||
<property name="serverConfig">standalone-ha.xml</property>
|
||||
<property name="jbossArguments">
|
||||
-Djboss.socket.binding.port-offset=${auth.server.crossdc01.port.offset}
|
||||
-Djboss.default.multicast.address=234.56.78.1
|
||||
-Dremote.cache.port=12232
|
||||
-Djboss.site.name=dc0
|
||||
-Djboss.node.name=auth-server-${node.name}-cross-dc-0_1
|
||||
</property>
|
||||
<property name="javaVmArguments">
|
||||
-Djava.net.preferIPv4Stack=true
|
||||
${auth.server.crossdc01.jvm.debug.args}
|
||||
</property>
|
||||
<property name="managementPort">${auth.server.crossdc01.management.port}</property>
|
||||
<property name="bindHttpPortOffset">-79</property>
|
||||
<property name="dataCenter">0</property>
|
||||
</configuration>
|
||||
</container>
|
||||
<container qualifier="auth-server-jboss-cross-dc-0_2-manual" mode="manual" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.jboss.crossdc}</property>
|
||||
<property name="adapterImplClass">${auth.server.adapter.impl.class}</property>
|
||||
<property name="jbossHome">${auth.server.crossdc02.home}</property>
|
||||
<property name="serverConfig">standalone-ha.xml</property>
|
||||
<property name="jbossArguments">
|
||||
-Djboss.socket.binding.port-offset=${auth.server.crossdc02.port.offset}
|
||||
-Djboss.default.multicast.address=234.56.78.1
|
||||
-Dremote.cache.port=12232
|
||||
-Djboss.site.name=dc0
|
||||
-Djboss.node.name=auth-server-${node.name}-cross-dc-0_2-manual
|
||||
</property>
|
||||
<property name="javaVmArguments">
|
||||
-Djava.net.preferIPv4Stack=true
|
||||
${auth.server.crossdc02.jvm.debug.args}
|
||||
</property>
|
||||
<property name="managementPort">${auth.server.crossdc02.management.port}</property>
|
||||
<property name="bindHttpPortOffset">-78</property>
|
||||
<property name="dataCenter">0</property>
|
||||
</configuration>
|
||||
</container>
|
||||
|
||||
<container qualifier="auth-server-jboss-cross-dc-1_1" mode="suite" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.jboss.crossdc}</property>
|
||||
<property name="adapterImplClass">${auth.server.adapter.impl.class}</property>
|
||||
<property name="jbossHome">${auth.server.crossdc11.home}</property>
|
||||
<property name="serverConfig">standalone-ha.xml</property>
|
||||
<property name="jbossArguments">
|
||||
-Djboss.socket.binding.port-offset=${auth.server.crossdc11.port.offset}
|
||||
-Djboss.default.multicast.address=234.56.78.2
|
||||
-Dremote.cache.port=13232
|
||||
-Djboss.site.name=dc1
|
||||
-Djboss.node.name=auth-server-${node.name}-cross-dc-1_1
|
||||
</property>
|
||||
<property name="javaVmArguments">
|
||||
-Djava.net.preferIPv4Stack=true
|
||||
${auth.server.crossdc11.jvm.debug.args}
|
||||
</property>
|
||||
<property name="managementPort">${auth.server.crossdc11.management.port}</property>
|
||||
<property name="bindHttpPortOffset">-69</property>
|
||||
<property name="dataCenter">1</property>
|
||||
</configuration>
|
||||
</container>
|
||||
<container qualifier="auth-server-jboss-cross-dc-1_2-manual" mode="manual" >
|
||||
<configuration>
|
||||
<property name="enabled">${auth.server.jboss.crossdc}</property>
|
||||
<property name="adapterImplClass">${auth.server.adapter.impl.class}</property>
|
||||
<property name="jbossHome">${auth.server.crossdc12.home}</property>
|
||||
<property name="serverConfig">standalone-ha.xml</property>
|
||||
<property name="jbossArguments">
|
||||
-Djboss.socket.binding.port-offset=${auth.server.crossdc12.port.offset}
|
||||
-Djboss.default.multicast.address=234.56.78.2
|
||||
-Dremote.cache.port=13232
|
||||
-Djboss.site.name=dc1
|
||||
-Djboss.node.name=auth-server-${node.name}-cross-dc-1_2-manual
|
||||
</property>
|
||||
<property name="javaVmArguments">
|
||||
-Djava.net.preferIPv4Stack=true
|
||||
${auth.server.crossdc12.jvm.debug.args}
|
||||
</property>
|
||||
<property name="managementPort">${auth.server.crossdc12.management.port}</property>
|
||||
<property name="bindHttpPortOffset">-68</property>
|
||||
<property name="dataCenter">1</property>
|
||||
</configuration>
|
||||
</container>
|
||||
</group>
|
||||
|
||||
|
||||
<container qualifier="auth-server-balancer-wildfly" mode="suite" >
|
||||
<configuration>
|
||||
|
|
|
@ -41,10 +41,12 @@
|
|||
<properties>
|
||||
<auth.server>undertow</auth.server>
|
||||
<auth.server.undertow>true</auth.server.undertow>
|
||||
<auth.server.undertow.crossdc>false</auth.server.undertow.crossdc>
|
||||
|
||||
<auth.server.crossdc>false</auth.server.crossdc>
|
||||
<auth.server.undertow.crossdc>false</auth.server.undertow.crossdc>
|
||||
<auth.server.jboss.crossdc>false</auth.server.jboss.crossdc>
|
||||
<cache.server.lifecycle.skip>false</cache.server.lifecycle.skip>
|
||||
|
||||
|
||||
<auth.server.container>auth-server-${auth.server}</auth.server.container>
|
||||
<auth.server.home>${containers.home}/${auth.server.container}</auth.server.home>
|
||||
<auth.server.config.dir>${auth.server.home}</auth.server.config.dir>
|
||||
|
@ -60,16 +62,16 @@
|
|||
<auth.server.memory.settings>-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m</auth.server.memory.settings>
|
||||
<auth.server.config.property.name>serverConfig</auth.server.config.property.name>
|
||||
<auth.server.adapter.impl.class>org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</auth.server.adapter.impl.class>
|
||||
|
||||
|
||||
<auth.server.jboss.artifactId>integration-arquillian-servers-auth-server-${auth.server}</auth.server.jboss.artifactId>
|
||||
<auth.server.jboss.skip.unpack>${auth.server.undertow}</auth.server.jboss.skip.unpack>
|
||||
<auth.server.jboss.startup.timeout>300</auth.server.jboss.startup.timeout>
|
||||
|
||||
|
||||
<!--debug properties-->
|
||||
<auth.server.debug.port>5005</auth.server.debug.port>
|
||||
<auth.server.debug.suspend>n</auth.server.debug.suspend>
|
||||
<auth.server.jboss.jvm.debug.args>-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.debug.suspend},address=${auth.server.host}:${auth.server.debug.port}</auth.server.jboss.jvm.debug.args>
|
||||
|
||||
|
||||
<auth.server.remote>false</auth.server.remote>
|
||||
<auth.server.profile/>
|
||||
<auth.server.feature/>
|
||||
|
@ -91,7 +93,7 @@
|
|||
<adapter.test.props/>
|
||||
<migration.import.properties/>
|
||||
<kie.maven.settings/>
|
||||
|
||||
|
||||
<examples.home>${project.build.directory}/examples</examples.home>
|
||||
|
||||
<browser>htmlUnit</browser>
|
||||
|
@ -242,10 +244,10 @@
|
|||
<auth.server.config.property.value>${auth.server.config.property.value}</auth.server.config.property.value>
|
||||
<auth.server.adapter.impl.class>${auth.server.adapter.impl.class}</auth.server.adapter.impl.class>
|
||||
<auth.server.jboss.jvm.debug.args>${auth.server.jboss.jvm.debug.args}</auth.server.jboss.jvm.debug.args>
|
||||
|
||||
|
||||
<auth.server.profile>${auth.server.profile}</auth.server.profile>
|
||||
<auth.server.feature>${auth.server.feature}</auth.server.feature>
|
||||
|
||||
|
||||
<frontend.console.output>${frontend.console.output}</frontend.console.output>
|
||||
<backends.console.output>${backend.console.output}</backends.console.output>
|
||||
|
||||
|
@ -254,7 +256,7 @@
|
|||
<adapter.test.props>${adapter.test.props}</adapter.test.props>
|
||||
<migration.import.properties>${migration.import.properties}</migration.import.properties>
|
||||
<kie.maven.settings>${kie.maven.settings}</kie.maven.settings>
|
||||
|
||||
|
||||
<testsuite.constants>${testsuite.constants}</testsuite.constants>
|
||||
<cli.log.output>${cli.log.output}</cli.log.output>
|
||||
<test.intermittent>${test.intermittent}</test.intermittent>
|
||||
|
@ -287,10 +289,11 @@
|
|||
<client.key.passphrase>${client.key.passphrase}</client.key.passphrase>
|
||||
|
||||
<auth.server.ocsp.responder.enabled>${auth.server.ocsp.responder.enabled}</auth.server.ocsp.responder.enabled>
|
||||
|
||||
|
||||
<!--cache server properties-->
|
||||
<auth.server.crossdc>${auth.server.crossdc}</auth.server.crossdc>
|
||||
<auth.server.undertow.crossdc>${auth.server.undertow.crossdc}</auth.server.undertow.crossdc>
|
||||
<auth.server.jboss.crossdc>${auth.server.jboss.crossdc}</auth.server.jboss.crossdc>
|
||||
<cache.server.lifecycle.skip>${cache.server.lifecycle.skip}</cache.server.lifecycle.skip>
|
||||
|
||||
<cache.server>${cache.server}</cache.server>
|
||||
|
@ -367,14 +370,13 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
|
||||
|
||||
<profile>
|
||||
<id>auth-server-wildfly</id>
|
||||
<properties>
|
||||
<auth.server>wildfly</auth.server>
|
||||
<auth.server.jboss>true</auth.server.jboss>
|
||||
<auth.server.undertow>false</auth.server.undertow>
|
||||
<auth.server.undertow.crossdc>false</auth.server.undertow.crossdc>
|
||||
<auth.server.config.property.value>standalone.xml</auth.server.config.property.value>
|
||||
<auth.server.config.dir>${auth.server.home}/standalone/configuration</auth.server.config.dir>
|
||||
<h2.version>1.3.173</h2.version>
|
||||
|
@ -393,7 +395,6 @@
|
|||
<auth.server>eap</auth.server>
|
||||
<auth.server.jboss>true</auth.server.jboss>
|
||||
<auth.server.undertow>false</auth.server.undertow>
|
||||
<auth.server.undertow.crossdc>false</auth.server.undertow.crossdc>
|
||||
<auth.server.config.property.value>standalone.xml</auth.server.config.property.value>
|
||||
<auth.server.config.dir>${auth.server.home}/standalone/configuration</auth.server.config.dir>
|
||||
<h2.version>1.3.173</h2.version>
|
||||
|
@ -406,14 +407,192 @@
|
|||
</dependencies>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>auth-servers-crossdc-undertow</id>
|
||||
<properties>
|
||||
<auth.servers.crossdc>true</auth.servers.crossdc>
|
||||
<auth.server.undertow.crossdc>true</auth.server.undertow.crossdc>
|
||||
<node.name>undertow</node.name>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-profile-activation</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireProperty>
|
||||
<property>cache.server.jboss</property>
|
||||
<message>Profile "auth-servers-crossdc-undertow" requires activation of another profile: either "cache-server-infinispan" or "cache-server-jdg".</message>
|
||||
<regex>true</regex>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<node.name>${node.name}</node.name>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>auth-servers-crossdc-jboss</id>
|
||||
<properties>
|
||||
<auth.servers.crossdc>true</auth.servers.crossdc>
|
||||
<auth.server.jboss.crossdc>true</auth.server.jboss.crossdc>
|
||||
<node.name>jboss</node.name>
|
||||
|
||||
<auth.server.crossdc01.home>${containers.home}/auth-server-${auth.server}-crossdc01</auth.server.crossdc01.home>
|
||||
<auth.server.crossdc02.home>${containers.home}/auth-server-${auth.server}-crossdc02</auth.server.crossdc02.home>
|
||||
<auth.server.crossdc11.home>${containers.home}/auth-server-${auth.server}-crossdc11</auth.server.crossdc11.home>
|
||||
<auth.server.crossdc12.home>${containers.home}/auth-server-${auth.server}-crossdc12</auth.server.crossdc12.home>
|
||||
|
||||
<!-- property specifies keycloak-add-user.json file destination -->
|
||||
<auth.server.config.dir>${auth.server.crossdc01.home}/standalone/configuration</auth.server.config.dir>
|
||||
|
||||
<auth.server.crossdc01.jvm.debug.port>5001</auth.server.crossdc01.jvm.debug.port>
|
||||
<auth.server.crossdc02.jvm.debug.port>5002</auth.server.crossdc02.jvm.debug.port>
|
||||
<auth.server.crossdc11.jvm.debug.port>5011</auth.server.crossdc11.jvm.debug.port>
|
||||
<auth.server.crossdc12.jvm.debug.port>5012</auth.server.crossdc12.jvm.debug.port>
|
||||
|
||||
<!-- default is "n", possible to override by e.g. -Dauth.server.crossdc01.debug.suspend=y -->
|
||||
<auth.server.crossdc01.debug.suspend>${auth.server.debug.suspend}</auth.server.crossdc01.debug.suspend>
|
||||
<auth.server.crossdc02.debug.suspend>${auth.server.debug.suspend}</auth.server.crossdc02.debug.suspend>
|
||||
<auth.server.crossdc11.debug.suspend>${auth.server.debug.suspend}</auth.server.crossdc11.debug.suspend>
|
||||
<auth.server.crossdc12.debug.suspend>${auth.server.debug.suspend}</auth.server.crossdc12.debug.suspend>
|
||||
</properties>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-auth-server-crossdc-nodes</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<move todir="${auth.server.crossdc01.home}">
|
||||
<fileset dir="${auth.server.home}"/>
|
||||
</move>
|
||||
<copy todir="${auth.server.crossdc02.home}">
|
||||
<fileset dir="${auth.server.crossdc01.home}"/>
|
||||
</copy>
|
||||
<copy todir="${auth.server.crossdc11.home}">
|
||||
<fileset dir="${auth.server.crossdc01.home}"/>
|
||||
</copy>
|
||||
<copy todir="${auth.server.crossdc12.home}">
|
||||
<fileset dir="${auth.server.crossdc01.home}"/>
|
||||
</copy>
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-profiles-activation</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireProperty>
|
||||
<property>cache.server.jboss</property>
|
||||
<message>Profile "auth-servers-crossdc-jboss" requires activation of another profile: either "cache-server-infinispan" or "cache-server-jdg".</message>
|
||||
<regex>true</regex>
|
||||
</requireProperty>
|
||||
<requireProperty>
|
||||
<property>auth.server.jboss</property>
|
||||
<message>Profile "auth-servers-crossdc-jboss" requires activation of another profile: either "auth-server-wildfly" or "auth-server-eap".</message>
|
||||
<regex>true</regex>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
|
||||
<run.h2>true</run.h2>
|
||||
<node.name>${node.name}</node.name>
|
||||
|
||||
<auth.server.crossdc01.home>${auth.server.crossdc01.home}</auth.server.crossdc01.home>
|
||||
<auth.server.crossdc02.home>${auth.server.crossdc02.home}</auth.server.crossdc02.home>
|
||||
<auth.server.crossdc11.home>${auth.server.crossdc11.home}</auth.server.crossdc11.home>
|
||||
<auth.server.crossdc12.home>${auth.server.crossdc12.home}</auth.server.crossdc12.home>
|
||||
|
||||
<!--8101-->
|
||||
<auth.server.crossdc01.port.offset>21</auth.server.crossdc01.port.offset>
|
||||
<!--8102-->
|
||||
<auth.server.crossdc02.port.offset>22</auth.server.crossdc02.port.offset>
|
||||
<!--8111-->
|
||||
<auth.server.crossdc11.port.offset>31</auth.server.crossdc11.port.offset>
|
||||
<!--8112-->
|
||||
<auth.server.crossdc12.port.offset>32</auth.server.crossdc12.port.offset>
|
||||
|
||||
<auth.server.crossdc01.management.port>10011</auth.server.crossdc01.management.port>
|
||||
<auth.server.crossdc02.management.port>10012</auth.server.crossdc02.management.port>
|
||||
<auth.server.crossdc11.management.port>10021</auth.server.crossdc11.management.port>
|
||||
<auth.server.crossdc12.management.port>10022</auth.server.crossdc12.management.port>
|
||||
|
||||
<auth.server.crossdc01.jvm.debug.args>
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.crossdc01.debug.suspend},address=localhost:${auth.server.crossdc01.jvm.debug.port}
|
||||
</auth.server.crossdc01.jvm.debug.args>
|
||||
<auth.server.crossdc02.jvm.debug.args>
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.crossdc02.debug.suspend},address=localhost:${auth.server.crossdc02.jvm.debug.port}
|
||||
</auth.server.crossdc02.jvm.debug.args>
|
||||
<auth.server.crossdc11.jvm.debug.args>
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.crossdc11.debug.suspend},address=localhost:${auth.server.crossdc11.jvm.debug.port}
|
||||
</auth.server.crossdc11.jvm.debug.args>
|
||||
<auth.server.crossdc12.jvm.debug.args>
|
||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.crossdc12.debug.suspend},address=localhost:${auth.server.crossdc12.jvm.debug.port}
|
||||
</auth.server.crossdc12.jvm.debug.args>
|
||||
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>${skipTests}</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>cache-server-infinispan</id>
|
||||
<properties>
|
||||
<cache.server>infinispan</cache.server>
|
||||
<auth.server.undertow.crossdc>true</auth.server.undertow.crossdc>
|
||||
<auth.server.crossdc>true</auth.server.crossdc>
|
||||
<cache.server.jboss>true</cache.server.jboss>
|
||||
<cache.server.config.dir>${cache.server.home}/standalone/configuration</cache.server.config.dir>
|
||||
<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>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
@ -429,17 +608,15 @@
|
|||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-profile-activation</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<!--requireActiveProfile 'auth-server-wildfly/eap' doesn't work unless the profiles are defined in all submodule poms
|
||||
using requireProperty instead-->
|
||||
<requireProperty>
|
||||
<property>cache.server</property>
|
||||
<regex>(infinispan)|(jdg)</regex>
|
||||
<regexMessage>Profile "cache-server-infinispan" requires activation of profile "cache-server-infinispan" or "cache-server-jdg".</regexMessage>
|
||||
<property>auth.servers.crossdc</property>
|
||||
<message>Profile "cache-server-infinispan" requires activation of another profile: either "auth-servers-crossdc-undertow" or "auth-servers-crossdc-jboss".</message>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
|
@ -480,12 +657,11 @@
|
|||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
|
||||
<profile>
|
||||
<id>cache-server-jdg</id>
|
||||
<properties>
|
||||
<cache.server>jdg</cache.server>
|
||||
<auth.server.undertow.crossdc>true</auth.server.undertow.crossdc>
|
||||
<auth.server.crossdc>true</auth.server.crossdc>
|
||||
<cache.server.jboss>true</cache.server.jboss>
|
||||
<cache.server.config.dir>${cache.server.home}/standalone/configuration</cache.server.config.dir>
|
||||
|
@ -504,17 +680,15 @@
|
|||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-profile-activation</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<!--requireActiveProfile 'auth-server-wildfly/eap' doesn't work unless the profiles are defined in all submodule poms
|
||||
using requireProperty instead-->
|
||||
<requireProperty>
|
||||
<property>cache.server</property>
|
||||
<regex>(infinispan)|(jdg)</regex>
|
||||
<regexMessage>Profile "cache-server-jdg" requires activation of profile "cache-server-infinispan" or "cache-server-jdg".</regexMessage>
|
||||
<property>auth.servers.crossdc</property>
|
||||
<message>Profile "cache-server-jdg" requires activation of another profile: either "auth-servers-crossdc-undertow" or "auth-servers-crossdc-jboss".</message>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
|
@ -569,8 +743,8 @@
|
|||
</profile>
|
||||
|
||||
<!--
|
||||
profile that enables/disables specified feature, for more details see
|
||||
https://keycloak.gitbooks.io/documentation/content/server_installation/topics/profiles.html
|
||||
profile that enables/disables specified feature, for more details see
|
||||
https://keycloak.gitbooks.io/documentation/content/server_installation/topics/profiles.html
|
||||
-->
|
||||
<profile>
|
||||
<id>auth-server-enable-disable-feature</id>
|
||||
|
@ -765,7 +939,7 @@
|
|||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
|
||||
<profile>
|
||||
<id>jdbc-driver-dependency</id>
|
||||
<activation>
|
||||
|
@ -807,13 +981,13 @@
|
|||
</profile>
|
||||
|
||||
<!-- Profiles for migration tests-->
|
||||
|
||||
|
||||
<profile>
|
||||
<id>auth-server-migration</id>
|
||||
<properties>
|
||||
<migration.import.file>target/test-classes/migration-test/migration-realm-${migrated.auth.server.version}.json</migration.import.file>
|
||||
<migration.import.props.previous>
|
||||
-Dkeycloak.migration.action=import
|
||||
-Dkeycloak.migration.action=import
|
||||
-Dkeycloak.migration.provider=singleFile
|
||||
-Dkeycloak.migration.file=${migration.import.file}
|
||||
-Dkeycloak.migration.strategy=OVERWRITE_EXISTING
|
||||
|
@ -883,8 +1057,8 @@
|
|||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>migration-import</id>
|
||||
<activation>
|
||||
|
@ -896,7 +1070,7 @@
|
|||
<properties>
|
||||
<migration.import.file>target/test-classes/migration-test/migration-realm-${migrated.auth.server.version}.json</migration.import.file>
|
||||
<migration.import.properties>
|
||||
-Dkeycloak.migration.action=import
|
||||
-Dkeycloak.migration.action=import
|
||||
-Dkeycloak.migration.provider=singleFile
|
||||
-Dkeycloak.migration.file=${migration.import.file}
|
||||
-Dkeycloak.migration.strategy=OVERWRITE_EXISTING
|
||||
|
@ -934,7 +1108,7 @@
|
|||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
|
||||
<profile>
|
||||
<id>migration-productized</id>
|
||||
<activation>
|
||||
|
@ -946,7 +1120,7 @@
|
|||
<migration.import.file>target/test-classes/migration-test/migration-realm-${migrated.version.import.file.suffix}.json</migration.import.file>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
|
||||
<profile>
|
||||
<id>no-account</id>
|
||||
<properties>
|
||||
|
@ -1280,7 +1454,7 @@
|
|||
<auth.server.management.port.jmx>9999</auth.server.management.port.jmx>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
|
||||
<profile>
|
||||
<!--see KEYCLOAK-4793-->
|
||||
<id>kie.maven.settings</id>
|
||||
|
@ -1299,7 +1473,7 @@
|
|||
</kie.maven.settings>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
|
|
Loading…
Reference in a new issue