Entry 999.0.0 in MIGRATION_MODEL prevents future migrations of the database
Closes #27941 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
parent
4acf61dd00
commit
2efc163b89
2 changed files with 87 additions and 0 deletions
|
@ -63,6 +63,7 @@ import org.keycloak.migration.migrators.Migration;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.DeploymentStateProvider;
|
import org.keycloak.models.DeploymentStateProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.storage.MigrationManager;
|
import org.keycloak.storage.MigrationManager;
|
||||||
|
@ -145,6 +146,14 @@ public class DefaultMigrationManager implements MigrationManager {
|
||||||
m.migrate(session);
|
m.migrate(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (currentVersion.lessThan(databaseVersion)) {
|
||||||
|
if (databaseVersion.equals(SNAPSHOT_VERSION)) {
|
||||||
|
throw new ModelException("Incorrect state of migration. You are trying to run server version '" + currentVersion + "' against a database which was migrated to snapshot version '"
|
||||||
|
+ databaseVersion + "'. Databases that have been migrated to a snapshot version can't be migrated to a released version of Keycloak or to a more recent snapshot version.");
|
||||||
|
} else {
|
||||||
|
logger.warnf("Possibly incorrect state of migration. You are trying to run server version '" + currentVersion + "' against database, which was already migrated to newer version '" +
|
||||||
|
databaseVersion + "'.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (databaseVersion == null || databaseVersion.lessThan(currentVersion)) {
|
if (databaseVersion == null || databaseVersion.lessThan(currentVersion)) {
|
||||||
|
@ -159,6 +168,7 @@ public class DefaultMigrationManager implements MigrationManager {
|
||||||
public static final ModelVersion RHSSO_VERSION_7_2_KEYCLOAK_VERSION = new ModelVersion("3.4.3");
|
public static final ModelVersion RHSSO_VERSION_7_2_KEYCLOAK_VERSION = new ModelVersion("3.4.3");
|
||||||
public static final ModelVersion RHSSO_VERSION_7_3_KEYCLOAK_VERSION = new ModelVersion("4.8.3");
|
public static final ModelVersion RHSSO_VERSION_7_3_KEYCLOAK_VERSION = new ModelVersion("4.8.3");
|
||||||
public static final ModelVersion RHSSO_VERSION_7_4_KEYCLOAK_VERSION = new ModelVersion("9.0.3");
|
public static final ModelVersion RHSSO_VERSION_7_4_KEYCLOAK_VERSION = new ModelVersion("9.0.3");
|
||||||
|
public static final ModelVersion SNAPSHOT_VERSION = new ModelVersion("999.0.0-SNAPSHOT");
|
||||||
|
|
||||||
private static final Map<Pattern, ModelVersion> PATTERN_MATCHER = new LinkedHashMap<>();
|
private static final Map<Pattern, ModelVersion> PATTERN_MATCHER = new LinkedHashMap<>();
|
||||||
static {
|
static {
|
||||||
|
@ -180,6 +190,12 @@ public class DefaultMigrationManager implements MigrationManager {
|
||||||
}
|
}
|
||||||
if (stored == null) {
|
if (stored == null) {
|
||||||
stored = migrations[0].getVersion();
|
stored = migrations[0].getVersion();
|
||||||
|
} else {
|
||||||
|
ModelVersion currentVersion = new ModelVersion(Version.VERSION);
|
||||||
|
if (currentVersion.lessThan(stored)) {
|
||||||
|
logger.warnf("Possibly incorrect state of migration during realm import. You are running server version '" + currentVersion + "' when importing JSON file, which was created in the newer version '" +
|
||||||
|
stored + "'.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Migration m : migrations) {
|
for (Migration m : migrations) {
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 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;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.common.Version;
|
||||||
|
import org.keycloak.migration.MigrationModel;
|
||||||
|
import org.keycloak.models.DeploymentStateProvider;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.storage.datastore.DefaultMigrationManager;
|
||||||
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class MigrationDeniedTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests migration should not be allowed when DB version is set to snapshot version like "999.0.0", but Keycloak server version is lower like "23.0.0"
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void testMigrationDenied(KeycloakSession session) {
|
||||||
|
MigrationModel model = session.getProvider(DeploymentStateProvider.class).getMigrationModel();
|
||||||
|
String databaseVersion = model.getStoredVersion() != null ? model.getStoredVersion() : null;
|
||||||
|
|
||||||
|
Assume.assumeTrue("Test ignored as it is working just with DB migrated in version '" + databaseVersion + "', but current DB version is " + databaseVersion,
|
||||||
|
DefaultMigrationManager.SNAPSHOT_VERSION.toString().equals(databaseVersion));
|
||||||
|
|
||||||
|
String currentVersion = Version.VERSION;
|
||||||
|
try {
|
||||||
|
// Simulate to manually set runtime version of KeycloakServer to 23. Migration should fail as the version is lower than DB version.
|
||||||
|
Version.VERSION = "23.0.0";
|
||||||
|
new DefaultMigrationManager(session).migrate();
|
||||||
|
Assert.fail("Not expected to successfully run migration. DB version was " + databaseVersion + ". Keycloak version was " + currentVersion);
|
||||||
|
} catch (ModelException expected) {
|
||||||
|
Assert.assertTrue(expected.getMessage().startsWith("Incorrect state of migration"));
|
||||||
|
} finally {
|
||||||
|
Version.VERSION = currentVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue