/* * Copyright 2013 Robert von Burg <eitch@eitchnet.ch> */ package li.strolch.persistence.postgresql; import static li.strolch.db.DbConstants.PROP_ALLOW_SCHEMA_CREATION; import static li.strolch.db.DbConstants.PROP_ALLOW_SCHEMA_DROP; import static li.strolch.db.DbConstants.PROP_ALLOW_SCHEMA_MIGRATION; import java.util.Map; import java.util.Map.Entry; import javax.sql.DataSource; import li.strolch.agent.api.StrolchAgent; import li.strolch.agent.api.StrolchRealm; import li.strolch.db.DbConnectionCheck; import li.strolch.db.DbException; import li.strolch.db.DbMigrationState; import li.strolch.db.DbSchemaVersionCheck; import li.strolch.privilege.model.Certificate; import li.strolch.privilege.model.PrivilegeContext; import li.strolch.runtime.configuration.ComponentConfiguration; import li.strolch.runtime.configuration.RuntimeConfiguration; import li.strolch.runtime.configuration.StrolchConfiguration; import li.strolch.runtime.configuration.StrolchConfigurationException; public class PostgreSqlDbInitializer extends PostgreSqlInitializer { private StrolchAgent agent; private PostgreSqlPersistenceHandler persistenceHandler; private RuntimeConfiguration runtimeConfig; private Certificate certificate; private boolean allowSchemaCreation; private boolean allowSchemaMigration; private boolean allowSchemaDrop; /** * @param agent * @param persistenceHandler */ public PostgreSqlDbInitializer(StrolchAgent agent, PostgreSqlPersistenceHandler persistenceHandler, ComponentConfiguration persistenceConfig) { super(agent, persistenceHandler); this.agent = agent; StrolchConfiguration strolchConfiguration = agent.getStrolchConfiguration(); this.runtimeConfig = strolchConfiguration.getRuntimeConfiguration(); this.persistenceHandler = persistenceHandler; this.allowSchemaCreation = persistenceConfig.getBoolean(PROP_ALLOW_SCHEMA_CREATION, Boolean.FALSE); this.allowSchemaMigration = persistenceConfig.getBoolean(PROP_ALLOW_SCHEMA_MIGRATION, Boolean.FALSE); this.allowSchemaDrop = persistenceConfig.getBoolean(PROP_ALLOW_SCHEMA_DROP, Boolean.FALSE); } @Override protected Certificate getCertificate() { return this.certificate; } @Override public void execute(PrivilegeContext privilegeContext) { this.certificate = privilegeContext.getCertificate(); // first make sure we can connect to the database Map<String, DataSource> dsMap = this.persistenceHandler.getDataSources(); DbConnectionCheck connectionCheck = new DbConnectionCheck(dsMap); try { connectionCheck.checkConnections(); } catch (DbException e) { throw new StrolchConfigurationException("At least one of the configured DB connections is invalid: " + e.getMessage(), e); } // first make sure that the data store files exist for (String realmName : this.agent.getContainer().getRealmNames()) { // throws exception if does not exist getDataStoreFile(this.runtimeConfig, this.realmConfig, realmName); } // for each connection info: // - make sure schema exists // - if it didn't exist, initialize with a set of data defined by the data store file DbSchemaVersionCheck schemaVersionCheck = new DbSchemaVersionCheck(PostgreSqlPersistenceHandler.SCRIPT_PREFIX, this.getClass(), this.allowSchemaCreation, this.allowSchemaMigration, this.allowSchemaDrop); for (Entry<String, DataSource> entry : dsMap.entrySet()) { String realmName = entry.getKey(); DataSource ds = entry.getValue(); StrolchRealm realm = this.agent.getContainer().getRealm(realmName); if (realm.getMode().isTransient()) continue; // check that the schema exists DbMigrationState migrationType; try { migrationType = schemaVersionCheck.checkSchemaVersion(realmName, ds); } catch (DbException e) { throw new RuntimeException("Failed to validate schema for connection " + ds, e); } // now init the DB if needed initSchemaFromDataStore(migrationType, realmName); } } }