Merge pull request #3340 from vramik/migration
KEYCLOAK-3589 Add support for manual upgrade of database schema to te…
This commit is contained in:
commit
4cbc665592
6 changed files with 187 additions and 51 deletions
|
@ -49,6 +49,10 @@
|
|||
<version.shrinkwrap.resolvers>2.2.2</version.shrinkwrap.resolvers>
|
||||
<undertow-embedded.version>1.0.0.Alpha2</undertow-embedded.version>
|
||||
|
||||
<!--migration properties-->
|
||||
<migration.project.version>2.2.1.Final</migration.project.version>
|
||||
<migration.product.version>1.9.8.Final</migration.product.version>
|
||||
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
</properties>
|
||||
|
@ -128,5 +132,20 @@
|
|||
<module>servers</module>
|
||||
<module>tests</module>
|
||||
</modules>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>test-project-migration</id>
|
||||
<properties>
|
||||
<migrated.auth.server.version>${migration.project.version}</migrated.auth.server.version>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>test-product-migration</id>
|
||||
<properties>
|
||||
<migrated.auth.server.version>${migration.product.version}</migrated.auth.server.version>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
<!--
|
||||
~ Copyright 2016 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.
|
||||
-->
|
||||
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:xalan="http://xml.apache.org/xalan"
|
||||
version="2.0"
|
||||
exclude-result-prefixes="xalan">
|
||||
|
||||
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="4" standalone="no"/>
|
||||
<xsl:strip-space elements="*"/>
|
||||
|
||||
<xsl:param name="migration.strategy" />
|
||||
<xsl:param name="initialize.empty" />
|
||||
|
||||
<xsl:variable name="nsKS" select="'urn:jboss:domain:keycloak-server'"/>
|
||||
|
||||
<!--set migrationStrategy-->
|
||||
<xsl:template match="//*[local-name()='subsystem' and starts-with(namespace-uri(), $nsKS)]
|
||||
/*[local-name()='spi' and starts-with(namespace-uri(), $nsKS) and @name='connectionsJpa']
|
||||
/*[local-name()='provider' and starts-with(namespace-uri(), $nsKS)]
|
||||
/*[local-name()='properties' and starts-with(namespace-uri(), $nsKS)]
|
||||
/*[local-name()='property' and starts-with(namespace-uri(), $nsKS) and @name='migrationStrategy']">
|
||||
<property name="migrationStrategy" value="{$migration.strategy}"/>
|
||||
</xsl:template>
|
||||
|
||||
<!--set initializeEmpty-->
|
||||
<xsl:template match="//*[local-name()='subsystem' and starts-with(namespace-uri(), $nsKS)]
|
||||
/*[local-name()='spi' and starts-with(namespace-uri(), $nsKS) and @name='connectionsJpa']
|
||||
/*[local-name()='provider' and starts-with(namespace-uri(), $nsKS)]
|
||||
/*[local-name()='properties' and starts-with(namespace-uri(), $nsKS)]
|
||||
/*[local-name()='property' and starts-with(namespace-uri(), $nsKS) and @name='initializeEmpty']">
|
||||
<property name="initializeEmpty" value="{$initialize.empty}"/>
|
||||
</xsl:template>
|
||||
|
||||
<!--copy everything else-->
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()" />
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
|
@ -571,6 +571,60 @@
|
|||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>migration-manual</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>migration.mode</name>
|
||||
<value>manual</value>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>xml-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>set-manual-migration-strategy</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>transform</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skip></skip>
|
||||
<transformationSets>
|
||||
<transformationSet>
|
||||
<dir>${auth.server.home}/standalone/configuration</dir>
|
||||
<includes>
|
||||
<include>standalone.xml</include>
|
||||
</includes>
|
||||
<stylesheet>${common.resources}/migration-strategy.xsl</stylesheet>
|
||||
<outputDir>${auth.server.home}/standalone/configuration</outputDir>
|
||||
<parameters>
|
||||
<parameter>
|
||||
<name>migration.strategy</name>
|
||||
<value>manual</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>initialize.empty</name>
|
||||
<value>false</value>
|
||||
</parameter>
|
||||
</parameters>
|
||||
</transformationSet>
|
||||
</transformationSets>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>auth-server-apply-patch</id>
|
||||
<activation>
|
||||
|
|
|
@ -64,7 +64,8 @@ public class AuthServerTestEnricher {
|
|||
private static final String AUTH_SERVER_CLUSTER_PROPERTY = "auth.server.cluster";
|
||||
public static final boolean AUTH_SERVER_CLUSTER = Boolean.parseBoolean(System.getProperty(AUTH_SERVER_CLUSTER_PROPERTY, "false"));
|
||||
|
||||
private static final Boolean AUTO_MIGRATION_ENABLED = "auto".equals(System.getProperty("migration.mode"));
|
||||
private static final Boolean START_MIGRATION_CONTAINER = "auto".equals(System.getProperty("migration.mode")) ||
|
||||
"manual".equals(System.getProperty("migration.mode"));
|
||||
|
||||
@Inject
|
||||
@SuiteScoped
|
||||
|
@ -130,7 +131,7 @@ public class AuthServerTestEnricher {
|
|||
throw new RuntimeException(String.format("No auth server container matching '%sN' found in arquillian.xml.", authServerBackend));
|
||||
}
|
||||
|
||||
if (AUTO_MIGRATION_ENABLED) {
|
||||
if (START_MIGRATION_CONTAINER) {
|
||||
// init migratedAuthServerInfo
|
||||
for (ContainerInfo container : suiteContext.getContainers()) {
|
||||
// migrated auth server
|
||||
|
|
|
@ -36,10 +36,8 @@ import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
|||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import static org.keycloak.testsuite.Assert.*;
|
||||
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
||||
|
||||
|
@ -49,6 +47,8 @@ import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
|
|||
public class MigrationTest extends AbstractKeycloakTest {
|
||||
|
||||
private final String MIGRATION = "Migration";
|
||||
private RealmResource migrationRealm;
|
||||
private RealmResource masterRealm;
|
||||
|
||||
@Override
|
||||
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||
|
@ -57,66 +57,74 @@ public class MigrationTest extends AbstractKeycloakTest {
|
|||
|
||||
@Before
|
||||
public void beforeMigrationTest() {
|
||||
migrationRealm = adminClient.realms().realm(MIGRATION);
|
||||
masterRealm = adminClient.realms().realm(MASTER);
|
||||
|
||||
//add migration realm to testRealmReps to make the migration removed after test
|
||||
testRealmReps.add(adminClient.realms().realm(MIGRATION).toRepresentation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Migration(versionFrom = "1.9.8.Final")
|
||||
public void migration198Test() {
|
||||
RealmResource migrationRealm = adminClient.realms().realm(MIGRATION);
|
||||
RealmResource masterRealm = adminClient.realms().realm(MASTER);
|
||||
|
||||
testMigratedMasterData(masterRealm);
|
||||
testMigratedMigrationData(migrationRealm);
|
||||
|
||||
// 2.0.0 - org.keycloak.migration.migrators.MigrateTo2_0_0
|
||||
testAuthorizationServices(masterRealm, migrationRealm);
|
||||
|
||||
// 2.1.0 - org.keycloak.migration.migrators.MigrateTo2_1_0
|
||||
testNameOfOTPRequiredAction(masterRealm, migrationRealm);
|
||||
//there is no migration of RolePolicies (MigrateTo2_1_0#migrateRolePolicies) between 1.9.8 to current version (2.3.0-SNAPSHOT)
|
||||
|
||||
// 2.2.0 - org.keycloak.migration.migrators.MigrateTo2_2_0
|
||||
testIdentityProviderAuthenticator(masterRealm, migrationRealm);
|
||||
public void migration1_9_8Test() {
|
||||
testMigratedData();
|
||||
testMigrationTo2_0_0();
|
||||
testMigrationTo2_1_0();
|
||||
testMigrationTo2_2_0();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Migration(versionFrom = "2.2.1.Final")
|
||||
public void migration221Test() {
|
||||
RealmResource migrationRealm = adminClient.realms().realm(MIGRATION);
|
||||
RealmResource masterRealm = adminClient.realms().realm(MASTER);
|
||||
|
||||
testMigratedMasterData(masterRealm);
|
||||
testMigratedMigrationData(migrationRealm);
|
||||
|
||||
// so far nothing else
|
||||
public void migration2_2_1Test() {
|
||||
testMigratedData();
|
||||
}
|
||||
|
||||
private void testMigratedMasterData(RealmResource master) {
|
||||
assertNames(master.roles().list(), "offline_access", "uma_authorization", "create-realm", "master-test-realm-role", "admin");
|
||||
assertNames(master.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account",
|
||||
private void testMigratedData() {
|
||||
//master realm
|
||||
assertNames(masterRealm.roles().list(), "offline_access", "uma_authorization", "create-realm", "master-test-realm-role", "admin");
|
||||
assertNames(masterRealm.clients().findAll(), "admin-cli", "security-admin-console", "broker", "account",
|
||||
"master-realm", "master-test-client", "Migration-realm");
|
||||
String id = master.clients().findByClientId("master-test-client").get(0).getId();
|
||||
assertNames(master.clients().get(id).roles().list(), "master-test-client-role");
|
||||
assertNames(master.users().search("", 0, 5), "admin", "master-test-user");
|
||||
assertNames(master.groups().groups(), "master-test-group");
|
||||
String id = masterRealm.clients().findByClientId("master-test-client").get(0).getId();
|
||||
assertNames(masterRealm.clients().get(id).roles().list(), "master-test-client-role");
|
||||
assertNames(masterRealm.users().search("", 0, 5), "admin", "master-test-user");
|
||||
assertNames(masterRealm.groups().groups(), "master-test-group");
|
||||
|
||||
//migrationRealm
|
||||
assertNames(migrationRealm.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
||||
assertNames(migrationRealm.clients().findAll(), "account", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console");
|
||||
String id2 = migrationRealm.clients().findByClientId("migration-test-client").get(0).getId();
|
||||
assertNames(migrationRealm.clients().get(id2).roles().list(), "migration-test-client-role");
|
||||
assertNames(migrationRealm.users().search("", 0, 5), "migration-test-user");
|
||||
assertNames(migrationRealm.groups().groups(), "migration-test-group");
|
||||
}
|
||||
|
||||
private void testMigratedMigrationData(RealmResource migration) {
|
||||
assertNames(migration.roles().list(), "offline_access", "uma_authorization", "migration-test-realm-role");
|
||||
assertNames(migration.clients().findAll(), "account", "admin-cli", "broker", "migration-test-client", "realm-management", "security-admin-console");
|
||||
String id = migration.clients().findByClientId("migration-test-client").get(0).getId();
|
||||
assertNames(migration.clients().get(id).roles().list(), "migration-test-client-role");
|
||||
assertNames(migration.users().search("", 0, 5), "migration-test-user");
|
||||
assertNames(migration.groups().groups(), "migration-test-group");
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_0_0
|
||||
*/
|
||||
private void testMigrationTo2_0_0() {
|
||||
testAuthorizationServices(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_1_0
|
||||
*/
|
||||
private void testMigrationTo2_1_0() {
|
||||
testNameOfOTPRequiredAction(masterRealm, migrationRealm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.keycloak.migration.migrators.MigrateTo2_2_0
|
||||
*/
|
||||
private void testMigrationTo2_2_0() {
|
||||
testIdentityProviderAuthenticator(masterRealm, migrationRealm);
|
||||
//MigrateTo2_2_0#migrateRolePolicies is not relevant any more
|
||||
}
|
||||
|
||||
private void testAuthorizationServices(RealmResource... realms) {
|
||||
for (RealmResource realm : realms) {
|
||||
//test setup of authorization services
|
||||
for (String roleName : Constants.AUTHZ_DEFAULT_AUTHORIZATION_ROLES) {
|
||||
RoleResource role = realm.roles().get(roleName); //throw javax.ws.rs.NotFoundException
|
||||
RoleResource role = realm.roles().get(roleName); //throws javax.ws.rs.NotFoundException if not found
|
||||
|
||||
assertFalse("Role's scopeParamRequired should be false.", role.toRepresentation().isScopeParamRequired());
|
||||
assertFalse("Role shouldn't be composite should be false.", role.toRepresentation().isComposite());
|
||||
|
|
|
@ -405,16 +405,10 @@
|
|||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Profile for migration tests-->
|
||||
<!-- Profiles for migration tests-->
|
||||
|
||||
<profile>
|
||||
<id>migration-auto</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>migration.mode</name>
|
||||
<value>auto</value>
|
||||
</property>
|
||||
</activation>
|
||||
<id>auth-server-migration</id>
|
||||
<properties>
|
||||
<migration.import.props.previous>
|
||||
-Dkeycloak.migration.action=import
|
||||
|
@ -438,6 +432,9 @@
|
|||
<requireProperty>
|
||||
<property>migrated.auth.server.version</property>
|
||||
</requireProperty>
|
||||
<requireProperty>
|
||||
<property>migration.mode</property>
|
||||
</requireProperty>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
|
Loading…
Reference in a new issue