All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.topia.persistence.TopiaConfigurationBuilder Maven / Gradle / Ivy

The newest version!
package org.nuiton.topia.persistence;

/*
 * #%L
 * ToPIA Extension :: API
 * %%
 * Copyright (C) 2018 - 2022 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.cfg.AvailableSettings;
import org.nuiton.topia.persistence.jdbc.JdbcConfiguration;
import org.nuiton.topia.persistence.jdbc.JdbcConfigurationBuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.sql.Driver;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Builder to create a {@link org.nuiton.topia.persistence.TopiaConfiguration} instance.
 * 

* A few methods from {@link org.nuiton.topia.persistence.jdbc.JdbcConfiguration} are delegated here. */ public class TopiaConfigurationBuilder { protected JdbcConfigurationBuilder jdbcConfigurationBuilder = new JdbcConfigurationBuilder(); protected static final String TOPIA_SERVICE_CONFIGURATION_PREFIX = "topia.service."; protected static final String CONFIG_DEFAULT_SCHEMA = AvailableSettings.DEFAULT_SCHEMA; protected static final String CONFIG_USER = AvailableSettings.USER; protected static final String CONFIG_PASS = AvailableSettings.PASS; protected static final String CONFIG_DRIVER = AvailableSettings.DRIVER; protected static final String CONFIG_URL = AvailableSettings.URL; protected static final String CONFIG_PERSISTENCE_TOPIA_ID_FACTORY_CLASS_NAME = "topia.persistence.topiaIdFactoryClassName"; protected static final String CONFIG_PERSISTENCE_INIT_SCHEMA = "topia.persistence.initSchema"; protected static final String CONFIG_PERSISTENCE_VALIDATE_SCHEMA = "topia.persistence.validateSchema"; protected static final String CONFIG_PERSISTENCE_USE_HIKARI_FOR_JDBC_CONNECTION_POOLING = "topia.persistence.useHikariForJdbcConnectionPooling"; /** * Configuration that must not be in {@link TopiaConfiguration#getHibernateExtraConfiguration()}. */ protected static final ImmutableSet MAIN_CONFIGURATION = ImmutableSet.of(CONFIG_DRIVER, CONFIG_URL, CONFIG_USER, CONFIG_PASS); /** * Do nothing but throws {@link TopiaMisconfigurationException} if there is a problem in * given configuration. * * @param topiaConfiguration FIXME * @throws TopiaMisconfigurationException FIXME */ public void check(TopiaConfiguration topiaConfiguration) throws TopiaMisconfigurationException { if (StringUtils.isBlank(topiaConfiguration.getJdbcConnectionUrl())) { throw new TopiaMisconfigurationException("you must provide JDBC connection URL", topiaConfiguration); } if (StringUtils.isBlank(topiaConfiguration.getJdbcConnectionUser())) { throw new TopiaMisconfigurationException("you must provide JDBC connection user", topiaConfiguration); } if (topiaConfiguration.getJdbcConnectionPassword() == null) { throw new TopiaMisconfigurationException("you must provide JDBC connection password", topiaConfiguration); } if (topiaConfiguration.getJdbcDriverClass() == null) { throw new TopiaMisconfigurationException("you must provide JDBC connection driver", topiaConfiguration); } Map hibernateExtraConfiguration = topiaConfiguration.getHibernateExtraConfiguration(); if (hibernateExtraConfiguration.containsKey(AvailableSettings.HBM2DDL_AUTO)) { throw new TopiaMisconfigurationException("you must not use " + AvailableSettings.HBM2DDL_AUTO + " configuration directive, if you want Hibernate to update the schema, use " + HibernateTopiaMigrationService.class.getName(), topiaConfiguration); } for (Map.Entry entry : hibernateExtraConfiguration.entrySet()) { String key = entry.getKey(); boolean entryIsOk = (key.startsWith("hibernate.") || key.startsWith("javax.persistence.")) && !MAIN_CONFIGURATION.contains(key); if (!entryIsOk) { throw new TopiaMisconfigurationException("hibernate extra configuration is " + hibernateExtraConfiguration + " but it should not contains a key " + key, topiaConfiguration); } } } public BeanTopiaConfiguration readProperties(File propertiesFile) { Properties properties = new Properties(); try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) { properties.load(fileInputStream); } catch (FileNotFoundException e) { throw new IllegalArgumentException("topia configuration file cannot be found " + propertiesFile, e); } catch (IOException e) { throw new UncheckedIOException("unable to read " + propertiesFile, e); } return readProperties(properties); } public BeanTopiaConfiguration readProperties(Properties properties) { return readMap((Map) ImmutableMap.copyOf(properties)); } public BeanTopiaConfiguration readMap(Map configuration) { // JDBC connection String url = configuration.get(CONFIG_URL); String user = configuration.get(CONFIG_USER); String password = configuration.get(CONFIG_PASS); String driverName = configuration.get(CONFIG_DRIVER); JdbcConfiguration jdbcConfiguration; if (StringUtils.isBlank(driverName)) { jdbcConfiguration = jdbcConfigurationBuilder.forDatabase(url, user, password); } else { jdbcConfiguration = jdbcConfigurationBuilder.forDatabase(url, user, password, driverName); } BeanTopiaConfiguration result = new BeanTopiaConfiguration(jdbcConfiguration); // Schema initialization String initSchemaConfigValue = configuration.get(CONFIG_PERSISTENCE_INIT_SCHEMA); boolean initSchema = StringUtils.isBlank(initSchemaConfigValue) || Boolean.parseBoolean(initSchemaConfigValue); result.setInitSchema(initSchema); // Schema validation String validateSchemaConfigValue = configuration.get(CONFIG_PERSISTENCE_VALIDATE_SCHEMA); boolean validateSchema = StringUtils.isBlank(validateSchemaConfigValue) || Boolean.parseBoolean(validateSchemaConfigValue); result.setValidateSchema(validateSchema); // Using Hikari CP String useHikariForJdbcConnectionPoolingConfigValue = configuration.get(CONFIG_PERSISTENCE_USE_HIKARI_FOR_JDBC_CONNECTION_POOLING); boolean useHikariForJdbcConnectionPooling = StringUtils.isBlank(useHikariForJdbcConnectionPoolingConfigValue) || Boolean.parseBoolean(useHikariForJdbcConnectionPoolingConfigValue); result.setUseHikariForJdbcConnectionPooling(useHikariForJdbcConnectionPooling); // others String topiaIdFactoryClassName = configuration.get(CONFIG_PERSISTENCE_TOPIA_ID_FACTORY_CLASS_NAME); if (!Strings.isNullOrEmpty(topiaIdFactoryClassName)) { result.setTopiaIdFactoryClassName(topiaIdFactoryClassName); } result.setSchemaName(configuration.get(CONFIG_DEFAULT_SCHEMA)); // Hibernate for (Map.Entry entry : configuration.entrySet()) { String key = entry.getKey(); boolean keyMustBeIncludedInHibernateExtraConfiguration = !MAIN_CONFIGURATION.contains(key) && (key.startsWith("hibernate.") || key.startsWith("javax.persistence.")); if (keyMustBeIncludedInHibernateExtraConfiguration) { result.getHibernateExtraConfiguration().put(key, entry.getValue()); } } // services for (Map.Entry entry : configuration.entrySet()) { String prefixedConfigurationKey = entry.getKey(); String configurationValue = entry.getValue(); if (prefixedConfigurationKey.startsWith(TOPIA_SERVICE_CONFIGURATION_PREFIX)) { String configurationKey = StringUtils.removeStart(prefixedConfigurationKey, TOPIA_SERVICE_CONFIGURATION_PREFIX); String[] split = StringUtils.split(configurationKey, '.'); Preconditions.checkState(split.length > 0, "'" + prefixedConfigurationKey + "' is not a valid configuration key"); String serviceName = split[0]; if (split.length == 1) { // service declaration instantiate it try { Class loadedClass = Class.forName(configurationValue); if (TopiaService.class.isAssignableFrom(loadedClass)) { @SuppressWarnings("unchecked") Class serviceClass = (Class) loadedClass; result.getDeclaredServices().put(serviceName, serviceClass); } else { throw new TopiaMisconfigurationException("class " + configurationValue + " is not a topia service, it does not implement " + TopiaService.class.getName(), null); } } catch (ClassNotFoundException e) { throw new TopiaMisconfigurationException("unable to find class " + configurationValue + " in classpath", null); } } else { // service configuration, save it to push it back later Map serviceConfiguration = result.getDeclaredServicesConfiguration().computeIfAbsent(serviceName, aServiceName -> new LinkedHashMap<>()); String serviceConfigurationKey = StringUtils.removeStart(configurationKey, serviceName + "."); serviceConfiguration.put(serviceConfigurationKey, configurationValue); } } } check(result); return result; } public Map toMap(TopiaConfiguration topiaConfiguration) { check(topiaConfiguration); Map map = new LinkedHashMap<>(); // JDBC connection map.put(CONFIG_URL, topiaConfiguration.getJdbcConnectionUrl()); map.put(CONFIG_USER, topiaConfiguration.getJdbcConnectionUser()); map.put(CONFIG_PASS, topiaConfiguration.getJdbcConnectionPassword()); map.put(CONFIG_DRIVER, topiaConfiguration.getJdbcDriverClass().getName()); // Schema initialization if (!topiaConfiguration.isInitSchema()) { map.put(CONFIG_PERSISTENCE_INIT_SCHEMA, String.valueOf(topiaConfiguration.isInitSchema())); } // Schema validation if (!topiaConfiguration.isValidateSchema()) { map.put(CONFIG_PERSISTENCE_VALIDATE_SCHEMA, String.valueOf(topiaConfiguration.isValidateSchema())); } // Using Hikari CP if (!topiaConfiguration.isUseHikariForJdbcConnectionPooling()) { map.put(CONFIG_PERSISTENCE_USE_HIKARI_FOR_JDBC_CONNECTION_POOLING, String.valueOf(topiaConfiguration.isUseHikariForJdbcConnectionPooling())); } // others map.put(CONFIG_PERSISTENCE_TOPIA_ID_FACTORY_CLASS_NAME, topiaConfiguration.getTopiaIdFactory().getClass().getName()); if (topiaConfiguration.getSchemaName() != null) { map.put(CONFIG_DEFAULT_SCHEMA, topiaConfiguration.getSchemaName()); } // Hibernate map.putAll(topiaConfiguration.getHibernateExtraConfiguration()); // services for (Map.Entry> entry : topiaConfiguration.getDeclaredServices().entrySet()) { String serviceName = entry.getKey(); String serviceDeclaration = TOPIA_SERVICE_CONFIGURATION_PREFIX + "." + serviceName; String serviceClassName = entry.getValue().getName(); Map serviceConfiguration = topiaConfiguration.getDeclaredServicesConfiguration().get(serviceName); map.put(serviceDeclaration, serviceClassName); if (serviceConfiguration != null) { for (Map.Entry serviceConfigurationEntry : serviceConfiguration.entrySet()) { map.put(serviceDeclaration + "." + serviceConfigurationEntry.getKey(), serviceConfigurationEntry.getValue()); } } } return map; } public Properties toProperties(TopiaConfiguration topiaConfiguration) { Map map = toMap(topiaConfiguration); Properties properties = new Properties(); properties.putAll(map); return properties; } public ConfigureInitSchemaStep forDatabase(JdbcConfiguration jdbcConfiguration) { BeanTopiaConfiguration beanTopiaConfiguration = new BeanTopiaConfiguration(jdbcConfiguration); return new ConfigureInitSchemaStep(beanTopiaConfiguration); } public BeanTopiaConfiguration forTest(Class testClass, String methodName) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forTestDatabase(testClass, methodName); return forDatabase(jdbcConfiguration) .onlyCreateSchemaIfDatabaseIsEmpty() .validateSchemaOnStartup() .useDefaultConnectionPool() .build(); } public class ConfigureInitSchemaStep { protected BeanTopiaConfiguration beanTopiaConfiguration; public ConfigureInitSchemaStep(BeanTopiaConfiguration beanTopiaConfiguration) { this.beanTopiaConfiguration = beanTopiaConfiguration; } public ConfigureValidateSchemaStep onlyCreateSchemaIfDatabaseIsEmpty() { beanTopiaConfiguration.setInitSchema(true); return nextStep(); } public ConfigureValidateSchemaStep useAlreadyExistingDatabaseAsIs() { beanTopiaConfiguration.setInitSchema(false); return nextStep(); } public ConfigureValidateSchemaStep useHibernateUpdate() { beanTopiaConfiguration.setInitSchema(true); beanTopiaConfiguration.addDeclaredService("migration", org.nuiton.topia.persistence.HibernateTopiaMigrationService.class, new LinkedHashMap<>()); return nextStep(); } public ConfigureValidateSchemaStep useFlyway() { beanTopiaConfiguration.setInitSchema(true); beanTopiaConfiguration.addDeclaredService("migration", "org.nuiton.topia.flyway.TopiaFlywayServiceImpl", new LinkedHashMap<>()); return nextStep(); } public ConfigureValidateSchemaStep useLiquibase() { beanTopiaConfiguration.setInitSchema(true); beanTopiaConfiguration.addDeclaredService("migration", "org.nuiton.topia.flyway.TopiaLiquibaseServiceImpl", new LinkedHashMap<>()); return nextStep(); } protected ConfigureValidateSchemaStep nextStep() { return new ConfigureValidateSchemaStep(beanTopiaConfiguration); } } public class ConfigureValidateSchemaStep { protected BeanTopiaConfiguration beanTopiaConfiguration; public ConfigureValidateSchemaStep(BeanTopiaConfiguration beanTopiaConfiguration) { this.beanTopiaConfiguration = beanTopiaConfiguration; } public ConfigureJdbcConnectionPoolingStep validateSchemaOnStartup() { beanTopiaConfiguration.setValidateSchema(true); return new ConfigureJdbcConnectionPoolingStep(beanTopiaConfiguration); } public ConfigureJdbcConnectionPoolingStep doNotValidateSchemaOnStartup() { beanTopiaConfiguration.setValidateSchema(false); return new ConfigureJdbcConnectionPoolingStep(beanTopiaConfiguration); } } public class ConfigureJdbcConnectionPoolingStep { protected BeanTopiaConfiguration beanTopiaConfiguration; public ConfigureJdbcConnectionPoolingStep(BeanTopiaConfiguration beanTopiaConfiguration) { this.beanTopiaConfiguration = beanTopiaConfiguration; } public BuildStep useDefaultConnectionPool() { return useHikariConnectionPool(); } public BuildStep useHikariConnectionPool() { beanTopiaConfiguration.setUseHikariForJdbcConnectionPooling(true); return new BuildStep(beanTopiaConfiguration); } public BuildStep useC3p0ConnectionPool() { beanTopiaConfiguration.setUseHikariForJdbcConnectionPooling(false); return new BuildStep(beanTopiaConfiguration); } } public class BuildStep { protected BeanTopiaConfiguration beanTopiaConfiguration; public BuildStep(BeanTopiaConfiguration beanTopiaConfiguration) { this.beanTopiaConfiguration = beanTopiaConfiguration; } public BeanTopiaConfiguration build() { check(beanTopiaConfiguration); return beanTopiaConfiguration; } public Properties buildProperties() { return toProperties(beanTopiaConfiguration); } public Map buildMap() { return toMap(beanTopiaConfiguration); } } /* * A few methods that delegates to jdbcConfigurationBuilder */ public ConfigureInitSchemaStep forInMemoryH2Database() { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forInMemoryH2Database(); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forDatabase(String jdbcConnectionUrl, String jdbcConnectionUser, String jdbcConnectionPassword, String jdbcDriverClassName) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forDatabase(jdbcConnectionUrl, jdbcConnectionUser, jdbcConnectionPassword, jdbcDriverClassName); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forDatabase(String jdbcConnectionUrl, String jdbcConnectionUser, String jdbcConnectionPassword, Class jdbcDriverClass) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forDatabase(jdbcConnectionUrl, jdbcConnectionUser, jdbcConnectionPassword, jdbcDriverClass); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forDatabase(String jdbcConnectionUrl, String jdbcConnectionUser, String jdbcConnectionPassword) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forDatabase(jdbcConnectionUrl, jdbcConnectionUser, jdbcConnectionPassword); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forPostgresqlDatabase(String jdbcConnectionUrl, String jdbcConnectionUser, String jdbcConnectionPassword) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forPostgresqlDatabase(jdbcConnectionUrl, jdbcConnectionUser, jdbcConnectionPassword); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forH2Database(String jdbcConnectionUrl, String jdbcConnectionUser, String jdbcConnectionPassword) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forH2Database(jdbcConnectionUrl, jdbcConnectionUser, jdbcConnectionPassword); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forH2Database(String jdbcConnectionUrl) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forH2Database(jdbcConnectionUrl); return forDatabase(jdbcConfiguration); } public ConfigureInitSchemaStep forH2Database(File file) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forH2Database(file); return forDatabase(jdbcConfiguration); } // public ConfigureInitSchemaStep forH2DatabaseInTempDirectory() { // JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forH2DatabaseInTempDirectory(); // return forDatabase(jdbcConfiguration); // } public ConfigureInitSchemaStep forTestDatabase(Class testClass, String methodName) { JdbcConfiguration jdbcConfiguration = jdbcConfigurationBuilder.forTestDatabase(testClass, methodName); return forDatabase(jdbcConfiguration); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy