From e6df30602efa8c52ccc19cd7829d2f8d93a5bf28 Mon Sep 17 00:00:00 2001 From: mposolda Date: Mon, 4 Apr 2016 17:53:58 +0200 Subject: [PATCH] KEYCLOAK-2744 connectionsJpa: the databaseSchema 'validate' should check if database schema is updated to latest version --- .../en/en-US/modules/server-installation.xml | 3 ++- .../DefaultJpaConnectionProviderFactory.java | 22 ++++++++++--------- .../LiquibaseJpaUpdaterProvider.java | 18 ++++++++++++--- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml index 7f0d631767..d247c8d1ee 100755 --- a/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml +++ b/docbook/auth-server-docs/reference/en/en-US/modules/server-installation.xml @@ -186,7 +186,8 @@ bin/add-user-keycloak.[sh|bat] -r master -u -p databaseSchema - Specify if schema should be updated or validated. Valid values are "update" and "validate" ("update is default). + Specify if schema should be updated or validated. Valid values are "update" and "validate". Value "update is default and means that DB schema will be updated to latest version. + Value "validate" won't touch database schema, but it will fail to start if schema is not updated to latest version. diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java index cd7c6e3477..11630e77ee 100755 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java @@ -95,8 +95,6 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide Connection connection = null; - String databaseSchema = config.get("databaseSchema"); - Map properties = new HashMap(); String unitName = "keycloak-default"; @@ -127,14 +125,18 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide properties.put(JpaUtils.HIBERNATE_DEFAULT_SCHEMA, schema); } - if (databaseSchema != null) { - if (databaseSchema.equals("development-update")) { - properties.put("hibernate.hbm2ddl.auto", "update"); - databaseSchema = null; - } else if (databaseSchema.equals("development-validate")) { - properties.put("hibernate.hbm2ddl.auto", "validate"); - databaseSchema = null; - } + + String databaseSchema = config.get("databaseSchema"); + if (databaseSchema == null) { + throw new RuntimeException("Property 'databaseSchema' needs to be specified in the configuration"); + } + + if (databaseSchema.equals("development-update")) { + properties.put("hibernate.hbm2ddl.auto", "update"); + databaseSchema = null; + } else if (databaseSchema.equals("development-validate")) { + properties.put("hibernate.hbm2ddl.auto", "validate"); + databaseSchema = null; } properties.put("hibernate.show_sql", config.getBoolean("showSql", false)); diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java index 61075c7d3c..4a505a3380 100755 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/LiquibaseJpaUpdaterProvider.java @@ -21,6 +21,7 @@ import liquibase.Contexts; import liquibase.Liquibase; import liquibase.changelog.ChangeSet; import liquibase.changelog.RanChangeSet; +import liquibase.exception.LiquibaseException; import org.jboss.logging.Logger; import org.keycloak.connections.jpa.updater.JpaUpdaterProvider; import org.keycloak.connections.jpa.updater.liquibase.conn.LiquibaseConnectionProvider; @@ -96,16 +97,27 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider { @Override public void validate(Connection connection, String defaultSchema) { + logger.debug("Validating if database is updated"); + try { Liquibase liquibase = getLiquibase(connection, defaultSchema); - liquibase.validate(); - } catch (Exception e) { + List changeSets = liquibase.listUnrunChangeSets((Contexts) null); + if (!changeSets.isEmpty()) { + List ranChangeSets = liquibase.getDatabase().getRanChangeSetList(); + String errorMessage = String.format("Failed to validate database schema. Schema needs updating database from %s to %s. Please change databaseSchema to 'update' or use other database", + ranChangeSets.get(ranChangeSets.size() - 1).getId(), changeSets.get(changeSets.size() - 1).getId()); + throw new RuntimeException(errorMessage); + } else { + logger.debug("Validation passed. Database is up-to-date"); + } + + } catch (LiquibaseException e) { throw new RuntimeException("Failed to validate database", e); } } - private Liquibase getLiquibase(Connection connection, String defaultSchema) throws Exception { + private Liquibase getLiquibase(Connection connection, String defaultSchema) throws LiquibaseException { LiquibaseConnectionProvider liquibaseProvider = session.getProvider(LiquibaseConnectionProvider.class); return liquibaseProvider.getLiquibase(connection, defaultSchema); }