Merge pull request #3312 from hmlnarik/KEYCLOAK-3697

KEYCLOAK-3697: Evaluate preconditions when generating SQL script
This commit is contained in:
Stian Thorgersen 2016-10-13 19:27:44 +02:00 committed by GitHub
commit 3bbbf30e64
4 changed files with 42 additions and 12 deletions

View file

@ -17,17 +17,15 @@ Creating a JPA change-set
------------------------- -------------------------
We use Liquibase to support updating the database. The change-sets are located in We use Liquibase to support updating the database. The change-sets are located in
`connections/jpa-liquibase/src/main/resources/META-INF`. There's a separate file for each release that requires database [`model/jpa/src/main/resources/META-INF`](../model/jpa/src/main/resources/META-INF).
changes. There's a separate file for each release that requires database changes.
To manually create a change-set add a new file in the above location with the name `jpa-changelog-<version>.xml`. This file To manually create a change-set add a new file in the above location with the name `jpa-changelog-<version>.xml`. This file
should contain a single `change-set` with `id` equal to the next version to be released and `author` set to your email should contain a single `change-set` with `id` equal to the next version to be released and `author` set to your email
address. Then look at Liquibase documentation on how to write this file. Add a reference to this file in `jpa-changelog-master.xml`. address. Then look at Liquibase documentation on how to write this file. Add a reference to this file in
[`jpa-changelog-master.xml`](../model/jpa/src/main/resources/META-INF/jpa-changelog-master.xml).
The file should have a single change-set and the id of the change-set should be the next version to be released. The file should have a single change-set and the id of the change-set should be the next version to be released.
You also need to update `org.keycloak.connections.jpa.updater.JpaUpdaterProvider#LAST_VERSION`. This
is used by Keycloak to quickly determine if the database is up to date or not.
You can also have Liquibase and Hibernate create one for you. To do this follow these steps: You can also have Liquibase and Hibernate create one for you. To do this follow these steps:
1. Delete existing databases 1. Delete existing databases

View file

@ -27,14 +27,45 @@ import java.sql.Connection;
*/ */
public interface JpaUpdaterProvider extends Provider { public interface JpaUpdaterProvider extends Provider {
/**
* Status of database up-to-dateness
*/
enum Status { enum Status {
VALID, EMPTY, OUTDATED /**
* Database is valid and up to date
*/
VALID,
/**
* No database exists.
*/
EMPTY,
/**
* Database needs to be updated
*/
OUTDATED
} }
/**
* Updates the Keycloak database
* @param connection DB connection
* @param defaultSchema DB connection
*/
void update(Connection connection, String defaultSchema); void update(Connection connection, String defaultSchema);
/**
* Checks whether Keycloak database is up to date with the most recent changesets
* @param connection DB connection
* @param defaultSchema DB schema to use
* @return
*/
Status validate(Connection connection, String defaultSchema); Status validate(Connection connection, String defaultSchema);
/**
* Exports the SQL update script into the given File.
* @param connection DB connection
* @param defaultSchema DB schema to use
* @param file File to write to
*/
void export(Connection connection, String defaultSchema, File file); void export(Connection connection, String defaultSchema, File file);
} }

View file

@ -37,6 +37,7 @@ import java.lang.reflect.Method;
import java.sql.Connection; import java.sql.Connection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import liquibase.LabelExpression;
/** /**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@ -95,7 +96,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider {
protected void updateChangeSet(Liquibase liquibase, String changelog, File exportFile) throws LiquibaseException, IOException { protected void updateChangeSet(Liquibase liquibase, String changelog, File exportFile) throws LiquibaseException, IOException {
List<ChangeSet> changeSets = liquibase.listUnrunChangeSets((Contexts) null); List<ChangeSet> changeSets = liquibase.listUnrunChangeSets((Contexts) null, new LabelExpression());
if (!changeSets.isEmpty()) { if (!changeSets.isEmpty()) {
List<RanChangeSet> ranChangeSets = liquibase.getDatabase().getRanChangeSetList(); List<RanChangeSet> ranChangeSets = liquibase.getDatabase().getRanChangeSetList();
if (ranChangeSets.isEmpty()) { if (ranChangeSets.isEmpty()) {
@ -159,7 +160,7 @@ public class LiquibaseJpaUpdaterProvider implements JpaUpdaterProvider {
} }
protected Status validateChangeSet(Liquibase liquibase, String changelog) throws LiquibaseException { protected Status validateChangeSet(Liquibase liquibase, String changelog) throws LiquibaseException {
List<ChangeSet> changeSets = liquibase.listUnrunChangeSets((Contexts) null); List<ChangeSet> changeSets = liquibase.listUnrunChangeSets((Contexts) null, new LabelExpression());
if (!changeSets.isEmpty()) { if (!changeSets.isEmpty()) {
if (changeSets.size() == liquibase.getDatabaseChangeLog().getChangeSets().size()) { if (changeSets.size() == liquibase.getDatabaseChangeLog().getChangeSets().size()) {
return Status.EMPTY; return Status.EMPTY;

View file

@ -19,7 +19,7 @@
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet author="mposolda@redhat.com" id="1.6.1_from15"> <changeSet author="mposolda@redhat.com" id="1.6.1_from15">
<preConditions onFail="MARK_RAN" onFailMessage="Upgrading from 1.6.0 version. Skipped 1.6.1_from15 changeSet and marked as ran"> <preConditions onFail="MARK_RAN" onFailMessage="Upgrading from 1.6.0 version. Skipped 1.6.1_from15 changeSet and marked as ran" onSqlOutput="TEST">
<not> <not>
<changeSetExecuted id="1.6.0" author="mposolda@redhat.com" changeLogFile="META-INF/jpa-changelog-1.6.0.xml" /> <changeSetExecuted id="1.6.0" author="mposolda@redhat.com" changeLogFile="META-INF/jpa-changelog-1.6.0.xml" />
</not> </not>
@ -84,7 +84,7 @@
<!-- KEYCLOAK-2404 - just for the update from 1.6.0 BUT not 1.6.1 or newer --> <!-- KEYCLOAK-2404 - just for the update from 1.6.0 BUT not 1.6.1 or newer -->
<changeSet author="mposolda@redhat.com" id="1.6.1_from16-pre"> <changeSet author="mposolda@redhat.com" id="1.6.1_from16-pre">
<preConditions onFail="MARK_RAN" onFailMessage="Skipped 1.6.1_from16-pre changeSet and marked as ran"> <preConditions onFail="MARK_RAN" onFailMessage="Skipped 1.6.1_from16-pre changeSet and marked as ran" onSqlOutput="TEST">
<and> <and>
<changeSetExecuted id="1.6.0" author="mposolda@redhat.com" changeLogFile="META-INF/jpa-changelog-1.6.0.xml" /> <changeSetExecuted id="1.6.0" author="mposolda@redhat.com" changeLogFile="META-INF/jpa-changelog-1.6.0.xml" />
<not> <not>
@ -101,7 +101,7 @@
<!-- Just for the update from 1.6.0 --> <!-- Just for the update from 1.6.0 -->
<changeSet author="mposolda@redhat.com" id="1.6.1_from16"> <changeSet author="mposolda@redhat.com" id="1.6.1_from16">
<preConditions onFail="MARK_RAN" onFailMessage="Upgrading from 1.5.0 or older version. Skipped 1.6.1_from16 changeSet and marked as ran"> <preConditions onFail="MARK_RAN" onFailMessage="Upgrading from 1.5.0 or older version. Skipped 1.6.1_from16 changeSet and marked as ran" onSqlOutput="TEST">
<changeSetExecuted id="1.6.0" author="mposolda@redhat.com" changeLogFile="META-INF/jpa-changelog-1.6.0.xml" /> <changeSetExecuted id="1.6.0" author="mposolda@redhat.com" changeLogFile="META-INF/jpa-changelog-1.6.0.xml" />
</preConditions> </preConditions>