KEYCLOAK-2737 connectionsMongo: Support for 'databaseSchema: validate'

This commit is contained in:
mposolda committed 2016-04-04 22:23:24 +02:00
1 parent a8732aa83c
commit 749130b689
6 files changed
+105 -34

No files matched your search

@@ -156,13 +156,24 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
}
private void update(KeycloakSession session) {
MongoUpdaterProvider mongoUpdater = session.getProvider(MongoUpdaterProvider.class);
String databaseSchema = config.get("databaseSchema");
if (mongoUpdater == null) {
throw new RuntimeException("Can't update database: Mongo updater provider not found");
if (databaseSchema == null) {
throw new RuntimeException("Property 'databaseSchema' needs to be specified in the configuration of mongo connections");
} else {
MongoUpdaterProvider mongoUpdater = session.getProvider(MongoUpdaterProvider.class);
if (mongoUpdater == null) {
throw new RuntimeException("Can't update database: Mongo updater provider not found");
}
if (databaseSchema.equals("update")) {
mongoUpdater.update(session, db);
} else if (databaseSchema.equals("validate")) {
mongoUpdater.validate(session, db);
} else {
throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
}
}
mongoUpdater.update(session, db);
}
@@ -26,6 +26,8 @@ import org.keycloak.provider.Provider;
*/
public interface MongoUpdaterProvider extends Provider {
public void update(KeycloakSession session, DB db);
void update(KeycloakSession session, DB db);
void validate(KeycloakSession session, DB db);
}
@@ -65,38 +65,19 @@ public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider {
log.debug("Starting database update");
try {
boolean changeLogExists = db.collectionExists(CHANGE_LOG_COLLECTION);
boolean realmExists = db.collectionExists("realms");
DBCollection changeLog = db.getCollection(CHANGE_LOG_COLLECTION);
List<String> executed = new LinkedList<String>();
if (!changeLogExists && realmExists) {
Update1_0_0_Final u = new Update1_0_0_Final();
executed.add(u.getId());
createLog(changeLog, u, 1);
} else if (changeLogExists) {
DBCursor cursor = changeLog.find().sort(new BasicDBObject("orderExecuted", 1));
while (cursor.hasNext()) {
executed.add((String) cursor.next().get("_id"));
}
}
List<Update> updatesToRun = new LinkedList<Update>();
for (Class<? extends Update> updateClass : updates) {
Update u = updateClass.newInstance();
if (!executed.contains(u.getId())) {
updatesToRun.add(u);
}
}
List<String> executed = getExecuted(db, changeLogExists, changeLog);
List<Update> updatesToRun = getUpdatesToRun(executed);
if (!updatesToRun.isEmpty()) {
if (executed.isEmpty()) {
log.info("Initializing database schema");
} else {
if (log.isDebugEnabled()) {
log.infov("Updating database from {0} to {1}", executed.get(executed.size() - 1), updatesToRun.get(updatesToRun.size() - 1).getId());
log.debugv("Updating database from {0} to {1}", executed.get(executed.size() - 1), updatesToRun.get(updatesToRun.size() - 1).getId());
} else {
log.debugv("Updating database");
log.info("Updating database");
}
}
@@ -121,10 +102,66 @@ public class DefaultMongoUpdaterProvider implements MongoUpdaterProvider {
}
}
@Override
public void validate(KeycloakSession session, DB db) {
log.debug("Validating database");
boolean changeLogExists = db.collectionExists(CHANGE_LOG_COLLECTION);
DBCollection changeLog = db.getCollection(CHANGE_LOG_COLLECTION);
List<String> executed = getExecuted(db, changeLogExists, changeLog);
List<Update> updatesToRun = getUpdatesToRun(executed);
if (!updatesToRun.isEmpty()) {
String errorMessage = String.format("Failed to validate Mongo database schema. Schema needs updating database from %s to %s. Please change databaseSchema to 'update'",
executed.get(executed.size() - 1), updatesToRun.get(updatesToRun.size() - 1).getId());
throw new RuntimeException(errorMessage);
} else {
log.debug("Validation passed. Database is up to date");
}
}
private List<String> getExecuted(DB db, boolean changeLogExists, DBCollection changeLog) {
boolean realmExists = db.collectionExists("realms");
List<String> executed = new LinkedList<>();
if (!changeLogExists && realmExists) {
Update1_0_0_Final u = new Update1_0_0_Final();
executed.add(u.getId());
createLog(changeLog, u, 1);
} else if (changeLogExists) {
DBCursor cursor = changeLog.find().sort(new BasicDBObject("orderExecuted", 1));
while (cursor.hasNext()) {
executed.add((String) cursor.next().get("_id"));
}
}
return executed;
}
private List<Update> getUpdatesToRun(List<String> executed) {
try {
List<Update> updatesToRun = new LinkedList<>();
for (Class<? extends Update> updateClass : updates) {
Update u = updateClass.newInstance();
if (!executed.contains(u.getId())) {
updatesToRun.add(u);
}
}
return updatesToRun;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void createLog(DBCollection changeLog, Update update, int orderExecuted) {
changeLog.insert(new BasicDBObject("_id", update.getId()).append("dateExecuted", new Date()).append("orderExecuted", orderExecuted));
}
@Override
public void close() {
}