diff --git a/gradle.properties b/gradle.properties index e7a9dfd60d1..e0c56f99f11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ title=Grails GORM projectDesc=GORM - Grails Data Access Framework projectUrl=https://gorm.grails.org/ -projectVersion=8.1.0 +projectVersion=8.1.1 githubSlug=grails/grails-data-mapping developers=Graeme Rocher,Jeff Brown,Burt Beckwith,James Kleeh,Puneet Behl hibernateValidatorVersion=6.2.5.Final @@ -22,7 +22,7 @@ javaParserCoreVersion=3.15.14 junitVersion=4.12 junit-jupiter.version=5.7.0 javassistVersion=3.30.2-GA -groovyVersion=3.0.20 +groovyVersion=3.0.21 org.gradle.caching=true org.gradle.parallel=true diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSourcesSupport.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSourcesSupport.java index ab0c2bf1031..22f9557f259 100644 --- a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSourcesSupport.java +++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSourcesSupport.java @@ -2,8 +2,10 @@ import org.grails.datastore.mapping.config.Entity; import org.grails.datastore.mapping.model.PersistentEntity; +import org.grails.datastore.mapping.multitenancy.TenantDataSourceConfig; import org.springframework.util.ClassUtils; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -56,7 +58,7 @@ public static List getConnectionSourceNames(PersistentEntity entity) { public static boolean usesConnectionSource(PersistentEntity entity, String connectionSourceName) { Class[] interfaces = ClassUtils.getAllInterfacesForClass(entity.getJavaClass()); if(isMultiTenant(interfaces)) { - return true; + return !isMultiTenantExcludedDataSource( entity, connectionSourceName ); } else { List names = getConnectionSourceNames(entity); @@ -74,4 +76,22 @@ protected static boolean isMultiTenant(Class[] interfaces) { } return false; } + + /** + * Returns whether the given entity should be excluded from given connection source name or not. + * It can be configured over {@link TenantDataSourceConfig} annotation + * + * @param entity The name of the multi tenant entity + * @param connectionSourceName The connection source name to check + * @return Whether the given connection should be excluded + */ + protected static boolean isMultiTenantExcludedDataSource(PersistentEntity entity, String connectionSourceName) { + TenantDataSourceConfig tdsc = (TenantDataSourceConfig) entity.getJavaClass().getAnnotation(TenantDataSourceConfig.class); + boolean result = false; + if ( null != tdsc ) { + final String[] dataSourcesToExclude = tdsc.dataSourcesToExclude(); + result = Arrays.asList(dataSourcesToExclude).contains(connectionSourceName); + } + return result; + } } diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/multitenancy/TenantDataSourceConfig.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/multitenancy/TenantDataSourceConfig.java new file mode 100644 index 00000000000..c19a37d2772 --- /dev/null +++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/multitenancy/TenantDataSourceConfig.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017 the original author or authors. + * + * 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 org.grails.datastore.mapping.multitenancy; + +import java.lang.annotation.*; + +/** + *

An annotation that adds possibility to configure whether a domain should be excluded from particular + * data source(s). For example:

+ * + *
+ * {@literal @}TenantDataSourceConfig(dataSourcesToExclude=["adminDataSource"])
+ * class Animal implements MultiTenant {
+ *       ...
+ * }
+ * 
+ */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface TenantDataSourceConfig { + String[] dataSourcesToExclude() default ""; +} diff --git a/settings.gradle b/settings.gradle index d0c1560f205..81341cbcb9f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,6 @@ plugins { id "com.gradle.enterprise" version "3.16.2" - id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.12.2' + id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.13' } gradleEnterprise {