diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md index b0cd9087db..d9689ed8a5 100644 --- a/testsuite/integration-arquillian/HOW-TO-RUN.md +++ b/testsuite/integration-arquillian/HOW-TO-RUN.md @@ -800,17 +800,39 @@ land by adjusting load balancer configuration (e.g. to direct the traffic to onl 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 by specifying -`cache-server-infinispan` or `cache-server-jdg` profile in maven. +The cross DC requires setting a profile specifying the used cache server. +Use `cache-server-infinispan` Maven profile for Infinispan 10 or higher, or `cache-server-legacy-infinispan` profile for Infinispan 9 and lower. +Use `cache-server-datagrid` Maven profile for Datagrid 8 or higher, or `cache-server-legacy-datagrid` profile for Datagrid 7 and lower. -Since JDG does not distribute `infinispan-server` zip artifact anymore, for `cache-server-jdg` profile it is -necessary to download the artifact and install it to local Maven repository. For JDG 7.3.8, the command is the following: +To specify a custom Java platform to run the cache server it is possible to set parameter: `-Dcache.server.java.home=`. + +### Cache Authentication + +With WildFLy/EAP based auth server option it is possible to enable authentication for the HotRod protocol by enabling profile `cache-auth`. + +It is possible to specify additional parameters: +- `-Dhotrod.sasl.mechanism`: SASL mechanism used by the hotrod protocol. Default value is `DIGEST-MD5`. +- `-Dkeycloak.connectionsInfinispan.hotrodProtocolVersion`: Version of the hotrod protocol. + +Example: `-Pauth-server-wildfly,cache-server-infinispan,cache-auth -Dhotrod.sasl.mechanism=SCRAM-SHA-512` + +Note: The `cache-auth` profile currently doesn't work with the legacy Infinispan/Datagrid modules. See: [KEYCLOAK-18336](https://issues.redhat.com/browse/KEYCLOAK-18336). + +### Data Grid + +Since Datagrid does not distribute `infinispan-server` zip artifact, for `cache-server-datagrid` profile it is +necessary to download the artifact and install it to local Maven repository. For Red Hat Data Grid 8 and above, the command is the following: mvn install:install-file \ - -DgroupId=org.infinispan.server -DartifactId=infinispan-server -Dpackaging=zip -Dclassifier=bin -DgeneratePom=true \ - -Dversion=9.4.21.Final-redhat-00002 -Dfile=jboss-datagrid-7.3.8-server.zip + -DgroupId=com.redhat -DartifactId=datagrid -Dpackaging=zip -Dclassifier=bin -DgeneratePom=true \ + -Dversion=${DATAGRID_VERSION} -Dfile=redhat-datagrid-${DATAGRID_VERSION}-server.zip -#### Run Cross-DC Tests from Maven +For Data Grid 7 and older use: `-Dfile=jboss-datagrid-${DATAGRID_VERSION}-server.zip`. + +### Run Cross-DC Tests from Maven + +Note: Profile `auth-servers-crossdc-undertow` currently doesn't work (see [KEYCLOAK-18335](https://issues.redhat.com/browse/KEYCLOAK-18335)). +Use `-Pauth-servers-crossdc-jboss,auth-server-wildfly` instead. a) Prepare the environment. Compile the infinispan server and eventually Keycloak on JBoss server. @@ -819,14 +841,14 @@ Infinispan/JDG test server via the following command: `mvn -Pcache-server-infinispan,auth-servers-crossdc-undertow -f testsuite/integration-arquillian -DskipTests clean install` -*note: 'cache-server-infinispan' can be replaced by 'cache-server-jdg'* +*note: 'cache-server-infinispan' can be replaced by 'cache-server-datagrid'* a2) If you want to use **JBoss-based** Keycloak backend containers instead of containers on Embedded Undertow, you need to prepare both the Infinispan/JDG test server and the Keycloak server on Wildfly/EAP. Run following command: `mvn -Pcache-server-infinispan,auth-servers-crossdc-jboss,auth-server-wildfly -f testsuite/integration-arquillian -DskipTests clean install` -*note: 'cache-server-infinispan' can be replaced by 'cache-server-jdg'* +*note: 'cache-server-infinispan' can be replaced by 'cache-server-datagrid'* *note: 'auth-server-wildfly' can be replaced by 'auth-server-eap'* @@ -838,7 +860,7 @@ b1) For **Undertow** Keycloak backend containers, you can run the tests using th `mvn -Pcache-server-infinispan,auth-servers-crossdc-undertow -Dtest=org.keycloak.testsuite.crossdc.**.*Test -pl testsuite/integration-arquillian/tests/base clean install` -*note: 'cache-server-infinispan' can be replaced by 'cache-server-jdg'* +*note: 'cache-server-infinispan' can be replaced by 'cache-server-datagrid'* *note: It can be useful to add additional system property to enable logging:* @@ -848,7 +870,7 @@ b2) For **JBoss-based** Keycloak backend containers, you can run the tests like `mvn -Pcache-server-infinispan,auth-servers-crossdc-jboss,auth-server-wildfly -Dtest=org.keycloak.testsuite.crossdc.**.*Test -pl testsuite/integration-arquillian/tests/base clean install` -*note: 'cache-server-infinispan' can be replaced by 'cache-server-jdg'* +*note: 'cache-server-infinispan' can be replaced by 'cache-server-datagrid'* *note: 'auth-server-wildfly can be replaced by auth-server-eap'* @@ -858,7 +880,9 @@ For **JBoss-based** Keycloak backend containers on real DB, the previous command `mvn -f testsuite/integration-arquillian -Dtest=org.keycloak.testsuite.crossdc.**.*Test -Pcache-server-infinispan,auth-servers-crossdc-jboss,auth-server-wildfly,jpa,db-mariadb clean install` -#### Run Cross-DC Tests from Intellij IDEA +### Run Cross-DC Tests from Intellij IDEA + +Note: Profile `auth-servers-crossdc-undertow` which is required in step (3) currently doesn't work (see [KEYCLOAK-18335](https://issues.redhat.com/browse/KEYCLOAK-18335)). First we will manually download, configure and run infinispan servers. Then we can run the tests from IDE against the servers. It's more effective during development as there is no need to restart infinispan server(s) among test runs. diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml index 5dc40b2c92..2382f73502 100644 --- a/testsuite/integration-arquillian/pom.xml +++ b/testsuite/integration-arquillian/pom.xml @@ -38,6 +38,7 @@ ${java.home} ${java.home} undertow + ${java.home} 21.0.2.Final diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/common/ant/configure.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/common/ant/configure.xml index 1691f83f8c..949349f9a2 100644 --- a/testsuite/integration-arquillian/servers/auth-server/jboss/common/ant/configure.xml +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/common/ant/configure.xml @@ -1,4 +1,4 @@ - + @@ -227,6 +227,15 @@ + + + + + + + + + diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/common/jboss-cli/cross-dc-setup_cache-auth.cli b/testsuite/integration-arquillian/servers/auth-server/jboss/common/jboss-cli/cross-dc-setup_cache-auth.cli new file mode 100644 index 0000000000..31bb050fc1 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/common/jboss-cli/cross-dc-setup_cache-auth.cli @@ -0,0 +1,125 @@ +echo ** Update replicated-cache work element ** +/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) + +echo ** Update distributed-cache sessions element ** +/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) + +echo ** Update distributed-cache offlineSessions element ** +/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) + +echo ** Update distributed-cache clientSessions element ** +/subsystem=infinispan/cache-container=keycloak/distributed-cache=clientSessions/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) + +echo ** Update distributed-cache offlineClientSessions element ** +/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineClientSessions/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) + +echo ** Update distributed-cache loginFailures element ** +/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) + +echo ** Update distributed-cache actionTokens element ** +/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=remote:write-attribute( \ + name=properties, \ + value={ \ + infinispan.client.hotrod.auth_username=myuser, \ + infinispan.client.hotrod.auth_password=qwer1234!, \ + infinispan.client.hotrod.auth_realm=default, \ + infinispan.client.hotrod.auth_server_name=infinispan, \ + infinispan.client.hotrod.sasl_mechanism=@HOTROD_SASL_MECHANISM@, \ + infinispan.client.hotrod.trust_store_file_name=${jboss.server.config.dir}/hotrod-client-truststore.jks, \ + infinispan.client.hotrod.trust_store_type=JKS, \ + infinispan.client.hotrod.trust_store_password=password, \ + rawValues=true, \ + marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \ + protocolVersion=${keycloak.connectionsInfinispan.hotrodProtocolVersion} \ + } \ +) diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/common/keystore/hotrod-client-truststore.jks b/testsuite/integration-arquillian/servers/auth-server/jboss/common/keystore/hotrod-client-truststore.jks new file mode 100644 index 0000000000..e296880e4a Binary files /dev/null and b/testsuite/integration-arquillian/servers/auth-server/jboss/common/keystore/hotrod-client-truststore.jks differ diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml index 1624dbbe8b..f0bdf8082e 100644 --- a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml @@ -70,6 +70,8 @@ ${project.parent.basedir}/../../../tests/base/src/test/resources + + false @@ -270,9 +272,12 @@ There's also another case, when we have a dynamic property (like "keycloak.connectionsJpa.url") that can change in the runtime. In such cases, we CAN NOT put is as a property (or Ant will see outdated values, not the dynamic ones). --> + ${auth.server.home} + + @@ -697,6 +702,13 @@ jdbc:mariadb:${mariadb.ha.mode}://${mariadb.hosts}/${mariadb.database}${mariadb.options} + + + cache-auth + + true + + diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/assembly.xml b/testsuite/integration-arquillian/servers/cache-server/infinispan/assembly.xml new file mode 100644 index 0000000000..91a25b6bd8 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/assembly.xml @@ -0,0 +1,47 @@ + + + + + cache-server-${cache.server} + + + zip + + + false + + + + ${cache.server.infinispan.home} + cache-server-${cache.server} + + **/*.sh + **/clustered.xml + + + + ${cache.server.infinispan.home} + cache-server-${cache.server} + + **/*.sh + + 0755 + + + + diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/common/add-keycloak-caches.xsl b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/add-keycloak-caches.xsl new file mode 100644 index 0000000000..20d8cc9417 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/add-keycloak-caches.xsl @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/common/cache-authentication-disabled.xsl b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/cache-authentication-disabled.xsl new file mode 100644 index 0000000000..c4bf750271 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/cache-authentication-disabled.xsl @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/common/cache-authentication-enabled.xsl b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/cache-authentication-enabled.xsl new file mode 100644 index 0000000000..96d5fa6adc --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/cache-authentication-enabled.xsl @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/common/server.jks b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/server.jks new file mode 100644 index 0000000000..cc62df9bb3 Binary files /dev/null and b/testsuite/integration-arquillian/servers/cache-server/infinispan/common/server.jks differ diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/datagrid/pom.xml b/testsuite/integration-arquillian/servers/cache-server/infinispan/datagrid/pom.xml new file mode 100644 index 0000000000..9e4b1f68f1 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/datagrid/pom.xml @@ -0,0 +1,69 @@ + + + + + + org.keycloak.testsuite + integration-arquillian-servers-cache-server-infinispan + 14.0.0-SNAPSHOT + + 4.0.0 + + integration-arquillian-servers-cache-server-infinispan-datagrid + pom + Keycloak Arquillian Integration TestSuite - Cache Server - Infinispan - Datagrid + + + datagrid + + com.redhat + datagrid + 8.1.0 + redhat-datagrid-${cache.server.infinispan.version}-server + + + + + + maven-dependency-plugin + + + unpack-cache-server + generate-resources + + unpack + + + + + ${cache.server.infinispan.groupId} + ${cache.server.infinispan.artifactId} + ${cache.server.infinispan.version} + zip + bin + ${containers.home} + + + + + + + + + diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/src/.dont-delete b/testsuite/integration-arquillian/servers/cache-server/infinispan/datagrid/src/.dont-delete similarity index 100% rename from testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/src/.dont-delete rename to testsuite/integration-arquillian/servers/cache-server/infinispan/datagrid/src/.dont-delete diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/infinispan/pom.xml b/testsuite/integration-arquillian/servers/cache-server/infinispan/infinispan/pom.xml new file mode 100644 index 0000000000..2ed2a3a488 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/infinispan/pom.xml @@ -0,0 +1,63 @@ + + + + + + org.keycloak.testsuite + integration-arquillian-servers-cache-server-infinispan + 14.0.0-SNAPSHOT + + 4.0.0 + + integration-arquillian-servers-cache-server-infinispan-infinispan + pom + Keycloak Arquillian Integration TestSuite - Cache Server - Infinispan - Infinispan + + + infinispan + + org.infinispan.server + infinispan-server + ${infinispan.version} + ${cache.server.infinispan.artifactId}-${cache.server.infinispan.version} + + + + + + com.googlecode.maven-download-plugin + download-maven-plugin + + + download-infinispan-server + generate-resources + + wget + + + http://downloads.jboss.org/infinispan/${cache.server.infinispan.version}/infinispan-server-${cache.server.infinispan.version}.zip + true + ${containers.home} + + + + + + + diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/src/.dont-delete b/testsuite/integration-arquillian/servers/cache-server/infinispan/infinispan/src/.dont-delete similarity index 100% rename from testsuite/integration-arquillian/servers/cache-server/jboss/jdg/src/.dont-delete rename to testsuite/integration-arquillian/servers/cache-server/infinispan/infinispan/src/.dont-delete diff --git a/testsuite/integration-arquillian/servers/cache-server/infinispan/pom.xml b/testsuite/integration-arquillian/servers/cache-server/infinispan/pom.xml new file mode 100644 index 0000000000..33c3019ce9 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/infinispan/pom.xml @@ -0,0 +1,302 @@ + + + + + + 4.0.0 + + + org.keycloak.testsuite + integration-arquillian-servers-cache-server + 14.0.0-SNAPSHOT + + + pom + integration-arquillian-servers-cache-server-infinispan + Keycloak Arquillian Integration TestSuite - Cache Server - Infinispan + + + ${project.parent.basedir}/common + ${project.parent.basedir}/assembly.xml + + ${containers.home}/${cache.server.infinispan.unpacked.folder.name} + true + ${cache.server.infinispan.home}/server/conf + + cache-authentication-disabled.xsl + + + + + + cache-auth + + cache-authentication-enabled.xsl + + + + + cache-server-infinispan-submodules + + + src + + + + + + + maven-enforcer-plugin + + + + enforce + + + + + cache.server.infinispan.groupId + cache.server.infinispan.artifactId + cache.server.infinispan.version + cache.server.infinispan.unpacked.folder.name + + + + + + + + + org.codehaus.mojo + xml-maven-plugin + + + configure-keycloak-caches + process-test-resources + + transform + + + + + + + ${cache.server.infinispan.config.dir} + + infinispan-xsite.xml + + ${common.resources}/add-keycloak-caches.xsl + + + local.site + dc-0 + + + remote.site + dc-1 + + + transactions.enabled + ${cache.server.infinispan.jdg-transactions-enabled} + + + ${cache.server.infinispan.config.dir} + + + ^(.*)\.xml$ + $1-1.xml + + + + + + + ${cache.server.infinispan.config.dir} + + infinispan-xsite.xml + + ${common.resources}/add-keycloak-caches.xsl + + + local.site + dc-1 + + + remote.site + dc-0 + + + transactions.enabled + ${cache.server.infinispan.jdg-transactions-enabled} + + + ${cache.server.infinispan.config.dir} + + + ^(.*)\.xml$ + $1-2.xml + + + + + + + + + + configure-keycloak-authorization + process-test-resources + + transform + + + + + + ${cache.server.infinispan.config.dir} + + infinispan-xsite-1.xml + infinispan-xsite-2.xml + + ${common.resources}/${cache.server.cache-auth-xsl} + + + hotrod.sasl.mechanism + ${hotrod.sasl.mechanism} + + + ${cache.server.infinispan.config.dir} + + + + + + + + + + maven-resources-plugin + + + copy-server-keystore + process-test-resources + + copy-resources + + + ${cache.server.infinispan.config.dir} + + + ${common.resources} + + server.jks + + + + true + + + + + + + + maven-antrun-plugin + + + remove-empty-xmlns + process-test-resources + + run + + + + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + create-infinispan-user + process-test-resources + + exec + + + ${cache.server.infinispan.home}/bin/cli.sh + ${cache.server.infinispan.home}/bin + + user + create + myuser + -p + "qwer1234!" + + + + + + + + maven-assembly-plugin + + + create-zip + package + + single + + + + ${assembly.xml} + + false + + + + + + + + + + + cache-server-infinispan + + infinispan + + + + cache-server-datagrid + + datagrid + + + + + + diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/assembly.xml b/testsuite/integration-arquillian/servers/cache-server/legacy/assembly.xml similarity index 89% rename from testsuite/integration-arquillian/servers/cache-server/jboss/assembly.xml rename to testsuite/integration-arquillian/servers/cache-server/legacy/assembly.xml index e0408089f9..c29505dfbe 100644 --- a/testsuite/integration-arquillian/servers/cache-server/jboss/assembly.xml +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/assembly.xml @@ -17,7 +17,7 @@ - ${cache.server.jboss} + cache-server-${cache.server} zip @@ -27,7 +27,7 @@ - ${cache.server.jboss.home} + ${cache.server.legacy.home} cache-server-${cache.server} **/*.sh @@ -35,7 +35,7 @@ - ${cache.server.jboss.home} + ${cache.server.legacy.home} cache-server-${cache.server} **/*.sh diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/common/add-keycloak-caches.xsl b/testsuite/integration-arquillian/servers/cache-server/legacy/common/add-keycloak-caches.xsl similarity index 100% rename from testsuite/integration-arquillian/servers/cache-server/jboss/common/add-keycloak-caches.xsl rename to testsuite/integration-arquillian/servers/cache-server/legacy/common/add-keycloak-caches.xsl diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/common/cache-authorization.xsl b/testsuite/integration-arquillian/servers/cache-server/legacy/common/cache-authorization.xsl similarity index 93% rename from testsuite/integration-arquillian/servers/cache-server/jboss/common/cache-authorization.xsl rename to testsuite/integration-arquillian/servers/cache-server/legacy/common/cache-authorization.xsl index 26ce283215..b7d987b073 100644 --- a/testsuite/integration-arquillian/servers/cache-server/jboss/common/cache-authorization.xsl +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/common/cache-authorization.xsl @@ -80,6 +80,11 @@ + + + + + diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/common/io.xsl b/testsuite/integration-arquillian/servers/cache-server/legacy/common/io.xsl similarity index 100% rename from testsuite/integration-arquillian/servers/cache-server/jboss/common/io.xsl rename to testsuite/integration-arquillian/servers/cache-server/legacy/common/io.xsl diff --git a/testsuite/integration-arquillian/servers/cache-server/legacy/common/server.jks b/testsuite/integration-arquillian/servers/cache-server/legacy/common/server.jks new file mode 100644 index 0000000000..cc62df9bb3 Binary files /dev/null and b/testsuite/integration-arquillian/servers/cache-server/legacy/common/server.jks differ diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml b/testsuite/integration-arquillian/servers/cache-server/legacy/datagrid/pom.xml similarity index 66% rename from testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml rename to testsuite/integration-arquillian/servers/cache-server/legacy/datagrid/pom.xml index cbc209b23e..93536933b4 100644 --- a/testsuite/integration-arquillian/servers/cache-server/jboss/jdg/pom.xml +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/datagrid/pom.xml @@ -20,27 +20,25 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> org.keycloak.testsuite - integration-arquillian-servers-cache-server-jboss + integration-arquillian-servers-cache-server-legacy 14.0.0-SNAPSHOT 4.0.0 - integration-arquillian-servers-cache-server-jdg + integration-arquillian-servers-cache-server-legacy-datagrid pom - Cache Server - JDG + Keycloak Arquillian Integration TestSuite - Cache Server - Legacy Datagrid - jdg - cache-server-${cache.server} - ${containers.home}/${cache.server.container} + legacy-datagrid - true - true - org.infinispan.server - infinispan-server - ${jdg.version} - ${cache.server.jboss.artifactId}-${jdg.version} + com.redhat + datagrid + 7.3.8 + jboss-datagrid-${cache.server.legacy.version}-server + true + true ${cache.default.worker.io-threads} ${cache.default.worker.task-max-threads} @@ -59,9 +57,9 @@ - ${cache.server.jboss.groupId} - ${cache.server.jboss.artifactId} - ${cache.server.jboss.version} + ${cache.server.legacy.groupId} + ${cache.server.legacy.artifactId} + ${cache.server.legacy.version} zip bin ${containers.home} diff --git a/testsuite/integration-arquillian/servers/cache-server/legacy/datagrid/src/.dont-delete b/testsuite/integration-arquillian/servers/cache-server/legacy/datagrid/src/.dont-delete new file mode 100644 index 0000000000..c969acacc9 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/datagrid/src/.dont-delete @@ -0,0 +1 @@ +This file is to mark this Maven project as a valid option for building cache server artifact diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml b/testsuite/integration-arquillian/servers/cache-server/legacy/infinispan/pom.xml similarity index 61% rename from testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml rename to testsuite/integration-arquillian/servers/cache-server/legacy/infinispan/pom.xml index bbc8fd82b8..305569aa03 100644 --- a/testsuite/integration-arquillian/servers/cache-server/jboss/infinispan/pom.xml +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/infinispan/pom.xml @@ -20,29 +20,25 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> org.keycloak.testsuite - integration-arquillian-servers-cache-server-jboss + integration-arquillian-servers-cache-server-legacy 14.0.0-SNAPSHOT 4.0.0 - integration-arquillian-servers-cache-server-infinispan + integration-arquillian-servers-cache-server-legacy-infinispan pom - Cache Server - JBoss - Infinispan + Keycloak Arquillian Integration TestSuite - Cache Server - Legacy Infinispan - infinispan - cache-server-${cache.server} - ${containers.home}/${cache.server.container} - - true - false - org.infinispan.server - infinispan-server - - 9.4.18.Final - ${cache.server.jboss.artifactId}-${cache.server.jboss.version} + legacy-infinispan + + org.infinispan.server + infinispan-server + 9.4.21.Final + ${cache.server.legacy.artifactId}-${cache.server.legacy.version} + true + false ${cache.default.worker.io-threads} ${cache.default.worker.task-max-threads} @@ -60,7 +56,7 @@ wget - http://downloads.jboss.org/infinispan/${cache.server.jboss.version}/infinispan-server-${cache.server.jboss.version}.zip + https://downloads.jboss.org/infinispan/${cache.server.legacy.version}/infinispan-server-${cache.server.legacy.version}.zip true ${containers.home} diff --git a/testsuite/integration-arquillian/servers/cache-server/legacy/infinispan/src/.dont-delete b/testsuite/integration-arquillian/servers/cache-server/legacy/infinispan/src/.dont-delete new file mode 100644 index 0000000000..c969acacc9 --- /dev/null +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/infinispan/src/.dont-delete @@ -0,0 +1 @@ +This file is to mark this Maven project as a valid option for building cache server artifact diff --git a/testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/cache-server/legacy/pom.xml similarity index 83% rename from testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml rename to testsuite/integration-arquillian/servers/cache-server/legacy/pom.xml index 1078722b7b..42bcc77721 100644 --- a/testsuite/integration-arquillian/servers/cache-server/jboss/pom.xml +++ b/testsuite/integration-arquillian/servers/cache-server/legacy/pom.xml @@ -25,22 +25,25 @@ 4.0.0 - integration-arquillian-servers-cache-server-jboss + integration-arquillian-servers-cache-server-legacy pom - Cache Server - JBoss Family + Keycloak Arquillian Integration TestSuite - Cache Server - Legacy ${project.parent.basedir}/common ${project.parent.basedir}/assembly.xml - ${containers.home}/${cache.server.jboss.unpacked.folder.name} - true - true + + ${containers.home}/${cache.server.legacy.unpacked.folder.name} + + true + true + - cache-server-jboss-submodules + cache-server-legacy-submodules src @@ -59,12 +62,11 @@ - cache.server - cache.server.jboss.cache-authorization-enabled - cache.server.jboss.groupId - cache.server.jboss.artifactId - cache.server.jboss.version - cache.server.jboss.unpacked.folder.name + cache.server.legacy.cache-authorization-enabled + cache.server.legacy.groupId + cache.server.legacy.artifactId + cache.server.legacy.version + cache.server.legacy.unpacked.folder.name @@ -87,7 +89,7 @@ - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration clustered.xml @@ -103,10 +105,10 @@ transactions.enabled - ${cache.server.jboss.jdg-transactions-enabled} + ${cache.server.legacy.jdg-transactions-enabled} - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration ^(.*)\.xml$ @@ -117,7 +119,7 @@ - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration clustered.xml @@ -133,10 +135,10 @@ transactions.enabled - ${cache.server.jboss.jdg-transactions-enabled} + ${cache.server.legacy.jdg-transactions-enabled} - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration ^(.*)\.xml$ @@ -156,17 +158,17 @@ transform - ${cache.server.jboss.cache-authorization-disabled} + ${cache.server.legacy.cache-authorization-disabled} - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration clustered-1.xml clustered-2.xml ${common.resources}/cache-authorization.xsl - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration @@ -181,13 +183,13 @@ - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration standalone.xml standalone-ha.xml ${common.resources}/io.xsl - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration worker.io-threads @@ -215,7 +217,7 @@ copy-resources - ${cache.server.jboss.home}/standalone/configuration + ${cache.server.legacy.home}/standalone/configuration ${common.resources} @@ -234,11 +236,30 @@ copy-resources - ${cache.server.jboss.home}/standalone-dc-2/deployments + ${cache.server.legacy.home}/standalone-dc-2/deployments true - ${cache.server.jboss.home}/standalone/deployments + ${cache.server.legacy.home}/standalone/deployments + + + true + + + + copy-server-keystore + process-resources + + copy-resources + + + ${cache.server.legacy.home}/standalone/configuration + + + ${common.resources} + + server.jks + true @@ -271,17 +292,18 @@ - cache-server-infinispan + cache-server-legacy-infinispan infinispan - cache-server-jdg + cache-server-legacy-datagrid - jdg + datagrid + diff --git a/testsuite/integration-arquillian/servers/cache-server/pom.xml b/testsuite/integration-arquillian/servers/cache-server/pom.xml index 54cbc86067..701a96b02d 100644 --- a/testsuite/integration-arquillian/servers/cache-server/pom.xml +++ b/testsuite/integration-arquillian/servers/cache-server/pom.xml @@ -27,15 +27,11 @@ integration-arquillian-servers-cache-server pom - Cache Server - - - ${jboss.default.worker.io-threads} - ${jboss.default.worker.task-max-threads} - + Keycloak Arquillian Integration TestSuite - Cache Server - jboss + infinispan + legacy diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml index 1c68005caa..0f0da2c034 100644 --- a/testsuite/integration-arquillian/servers/pom.xml +++ b/testsuite/integration-arquillian/servers/pom.xml @@ -37,15 +37,13 @@ 7.1.5.GA-redhat-00002 7.1.1.Final - - 9.4.6.Final-redhat-00002 - 16 128 500 2 4 + DIGEST-MD5 jboss-cli.sh diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java index 6dd2dbc089..1b9425fb78 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/AuthServerTestEnricher.java @@ -259,11 +259,15 @@ public class AuthServerTestEnricher { }); containers.stream() - .filter(c -> c.getQualifier().startsWith("cache-server-cross-dc-")) + .filter(c -> c.getQualifier().startsWith("cache-server-")) .sorted((a, b) -> a.getQualifier().compareTo(b.getQualifier())) .forEach(containerInfo -> { - int prefixSize = "cache-server-cross-dc-".length(); - int dcIndex = Integer.parseInt(containerInfo.getQualifier().substring(prefixSize)) -1; + + log.info(String.format("cache container: %s", containerInfo.getQualifier())); + + int prefixSize = containerInfo.getQualifier().lastIndexOf("-") + 1; + int dcIndex = Integer.parseInt(containerInfo.getQualifier().substring(prefixSize)) - 1; + suiteContext.addCacheServerInfo(dcIndex, containerInfo); }); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CacheStatisticsControllerEnricher.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CacheStatisticsControllerEnricher.java index 8d862d83be..d0e2b4e8f6 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CacheStatisticsControllerEnricher.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/CacheStatisticsControllerEnricher.java @@ -7,6 +7,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.net.MalformedURLException; +import java.rmi.UnmarshalException; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; @@ -41,6 +42,7 @@ import org.keycloak.connections.infinispan.InfinispanConnectionProvider; import org.keycloak.common.util.Retry; import org.keycloak.testsuite.arquillian.annotation.JmxInfinispanCacheStatistics; import org.keycloak.testsuite.arquillian.annotation.JmxInfinispanChannelStatistics; +import org.keycloak.testsuite.arquillian.containers.InfinispanServerDeployableContainer; import org.keycloak.testsuite.arquillian.jmx.JmxConnectorRegistry; import org.keycloak.testsuite.arquillian.undertow.KeycloakOnUndertow; import org.keycloak.testsuite.crossdc.DC; @@ -123,8 +125,9 @@ public class CacheStatisticsControllerEnricher implements TestEnricher { private InfinispanStatistics getJGroupsChannelStatistics(JmxInfinispanChannelStatistics annotation) throws MalformedObjectNameException, IOException, MalformedURLException { ObjectName mbeanName = new ObjectName(String.format( - "%s:type=%s,cluster=\"%s\"", + "%s:%stype=%s,cluster=\"%s\"", annotation.domain().isEmpty() ? getDefaultDomain(annotation.dc().getDcIndex(), annotation.dcNodeIndex()) : InfinispanConnectionProvider.JMX_DOMAIN, + isLegacyInfinispan() ? "" : "manager=\"default\",", annotation.type(), annotation.cluster() )); @@ -182,9 +185,13 @@ public class CacheStatisticsControllerEnricher implements TestEnricher { } //cache-server - return InfinispanConnectionProvider.JMX_DOMAIN; + return isLegacyInfinispan() ? "jboss.datagrid-infinispan" : "org.infinispan"; } - + + private boolean isLegacyInfinispan() { // infinispan 9 or lower + return Boolean.parseBoolean(System.getProperty("cache.server.legacy", "false")); + } + private Supplier getJmxServerConnection(JmxInfinispanCacheStatistics annotation) throws MalformedURLException { final String host; final int port; @@ -200,6 +207,19 @@ public class CacheStatisticsControllerEnricher implements TestEnricher { ? Integer.valueOf(container.getContainerConfiguration().getContainerProperties().get("managementPort")) : 9990; } else { + Container container = suiteContext.get().getCacheServersInfo().get(0).getArquillianContainer(); + if (container.getDeployableContainer() instanceof InfinispanServerDeployableContainer) { + // jmx connection to infinispan server + return () -> { + try { + return jmxConnectorRegistry.get().getConnection( + ((InfinispanServerDeployableContainer) container.getDeployableContainer()).getJMXServiceURL() + ).getMBeanServerConnection(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + }; + } host = annotation.host().isEmpty() ? System.getProperty((annotation.hostProperty().isEmpty() ? "keycloak.connectionsInfinispan.remoteStoreServer" @@ -239,6 +259,19 @@ public class CacheStatisticsControllerEnricher implements TestEnricher { ? Integer.valueOf(container.getContainerConfiguration().getContainerProperties().get("managementPort")) : 9990; } else { + Container container = suiteContext.get().getCacheServersInfo().get(0).getArquillianContainer(); + if (container.getDeployableContainer() instanceof InfinispanServerDeployableContainer) { + // jmx connection to infinispan server + return () -> { + try { + return jmxConnectorRegistry.get().getConnection( + ((InfinispanServerDeployableContainer) container.getDeployableContainer()).getJMXServiceURL() + ).getMBeanServerConnection(); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + }; + } host = annotation.host().isEmpty() ? System.getProperty((annotation.hostProperty().isEmpty() ? "keycloak.connectionsInfinispan.remoteStoreServer" @@ -384,7 +417,7 @@ public class CacheStatisticsControllerEnricher implements TestEnricher { public void reset() { try { getConnection().invoke(getMbeanName(), "resetStats", new Object[] {}, new String[] {}); - } catch (NotSerializableException ex) { + } catch (NotSerializableException | UnmarshalException ex) { // Ignore return value not serializable, the invocation has already done its job } catch (IOException | InstanceNotFoundException | MBeanException | ReflectionException ex) { throw new RuntimeException(ex); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/InfinispanServerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/InfinispanServerConfiguration.java new file mode 100644 index 0000000000..0c1cf43860 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/InfinispanServerConfiguration.java @@ -0,0 +1,101 @@ +/* + * Copyright 2019 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.keycloak.testsuite.arquillian.containers; + +import java.io.File; +import org.apache.commons.validator.routines.IntegerValidator; +import org.jboss.arquillian.container.spi.ConfigurationException; +import org.jboss.arquillian.container.spi.client.container.ContainerConfiguration; + +/** + * + * @author tkyjovsk + */ +public class InfinispanServerConfiguration implements ContainerConfiguration { + + private String infinispanHome; + private String serverConfig; + private Integer portOffset; + private Integer managementPort; + private String additionalParameters; + + @Override + public void validate() throws ConfigurationException { + if (infinispanHome == null) { + throw new ConfigurationException("`infinispanHome` cannot be null"); + } + if (!new File(infinispanHome).isDirectory()) { + throw new ConfigurationException(String.format("`infinispanHome` is not a valid directory: '%s'", infinispanHome)); + } + + if (portOffset == null) { + portOffset = 0; + } + if (!IntegerValidator.getInstance().isInRange(portOffset, 1000, 64535)) { + throw new ConfigurationException(String.format("Invalid portOffset: %s", portOffset)); + } + + if (managementPort == null) { + managementPort = 9990 + portOffset; + } + if (!IntegerValidator.getInstance().isInRange(managementPort, 1000, 65535)) { + throw new ConfigurationException(String.format("Invalid managementPort: %s", managementPort)); + } + + } + + public String getInfinispanHome() { + return infinispanHome; + } + + public void setInfinispanHome(String infinispanHome) { + this.infinispanHome = infinispanHome; + } + + public String getServerConfig() { + return serverConfig; + } + + public void setServerConfig(String serverConfig) { + this.serverConfig = serverConfig; + } + + public Integer getPortOffset() { + return portOffset; + } + + public void setPortOffset(Integer portOffset) { + this.portOffset = portOffset; + } + + public String getAdditionalParameters() { + return additionalParameters; + } + + public void setAdditionalParameters(String additionalParameters) { + this.additionalParameters = additionalParameters; + } + + public Integer getManagementPort() { + return managementPort; + } + + public void setManagementPort(Integer managementPort) { + this.managementPort = managementPort; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/InfinispanServerDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/InfinispanServerDeployableContainer.java new file mode 100644 index 0000000000..d9a446e7ea --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/InfinispanServerDeployableContainer.java @@ -0,0 +1,246 @@ +/* + * Copyright 2019 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.keycloak.testsuite.arquillian.containers; + +import java.io.File; +import java.io.IOException; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; +import javax.management.remote.JMXServiceURL; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.jboss.arquillian.container.spi.client.container.DeployableContainer; +import org.jboss.arquillian.container.spi.client.container.DeploymentException; +import org.jboss.arquillian.container.spi.client.container.LifecycleException; +import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; +import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData; +import org.jboss.logging.Logger; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.descriptor.api.Descriptor; + +/** + * + * @author tkyjovsk + */ +public class InfinispanServerDeployableContainer implements DeployableContainer { + + protected static final Logger log = Logger.getLogger(InfinispanServerDeployableContainer.class); + + InfinispanServerConfiguration configuration; + private Process infinispanServerProcess; + + private File pidFile; + private JMXServiceURL jmxServiceURL; + + private static final Boolean CACHE_SERVER_AUTH = Boolean.parseBoolean(System.getProperty("cache.server.auth", "false")); + + @Override + public Class getConfigurationClass() { + return InfinispanServerConfiguration.class; + } + + @Override + public void setup(InfinispanServerConfiguration configuration) { + this.configuration = configuration; + pidFile = new File(configuration.getInfinispanHome(), "bin/server.pid"); + } + + @Override + public void start() throws LifecycleException { + List commands = new ArrayList<>(); + commands.add("./server.sh"); + + if (configuration.getServerConfig() != null) { + commands.add("-c"); + commands.add(configuration.getServerConfig()); + } + + if (configuration.getPortOffset() != null && configuration.getPortOffset() > 0) { + commands.add("-o"); + commands.add(configuration.getPortOffset().toString()); + } + + commands.add(String.format("-Dcom.sun.management.jmxremote.port=%s", configuration.getManagementPort())); + commands.add("-Dcom.sun.management.jmxremote.authenticate=false"); + commands.add("-Dcom.sun.management.jmxremote.ssl=false"); + + if (configuration.getAdditionalParameters() != null) { + commands.addAll(Arrays.asList(configuration.getAdditionalParameters().split("\\s+"))); + } + + ProcessBuilder pb = new ProcessBuilder(commands); + pb = pb.directory(new File(configuration.getInfinispanHome(), "/bin")).inheritIO().redirectErrorStream(true); + pb.environment().put("LAUNCH_ISPN_IN_BACKGROUND", "false"); + pb.environment().put("ISPN_PIDFILE", pidFile.getAbsolutePath()); + String javaHome = System.getProperty("cache.server.java.home"); + if (javaHome != null) { + pb.environment().put("JAVA_HOME", javaHome); + } + try { + log.info("Starting Infinispan server"); + log.info(configuration.getInfinispanHome()); + log.info(commands); + infinispanServerProcess = pb.start(); + + trustAllCertificates(); + + long startTimeMillis = System.currentTimeMillis(); + long startupTimeoutMillis = 30 * 1000; + URL consoleURL = new URL(String.format("%s://localhost:%s/console/", + CACHE_SERVER_AUTH ? "https" : "http", + 11222 + configuration.getPortOffset())); + + while (true) { + Thread.sleep(1000); + if (System.currentTimeMillis() > startTimeMillis + startupTimeoutMillis) { + stop(); + throw new LifecycleException("Infinispan server startup timed out."); + } + + HttpURLConnection connection = (HttpURLConnection) consoleURL.openConnection(); + connection.setReadTimeout(1000); + connection.setConnectTimeout(1000); + try { + connection.connect(); + if (connection.getResponseCode() == 200) { + break; + } + connection.disconnect(); + } catch (ConnectException ex) { + // ignoring + } + } + + log.info("Infinispan server started."); + + } catch (IOException ex) { + throw new LifecycleException("Unable to start Infinispan server.", ex); + } catch (InterruptedException ex) { + log.error("Infinispan server startup process interupted.", ex); + stop(); + } + } + + private void trustAllCertificates() { + + TrustManager[] trustAllCerts; + trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + + @Override + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + // Install the all-trusting trust manager + try { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + } catch (KeyManagementException | NoSuchAlgorithmException e) { + throw new RuntimeException("Unable to initialize a 'trust-all' trust manager."); + } + } + + @Override + public void stop() throws LifecycleException { + log.info("Stopping Infinispan server"); + infinispanServerProcess.destroy(); + try { + infinispanServerProcess.waitFor(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + log.info("Unable to stop Infinispan server within timeout. Stopping forcibly."); + infinispanServerProcess.destroyForcibly(); + } + log.info("Infinispan server stopped"); + } + + private long getPID() throws IOException { + if (pidFile == null) { + throw new IllegalStateException(String.format("Unable to find PID file '%s'", pidFile)); + } + return Long.parseLong(Files.readAllLines(pidFile.toPath()).get(0).trim()); + } + + /** + * Attach to a local Infinispan JVM, launch a management-agent, and return + * its JMXServiceURL. + * + * @return + */ + public JMXServiceURL getJMXServiceURL() throws IOException { + if (jmxServiceURL == null) { + jmxServiceURL = new JMXServiceURL(String.format("service:jmx:rmi:///jndi/rmi://localhost:%s/jmxrmi", configuration.getManagementPort())); + } + return jmxServiceURL; + } + + @Override + public ProtocolDescription getDefaultProtocol() { + return ProtocolDescription.DEFAULT; + } + + @Override + public ProtocolMetaData deploy(Archive archv) throws DeploymentException { + throw new UnsupportedOperationException(); + } + + @Override + public void undeploy(Archive archv) throws DeploymentException { + throw new UnsupportedOperationException(); + } + + @Override + public void deploy(Descriptor d) throws DeploymentException { + throw new UnsupportedOperationException(); + } + + @Override + public void undeploy(Descriptor d) throws DeploymentException { + throw new UnsupportedOperationException(); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java index c2ec2af176..3d336be347 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java @@ -43,7 +43,8 @@ public class MultipleContainersExtension implements LoadableExtension { logger.info("Multiple containers extension registering."); - builder.service(DeployableContainer.class, KeycloakQuarkusServerDeployableContainer.class); + builder.service(DeployableContainer.class, KeycloakQuarkusServerDeployableContainer.class) + .service(DeployableContainer.class, InfinispanServerDeployableContainer.class); builder.context(ContainerContextImpl.class).context(DeploymentContextImpl.class); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/crossdc/SAMLAdapterCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/crossdc/SAMLAdapterCrossDCTest.java index 5767265d14..8d81e3032c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/crossdc/SAMLAdapterCrossDCTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/crossdc/SAMLAdapterCrossDCTest.java @@ -31,7 +31,7 @@ import org.keycloak.testsuite.utils.arquillian.ContainerConstants; import org.keycloak.testsuite.crossdc.ServerSetup; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; import static org.keycloak.testsuite.adapter.AbstractServletsAdapterTest.samlServletDeployment; /** @@ -46,7 +46,7 @@ public class SAMLAdapterCrossDCTest extends AbstractSAMLAdapterClusteredTest { @BeforeClass public static void checkCrossDcTest() { - Assume.assumeThat("Seems not to be running cross-DC tests", System.getProperty("cache.server"), not(is("undefined"))); + Assume.assumeThat("Seems not to be running cross-DC tests", System.getProperty("cache.server"), is(notNullValue())); } private static final String SESSION_CACHE_NAME = EmployeeServletDistributable.DEPLOYMENT_NAME + "-cache"; diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml index c8bddbc255..64e318563e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -302,9 +302,9 @@ - + - ${auth.server.crossdc} && ! ${cache.server.lifecycle.skip} + ${auth.server.crossdc} && ! ${cache.server.lifecycle.skip} && ${cache.server.legacy} org.jboss.as.arquillian.container.managed.ManagedDeployableContainer ${cache.server.home} clustered-1.xml @@ -328,12 +328,13 @@ ${cache.server.console.output} ${cache.server.management.port} ${auth.server.jboss.startup.timeout} + ${cache.server.java.home} - + - ${auth.server.crossdc} && ! ${cache.server.lifecycle.skip} + ${auth.server.crossdc} && ! ${cache.server.lifecycle.skip} && ${cache.server.legacy} org.jboss.as.arquillian.container.managed.ManagedDeployableContainer ${cache.server.home} true @@ -359,6 +360,36 @@ ${cache.server.console.output} ${cache.server.2.management.port} ${auth.server.jboss.startup.timeout} + ${cache.server.java.home} + + + + + + ${auth.server.crossdc} && ! ${cache.server.lifecycle.skip} && ! ${cache.server.legacy} + org.keycloak.testsuite.arquillian.containers.InfinispanServerDeployableContainer + ${cache.server.home}-dc1 + infinispan-xsite.xml + ${cache.server.1.port.offset} + ${cache.server.management.port} + + -Djgroups.udp.mcast_port=46698 + -Djgroups.tcpping.initial_hosts=127.0.0.1[8810],127.0.0.1[9810] + + + + + + ${auth.server.crossdc} && ! ${cache.server.lifecycle.skip} && ! ${cache.server.legacy} + org.keycloak.testsuite.arquillian.containers.InfinispanServerDeployableContainer + ${cache.server.home}-dc2 + infinispan-xsite.xml + ${cache.server.2.port.offset} + ${cache.server.2.management.port} + + -Djgroups.udp.mcast_port=47698 + -Djgroups.tcpping.initial_hosts=127.0.0.1[8810],127.0.0.1[9810] + diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index 78335ce763..08a5dd57b4 100755 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -125,14 +125,14 @@ - undefined - cache-server-${cache.server} - ${containers.home}/${cache.server.container} + false + ${containers.home}/cache-server-${cache.server} 1010 11000 2010 12000 true + false