From 57f887f8683c730b9c4082441a0dc846ae5e8103 Mon Sep 17 00:00:00 2001 From: Andrus Adamchik Date: Sat, 9 Dec 2023 16:19:04 -0500 Subject: [PATCH] Switching to injectable factories per bootique/bootique#345 --- .../bootique/cayenne/v42/CayenneModule.java | 154 +--------- .../cayenne/v42/ServerRuntimeFactory.java | 263 ++++++++++++++---- .../bootique/cayenne/v42/CayenneModuleIT.java | 75 +++-- .../cayenne/v42/ServerRuntimeFactoryTest.java | 142 ---------- .../src/test/resources/noconfig-named.yml | 21 ++ .../src/test/resources/noconfig.yml | 3 +- .../src/test/resources/twoconfigs.yml | 23 ++ 7 files changed, 307 insertions(+), 374 deletions(-) delete mode 100644 bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/ServerRuntimeFactoryTest.java create mode 100644 bootique-cayenne42/src/test/resources/noconfig-named.yml create mode 100644 bootique-cayenne42/src/test/resources/twoconfigs.yml diff --git a/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/CayenneModule.java b/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/CayenneModule.java index fb48486b..67a68a96 100644 --- a/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/CayenneModule.java +++ b/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/CayenneModule.java @@ -21,35 +21,12 @@ import io.bootique.BQModule; import io.bootique.ModuleCrate; -import io.bootique.cayenne.v42.annotation.CayenneConfigs; -import io.bootique.cayenne.v42.annotation.CayenneListener; -import io.bootique.cayenne.v42.commitlog.CommitLogModuleBuilder; -import io.bootique.cayenne.v42.commitlog.MappedCommitLogListener; -import io.bootique.cayenne.v42.commitlog.MappedCommitLogListenerType; -import io.bootique.cayenne.v42.syncfilter.MappedDataChannelSyncFilter; -import io.bootique.cayenne.v42.syncfilter.MappedDataChannelSyncFilterType; import io.bootique.config.ConfigurationFactory; import io.bootique.di.Binder; -import io.bootique.di.Injector; import io.bootique.di.Provides; -import io.bootique.jdbc.DataSourceFactory; -import io.bootique.shutdown.ShutdownManager; -import org.apache.cayenne.DataChannelQueryFilter; -import org.apache.cayenne.DataChannelSyncFilter; -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.access.types.ExtendedType; -import org.apache.cayenne.access.types.ValueObjectType; -import org.apache.cayenne.configuration.server.ServerModule; import org.apache.cayenne.configuration.server.ServerRuntime; -import org.apache.cayenne.di.ListBuilder; -import org.apache.cayenne.di.Module; -import org.apache.cayenne.tx.TransactionFilter; import javax.inject.Singleton; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; /** * @since 2.0 @@ -87,134 +64,7 @@ CayenneConfigMerger provideConfigMerger() { @Provides @Singleton - ServerRuntimeFactory createServerRuntimeFactory(ConfigurationFactory configFactory) { - return configFactory.config(ServerRuntimeFactory.class, CONFIG_PREFIX); - } - - @Provides - @Singleton - protected ServerRuntime createCayenneRuntime( - Injector injector, - ServerRuntimeFactory serverRuntimeFactory, - DataSourceFactory dataSourceFactory, - ShutdownManager shutdownManager, - Set customModules, - @CayenneListener Set listeners, - Set queryFilters, - Set syncFilters, - Set syncFilterTypes, - CayenneConfigMerger configMerger, - @CayenneConfigs Set injectedCayenneConfigs, - Set startupCallbacks, - Set commitLogListeners, - Set commitLogListenerTypes, - Set extendedTypes, - Set valueObjectTypes) { - - Collection extras = new ArrayList<>(customModules); - - appendExtendedTypesModule(extras, extendedTypes); - appendValueObjectTypesModule(extras, valueObjectTypes); - - appendQueryFiltersModule(extras, queryFilters); - appendSyncFiltersModule(extras, injector, syncFilters, syncFilterTypes); - appendCommitLogModules(extras, injector, commitLogListeners, commitLogListenerTypes); - - ServerRuntime runtime = serverRuntimeFactory.createCayenneRuntime( - dataSourceFactory, - configMerger, - extras, - injectedCayenneConfigs); - - shutdownManager.onShutdown(runtime, ServerRuntime::shutdown); - - // TODO: listeners should be wrapped in a CayenneModule and added to Cayenne via DI, just like filters... - if (!listeners.isEmpty()) { - DataDomain domain = runtime.getDataDomain(); - listeners.forEach(domain::addListener); - } - - startupCallbacks.forEach(c -> c.onRuntimeCreated(runtime)); - - return runtime; - } - - protected void appendExtendedTypesModule( - Collection modules, - Set types) { - - if (!types.isEmpty()) { - modules.add(b -> { - ListBuilder listBinder = ServerModule.contributeUserTypes(b); - types.forEach(listBinder::add); - }); - } - } - - protected void appendValueObjectTypesModule( - Collection modules, - Set types) { - - if (!types.isEmpty()) { - modules.add(b -> { - ListBuilder listBinder = ServerModule.contributeValueObjectTypes(b); - types.forEach(listBinder::add); - }); - } - } - - protected void appendQueryFiltersModule( - Collection modules, - Set queryFilters) { - - modules.add(b -> { - ListBuilder listBinder = ServerModule.contributeDomainQueryFilters(b); - queryFilters.forEach(listBinder::add); - }); - } - - protected void appendSyncFiltersModule( - Collection modules, - Injector injector, - Set syncFilters, - Set syncFilterTypes) { - - if (syncFilters.isEmpty() && syncFilterTypes.isEmpty()) { - return; - } - - List combined = new ArrayList<>(syncFilters.size() + syncFilterTypes.size()); - combined.addAll(syncFilters); - syncFilterTypes.stream() - .map(t -> new MappedDataChannelSyncFilter(injector.getInstance(t.getFilterType()), t.isIncludeInTransaction())) - .forEach(combined::add); - - modules.add(b -> { - ListBuilder listBinder = ServerModule.contributeDomainSyncFilters(b); - combined.forEach(mf -> { - if (mf.isIncludeInTransaction()) { - listBinder.insertBefore(mf.getFilter(), TransactionFilter.class); - } else { - listBinder.addAfter(mf.getFilter(), TransactionFilter.class); - } - }); - }); - } - - protected void appendCommitLogModules( - Collection modules, - Injector injector, - Set commitLogListeners, - Set commitLogListenerTypes) { - - if (commitLogListeners.isEmpty() && commitLogListenerTypes.isEmpty()) { - return; - } - - CommitLogModuleBuilder builder = new CommitLogModuleBuilder(); - commitLogListeners.forEach(builder::add); - commitLogListenerTypes.forEach(t -> builder.add(t.resolve(injector))); - - builder.appendModules(modules); + ServerRuntime createCayenneRuntime(ConfigurationFactory configFactory) { + return configFactory.config(ServerRuntimeFactory.class, CONFIG_PREFIX).create(); } } diff --git a/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/ServerRuntimeFactory.java b/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/ServerRuntimeFactory.java index 1f29b030..70413cf0 100644 --- a/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/ServerRuntimeFactory.java +++ b/bootique-cayenne42/src/main/java/io/bootique/cayenne/v42/ServerRuntimeFactory.java @@ -21,15 +21,32 @@ import io.bootique.annotation.BQConfig; import io.bootique.annotation.BQConfigProperty; +import io.bootique.cayenne.v42.annotation.CayenneConfigs; +import io.bootique.cayenne.v42.annotation.CayenneListener; +import io.bootique.cayenne.v42.commitlog.CommitLogModuleBuilder; +import io.bootique.cayenne.v42.commitlog.MappedCommitLogListener; +import io.bootique.cayenne.v42.commitlog.MappedCommitLogListenerType; +import io.bootique.cayenne.v42.syncfilter.MappedDataChannelSyncFilter; +import io.bootique.cayenne.v42.syncfilter.MappedDataChannelSyncFilterType; +import io.bootique.di.Injector; import io.bootique.jdbc.DataSourceFactory; +import io.bootique.shutdown.ShutdownManager; +import org.apache.cayenne.DataChannelQueryFilter; +import org.apache.cayenne.DataChannelSyncFilter; import org.apache.cayenne.access.DataDomain; import org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy; import org.apache.cayenne.access.dbsync.SchemaUpdateStrategyFactory; +import org.apache.cayenne.access.types.ExtendedType; +import org.apache.cayenne.access.types.ValueObjectType; +import org.apache.cayenne.configuration.server.ServerModule; import org.apache.cayenne.configuration.server.ServerRuntime; import org.apache.cayenne.configuration.server.ServerRuntimeBuilder; import org.apache.cayenne.di.Key; +import org.apache.cayenne.di.ListBuilder; import org.apache.cayenne.di.Module; +import org.apache.cayenne.tx.TransactionFilter; +import javax.inject.Inject; import java.util.*; @BQConfig("Configures Cayenne stack, providing injectable ServerRuntime.") @@ -37,29 +54,147 @@ public class ServerRuntimeFactory { private static final String DEFAULT_CONFIG = "cayenne-project.xml"; + private final Injector injector; + private final ShutdownManager shutdownManager; + private final DataSourceFactory dataSourceFactory; + private final CayenneConfigMerger configMerger; + private final Set injectedCayenneConfigs; + private final Set customModules; + private final Set listeners; + private final Set queryFilters; + private final Set syncFilters; + private final Set syncFilterTypes; + private final Set startupCallbacks; + private final Set commitLogListeners; + private final Set commitLogListenerTypes; + private final Set extendedTypes; + private final Set valueObjectTypes; + private String name; private Collection configs; private Map maps; private String datasource; private boolean createSchema; - public ServerRuntimeFactory() { - this.configs = new ArrayList<>(); - this.maps = new HashMap<>(); - } - - public ServerRuntime createCayenneRuntime( + @Inject + public ServerRuntimeFactory( + Injector injector, + ShutdownManager shutdownManager, DataSourceFactory dataSourceFactory, CayenneConfigMerger configMerger, - Collection extraModules, - Collection extraConfigs) { + @CayenneConfigs Set injectedCayenneConfigs, + Set customModules, + @CayenneListener Set listeners, + Set queryFilters, + Set syncFilters, + Set syncFilterTypes, + Set startupCallbacks, + Set commitLogListeners, + Set commitLogListenerTypes, + Set extendedTypes, + Set valueObjectTypes) { + + this.injector = injector; + + this.shutdownManager = shutdownManager; + this.dataSourceFactory = dataSourceFactory; + this.configMerger = configMerger; + this.injectedCayenneConfigs = injectedCayenneConfigs; + this.customModules = customModules; + this.listeners = listeners; + this.queryFilters = queryFilters; + this.syncFilters = syncFilters; + this.syncFilterTypes = syncFilterTypes; + this.startupCallbacks = startupCallbacks; + this.commitLogListeners = commitLogListeners; + this.commitLogListenerTypes = commitLogListenerTypes; + this.extendedTypes = extendedTypes; + this.valueObjectTypes = valueObjectTypes; + } + + /** + * Sets an optional collection of Cayenne projects to load in runtime. If missing, will try to locate a file + * 'cayenne-project.xml' on classpath. + * + * @param configs a collection of Cayenne config XML files. + */ + @BQConfigProperty("An optional collection of Cayenne projects to load in runtime. If missing, will try to locate a " + + "file 'cayenne-project.xml' on classpath.") + public void setConfigs(Collection configs) { + this.configs = configs; + } + + /** + * Sets a map of DataMaps that are included in the app runtime without an explicit refrence in 'cayenne-project.xml'. + * + * @param maps map of DataMap configs + */ + @BQConfigProperty("A list of DataMaps that are included in the app runtime without an explicit refrence in " + + "'cayenne-project.xml'.") + public void setMaps(Map maps) { + this.maps = maps; + } + + /** + * Sets an optional name of the Cayenne stack we are created. This will be the name assigned to Cayenne DataDomain and + * used in event dispatches, etc. + * + * @param name a name of Cayenne stack created by the factory. + */ + @BQConfigProperty("An optional name of the Cayenne stack we are created. This will be the name assigned to Cayenne" + + " DataDomain and used in event dispatches, etc.") + public void setName(String name) { + this.name = name; + } + + @BQConfigProperty("An optional name of the DataSource to use in Cayenne. A DataSource with the matching name " + + "must be defined in 'bootique-jdbc' configuration. If missing, a DataSource from Cayenne project or a " + + "default DataSource from 'bootique-jdbc' is used.") + public void setDatasource(String datasource) { + this.datasource = datasource; + } + + /** + * Sets a flag that defines whether to attempt creation of the DB schema on startup based on Cayenne mapping. The + * default is 'false'. Automatic schema creation is often used in unit tests. + * + * @param createSchema if true, Cayenne will attempt to create database schema if it is missing. + */ + @BQConfigProperty("Whether to attempt creation of the DB schema on startup based on Cayenne mapping. The default is " + + "'false'. Automatic schema creation is often used in unit tests.") + public void setCreateSchema(boolean createSchema) { + this.createSchema = createSchema; + } + + public ServerRuntime create() { Collection factoryConfigs = configs(); - return cayenneBuilder(dataSourceFactory) - .addConfigs(configMerger.merge(factoryConfigs, extraConfigs)) - .addModules(extraModules) + Collection extras = new ArrayList<>(customModules); + + appendExtendedTypesModule(extras, extendedTypes); + appendValueObjectTypesModule(extras, valueObjectTypes); + + appendQueryFiltersModule(extras, queryFilters); + appendSyncFiltersModule(extras, injector, syncFilters, syncFilterTypes); + appendCommitLogModules(extras, injector, commitLogListeners, commitLogListenerTypes); + + ServerRuntime runtime = cayenneBuilder(dataSourceFactory) + .addConfigs(configMerger.merge(factoryConfigs, injectedCayenneConfigs)) + .addModules(extras) .build(); + + shutdownManager.onShutdown(runtime, ServerRuntime::shutdown); + + // TODO: listeners should be wrapped in a CayenneModule and added to Cayenne via DI, just like filters... + if (!listeners.isEmpty()) { + DataDomain domain = runtime.getDataDomain(); + listeners.forEach(domain::addListener); + } + + startupCallbacks.forEach(c -> c.onRuntimeCreated(runtime)); + + return runtime; } /** @@ -82,7 +217,7 @@ protected Module factoryModule(DataSourceFactory dataSourceFactory) { DefaultDataSourceName defaultDataSourceName = defaultDataSourceName(dataSourceFactory); binder.bind(Key.get(DefaultDataSourceName.class)).toInstance(defaultDataSourceName); - binder.bindMap(DataMapConfig.class).putAll(maps); + binder.bindMap(DataMapConfig.class).putAll(maps != null ? maps : Map.of()); // provide default DataNode // TODO: copied from Cayenne, as the corresponding provider is not public or rather @@ -134,57 +269,73 @@ DefaultDataSourceName defaultDataSourceName(DataSourceFactory dataSourceFactory) return new DefaultDataSourceName(null); } - /** - * Sets an optional collection of Cayenne projects to load in runtime. If missing, will try to locate a file - * 'cayenne-project.xml' on classpath. - * - * @param configs a collection of Cayenne config XML files. - */ - @BQConfigProperty("An optional collection of Cayenne projects to load in runtime. If missing, will try to locate a " + - "file 'cayenne-project.xml' on classpath.") - public void setConfigs(Collection configs) { - this.configs = configs; + protected void appendExtendedTypesModule(Collection modules, Set types) { + if (!types.isEmpty()) { + modules.add(b -> { + ListBuilder listBinder = ServerModule.contributeUserTypes(b); + types.forEach(listBinder::add); + }); + } } - /** - * Sets a map of DataMaps that are included in the app runtime without an explicit refrence in 'cayenne-project.xml'. - * - * @param maps map of DataMap configs - */ - @BQConfigProperty("A list of DataMaps that are included in the app runtime without an explicit refrence in " + - "'cayenne-project.xml'.") - public void setMaps(Map maps) { - this.maps = maps; + protected void appendValueObjectTypesModule(Collection modules, Set types) { + if (!types.isEmpty()) { + modules.add(b -> { + ListBuilder listBinder = ServerModule.contributeValueObjectTypes(b); + types.forEach(listBinder::add); + }); + } } - /** - * Sets an optional name of the Cayenne stack we are created. This will be the name assigned to Cayenne DataDomain and - * used in event dispatches, etc. - * - * @param name a name of Cayenne stack created by the factory. - */ - @BQConfigProperty("An optional name of the Cayenne stack we are created. This will be the name assigned to Cayenne" + - " DataDomain and used in event dispatches, etc.") - public void setName(String name) { - this.name = name; + protected void appendQueryFiltersModule(Collection modules, Set queryFilters) { + modules.add(b -> { + ListBuilder listBinder = ServerModule.contributeDomainQueryFilters(b); + queryFilters.forEach(listBinder::add); + }); } - @BQConfigProperty("An optional name of the DataSource to use in Cayenne. A DataSource with the matching name " + - "must be defined in 'bootique-jdbc' configuration. If missing, a DataSource from Cayenne project or a " + - "default DataSource from 'bootique-jdbc' is used.") - public void setDatasource(String datasource) { - this.datasource = datasource; + protected void appendSyncFiltersModule( + Collection modules, + Injector injector, + Set syncFilters, + Set syncFilterTypes) { + + if (syncFilters.isEmpty() && syncFilterTypes.isEmpty()) { + return; + } + + List combined = new ArrayList<>(syncFilters.size() + syncFilterTypes.size()); + combined.addAll(syncFilters); + syncFilterTypes.stream() + .map(t -> new MappedDataChannelSyncFilter(injector.getInstance(t.getFilterType()), t.isIncludeInTransaction())) + .forEach(combined::add); + + modules.add(b -> { + ListBuilder listBinder = ServerModule.contributeDomainSyncFilters(b); + combined.forEach(mf -> { + if (mf.isIncludeInTransaction()) { + listBinder.insertBefore(mf.getFilter(), TransactionFilter.class); + } else { + listBinder.addAfter(mf.getFilter(), TransactionFilter.class); + } + }); + }); } - /** - * Sets a flag that defines whether to attempt creation of the DB schema on startup based on Cayenne mapping. The - * default is 'false'. Automatic schema creation is often used in unit tests. - * - * @param createSchema if true, Cayenne will attempt to create database schema if it is missing. - */ - @BQConfigProperty("Whether to attempt creation of the DB schema on startup based on Cayenne mapping. The default is " + - "'false'. Automatic schema creation is often used in unit tests.") - public void setCreateSchema(boolean createSchema) { - this.createSchema = createSchema; + protected void appendCommitLogModules( + Collection modules, + Injector injector, + Set commitLogListeners, + Set commitLogListenerTypes) { + + if (commitLogListeners.isEmpty() && commitLogListenerTypes.isEmpty()) { + return; + } + + CommitLogModuleBuilder builder = new CommitLogModuleBuilder(); + commitLogListeners.forEach(builder::add); + commitLogListenerTypes.forEach(t -> builder.add(t.resolve(injector))); + + builder.appendModules(modules); } } diff --git a/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/CayenneModuleIT.java b/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/CayenneModuleIT.java index 3a561f00..1b7c5d6c 100644 --- a/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/CayenneModuleIT.java +++ b/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/CayenneModuleIT.java @@ -42,15 +42,57 @@ public class CayenneModuleIT { @BQTestTool final BQTestFactory testFactory = new BQTestFactory(); + @Test + public void noConfig() { + + ServerRuntime runtime = testFactory.app("-c", "classpath:noconfig.yml") + .autoLoadModules() + .createRuntime() + .getInstance(ServerRuntime.class); + + DataDomain domain = runtime.getDataDomain(); + assertEquals("cayenne", domain.getName()); + assertEquals("cayenne", domain.getDefaultNode().getName()); + + assertTrue(domain.getEntityResolver().getDbEntities().isEmpty()); + } + + @Test + public void noConfig_Name() { + + ServerRuntime runtime = testFactory.app("-c", "classpath:noconfig-named.yml") + .autoLoadModules() + .createRuntime() + .getInstance(ServerRuntime.class); + + DataDomain domain = runtime.getDataDomain(); + assertEquals("my", domain.getName()); + assertEquals("my", domain.getDefaultNode().getName()); + } + @Test public void fullConfig() { + ServerRuntime runtime = testFactory.app("-c", "classpath:fullconfig.yml") + .autoLoadModules() + .createRuntime() + .getInstance(ServerRuntime.class); + + DataDomain domain = runtime.getDataDomain(); + assertNotNull(domain.getEntityResolver().getDbEntity("db_entity2")); - ServerRuntime runtime = testFactory.app("--config=classpath:fullconfig.yml") + // trigger a DB op + SQLSelect.dataRowQuery("SELECT * FROM db_entity2").select(runtime.newContext()); + } + + @Test + public void twoConfigs() { + ServerRuntime runtime = testFactory.app("-c", "classpath:twoconfigs.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); DataDomain domain = runtime.getDataDomain(); + assertNotNull(domain.getEntityResolver().getDbEntity("db_entity")); assertNotNull(domain.getEntityResolver().getDbEntity("db_entity2")); // trigger a DB op @@ -60,7 +102,7 @@ public void fullConfig() { @Test public void config_ExplicitMaps_SharedDataSource() { - ServerRuntime runtime = testFactory.app("--config=classpath:config_explicit_maps.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:config_explicit_maps.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); @@ -77,7 +119,7 @@ public void config_ExplicitMaps_SharedDataSource() { @Test public void config_ExplicitMaps_DifferentDataSources() { - ServerRuntime runtime = testFactory.app("--config=classpath:config_explicit_maps_2.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:config_explicit_maps_2.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); @@ -94,7 +136,7 @@ public void config_ExplicitMaps_DifferentDataSources() { @Test public void defaultDataSource() throws SQLException { - ServerRuntime runtime = testFactory.app("--config=classpath:noconfig.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:noconfig.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); @@ -111,7 +153,7 @@ public void defaultDataSource() throws SQLException { @Test public void undefinedDataSource() { - ServerRuntime runtime = testFactory.app("--config=classpath:noconfig_2ds.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:noconfig_2ds.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); @@ -127,7 +169,7 @@ public void undefinedDataSource() { @Test public void unmatchedDataSource() { - ServerRuntime runtime = testFactory.app("--config=classpath:noconfig_2ds_unmatched.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:noconfig_2ds_unmatched.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); @@ -141,18 +183,6 @@ public void unmatchedDataSource() { } } - @Test - public void noConfig() { - - ServerRuntime runtime = testFactory.app("--config=classpath:noconfig.yml") - .autoLoadModules() - .createRuntime() - .getInstance(ServerRuntime.class); - - DataDomain domain = runtime.getDataDomain(); - assertTrue(domain.getEntityResolver().getDbEntities().isEmpty()); - } - @Test public void contributeModules() { @@ -164,7 +194,7 @@ public void contributeModules() { CayenneModule.extend(b).addModule(cayenneModule); }; - ServerRuntime runtime = testFactory.app("--config=classpath:fullconfig.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:fullconfig.yml") .autoLoadModules() .module(bqModule) .createRuntime() @@ -178,7 +208,7 @@ public void mergeConfigs() { BQModule cayenneProjectModule = binder -> CayenneModule.extend(binder).addProject("cayenne-project2.xml"); - ServerRuntime runtime = testFactory.app("--config=classpath:noconfig.yml") + ServerRuntime runtime = testFactory.app("-c", "classpath:noconfig.yml") .autoLoadModules() .module(cayenneProjectModule) .createRuntime() @@ -220,8 +250,9 @@ public void configMaps_Plus_AddProject_DataSourceAssignment() { @Test public void config_ExplicitMaps_DifferentConfig() { - ServerRuntime runtime = testFactory.app("--config=classpath:config_explicit_maps_2_1.yml" - , "--config=classpath:config_explicit_maps_2_2.yml") + ServerRuntime runtime = testFactory.app( + "-c", "classpath:config_explicit_maps_2_1.yml", + "-c", "classpath:config_explicit_maps_2_2.yml") .autoLoadModules() .createRuntime() .getInstance(ServerRuntime.class); diff --git a/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/ServerRuntimeFactoryTest.java b/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/ServerRuntimeFactoryTest.java deleted file mode 100644 index e7da82c6..00000000 --- a/bootique-cayenne42/src/test/java/io/bootique/cayenne/v42/ServerRuntimeFactoryTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Licensed to ObjectStyle LLC under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ObjectStyle LLC 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 - * - * 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.bootique.cayenne.v42; - -import io.bootique.cayenne.v42.CayenneConfigMerger; -import io.bootique.cayenne.v42.ServerRuntimeFactory; -import io.bootique.jdbc.DataSourceFactory; -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.configuration.server.ServerRuntime; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import javax.sql.DataSource; -import java.util.Collections; - -import static java.util.Arrays.asList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ServerRuntimeFactoryTest { - - private DataSourceFactory mockDSFactory; - private CayenneConfigMerger configMerger; - - @BeforeEach - public void before() { - this.mockDSFactory = mock(DataSourceFactory.class); - when(mockDSFactory.forName(anyString())).thenReturn(mock(DataSource.class)); - - this.configMerger = new CayenneConfigMerger(); - } - - @Test - public void createCayenneRuntime_NoName() { - ServerRuntimeFactory factory = new ServerRuntimeFactory(); - factory.setDatasource("ds1"); - - ServerRuntime runtime = factory.createCayenneRuntime( - mockDSFactory, - configMerger, - Collections.emptyList(), - Collections.emptyList()); - try { - DataDomain domain = runtime.getDataDomain(); - assertEquals("cayenne", domain.getName()); - - assertEquals(1, domain.getDataNodes().size()); - assertNotNull(domain.getDefaultNode()); - assertEquals("cayenne", domain.getDefaultNode().getName()); - - } finally { - runtime.shutdown(); - } - } - - @Test - public void createCayenneRuntime_Name() { - ServerRuntimeFactory factory = new ServerRuntimeFactory(); - factory.setConfigs(asList("cayenne-project1.xml")); - factory.setDatasource("ds1"); - factory.setName("me"); - - ServerRuntime runtime = factory.createCayenneRuntime( - mockDSFactory, - configMerger, - Collections.emptyList(), - Collections.emptyList()); - try { - - DataDomain domain = runtime.getDataDomain(); - assertEquals("me", domain.getName()); - - assertEquals(1, domain.getDataNodes().size()); - assertNotNull(domain.getDefaultNode()); - assertEquals("me", domain.getDefaultNode().getName()); - - } finally { - runtime.shutdown(); - } - } - - @Test - public void createCayenneRuntime_Configs() { - ServerRuntimeFactory factory = new ServerRuntimeFactory(); - factory.setDatasource("ds1"); - factory.setConfigs(asList("cayenne-project2.xml", "cayenne-project1.xml")); - - ServerRuntime runtime = factory.createCayenneRuntime( - mockDSFactory, - configMerger, - Collections.emptyList(), - Collections.emptyList()); - try { - - DataDomain domain = runtime.getDataDomain(); - assertNotNull(domain.getEntityResolver().getDbEntity("db_entity")); - assertNotNull(domain.getEntityResolver().getDbEntity("db_entity2")); - - } finally { - runtime.shutdown(); - } - } - - @Test - public void createCayenneRuntime_NoConfig() { - ServerRuntimeFactory factory = new ServerRuntimeFactory(); - factory.setDatasource("ds1"); - - ServerRuntime runtime = factory.createCayenneRuntime( - mockDSFactory, - configMerger, - Collections.emptyList(), - Collections.emptyList()); - try { - - DataDomain domain = runtime.getDataDomain(); - assertTrue(domain.getEntityResolver().getDbEntities().isEmpty()); - - } finally { - runtime.shutdown(); - } - } -} diff --git a/bootique-cayenne42/src/test/resources/noconfig-named.yml b/bootique-cayenne42/src/test/resources/noconfig-named.yml new file mode 100644 index 00000000..113fe56e --- /dev/null +++ b/bootique-cayenne42/src/test/resources/noconfig-named.yml @@ -0,0 +1,21 @@ +# Licensed to ObjectStyle LLC under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ObjectStyle LLC 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 +# +# 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. + +jdbc: + ds: + jdbcUrl: jdbc:derby:target/derby/bqjdbc_noconfig;create=true + +cayenne: + name: my diff --git a/bootique-cayenne42/src/test/resources/noconfig.yml b/bootique-cayenne42/src/test/resources/noconfig.yml index 1b82827a..fc3658c7 100644 --- a/bootique-cayenne42/src/test/resources/noconfig.yml +++ b/bootique-cayenne42/src/test/resources/noconfig.yml @@ -17,5 +17,4 @@ jdbc: ds: jdbcUrl: jdbc:derby:target/derby/bqjdbc_noconfig;create=true -cayenne: - createSchema: true +cayenne: {} diff --git a/bootique-cayenne42/src/test/resources/twoconfigs.yml b/bootique-cayenne42/src/test/resources/twoconfigs.yml new file mode 100644 index 00000000..dbf892b9 --- /dev/null +++ b/bootique-cayenne42/src/test/resources/twoconfigs.yml @@ -0,0 +1,23 @@ +# Licensed to ObjectStyle LLC under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ObjectStyle LLC 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 +# +# 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. + +jdbc: + ds: + jdbcUrl: jdbc:derby:target/derby/bqjdbc_fullconfig;create=true + +cayenne: + configs: + - cayenne-project1.xml + - cayenne-project2.xml