This is an automated email from the ASF dual-hosted git repository. jamesfredley pushed a commit to branch fix/gorm-api-registration-scaling in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 2498f91f6061fd6c27c79814bd627df3d6ee196f Author: James Fredley <[email protected]> AuthorDate: Fri Jun 26 15:42:33 2026 -0400 Cover Hibernate GORM API allocation combinations Add mirrored Hibernate 5 and Hibernate 7 regression specs for the GORM API allocation matrix across discriminator, schema, and database multi-tenancy modes, explicit datasources, multiple datasources, and ConnectionSource.ALL mappings. Assisted-by: Hephaestus:openai/gpt-5.5 --- .../connections/GormApiAllocationSpec.groovy | 282 +++++++++++++++++++++ .../connections/GormApiAllocationSpec.groovy | 282 +++++++++++++++++++++ 2 files changed, 564 insertions(+) diff --git a/grails-data-hibernate5/core/src/test/groovy/org/grails/orm/hibernate/connections/GormApiAllocationSpec.groovy b/grails-data-hibernate5/core/src/test/groovy/org/grails/orm/hibernate/connections/GormApiAllocationSpec.groovy new file mode 100644 index 0000000000..10b88ad910 --- /dev/null +++ b/grails-data-hibernate5/core/src/test/groovy/org/grails/orm/hibernate/connections/GormApiAllocationSpec.groovy @@ -0,0 +1,282 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * https://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.orm.hibernate.connections + +import java.util.UUID + +import org.hibernate.dialect.H2Dialect +import spock.lang.AutoCleanup +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties + +import grails.gorm.MultiTenant +import grails.gorm.annotation.Entity +import org.grails.datastore.gorm.GormEnhancer +import org.grails.datastore.gorm.GormEntity +import org.grails.datastore.mapping.core.DatastoreUtils +import org.grails.datastore.mapping.core.connections.ConnectionSource +import org.grails.datastore.mapping.multitenancy.AllTenantsResolver +import org.grails.datastore.mapping.multitenancy.MultiTenancySettings +import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver +import org.grails.orm.hibernate.HibernateDatastore + +@RestoreSystemProperties +class GormApiAllocationSpec extends Specification { + + @AutoCleanup HibernateDatastore datastore + + void cleanup() { + System.clearProperty(SystemPropertyTenantResolver.PROPERTY_NAME) + } + + void "DISCRIMINATOR multi tenant single datasource uses only default APIs"() { + when: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, [], H5AllocationDefaultTenant) + + then: + hasAllApis(H5AllocationDefaultTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H5AllocationDefaultTenant, 'tenantA') + + when: + def result = H5AllocationDefaultTenant.withTenant('tenantA') { true } + + then: + result + !hasAnyApis(H5AllocationDefaultTenant, 'tenantA') + } + + void "DISCRIMINATOR multi tenant default datasource with multiple configured datasources creates non-default APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting'], H5AllocationDefaultTenant) + + expect: + hasAllApis(H5AllocationDefaultTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H5AllocationDefaultTenant, 'analytics') + !hasAnyApis(H5AllocationDefaultTenant, 'reporting') + + when: + def staticApi = GormEnhancer.findStaticApi(H5AllocationDefaultTenant, 'analytics') + def instanceApi = GormEnhancer.findInstanceApi(H5AllocationDefaultTenant, 'analytics') + def validationApi = GormEnhancer.findValidationApi(H5AllocationDefaultTenant, 'analytics') + + then: + hasAllApis(H5AllocationDefaultTenant, 'analytics') + !hasAnyApis(H5AllocationDefaultTenant, 'reporting') + !staticApi.is(GormEnhancer.findStaticApi(H5AllocationDefaultTenant, ConnectionSource.DEFAULT)) + instanceApi.is(GormEnhancer.findInstanceApi(H5AllocationDefaultTenant, 'analytics')) + validationApi.is(GormEnhancer.findValidationApi(H5AllocationDefaultTenant, 'analytics')) + } + + void "SCHEMA multi tenant single datasource creates tenant APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.SCHEMA, [], H5AllocationSchemaTenant) + + expect: + hasAllApis(H5AllocationSchemaTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H5AllocationSchemaTenant, 'tenantA') + !hasAnyApis(H5AllocationSchemaTenant, 'tenantB') + + when: + def staticApi = GormEnhancer.findStaticApi(H5AllocationSchemaTenant, 'tenantA') + def instanceApi = GormEnhancer.findInstanceApi(H5AllocationSchemaTenant, 'tenantA') + def validationApi = GormEnhancer.findValidationApi(H5AllocationSchemaTenant, 'tenantA') + + then: + hasAllApis(H5AllocationSchemaTenant, 'tenantA') + !hasAnyApis(H5AllocationSchemaTenant, 'tenantB') + !staticApi.is(GormEnhancer.findStaticApi(H5AllocationSchemaTenant, ConnectionSource.DEFAULT)) + instanceApi.is(GormEnhancer.findInstanceApi(H5AllocationSchemaTenant, 'tenantA')) + validationApi.is(GormEnhancer.findValidationApi(H5AllocationSchemaTenant, 'tenantA')) + } + + void "DATABASE multi tenant creates tenant APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DATABASE, ['tenantA', 'tenantB'], H5AllocationDatabaseTenant) + + expect: + hasAllApis(H5AllocationDatabaseTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H5AllocationDatabaseTenant, 'tenantA') + !hasAnyApis(H5AllocationDatabaseTenant, 'tenantB') + + when: + def staticApi = GormEnhancer.findStaticApi(H5AllocationDatabaseTenant, 'tenantA') + def instanceApi = GormEnhancer.findInstanceApi(H5AllocationDatabaseTenant, 'tenantA') + def validationApi = GormEnhancer.findValidationApi(H5AllocationDatabaseTenant, 'tenantA') + + then: + hasAllApis(H5AllocationDatabaseTenant, 'tenantA') + !hasAnyApis(H5AllocationDatabaseTenant, 'tenantB') + !staticApi.is(GormEnhancer.findStaticApi(H5AllocationDatabaseTenant, ConnectionSource.DEFAULT)) + instanceApi.is(GormEnhancer.findInstanceApi(H5AllocationDatabaseTenant, 'tenantA')) + validationApi.is(GormEnhancer.findValidationApi(H5AllocationDatabaseTenant, 'tenantA')) + } + + void "DISCRIMINATOR multi tenant explicit datasource allocates only mapped datasource APIs"() { + when: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting'], H5AllocationAnalyticsTenant) + + then: + hasAllApis(H5AllocationAnalyticsTenant, ConnectionSource.DEFAULT) + hasAllApis(H5AllocationAnalyticsTenant, 'analytics') + !hasAnyApis(H5AllocationAnalyticsTenant, 'reporting') + } + + void "DISCRIMINATOR multi tenant explicit multiple datasources allocates only mapped datasource APIs"() { + when: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting', 'audit'], H5AllocationMultipleDatasourceTenant) + + then: + hasAllApis(H5AllocationMultipleDatasourceTenant, ConnectionSource.DEFAULT) + hasAllApis(H5AllocationMultipleDatasourceTenant, 'analytics') + hasAllApis(H5AllocationMultipleDatasourceTenant, 'reporting') + !hasAnyApis(H5AllocationMultipleDatasourceTenant, 'audit') + } + + void "DISCRIMINATOR multi tenant ALL datasource creates non-default datasource APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting'], H5AllocationAllDatasourceTenant) + + expect: + hasAllApis(H5AllocationAllDatasourceTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H5AllocationAllDatasourceTenant, 'analytics') + !hasAnyApis(H5AllocationAllDatasourceTenant, 'reporting') + + when: + GormEnhancer.findStaticApi(H5AllocationAllDatasourceTenant, 'analytics') + GormEnhancer.findInstanceApi(H5AllocationAllDatasourceTenant, 'analytics') + GormEnhancer.findValidationApi(H5AllocationAllDatasourceTenant, 'analytics') + + then: + hasAllApis(H5AllocationAllDatasourceTenant, 'analytics') + !hasAnyApis(H5AllocationAllDatasourceTenant, 'reporting') + } + + private HibernateDatastore newDatastore(MultiTenancySettings.MultiTenancyMode mode, List<String> extraDataSources, Class<?>... domainClasses) { + Map config = baseConfig(mode, domainClasses[0].simpleName) + extraDataSources.each { String name -> + config["dataSources.${name}.url".toString()] = "jdbc:h2:mem:${databaseName(domainClasses[0].simpleName + name)};LOCK_TIMEOUT=10000".toString() + } + new HibernateDatastore(DatastoreUtils.createPropertyResolver(config), domainClasses) + } + + private static Map baseConfig(MultiTenancySettings.MultiTenancyMode mode, String name) { + [ + 'grails.gorm.multiTenancy.mode': mode, + 'grails.gorm.multiTenancy.tenantResolverClass': H5AllocationTenantResolver, + 'dataSource.url': "jdbc:h2:mem:${databaseName(name)};LOCK_TIMEOUT=10000".toString(), + 'dataSource.dbCreate': mode == MultiTenancySettings.MultiTenancyMode.SCHEMA ? 'update' : 'create-drop', + 'dataSource.dialect': H2Dialect.name, + 'dataSource.formatSql': 'true', + 'hibernate.flush.mode': 'COMMIT', + 'hibernate.hbm2ddl.auto': mode == MultiTenancySettings.MultiTenancyMode.SCHEMA ? 'create' : 'create-drop' + ] + } + + private static String databaseName(String name) { + "h5_${name}_${UUID.randomUUID().toString().replace('-', '')}" + } + + private static boolean hasAllApis(Class<?> type, String qualifier) { + hasStaticApi(type, qualifier) && hasInstanceApi(type, qualifier) && hasValidationApi(type, qualifier) + } + + private static boolean hasAnyApis(Class<?> type, String qualifier) { + hasStaticApi(type, qualifier) || hasInstanceApi(type, qualifier) || hasValidationApi(type, qualifier) + } + + private static boolean hasStaticApi(Class<?> type, String qualifier) { + GormEnhancer.@STATIC_APIS.get(qualifier).containsKey(type.name) + } + + private static boolean hasInstanceApi(Class<?> type, String qualifier) { + GormEnhancer.@INSTANCE_APIS.get(qualifier).containsKey(type.name) + } + + private static boolean hasValidationApi(Class<?> type, String qualifier) { + GormEnhancer.@VALIDATION_APIS.get(qualifier).containsKey(type.name) + } +} + +class H5AllocationTenantResolver extends SystemPropertyTenantResolver implements AllTenantsResolver { + + @Override + Iterable<Serializable> resolveTenantIds() { + ['tenantA', 'tenantB'] + } +} + +@Entity +class H5AllocationDefaultTenant implements GormEntity<H5AllocationDefaultTenant>, MultiTenant<H5AllocationDefaultTenant> { + Long id + Long version + String tenantId + String name +} + +@Entity +class H5AllocationSchemaTenant implements GormEntity<H5AllocationSchemaTenant>, MultiTenant<H5AllocationSchemaTenant> { + Long id + Long version + String tenantId + String name +} + +@Entity +class H5AllocationDatabaseTenant implements GormEntity<H5AllocationDatabaseTenant>, MultiTenant<H5AllocationDatabaseTenant> { + Long id + Long version + String tenantId + String name +} + +@Entity +class H5AllocationAnalyticsTenant implements GormEntity<H5AllocationAnalyticsTenant>, MultiTenant<H5AllocationAnalyticsTenant> { + Long id + Long version + String tenantId + String name + + static mapping = { + datasource 'analytics' + } +} + +@Entity +class H5AllocationMultipleDatasourceTenant implements GormEntity<H5AllocationMultipleDatasourceTenant>, MultiTenant<H5AllocationMultipleDatasourceTenant> { + Long id + Long version + String tenantId + String name + + static mapping = { + datasources(['analytics', 'reporting']) + } +} + +@Entity +class H5AllocationAllDatasourceTenant implements GormEntity<H5AllocationAllDatasourceTenant>, MultiTenant<H5AllocationAllDatasourceTenant> { + Long id + Long version + String tenantId + String name + + static mapping = { + datasource ConnectionSource.ALL + } +} diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/connections/GormApiAllocationSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/connections/GormApiAllocationSpec.groovy new file mode 100644 index 0000000000..9b53ca9322 --- /dev/null +++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/connections/GormApiAllocationSpec.groovy @@ -0,0 +1,282 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * https://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.orm.hibernate.connections + +import java.util.UUID + +import org.hibernate.dialect.H2Dialect +import spock.lang.AutoCleanup +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties + +import grails.gorm.MultiTenant +import grails.gorm.annotation.Entity +import org.grails.datastore.gorm.GormEnhancer +import org.grails.datastore.gorm.GormEntity +import org.grails.datastore.mapping.core.DatastoreUtils +import org.grails.datastore.mapping.core.connections.ConnectionSource +import org.grails.datastore.mapping.multitenancy.AllTenantsResolver +import org.grails.datastore.mapping.multitenancy.MultiTenancySettings +import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver +import org.grails.orm.hibernate.HibernateDatastore + +@RestoreSystemProperties +class GormApiAllocationSpec extends Specification { + + @AutoCleanup HibernateDatastore datastore + + void cleanup() { + System.clearProperty(SystemPropertyTenantResolver.PROPERTY_NAME) + } + + void "DISCRIMINATOR multi tenant single datasource uses only default APIs"() { + when: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, [], H7AllocationDefaultTenant) + + then: + hasAllApis(H7AllocationDefaultTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H7AllocationDefaultTenant, 'tenantA') + + when: + def result = H7AllocationDefaultTenant.withTenant('tenantA') { true } + + then: + result + !hasAnyApis(H7AllocationDefaultTenant, 'tenantA') + } + + void "DISCRIMINATOR multi tenant default datasource with multiple configured datasources creates non-default APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting'], H7AllocationDefaultTenant) + + expect: + hasAllApis(H7AllocationDefaultTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H7AllocationDefaultTenant, 'analytics') + !hasAnyApis(H7AllocationDefaultTenant, 'reporting') + + when: + def staticApi = GormEnhancer.findStaticApi(H7AllocationDefaultTenant, 'analytics') + def instanceApi = GormEnhancer.findInstanceApi(H7AllocationDefaultTenant, 'analytics') + def validationApi = GormEnhancer.findValidationApi(H7AllocationDefaultTenant, 'analytics') + + then: + hasAllApis(H7AllocationDefaultTenant, 'analytics') + !hasAnyApis(H7AllocationDefaultTenant, 'reporting') + !staticApi.is(GormEnhancer.findStaticApi(H7AllocationDefaultTenant, ConnectionSource.DEFAULT)) + instanceApi.is(GormEnhancer.findInstanceApi(H7AllocationDefaultTenant, 'analytics')) + validationApi.is(GormEnhancer.findValidationApi(H7AllocationDefaultTenant, 'analytics')) + } + + void "SCHEMA multi tenant single datasource creates tenant APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.SCHEMA, [], H7AllocationSchemaTenant) + + expect: + hasAllApis(H7AllocationSchemaTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H7AllocationSchemaTenant, 'tenantA') + !hasAnyApis(H7AllocationSchemaTenant, 'tenantB') + + when: + def staticApi = GormEnhancer.findStaticApi(H7AllocationSchemaTenant, 'tenantA') + def instanceApi = GormEnhancer.findInstanceApi(H7AllocationSchemaTenant, 'tenantA') + def validationApi = GormEnhancer.findValidationApi(H7AllocationSchemaTenant, 'tenantA') + + then: + hasAllApis(H7AllocationSchemaTenant, 'tenantA') + !hasAnyApis(H7AllocationSchemaTenant, 'tenantB') + !staticApi.is(GormEnhancer.findStaticApi(H7AllocationSchemaTenant, ConnectionSource.DEFAULT)) + instanceApi.is(GormEnhancer.findInstanceApi(H7AllocationSchemaTenant, 'tenantA')) + validationApi.is(GormEnhancer.findValidationApi(H7AllocationSchemaTenant, 'tenantA')) + } + + void "DATABASE multi tenant creates tenant APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DATABASE, ['tenantA', 'tenantB'], H7AllocationDatabaseTenant) + + expect: + hasAllApis(H7AllocationDatabaseTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H7AllocationDatabaseTenant, 'tenantA') + !hasAnyApis(H7AllocationDatabaseTenant, 'tenantB') + + when: + def staticApi = GormEnhancer.findStaticApi(H7AllocationDatabaseTenant, 'tenantA') + def instanceApi = GormEnhancer.findInstanceApi(H7AllocationDatabaseTenant, 'tenantA') + def validationApi = GormEnhancer.findValidationApi(H7AllocationDatabaseTenant, 'tenantA') + + then: + hasAllApis(H7AllocationDatabaseTenant, 'tenantA') + !hasAnyApis(H7AllocationDatabaseTenant, 'tenantB') + !staticApi.is(GormEnhancer.findStaticApi(H7AllocationDatabaseTenant, ConnectionSource.DEFAULT)) + instanceApi.is(GormEnhancer.findInstanceApi(H7AllocationDatabaseTenant, 'tenantA')) + validationApi.is(GormEnhancer.findValidationApi(H7AllocationDatabaseTenant, 'tenantA')) + } + + void "DISCRIMINATOR multi tenant explicit datasource allocates only mapped datasource APIs"() { + when: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting'], H7AllocationAnalyticsTenant) + + then: + hasAllApis(H7AllocationAnalyticsTenant, ConnectionSource.DEFAULT) + hasAllApis(H7AllocationAnalyticsTenant, 'analytics') + !hasAnyApis(H7AllocationAnalyticsTenant, 'reporting') + } + + void "DISCRIMINATOR multi tenant explicit multiple datasources allocates only mapped datasource APIs"() { + when: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting', 'audit'], H7AllocationMultipleDatasourceTenant) + + then: + hasAllApis(H7AllocationMultipleDatasourceTenant, ConnectionSource.DEFAULT) + hasAllApis(H7AllocationMultipleDatasourceTenant, 'analytics') + hasAllApis(H7AllocationMultipleDatasourceTenant, 'reporting') + !hasAnyApis(H7AllocationMultipleDatasourceTenant, 'audit') + } + + void "DISCRIMINATOR multi tenant ALL datasource creates non-default datasource APIs lazily"() { + given: + datastore = newDatastore(MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR, ['analytics', 'reporting'], H7AllocationAllDatasourceTenant) + + expect: + hasAllApis(H7AllocationAllDatasourceTenant, ConnectionSource.DEFAULT) + !hasAnyApis(H7AllocationAllDatasourceTenant, 'analytics') + !hasAnyApis(H7AllocationAllDatasourceTenant, 'reporting') + + when: + GormEnhancer.findStaticApi(H7AllocationAllDatasourceTenant, 'analytics') + GormEnhancer.findInstanceApi(H7AllocationAllDatasourceTenant, 'analytics') + GormEnhancer.findValidationApi(H7AllocationAllDatasourceTenant, 'analytics') + + then: + hasAllApis(H7AllocationAllDatasourceTenant, 'analytics') + !hasAnyApis(H7AllocationAllDatasourceTenant, 'reporting') + } + + private HibernateDatastore newDatastore(MultiTenancySettings.MultiTenancyMode mode, List<String> extraDataSources, Class<?>... domainClasses) { + Map config = baseConfig(mode, domainClasses[0].simpleName) + extraDataSources.each { String name -> + config["dataSources.${name}.url".toString()] = "jdbc:h2:mem:${databaseName(domainClasses[0].simpleName + name)};LOCK_TIMEOUT=10000".toString() + } + new HibernateDatastore(DatastoreUtils.createPropertyResolver(config), domainClasses) + } + + private static Map baseConfig(MultiTenancySettings.MultiTenancyMode mode, String name) { + [ + 'grails.gorm.multiTenancy.mode': mode, + 'grails.gorm.multiTenancy.tenantResolverClass': H7AllocationTenantResolver, + 'dataSource.url': "jdbc:h2:mem:${databaseName(name)};LOCK_TIMEOUT=10000".toString(), + 'dataSource.dbCreate': mode == MultiTenancySettings.MultiTenancyMode.SCHEMA ? 'update' : 'create-drop', + 'dataSource.dialect': H2Dialect.name, + 'dataSource.formatSql': 'true', + 'hibernate.flush.mode': 'COMMIT', + 'hibernate.hbm2ddl.auto': mode == MultiTenancySettings.MultiTenancyMode.SCHEMA ? 'create' : 'create-drop' + ] + } + + private static String databaseName(String name) { + "h7_${name}_${UUID.randomUUID().toString().replace('-', '')}" + } + + private static boolean hasAllApis(Class<?> type, String qualifier) { + hasStaticApi(type, qualifier) && hasInstanceApi(type, qualifier) && hasValidationApi(type, qualifier) + } + + private static boolean hasAnyApis(Class<?> type, String qualifier) { + hasStaticApi(type, qualifier) || hasInstanceApi(type, qualifier) || hasValidationApi(type, qualifier) + } + + private static boolean hasStaticApi(Class<?> type, String qualifier) { + GormEnhancer.@STATIC_APIS.get(qualifier).containsKey(type.name) + } + + private static boolean hasInstanceApi(Class<?> type, String qualifier) { + GormEnhancer.@INSTANCE_APIS.get(qualifier).containsKey(type.name) + } + + private static boolean hasValidationApi(Class<?> type, String qualifier) { + GormEnhancer.@VALIDATION_APIS.get(qualifier).containsKey(type.name) + } +} + +class H7AllocationTenantResolver extends SystemPropertyTenantResolver implements AllTenantsResolver { + + @Override + Iterable<Serializable> resolveTenantIds() { + ['tenantA', 'tenantB'] + } +} + +@Entity +class H7AllocationDefaultTenant implements GormEntity<H7AllocationDefaultTenant>, MultiTenant<H7AllocationDefaultTenant> { + Long id + Long version + String tenantId + String name +} + +@Entity +class H7AllocationSchemaTenant implements GormEntity<H7AllocationSchemaTenant>, MultiTenant<H7AllocationSchemaTenant> { + Long id + Long version + String tenantId + String name +} + +@Entity +class H7AllocationDatabaseTenant implements GormEntity<H7AllocationDatabaseTenant>, MultiTenant<H7AllocationDatabaseTenant> { + Long id + Long version + String tenantId + String name +} + +@Entity +class H7AllocationAnalyticsTenant implements GormEntity<H7AllocationAnalyticsTenant>, MultiTenant<H7AllocationAnalyticsTenant> { + Long id + Long version + String tenantId + String name + + static mapping = { + datasource 'analytics' + } +} + +@Entity +class H7AllocationMultipleDatasourceTenant implements GormEntity<H7AllocationMultipleDatasourceTenant>, MultiTenant<H7AllocationMultipleDatasourceTenant> { + Long id + Long version + String tenantId + String name + + static mapping = { + datasources(['analytics', 'reporting']) + } +} + +@Entity +class H7AllocationAllDatasourceTenant implements GormEntity<H7AllocationAllDatasourceTenant>, MultiTenant<H7AllocationAllDatasourceTenant> { + Long id + Long version + String tenantId + String name + + static mapping = { + datasource ConnectionSource.ALL + } +}
