KEYCLOAK-14141 0 downtime upgrade test
This commit is contained in:
parent
63e6e13cd3
commit
d63b3ceca4
15 changed files with 709 additions and 9 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -54,6 +54,7 @@ nbproject
|
||||||
# Logs and databases #
|
# Logs and databases #
|
||||||
######################
|
######################
|
||||||
*.log
|
*.log
|
||||||
|
.attach_pid*
|
||||||
|
|
||||||
# Maven #
|
# Maven #
|
||||||
#########
|
#########
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<!--
|
||||||
|
~ Copyright 2020 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<assembly>
|
||||||
|
|
||||||
|
<id>auth-server-legacy</id>
|
||||||
|
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>${auth.server.home}</directory>
|
||||||
|
<outputDirectory>auth-server-legacy</outputDirectory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.sh</exclude>
|
||||||
|
</excludes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>${auth.server.home}</directory>
|
||||||
|
<outputDirectory>auth-server-legacy</outputDirectory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.sh</include>
|
||||||
|
</includes>
|
||||||
|
<fileMode>0755</fileMode>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
|
||||||
|
</assembly>
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2020 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<parent>
|
||||||
|
<groupId>org.keycloak.testsuite</groupId>
|
||||||
|
<artifactId>integration-arquillian-servers-auth-server-jboss</artifactId>
|
||||||
|
<version>11.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<artifactId>integration-arquillian-servers-auth-server-legacy</artifactId>
|
||||||
|
|
||||||
|
<name>Auth Server - Legacy</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<unpacked.artifact.version>${auth.server.legacy.version}</unpacked.artifact.version>
|
||||||
|
<auth.server.dist.unpacked.folder.name>keycloak-${auth.server.legacy.version}</auth.server.dist.unpacked.folder.name>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>false</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>create-zip</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>assembly.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
<appendAssemblyId>false</appendAssemblyId>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>product</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>product</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<auth.server.dist.unpacked.folder.name>${product.name}-${auth.server.legacy.filename.version}</auth.server.dist.unpacked.folder.name>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
|
@ -0,0 +1 @@
|
||||||
|
This file is to mark this Maven project as a valid option for building auth server artifact
|
|
@ -655,6 +655,18 @@
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>auth-server-legacy</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>auth.server.legacy.version</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<modules>
|
||||||
|
<module>legacy</module>
|
||||||
|
</modules>
|
||||||
|
</profile>
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
<id>auth-server-wildfly</id>
|
<id>auth-server-wildfly</id>
|
||||||
<modules>
|
<modules>
|
||||||
|
|
|
@ -126,6 +126,11 @@
|
||||||
<groupId>org.apache.maven.resolver</groupId>
|
<groupId>org.apache.maven.resolver</groupId>
|
||||||
<artifactId>maven-resolver-api</artifactId>
|
<artifactId>maven-resolver-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss</groupId>
|
||||||
|
<artifactId>jandex</artifactId>
|
||||||
|
<version>2.1.3.Final</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -121,6 +121,8 @@ public class AuthServerTestEnricher {
|
||||||
public static final String AUTH_SERVER_BACKEND_PROPERTY = "auth.server.backend";
|
public static final String AUTH_SERVER_BACKEND_PROPERTY = "auth.server.backend";
|
||||||
public static final String AUTH_SERVER_BACKEND = System.getProperty(AUTH_SERVER_BACKEND_PROPERTY, AUTH_SERVER_BACKEND_DEFAULT);
|
public static final String AUTH_SERVER_BACKEND = System.getProperty(AUTH_SERVER_BACKEND_PROPERTY, AUTH_SERVER_BACKEND_DEFAULT);
|
||||||
|
|
||||||
|
public static final String AUTH_SERVER_LEGACY = "auth-server-legacy";
|
||||||
|
|
||||||
public static final String AUTH_SERVER_BALANCER_DEFAULT = "auth-server-balancer";
|
public static final String AUTH_SERVER_BALANCER_DEFAULT = "auth-server-balancer";
|
||||||
public static final String AUTH_SERVER_BALANCER_PROPERTY = "auth.server.balancer";
|
public static final String AUTH_SERVER_BALANCER_PROPERTY = "auth.server.balancer";
|
||||||
public static final String AUTH_SERVER_BALANCER = System.getProperty(AUTH_SERVER_BALANCER_PROPERTY, AUTH_SERVER_BALANCER_DEFAULT);
|
public static final String AUTH_SERVER_BALANCER = System.getProperty(AUTH_SERVER_BALANCER_PROPERTY, AUTH_SERVER_BALANCER_DEFAULT);
|
||||||
|
@ -298,6 +300,15 @@ public class AuthServerTestEnricher {
|
||||||
suiteContext.addAuthServerBackendsInfo(0, c);
|
suiteContext.addAuthServerBackendsInfo(0, c);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (Boolean.parseBoolean(System.getProperty("auth.server.jboss.legacy"))) {
|
||||||
|
ContainerInfo legacy = containers.stream()
|
||||||
|
.filter(c -> c.getQualifier().startsWith(AUTH_SERVER_LEGACY))
|
||||||
|
.findAny()
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Not found legacy container: " + AUTH_SERVER_LEGACY));
|
||||||
|
updateWithAuthServerInfo(legacy, 500);
|
||||||
|
suiteContext.setLegacyAuthServerInfo(legacy);
|
||||||
|
}
|
||||||
|
|
||||||
if (suiteContext.getAuthServerBackendsInfo().isEmpty()) {
|
if (suiteContext.getAuthServerBackendsInfo().isEmpty()) {
|
||||||
throw new RuntimeException(String.format("No auth server container matching '%s' found in arquillian.xml.", AUTH_SERVER_BACKEND));
|
throw new RuntimeException(String.format("No auth server container matching '%s' found in arquillian.xml.", AUTH_SERVER_BACKEND));
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public final class SuiteContext {
|
||||||
|
|
||||||
private List<ContainerInfo> authServerInfo = new LinkedList<>();
|
private List<ContainerInfo> authServerInfo = new LinkedList<>();
|
||||||
private final List<List<ContainerInfo>> authServerBackendsInfo = new ArrayList<>();
|
private final List<List<ContainerInfo>> authServerBackendsInfo = new ArrayList<>();
|
||||||
|
private ContainerInfo legacyAuthServerInfo;
|
||||||
|
|
||||||
private final List<ContainerInfo> cacheServersInfo = new ArrayList<>();
|
private final List<ContainerInfo> cacheServersInfo = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -149,6 +150,14 @@ public final class SuiteContext {
|
||||||
authServerBackendsInfo.get(dcIndex).add(container);
|
authServerBackendsInfo.get(dcIndex).add(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ContainerInfo getLegacyAuthServerInfo() {
|
||||||
|
return legacyAuthServerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLegacyAuthServerInfo(ContainerInfo legacyAuthServerInfo) {
|
||||||
|
this.legacyAuthServerInfo = legacyAuthServerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
public ContainerInfo getMigratedAuthServerInfo() {
|
public ContainerInfo getMigratedAuthServerInfo() {
|
||||||
return migratedAuthServerInfo;
|
return migratedAuthServerInfo;
|
||||||
}
|
}
|
||||||
|
@ -205,6 +214,9 @@ public final class SuiteContext {
|
||||||
.append("\n");
|
.append("\n");
|
||||||
|
|
||||||
getAuthServerBackendsInfo().forEach(bInfo -> sb.append(" Backend: ").append(bInfo).append(" - ").append(bInfo.getContextRoot().toExternalForm()).append("\n"));
|
getAuthServerBackendsInfo().forEach(bInfo -> sb.append(" Backend: ").append(bInfo).append(" - ").append(bInfo.getContextRoot().toExternalForm()).append("\n"));
|
||||||
|
if (Boolean.parseBoolean(System.getProperty("auth.server.jboss.legacy"))) {
|
||||||
|
sb.append(" Legacy: ").append(getLegacyAuthServerInfo()).append(" - ").append(getLegacyAuthServerInfo().getContextRoot().toExternalForm()).append("\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sb.append(getAuthServerInfo().getQualifier())
|
sb.append(getAuthServerInfo().getQualifier())
|
||||||
.append("\n");
|
.append("\n");
|
||||||
|
|
|
@ -23,6 +23,7 @@ public class TestClassProvider {
|
||||||
"/org/jboss/resteasy/client",
|
"/org/jboss/resteasy/client",
|
||||||
"/org/jboss/arquillian",
|
"/org/jboss/arquillian",
|
||||||
"/org/jboss/shrinkwrap",
|
"/org/jboss/shrinkwrap",
|
||||||
|
"/org/jboss/jandex",
|
||||||
"/org/openqa/selenium"
|
"/org/openqa/selenium"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
import org.jboss.shrinkwrap.api.asset.StringAsset;
|
import org.jboss.shrinkwrap.api.asset.StringAsset;
|
||||||
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
|
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
|
||||||
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.keycloak.common.Profile;
|
|
||||||
import org.keycloak.helpers.DropAllServlet;
|
import org.keycloak.helpers.DropAllServlet;
|
||||||
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.RestartContainer;
|
import org.keycloak.testsuite.arquillian.annotation.RestartContainer;
|
||||||
|
@ -53,14 +52,7 @@ import org.wildfly.extras.creaper.core.online.OnlineOptions;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
import java.nio.file.FileAlreadyExistsException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Properties;
|
|
||||||
import org.keycloak.testsuite.util.ContainerAssume;
|
import org.keycloak.testsuite.util.ContainerAssume;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,4 +243,23 @@ public class KeycloakContainerEventsController extends ContainerEventController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void deploy(Archive archive, ContainerInfo containerInfo) throws CommandFailedException, IOException {
|
||||||
|
ManagementClient.online(OnlineOptions
|
||||||
|
.standalone()
|
||||||
|
.hostAndPort("localhost", containerInfo.getContextRoot().getPort() + 1547)
|
||||||
|
.build())
|
||||||
|
.apply(new Deploy.Builder(
|
||||||
|
archive.as(ZipExporter.class).exportAsInputStream(),
|
||||||
|
archive.getName(),
|
||||||
|
true).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void undeploy(Archive archive, ContainerInfo containerInfo) throws CommandFailedException, IOException {
|
||||||
|
ManagementClient.online(OnlineOptions
|
||||||
|
.standalone()
|
||||||
|
.hostAndPort("localhost", containerInfo.getContextRoot().getPort() + 1547)
|
||||||
|
.build())
|
||||||
|
.apply(new Undeploy.Builder(archive.getName()).build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,388 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.migration.cluster;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.jar.JarEntry;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import org.infinispan.Cache;
|
||||||
|
import org.infinispan.remoting.RemoteException;
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.DotName;
|
||||||
|
import org.jboss.jandex.Indexer;
|
||||||
|
import org.jboss.modules.Module;
|
||||||
|
import org.jboss.modules.ModuleClassLoader;
|
||||||
|
import org.jboss.modules.ModuleLoader;
|
||||||
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.OAuth2Constants;
|
||||||
|
import org.keycloak.cluster.ClusterEvent;
|
||||||
|
import org.keycloak.cluster.infinispan.WrapperClusterEvent;
|
||||||
|
import org.keycloak.common.util.reflections.Reflections;
|
||||||
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
import org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionStore;
|
||||||
|
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
|
||||||
|
import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||||
|
import org.keycloak.testsuite.cluster.AbstractClusterTest;
|
||||||
|
import static org.keycloak.testsuite.arquillian.containers.KeycloakContainerEventsController.deploy;
|
||||||
|
import static org.keycloak.testsuite.arquillian.containers.KeycloakContainerEventsController.undeploy;
|
||||||
|
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
||||||
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
import org.keycloak.testsuite.rest.TestClassLoader;
|
||||||
|
import org.keycloak.testsuite.runonserver.RunOnServerException;
|
||||||
|
import org.keycloak.testsuite.runonserver.SerializationUtil;
|
||||||
|
import org.keycloak.testsuite.util.DroneUtils;
|
||||||
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
|
public class MultiVersionClusterTest extends AbstractClusterTest {
|
||||||
|
|
||||||
|
private static ContainerInfo currentNode;
|
||||||
|
private static ContainerInfo legacyNode;
|
||||||
|
private static boolean initialized = false;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
static class CacheValuesHolder {
|
||||||
|
private Map<String, Map<String, Object>> values;
|
||||||
|
|
||||||
|
public CacheValuesHolder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CacheValuesHolder(final Map<String, Map<String, Object>> values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Map<String, Object>> getValues() {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValues(Map<String, Map<String, Object>> values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void enabled() {
|
||||||
|
Assume.assumeThat(System.getProperty("auth.server.legacy.version"), notNullValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void beforeClusterTest() {
|
||||||
|
if (!initialized) {
|
||||||
|
currentNode = backendNode(0);
|
||||||
|
legacyNode = suiteContext.getLegacyAuthServerInfo();
|
||||||
|
addAdminJsonFileToLegacy();
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
startBackendNode(legacyNode);
|
||||||
|
startBackendNode(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() {
|
||||||
|
killBackendNode(legacyNode);
|
||||||
|
killBackendNode(currentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JavaArchive deployment() {
|
||||||
|
return ShrinkWrap.create(JavaArchive.class, "negative.jar")
|
||||||
|
.addPackage("org/keycloak/testsuite")
|
||||||
|
.addClass(SerializableTestClass.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyFailureOnLegacy() throws Exception {
|
||||||
|
|
||||||
|
deploy(deployment(), currentNode);
|
||||||
|
|
||||||
|
try {
|
||||||
|
backendTestingClients.get(currentNode).server().run(session -> {
|
||||||
|
try {
|
||||||
|
Class<?> itShouldFail = Module.getContextModuleLoader().loadModule("deployment.negative.jar").getClassLoader()
|
||||||
|
.loadClassLocal(SerializableTestClass.class.getName());
|
||||||
|
session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME)
|
||||||
|
.put("itShouldFail", Reflections.newInstance(itShouldFail));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RunOnServerException(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertThat(e, instanceOf(RunOnServerException.class));
|
||||||
|
assertThat(e.getCause().getCause(), instanceOf(RemoteException.class));
|
||||||
|
} finally {
|
||||||
|
undeploy(deployment(), currentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyFailureOnCurrent() throws Exception {
|
||||||
|
|
||||||
|
deploy(deployment(), legacyNode);
|
||||||
|
|
||||||
|
try {
|
||||||
|
backendTestingClients.get(legacyNode).server().run(session -> {
|
||||||
|
try {
|
||||||
|
Class<?> itShouldFail = Module.getContextModuleLoader().loadModule("deployment.negative.jar").getClassLoader()
|
||||||
|
.loadClassLocal(SerializableTestClass.class.getName());
|
||||||
|
session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME)
|
||||||
|
.put("itShouldFail", Reflections.newInstance(itShouldFail));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RunOnServerException(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertThat(e, instanceOf(RunOnServerException.class));
|
||||||
|
assertThat(e.getCause().getCause(), instanceOf(RemoteException.class));
|
||||||
|
} finally {
|
||||||
|
undeploy(deployment(), legacyNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests if legacy node remains usable (login) after current node connects to cluster
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void loginSuccessToLegacy() throws Exception {
|
||||||
|
String originalServerRoot = OAuthClient.SERVER_ROOT;
|
||||||
|
try {
|
||||||
|
OAuthClient.updateURLs(legacyNode.getContextRoot().toString());
|
||||||
|
OAuthClient oauth = new OAuthClient();
|
||||||
|
oauth.init(DroneUtils.getCurrentDriver());
|
||||||
|
oauth.realm(MASTER).clientId("account").redirectUri(legacyNode.getContextRoot().toString() + "/auth/realms/master/account/");
|
||||||
|
|
||||||
|
oauth.openLoginForm();
|
||||||
|
assertThat(DroneUtils.getCurrentDriver().getTitle(), containsString("Log in to "));
|
||||||
|
loginPage.login("admin", "admin");
|
||||||
|
|
||||||
|
assertThat("Login was not successful.", oauth.getCurrentQuery().get(OAuth2Constants.CODE), notNullValue());
|
||||||
|
} finally {
|
||||||
|
OAuthClient.updateURLs(originalServerRoot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromLegacyToCurrent() {
|
||||||
|
Map<String, Map<String, Object>> expected = createCacheAndGetFromServer(legacyNode);
|
||||||
|
Map<String, Map<String, Object>> actual = getFromServer(currentNode, SerializationUtil.encode(expected.keySet().toString()));
|
||||||
|
Assert.assertThat(actual, equalTo(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromCurrentToLegacy() {
|
||||||
|
Map<String, Map<String, Object>> expected = createCacheAndGetFromServer(currentNode);
|
||||||
|
Map<String, Map<String, Object>> actual = getFromServer(legacyNode, SerializationUtil.encode(expected.keySet().toString()));
|
||||||
|
Assert.assertThat(actual, equalTo(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAdminJsonFileToLegacy() {
|
||||||
|
try {
|
||||||
|
FileUtils.copyFile(new File("target/test-classes/keycloak-add-user.json"),
|
||||||
|
new File(System.getProperty("auth.server.legacy.home")
|
||||||
|
+ "/standalone/configuration/keycloak-add-user.json"));
|
||||||
|
log.debug("Successfully added keycloak-add-user.json to " + System.getProperty("auth.server.legacy.home")
|
||||||
|
+ "/standalone/configuration/keycloak-add-user.json");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException("Adding admin json file failed.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Map<String, Object>> createCacheAndGetFromServer(ContainerInfo container) {
|
||||||
|
return backendTestingClients.get(container).server().fetch(session -> {
|
||||||
|
Map<String, Map<String, Object>> result = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Indexer indexer = new Indexer();
|
||||||
|
DotName serializeWith = DotName.createSimple("org.infinispan.commons.marshall.SerializeWith");
|
||||||
|
|
||||||
|
ModuleLoader contextModuleLoader = Module.getContextModuleLoader();
|
||||||
|
Module module = contextModuleLoader.loadModule("org.keycloak.keycloak-model-infinispan");
|
||||||
|
ModuleClassLoader classLoader = module.getClassLoader();
|
||||||
|
|
||||||
|
Enumeration<URL> resources = classLoader.getResources("org/keycloak");
|
||||||
|
while (resources.hasMoreElements()) {
|
||||||
|
URL nextElement = resources.nextElement();
|
||||||
|
Enumeration<JarEntry> entries = new JarFile(nextElement.getFile().replace("file:", "").replace("!/org/keycloak", "")).entries();
|
||||||
|
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
JarEntry entry = entries.nextElement();
|
||||||
|
if (entry.getName().endsWith(".class")) {
|
||||||
|
indexer.index(classLoader.getResourceAsStream(entry.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache<Object, Object> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME);
|
||||||
|
|
||||||
|
for (AnnotationInstance annotation : indexer.complete().getAnnotations(serializeWith)) {
|
||||||
|
|
||||||
|
switch (annotation.target().kind()) {
|
||||||
|
case CLASS:
|
||||||
|
Map<String, Object> fieldValue = new HashMap<>();
|
||||||
|
String className = annotation.target().asClass().name().toString();
|
||||||
|
Class<Serializable> classForName = Reflections.classForName(className, classLoader);
|
||||||
|
Object newInstance;
|
||||||
|
|
||||||
|
if (Arrays.asList(classForName.getDeclaredConstructors()).stream()
|
||||||
|
.filter(c -> !c.isSynthetic())
|
||||||
|
.anyMatch(c -> c.getParameterTypes().length == 0 )) {
|
||||||
|
newInstance = Reflections.newInstance(classForName);
|
||||||
|
} else {
|
||||||
|
Constructor<?> constructor = Arrays.asList(classForName.getDeclaredConstructors()).stream()
|
||||||
|
.filter(c -> !c.isSynthetic())
|
||||||
|
.findFirst().get();
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
|
||||||
|
List<Object> parameters = new ArrayList<>();
|
||||||
|
for (Class<?> type : constructor.getParameterTypes()) {
|
||||||
|
if (type.isPrimitive()) { // we have to set all primitive values in constructor
|
||||||
|
if (type.equals(Boolean.TYPE)) {
|
||||||
|
parameters.add(false);
|
||||||
|
} else if (type.equals(Character.TYPE)) {
|
||||||
|
parameters.add(' ');
|
||||||
|
} else {
|
||||||
|
parameters.add(0);
|
||||||
|
}
|
||||||
|
} else if (type.equals(UUID.class)) { //UUID cannot be null
|
||||||
|
parameters.add(UUID.randomUUID());
|
||||||
|
} else {
|
||||||
|
parameters.add(null); // all fields will be set in next step
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newInstance = constructor.newInstance(parameters.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Field> fields = Reflections.getAllDeclaredFields(classForName).stream()
|
||||||
|
.filter(field -> !Modifier.isStatic(field.getModifiers()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
for (Field field : fields) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
Class<?> type = field.getType();
|
||||||
|
Object value;
|
||||||
|
if (type.equals(KeycloakSession.class)) {
|
||||||
|
value = session;
|
||||||
|
} else if (type.equals(String.class)) {
|
||||||
|
value = UUID.randomUUID().toString();
|
||||||
|
} else if (type.equals(Boolean.TYPE) || type.equals(Boolean.class)) {
|
||||||
|
value = Boolean.FALSE;
|
||||||
|
} else if (type.equals(Integer.TYPE) || type.equals(Integer.class)) {
|
||||||
|
value = new Random().nextInt();
|
||||||
|
} else if (type.equals(Long.TYPE) || type.equals(Long.class)) {
|
||||||
|
value = new Random().nextLong();
|
||||||
|
} else if (type.equals(AuthenticatedClientSessionStore.class)) {
|
||||||
|
value = new AuthenticatedClientSessionStore();
|
||||||
|
} else if (type.equals(UserSessionModel.State.class)) {
|
||||||
|
value = UserSessionModel.State.LOGGING_OUT;
|
||||||
|
} else if (type.equals(Map.class)) {
|
||||||
|
value = new HashMap();
|
||||||
|
} else if (type.equals(ConcurrentHashMap.class)) {
|
||||||
|
value = new ConcurrentHashMap();
|
||||||
|
} else if (type.equals(Set.class)) {
|
||||||
|
value = new HashSet();
|
||||||
|
} else if (type.equals(ClusterEvent.class)) {
|
||||||
|
value = new WrapperClusterEvent();
|
||||||
|
} else if (type.equals(UUID.class)) {
|
||||||
|
value = UUID.randomUUID();
|
||||||
|
} else if (type.equals(SessionEntity.class)) {
|
||||||
|
value = new UserSessionEntity();
|
||||||
|
} else if (type.equals(BitSet.class)) {
|
||||||
|
value = new BitSet();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException(className + " - Uncovered parameter type: " + type);
|
||||||
|
}
|
||||||
|
field.set(newInstance, value);
|
||||||
|
fieldValue.put(field.getName(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
cache.put(className, newInstance);
|
||||||
|
result.put(className, fieldValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
return new CacheValuesHolder(result);
|
||||||
|
}, CacheValuesHolder.class).getValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Map<String, Object>> getFromServer(ContainerInfo container, final String classes) {
|
||||||
|
return backendTestingClients.get(container).server().fetch(session -> {
|
||||||
|
|
||||||
|
Map<String, Map<String, Object>> mapa = new HashMap<>();
|
||||||
|
Cache<Object, Object> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME);
|
||||||
|
|
||||||
|
String decoded = (String) SerializationUtil.decode(classes, TestClassLoader.getInstance());
|
||||||
|
for (String className : decoded.replace("[", "").replace("]", "").split(", ")) {
|
||||||
|
Map<String, Object> fieldValues = new HashMap<>();
|
||||||
|
Object cacheEntry = cache.get(className);
|
||||||
|
Reflections.getAllDeclaredFields(cacheEntry.getClass()).stream()
|
||||||
|
.filter(field -> !Modifier.isStatic(field.getModifiers()))
|
||||||
|
.forEach(field -> {
|
||||||
|
field.setAccessible(true);
|
||||||
|
Object fieldValue = Reflections.getFieldValue(field, cacheEntry);
|
||||||
|
fieldValues.put(field.getName(), fieldValue);
|
||||||
|
});
|
||||||
|
mapa.put(className, fieldValues);
|
||||||
|
}
|
||||||
|
return new CacheValuesHolder(mapa);
|
||||||
|
}, CacheValuesHolder.class).getValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2020 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.migration.cluster;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInput;
|
||||||
|
import java.io.ObjectOutput;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import org.infinispan.commons.marshall.Externalizer;
|
||||||
|
import org.infinispan.commons.marshall.SerializeWith;
|
||||||
|
|
||||||
|
@SerializeWith(SerializableTestClass.ExternalizerImpl.class)
|
||||||
|
public class SerializableTestClass implements Serializable {
|
||||||
|
public static class ExternalizerImpl implements Externalizer<SerializableTestClass> {
|
||||||
|
|
||||||
|
private static final int VERSION_1 = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeObject(ObjectOutput oo, SerializableTestClass t) throws IOException {
|
||||||
|
oo.writeByte(VERSION_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SerializableTestClass readObject(ObjectInput oi) throws IOException, ClassNotFoundException {
|
||||||
|
switch (oi.readByte()) {
|
||||||
|
case VERSION_1:
|
||||||
|
return new SerializableTestClass();
|
||||||
|
default:
|
||||||
|
throw new IOException("Unknown version");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -174,6 +174,7 @@
|
||||||
-Dauth.server.db.host=${auth.server.db.host}
|
-Dauth.server.db.host=${auth.server.db.host}
|
||||||
</property>
|
</property>
|
||||||
<property name="javaVmArguments">
|
<property name="javaVmArguments">
|
||||||
|
${auth.server.backend1.jvm.debug.args}
|
||||||
${auth.server.memory.settings}
|
${auth.server.memory.settings}
|
||||||
-Djava.net.preferIPv4Stack=true
|
-Djava.net.preferIPv4Stack=true
|
||||||
${auth.server.jvm.args.extra}
|
${auth.server.jvm.args.extra}
|
||||||
|
@ -201,6 +202,7 @@
|
||||||
-Dauth.server.db.host=${auth.server.db.host}
|
-Dauth.server.db.host=${auth.server.db.host}
|
||||||
</property>
|
</property>
|
||||||
<property name="javaVmArguments">
|
<property name="javaVmArguments">
|
||||||
|
${auth.server.backend2.jvm.debug.args}
|
||||||
${auth.server.memory.settings}
|
${auth.server.memory.settings}
|
||||||
-Djava.net.preferIPv4Stack=true
|
-Djava.net.preferIPv4Stack=true
|
||||||
${auth.server.jvm.args.extra}
|
${auth.server.jvm.args.extra}
|
||||||
|
@ -211,6 +213,32 @@
|
||||||
<property name="bindHttpPortOffset">${auth.server.backend2.port.offset}</property>
|
<property name="bindHttpPortOffset">${auth.server.backend2.port.offset}</property>
|
||||||
</configuration>
|
</configuration>
|
||||||
</container>
|
</container>
|
||||||
|
<container qualifier="auth-server-legacy" mode="manual" >
|
||||||
|
<configuration>
|
||||||
|
<property name="enabled">${auth.server.jboss.legacy}</property>
|
||||||
|
<property name="adapterImplClass">org.jboss.as.arquillian.container.managed.ManagedDeployableContainer</property>
|
||||||
|
<property name="jbossHome">${auth.server.legacy.home}</property>
|
||||||
|
<property name="serverConfig">standalone-ha.xml</property>
|
||||||
|
<property name="jbossArguments">
|
||||||
|
-Djboss.as.management.blocking.timeout=${auth.server.jboss.startup.timeout}
|
||||||
|
-Djboss.socket.binding.port-offset=${auth.server.legacy.port.offset}
|
||||||
|
-Djboss.node.name=legacy
|
||||||
|
-Dauth.server.truststore=${auth.server.truststore}
|
||||||
|
-Dauth.server.truststore.password=${auth.server.truststore.password}
|
||||||
|
-Dauth.server.db.host=${auth.server.db.host}
|
||||||
|
</property>
|
||||||
|
<property name="javaVmArguments">
|
||||||
|
${auth.server.legacy.jvm.debug.args}
|
||||||
|
${auth.server.memory.settings}
|
||||||
|
-Djava.net.preferIPv4Stack=true
|
||||||
|
${auth.server.jvm.args.extra}
|
||||||
|
</property>
|
||||||
|
<property name="outputToConsole">true</property>
|
||||||
|
<property name="managementPort">${auth.server.legacy.management.port}</property>
|
||||||
|
<property name="startupTimeoutInSeconds">${auth.server.jboss.startup.timeout}</property>
|
||||||
|
<property name="bindHttpPortOffset">${auth.server.legacy.port.offset}</property>
|
||||||
|
</configuration>
|
||||||
|
</container>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<!-- Clustering with embedded undertow -->
|
<!-- Clustering with embedded undertow -->
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
<auth.server.cluster>false</auth.server.cluster>
|
<auth.server.cluster>false</auth.server.cluster>
|
||||||
<auth.server.undertow.cluster>false</auth.server.undertow.cluster>
|
<auth.server.undertow.cluster>false</auth.server.undertow.cluster>
|
||||||
<auth.server.jboss.cluster>false</auth.server.jboss.cluster>
|
<auth.server.jboss.cluster>false</auth.server.jboss.cluster>
|
||||||
|
<auth.server.jboss.legacy>false</auth.server.jboss.legacy>
|
||||||
|
|
||||||
<auth.server.crossdc>false</auth.server.crossdc>
|
<auth.server.crossdc>false</auth.server.crossdc>
|
||||||
<auth.server.undertow.crossdc>false</auth.server.undertow.crossdc>
|
<auth.server.undertow.crossdc>false</auth.server.undertow.crossdc>
|
||||||
|
@ -578,6 +579,7 @@
|
||||||
<auth.server.cluster>${auth.server.cluster}</auth.server.cluster>
|
<auth.server.cluster>${auth.server.cluster}</auth.server.cluster>
|
||||||
<auth.server.undertow.cluster>${auth.server.undertow.cluster}</auth.server.undertow.cluster>
|
<auth.server.undertow.cluster>${auth.server.undertow.cluster}</auth.server.undertow.cluster>
|
||||||
<auth.server.jboss.cluster>${auth.server.jboss.cluster}</auth.server.jboss.cluster>
|
<auth.server.jboss.cluster>${auth.server.jboss.cluster}</auth.server.jboss.cluster>
|
||||||
|
<auth.server.jboss.legacy>${auth.server.jboss.legacy}</auth.server.jboss.legacy>
|
||||||
|
|
||||||
<!--cache server properties-->
|
<!--cache server properties-->
|
||||||
<auth.server.crossdc>${auth.server.crossdc}</auth.server.crossdc>
|
<auth.server.crossdc>${auth.server.crossdc}</auth.server.crossdc>
|
||||||
|
@ -1192,6 +1194,11 @@
|
||||||
|
|
||||||
<auth.server.backend1.home>${containers.home}/auth-server-${auth.server}-backend1</auth.server.backend1.home>
|
<auth.server.backend1.home>${containers.home}/auth-server-${auth.server}-backend1</auth.server.backend1.home>
|
||||||
<auth.server.backend2.home>${containers.home}/auth-server-${auth.server}-backend2</auth.server.backend2.home>
|
<auth.server.backend2.home>${containers.home}/auth-server-${auth.server}-backend2</auth.server.backend2.home>
|
||||||
|
<auth.server.backend1.debug.port>5008</auth.server.backend1.debug.port>
|
||||||
|
<auth.server.backend2.debug.port>5009</auth.server.backend2.debug.port>
|
||||||
|
|
||||||
|
<auth.server.legacy.home>${containers.home}/auth-server-legacy</auth.server.legacy.home>
|
||||||
|
<auth.server.legacy.debug.port>5010</auth.server.legacy.debug.port>
|
||||||
|
|
||||||
<auth.server.config.dir>${auth.server.backend1.home}/standalone/configuration</auth.server.config.dir>
|
<auth.server.config.dir>${auth.server.backend1.home}/standalone/configuration</auth.server.config.dir>
|
||||||
|
|
||||||
|
@ -1256,6 +1263,8 @@
|
||||||
|
|
||||||
<auth.server.backend1.home>${auth.server.backend1.home}</auth.server.backend1.home>
|
<auth.server.backend1.home>${auth.server.backend1.home}</auth.server.backend1.home>
|
||||||
<auth.server.backend2.home>${auth.server.backend2.home}</auth.server.backend2.home>
|
<auth.server.backend2.home>${auth.server.backend2.home}</auth.server.backend2.home>
|
||||||
|
<auth.server.backend1.jvm.debug.args>-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.debug.suspend},address=${auth.server.host}:${auth.server.backend1.debug.port}</auth.server.backend1.jvm.debug.args>
|
||||||
|
<auth.server.backend2.jvm.debug.args>-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.debug.suspend},address=${auth.server.host}:${auth.server.backend2.debug.port}</auth.server.backend2.jvm.debug.args>
|
||||||
|
|
||||||
<!--100-->
|
<!--100-->
|
||||||
<auth.server.backend1.port.offset>101</auth.server.backend1.port.offset>
|
<auth.server.backend1.port.offset>101</auth.server.backend1.port.offset>
|
||||||
|
@ -1272,6 +1281,11 @@
|
||||||
<!--10099-->
|
<!--10099-->
|
||||||
<auth.server.backend1.management.port.jmx>10100</auth.server.backend1.management.port.jmx>
|
<auth.server.backend1.management.port.jmx>10100</auth.server.backend1.management.port.jmx>
|
||||||
<auth.server.backend2.management.port.jmx>10101</auth.server.backend2.management.port.jmx>
|
<auth.server.backend2.management.port.jmx>10101</auth.server.backend2.management.port.jmx>
|
||||||
|
|
||||||
|
<auth.server.legacy.home>${auth.server.legacy.home}</auth.server.legacy.home>
|
||||||
|
<auth.server.legacy.jvm.debug.args>-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.debug.suspend},address=${auth.server.host}:${auth.server.legacy.debug.port}</auth.server.legacy.jvm.debug.args>
|
||||||
|
<auth.server.legacy.port.offset>600</auth.server.legacy.port.offset>
|
||||||
|
<auth.server.legacy.management.port>10590</auth.server.legacy.management.port>
|
||||||
</systemPropertyVariables>
|
</systemPropertyVariables>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
@ -1280,6 +1294,47 @@
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>auth-server-legacy</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>auth.server.legacy.version</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<auth.server.jboss.legacy>true</auth.server.jboss.legacy>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>unpack-auth-server-legacy</id>
|
||||||
|
<phase>generate-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>unpack</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.keycloak.testsuite</groupId>
|
||||||
|
<artifactId>integration-arquillian-servers-auth-server-legacy</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>zip</type>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
<outputDirectory>${containers.home}</outputDirectory>
|
||||||
|
<overWriteIfNewer>true</overWriteIfNewer>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
<id>clean-jpa</id>
|
<id>clean-jpa</id>
|
||||||
|
|
Loading…
Reference in a new issue