Skip to content
Permalink
Browse files
Merge pull request #6 from myrle-krantz/develop
1st pass: cross-tenant db
  • Loading branch information
myrle-krantz committed May 17, 2017
2 parents bc9ccf9 + 51b6844 commit a42774cf26bb0abbe76fc5deeccd843eb89d6a45
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 44 deletions.
@@ -59,6 +59,10 @@ dependencies {
)
}

jar {
from sourceSets.main.allSource
}

publishing {
publications {
mariadbPublication(MavenPublication) {
@@ -24,11 +24,12 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@SuppressWarnings({"WeakerAccess", "unused"})
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({MariaDBJavaConfiguration.class})
@Import({MariaDBJavaConfigurationImportSelector.class})
public @interface EnableMariaDB {

boolean forTenantContext() default true;
}
@@ -15,17 +15,16 @@
*/
package io.mifos.core.mariadb.config;


import com.jolbox.bonecp.BoneCPDataSource;
import io.mifos.core.lang.ApplicationName;
import io.mifos.core.lang.config.EnableApplicationName;
import io.mifos.core.mariadb.domain.ContextAwareRoutingDataSource;
import io.mifos.core.mariadb.domain.FlywayFactoryBean;
import io.mifos.core.mariadb.util.JdbcUrlBuilder;
import io.mifos.core.mariadb.util.MariaDBConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -40,7 +39,6 @@

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Properties;

@SuppressWarnings("WeakerAccess")
@@ -78,61 +76,57 @@ public LocalContainerEntityManagerFactoryBean entityManagerFactory(final DataSou
}

@Bean
public DataSource dataSource(@Qualifier(MariaDBConstants.LOGGER_NAME) final Logger logger) {
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}

@Bean
public FlywayFactoryBean flywayFactoryBean(final ApplicationName applicationName) {
return new FlywayFactoryBean(applicationName);
}

@Bean
public MetaDataSourceWrapper metaDataSourceWrapper() {

final BoneCPDataSource boneCPDataSource = new BoneCPDataSource();
boneCPDataSource.setDriverClass(
this.env.getProperty(MariaDBConstants.MARIADB_DRIVER_CLASS_PROP, MariaDBConstants.MARIADB_DRIVER_CLASS_DEFAULT));
this.env.getProperty(MariaDBConstants.MARIADB_DRIVER_CLASS_PROP, MariaDBConstants.MARIADB_DRIVER_CLASS_DEFAULT));
boneCPDataSource.setJdbcUrl(JdbcUrlBuilder
.create(JdbcUrlBuilder.DatabaseType.MARIADB)
.host(this.env.getProperty(MariaDBConstants.MARIADB_HOST_PROP, MariaDBConstants.MARIADB_HOST_DEFAULT))
.port(this.env.getProperty(MariaDBConstants.MARIADB_PORT_PROP, MariaDBConstants.MARIADB_PORT_DEFAULT))
.instanceName(this.env.getProperty(MariaDBConstants.MARIADB_DATABASE_NAME_PROP, MariaDBConstants.MARIADB_DATABASE_NAME_DEFAULT))
.build());
.create(JdbcUrlBuilder.DatabaseType.MARIADB)
.host(this.env.getProperty(MariaDBConstants.MARIADB_HOST_PROP, MariaDBConstants.MARIADB_HOST_DEFAULT))
.port(this.env.getProperty(MariaDBConstants.MARIADB_PORT_PROP, MariaDBConstants.MARIADB_PORT_DEFAULT))
.instanceName(this.env.getProperty(MariaDBConstants.MARIADB_DATABASE_NAME_PROP, MariaDBConstants.MARIADB_DATABASE_NAME_DEFAULT))
.build());
boneCPDataSource.setUsername(
this.env.getProperty(MariaDBConstants.MARIADB_USER_PROP, MariaDBConstants.MARIADB_USER_DEFAULT));
this.env.getProperty(MariaDBConstants.MARIADB_USER_PROP, MariaDBConstants.MARIADB_USER_DEFAULT));
boneCPDataSource.setPassword(
this.env.getProperty(MariaDBConstants.MARIADB_PASSWORD_PROP, MariaDBConstants.MARIADB_PASSWORD_DEFAULT));
this.env.getProperty(MariaDBConstants.MARIADB_PASSWORD_PROP, MariaDBConstants.MARIADB_PASSWORD_DEFAULT));
boneCPDataSource.setIdleConnectionTestPeriodInMinutes(
Long.valueOf(this.env.getProperty(MariaDBConstants.BONECP_IDLE_CONNECTION_TEST_PROP, MariaDBConstants.BONECP_IDLE_CONNECTION_TEST_DEFAULT)));
Long.valueOf(this.env.getProperty(MariaDBConstants.BONECP_IDLE_CONNECTION_TEST_PROP, MariaDBConstants.BONECP_IDLE_CONNECTION_TEST_DEFAULT)));
boneCPDataSource.setIdleMaxAgeInMinutes(
Long.valueOf(this.env.getProperty(MariaDBConstants.BONECP_IDLE_MAX_AGE_PROP, MariaDBConstants.BONECP_IDLE_MAX_AGE_DEFAULT)));
Long.valueOf(this.env.getProperty(MariaDBConstants.BONECP_IDLE_MAX_AGE_PROP, MariaDBConstants.BONECP_IDLE_MAX_AGE_DEFAULT)));
boneCPDataSource.setMaxConnectionsPerPartition(
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_MAX_CONNECTION_PARTITION_PROP, MariaDBConstants.BONECP_MAX_CONNECTION_PARTITION_DEFAULT)));
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_MAX_CONNECTION_PARTITION_PROP, MariaDBConstants.BONECP_MAX_CONNECTION_PARTITION_DEFAULT)));
boneCPDataSource.setMinConnectionsPerPartition(
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_MIN_CONNECTION_PARTITION_PROP, MariaDBConstants.BONECP_MIN_CONNECTION_PARTITION_DEFAULT)));
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_MIN_CONNECTION_PARTITION_PROP, MariaDBConstants.BONECP_MIN_CONNECTION_PARTITION_DEFAULT)));
boneCPDataSource.setPartitionCount(
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_PARTITION_COUNT_PROP, MariaDBConstants.BONECP_PARTITION_COUNT_DEFAULT)));
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_PARTITION_COUNT_PROP, MariaDBConstants.BONECP_PARTITION_COUNT_DEFAULT)));
boneCPDataSource.setAcquireIncrement(
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_ACQUIRE_INCREMENT_PROP, MariaDBConstants.BONECP_ACQUIRE_INCREMENT_DEFAULT)));
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_ACQUIRE_INCREMENT_PROP, MariaDBConstants.BONECP_ACQUIRE_INCREMENT_DEFAULT)));
boneCPDataSource.setStatementsCacheSize(
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_STATEMENT_CACHE_PROP, MariaDBConstants.BONECP_STATEMENT_CACHE_DEFAULT)));
Integer.valueOf(this.env.getProperty(MariaDBConstants.BONECP_STATEMENT_CACHE_PROP, MariaDBConstants.BONECP_STATEMENT_CACHE_DEFAULT)));

final Properties driverProperties = new Properties();
driverProperties.setProperty("useServerPrepStmts", "false");
boneCPDataSource.setDriverProperties(driverProperties);

final ContextAwareRoutingDataSource dataSource = new ContextAwareRoutingDataSource(logger, JdbcUrlBuilder.DatabaseType.MARIADB);
dataSource.setMetaDataSource(boneCPDataSource);
final HashMap<Object, Object> targetDataSources = new HashMap<>();
dataSource.setTargetDataSources(targetDataSources);
return dataSource;
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}

@Bean
public FlywayFactoryBean flywayFactoryBean(final ApplicationName applicationName) {
return new FlywayFactoryBean(applicationName);
return new MetaDataSourceWrapper(boneCPDataSource);
}

private Properties additionalProperties() {
@@ -0,0 +1,47 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.core.mariadb.config;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

import java.util.HashSet;
import java.util.Set;

/**
* @author Myrle Krantz
*/
class MariaDBJavaConfigurationImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
final boolean forTenantContext = (boolean)importingClassMetadata
.getAnnotationAttributes(EnableMariaDB.class.getTypeName())
.get("forTenantContext");

final Set<Class> classesToImport = new HashSet<>();
final String prop = System.getProperty("mariadb.enabled");
if (prop == null || "true".equals(prop)) {
classesToImport.add(MariaDBJavaConfiguration.class);
if (forTenantContext) {
classesToImport.add(MariaDBTenantBasedJavaConfiguration.class);
}
else {
classesToImport.add(MariaDBTenantFreeJavaConfiguration.class);
}
}
return classesToImport.stream().map(Class::getCanonicalName).toArray(String[]::new);
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.core.mariadb.config;

import io.mifos.core.mariadb.domain.ContextAwareRoutingDataSource;
import io.mifos.core.mariadb.util.JdbcUrlBuilder;
import io.mifos.core.mariadb.util.MariaDBConstants;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;

@SuppressWarnings("WeakerAccess")
@Configuration
@ConditionalOnProperty(prefix = "mariadb", name = "enabled", matchIfMissing = true)
public class MariaDBTenantBasedJavaConfiguration {
@Bean
public DataSource dataSource(@Qualifier(MariaDBConstants.LOGGER_NAME) final Logger logger,
final MetaDataSourceWrapper metaDataSource) {

final ContextAwareRoutingDataSource dataSource = new ContextAwareRoutingDataSource(logger, JdbcUrlBuilder.DatabaseType.MARIADB);
dataSource.setMetaDataSource(metaDataSource.getMetaDataSource());
final HashMap<Object, Object> targetDataSources = new HashMap<>();
dataSource.setTargetDataSources(targetDataSources);
return dataSource;
}
}
@@ -0,0 +1,36 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.core.mariadb.config;


import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
* @author Myrle Krantz
*/
@SuppressWarnings("WeakerAccess")
@Configuration
@ConditionalOnProperty(prefix = "mariadb", name = "enabled", matchIfMissing = true)
public class MariaDBTenantFreeJavaConfiguration {
@Bean
public DataSource dataSource(final MetaDataSourceWrapper metaDataSource) {
return metaDataSource.getMetaDataSource();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.core.mariadb.config;

import com.jolbox.bonecp.BoneCPDataSource;

/**
* @author Myrle Krantz
*/
public class MetaDataSourceWrapper {
private final BoneCPDataSource metaDataSource;

public MetaDataSourceWrapper(final BoneCPDataSource metaDataSource) {
this.metaDataSource = metaDataSource;
}

BoneCPDataSource getMetaDataSource() {
return metaDataSource;
}
}

0 comments on commit a42774c

Please sign in to comment.