Merge remote-tracking branch 'upstream/master'

# Conflicts:
#	ebean-bom/pom.xml
#	tests/test-kotlin/pom.xml
This commit is contained in:
Roland Praml
2022-05-02 16:15:18 +02:00
30 changed files with 475 additions and 1849 deletions
+30 -1
View File
@@ -55,9 +55,38 @@ Post questions or issues to the Ebean google group - https://groups.google.com/f
## Documentation
Goto [https://ebean.io/docs/](https://ebean.io/docs/)
## Maven central
[Maven central - io.ebean](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22io.ebean%22%20)
## Building Ebean from source
- JDK 11 or higher installed
- Maven installed
- `git clone git@github.com:ebean-orm/ebean.git`
- `mvn clean install`
Ebean 13 uses Java modules with module-info. This means that there are stricter compilation
rules in place now than when building with classpath pre version 13.
For Maven Surefire testing we use `<surefire.useModulePath>false</surefire.useModulePath>` such
that tests run using classpath and not module-path. We are doing this until all the tooling
(Maven, IDE) improves in the area of testing with module-info.
#### Eclipse IDE
Right now we can't use Eclipse IDE to build Ebean and run its tests due to its poor support
for java modules. See [ebean/issues/2653](https://github.com/ebean-orm/ebean/issues/2653)
The current recommendation is to use IntelliJ IDEA as the IDE to build and hack Ebean.
#### IntelliJ IDEA
We want to get IntelliJ to run tests using classpath similar to Maven Surefire. To do this set:
`JUnit -> modify options -> Do not use module-path option`
To set this option as the global default for IntelliJ use:
`Run - Edit Configurations -> Edit configuration templates -> JUnit -> modify options - Do not use module-path option`
File diff suppressed because it is too large Load Diff
@@ -1,15 +0,0 @@
package io.ebean;
/**
* Deprecated - please migrate to <code>io.ebean.Database</code>.
* Provides the API for fetching and saving beans to a particular Database.
* <p>
* Effectively this is an alias for {@link Database} which is now the new
* and improved name for EbeanServer.
* <p>
* The preference is to use DB and Database rather than Ebean and EbeanServer.
*/
@Deprecated
public interface EbeanServer extends Database {
}
@@ -1,70 +0,0 @@
package io.ebean;
import io.ebean.config.ContainerConfig;
import io.ebean.config.ServerConfig;
/**
* Deprecated - please migrate to DatabaseFactory.
* <p>
* Creates EbeanServer instances.
* <p>
* This uses either a ServerConfig or properties in the ebean.properties file to
* configure and create a EbeanServer instance.
* </p>
* <p>
* The EbeanServer instance can either be registered with the Ebean singleton or
* not. The Ebean singleton effectively holds a map of EbeanServers by a name.
* If the EbeanServer is registered with the Ebean singleton you can retrieve it
* later via {@link Ebean#getServer(String)}.
* </p>
* <p>
* One EbeanServer can be nominated as the 'default/primary' EbeanServer. Many
* methods on the Ebean singleton such as {@link Ebean#find(Class)} are just a
* convenient way of using the 'default/primary' EbeanServer.
* </p>
*/
@Deprecated
public class EbeanServerFactory {
/**
* Initialise the container with clustering configuration.
* <p>
* Call this prior to creating any EbeanServer instances or alternatively set the
* ContainerConfig on the ServerConfig when creating the first EbeanServer instance.
*/
public static void initialiseContainer(ContainerConfig containerConfig) {
DatabaseFactory.initialiseContainer(containerConfig);
}
/**
* Create using ebean.properties to configure the database.
*/
public static EbeanServer create(String name) {
return (EbeanServer)DatabaseFactory.create(name);
}
/**
* Create using the ServerConfig object to configure the database.
*/
public static EbeanServer create(ServerConfig config) {
return (EbeanServer)DatabaseFactory.create(config);
}
/**
* Create using the ServerConfig additionally specifying a classLoader to use as the context class loader.
*/
public static EbeanServer createWithContextClassLoader(ServerConfig config, ClassLoader classLoader) {
return (EbeanServer)DatabaseFactory.createWithContextClassLoader(config, classLoader);
}
/**
* Shutdown gracefully all EbeanServers cleaning up any resources as required.
* <p>
* This is typically invoked via JVM shutdown hook and not explicitly called.
* </p>
*/
public static void shutdown() {
DatabaseFactory.shutdown();
}
}
@@ -1,47 +0,0 @@
package io.ebean.config;
import io.ebean.DatabaseFactory;
/**
* Deprecated - please migrate to <code>io.ebean.DatabaseConfig</code>.
*
* The configuration used for creating a Database.
* <p>
* Used to programmatically construct a Database and optionally register it
* with the DB singleton.
* </p>
* <p>
* If you just use DB without this programmatic configuration DB will read
* the application.properties file and take the configuration from there. This usually
* includes searching the class path and automatically registering any entity
* classes and listeners etc.
* </p>
* <pre>{@code
*
* ServerConfig config = new ServerConfig();
*
* // read the ebean.properties and load
* // those settings into this serverConfig object
* config.loadFromProperties();
*
* // explicitly register the entity beans to avoid classpath scanning
* config.addClass(Customer.class);
* config.addClass(User.class);
*
* Database database = DatabaseFactory.create(config);
*
* }</pre>
*
* <p>
* Note that ServerConfigProvider provides a standard Java ServiceLoader mechanism that can
* be used to apply configuration to the ServerConfig.
* </p>
*
* @author emcgreal
* @author rbygrave
* @see DatabaseFactory
*/
@Deprecated
public class ServerConfig extends DatabaseConfig {
}
@@ -1,41 +0,0 @@
package io.ebean.config;
/**
* Deprecated - migrate to DatabaseConfigProvider.
* <p>
* Provides a ServiceLoader based mechanism to configure a ServerConfig.
* <p>
* Provide an implementation and register it via the standard Java ServiceLoader mechanism
* via a file at <code>META-INF/services/io.ebean.config.ServerConfigProvider</code>.
* <p>
* If you are using a DI container like Spring or Guice you are unlikely to use this but instead use a
* spring specific configuration. When we are not using a DI container we may use this mechanism to
* explicitly register the entity beans and avoid classpath scanning.
* </p>
* <pre>{@code
*
* public class EbeanConfigProvider implements ServerConfigProvider {
*
* @Override
* public void apply(ServerConfig config) {
*
* // register the entity bean classes explicitly
* config.addClass(Customer.class);
* config.addClass(User.class);
* ...
* }
* }
*
* }</pre>
*/
@Deprecated
public interface ServerConfigProvider {
/**
* Apply the configuration to the ServerConfig.
* <p>
* Typically we explicitly register entity bean classes and thus avoid classpath scanning.
* </p>
*/
void apply(ServerConfig config);
}
@@ -23,7 +23,7 @@ import java.util.stream.Stream;
/**
* Service Provider extension to EbeanServer.
*/
public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer, BeanCollectionLoader {
public interface SpiEbeanServer extends SpiServer, ExtendedServer, BeanCollectionLoader {
/**
* Return true if the L2 cache has been disabled.
@@ -55,7 +55,6 @@ public interface SpiEbeanServer extends SpiServer, ExtendedServer, EbeanServer,
* <p>
* Typically used to identify the origin of queries for AutoTune and object
* graph costing.
* </p>
*/
CallOrigin createCallOrigin();
@@ -13,6 +13,8 @@ import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
/**
* The default cache implementation.
@@ -43,10 +45,13 @@ public class DefaultServerCache implements ServerCache {
protected final String name;
protected final String shortName;
private final int maxSize;
private final int trimFrequency;
private final int maxIdleSecs;
private final int maxSecsToLive;
protected final int maxSize;
protected final int trimFrequency;
protected final int maxIdleSecs;
protected final int maxSecsToLive;
protected final long trimOnPut;
protected final ReentrantLock lock = new ReentrantLock();
protected final AtomicLong mutationCounter = new AtomicLong();
public DefaultServerCache(DefaultServerCacheConfig config) {
this.name = config.getName();
@@ -56,6 +61,7 @@ public class DefaultServerCache implements ServerCache {
this.maxIdleSecs = config.getMaxIdleSecs();
this.maxSecsToLive = config.getMaxSecsToLive();
this.trimFrequency = config.determineTrimFrequency();
this.trimOnPut = config.determineTrimOnPut();
MetricFactory factory = MetricFactory.get();
String prefix = "l2n.";
@@ -187,6 +193,9 @@ public class DefaultServerCache implements ServerCache {
public void put(Object key, Object value) {
map.put(key, new SoftReference<>(new CacheEntry(key, value)));
putCount.increment();
if (mutationCounter.incrementAndGet() > trimOnPut) {
runEviction();
}
}
/**
@@ -222,62 +231,72 @@ public class DefaultServerCache implements ServerCache {
* Run the eviction based on Idle time, Time to live and LRU last access.
*/
public void runEviction() {
long trimForMaxSize;
if (maxSize == 0) {
trimForMaxSize = 0;
} else {
trimForMaxSize = size() - maxSize;
}
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
// nothing to trim on this cache
return;
}
long startNanos = System.nanoTime();
long trimmedByIdle = 0;
long trimmedByGC = 0;
long trimmedByTTL = 0;
long trimmedByLRU = 0;
List<CacheEntry> activeList = new ArrayList<>(map.size());
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
while (it.hasNext()) {
SoftReference<CacheEntry> ref = it.next();
final CacheEntry cacheEntry = ref.get();
if (cacheEntry == null) {
it.remove();
trimmedByGC++;
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
it.remove();
trimmedByIdle++;
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
it.remove();
trimmedByTTL++;
} else if (trimForMaxSize > 0) {
activeList.add(cacheEntry);
lock.lock();
try {
long trimForMaxSize;
if (maxSize == 0) {
trimForMaxSize = 0;
} else {
trimForMaxSize = size() - maxSize;
}
}
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
// sort into last access time ascending
activeList.sort(BY_LAST_ACCESS);
int trimSize = getTrimSize();
for (int i = trimSize; i < activeList.size(); i++) {
// remove if still in the cache
if (map.remove(activeList.get(i).getKey()) != null) {
trimmedByLRU++;
if (maxIdleSecs == 0 && maxSecsToLive == 0 && trimForMaxSize < 0) {
// nothing to trim on this cache
mutationCounter.set(0);
return;
}
long startNanos = System.nanoTime();
long trimmedByIdle = 0;
long trimmedByGC = 0;
long trimmedByTTL = 0;
long trimmedByLRU = 0;
try {
List<CacheEntry> activeList = new ArrayList<>(map.size());
long idleExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxIdleSecs);
long ttlExpireNano = startNanos - TimeUnit.SECONDS.toNanos(maxSecsToLive);
Iterator<SoftReference<CacheEntry>> it = map.values().iterator();
while (it.hasNext()) {
SoftReference<CacheEntry> ref = it.next();
final CacheEntry cacheEntry = ref.get();
if (cacheEntry == null) {
it.remove();
trimmedByGC++;
} else if (maxIdleSecs > 0 && idleExpireNano > cacheEntry.getLastAccessTime()) {
it.remove();
trimmedByIdle++;
} else if (maxSecsToLive > 0 && ttlExpireNano > cacheEntry.getCreateTime()) {
it.remove();
trimmedByTTL++;
} else if (trimForMaxSize > 0) {
activeList.add(cacheEntry.forSort());
}
}
if (trimForMaxSize > 0 && activeList.size() > maxSize) {
// sort into last access time ascending
activeList.sort(BY_LAST_ACCESS);
int trimSize = getTrimSize();
for (int i = trimSize; i < activeList.size(); i++) {
// remove if still in the cache
if (map.remove(activeList.get(i).getKey()) != null) {
trimmedByLRU++;
}
}
}
mutationCounter.set(0);
evictCount.add(trimmedByIdle);
evictCount.add(trimmedByGC);
evictCount.add(trimmedByTTL);
evictCount.add(trimmedByLRU);
if (logger.isTraceEnabled()) {
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
}
} catch (Throwable e) {
logger.warn("Error during trim of DefaultServerCache [" + name + "]. Cache might be bigger than desired.", e);
}
}
evictCount.add(trimmedByIdle);
evictCount.add(trimmedByGC);
evictCount.add(trimmedByTTL);
evictCount.add(trimmedByLRU);
if (logger.isTraceEnabled()) {
long exeMicros = TimeUnit.MICROSECONDS.convert(System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
logger.trace("Executed trim of cache {} in [{}]millis idle[{}] timeToLive[{}] accessTime[{}] gc[{}]",
name, exeMicros, trimmedByIdle, trimmedByTTL, trimmedByLRU, trimmedByGC);
} finally {
lock.unlock();
}
}
@@ -293,7 +312,7 @@ public class DefaultServerCache implements ServerCache {
}
/**
* Comparator for sorting by last access time.
* Comparator for sorting by last access sort, a copy of last access time that should not mutate during trim processing.
*/
public static final class CompareByLastAccess implements Comparator<CacheEntry>, Serializable {
@@ -301,7 +320,7 @@ public class DefaultServerCache implements ServerCache {
@Override
public int compare(CacheEntry e1, CacheEntry e2) {
return Long.compare(e1.getLastAccessTime(), e2.getLastAccessTime());
return Long.compare(e1.lastAccessSort, e2.lastAccessSort);
}
}
@@ -314,6 +333,7 @@ public class DefaultServerCache implements ServerCache {
private final Object value;
private final long createTime;
private long lastAccessTime;
private long lastAccessSort;
public CacheEntry(Object key, Object value) {
this.key = key;
@@ -322,6 +342,14 @@ public class DefaultServerCache implements ServerCache {
this.lastAccessTime = createTime;
}
/**
* Store a copy of lastAccessTime used for sorting. This value should not change during trim processing.
*/
public CacheEntry forSort() {
this.lastAccessSort = lastAccessTime;
return this;
}
/**
* Return the entry key.
*/
@@ -76,4 +76,14 @@ public final class DefaultServerCacheConfig {
}
return 0;
}
/**
* Determine the number of mutations/puts required to trigger a runEviction() in the foreground.
*/
public long determineTrimOnPut() {
if (maxSize > 0) {
return maxSize / 10;
}
return 1000;
}
}
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.cluster;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.config.ContainerConfig;
import io.ebeaninternal.server.transaction.RemoteTransactionEvent;
import org.slf4j.Logger;
@@ -20,7 +20,7 @@ public class ClusterManager implements ServerLookup {
private final ReentrantLock lock = new ReentrantLock();
private final ConcurrentHashMap<String, EbeanServer> serverMap = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Database> serverMap = new ConcurrentHashMap<>();
private final Object monitor = new Object();
@@ -53,7 +53,7 @@ public class ClusterManager implements ServerLookup {
return factory;
}
public void registerServer(EbeanServer server) {
public void registerServer(Database server) {
lock.lock();
try {
serverMap.put(server.name(), server);
@@ -66,7 +66,7 @@ public class ClusterManager implements ServerLookup {
}
@Override
public EbeanServer getServer(String name) {
public Database getServer(String name) {
lock.lock();
try {
return serverMap.get(name);
@@ -1,14 +1,14 @@
package io.ebeaninternal.server.cluster;
import io.ebean.EbeanServer;
import io.ebean.Database;
/**
* Returns EbeanServer instances for remote message reading.
* Returns Database instances for remote message reading.
*/
public interface ServerLookup {
/**
* Return the EbeanServer instance by name.
*/
EbeanServer getServer(String name);
Database getServer(String name);
}
@@ -5,8 +5,6 @@ import io.ebean.config.ContainerConfig;
import io.ebean.config.DatabaseConfig;
import io.ebean.config.DatabaseConfigProvider;
import io.ebean.config.ModuleInfoLoader;
import io.ebean.config.ServerConfig;
import io.ebean.config.ServerConfigProvider;
import io.ebean.config.TenantMode;
import io.ebean.config.UnderscoreNamingConvention;
import io.ebean.config.dbplatform.DatabasePlatform;
@@ -128,15 +126,8 @@ public final class DefaultContainer implements SpiContainer {
private void applyConfigServices(DatabaseConfig config) {
if (config.isDefaultServer()) {
boolean appliedConfig = false;
for (DatabaseConfigProvider configProvider : ServiceLoader.load(DatabaseConfigProvider.class)) {
configProvider.apply(config);
appliedConfig = true;
}
if (!appliedConfig && config instanceof ServerConfig) {
for (ServerConfigProvider configProvider : ServiceLoader.load(ServerConfigProvider.class)) {
configProvider.apply((ServerConfig)config);
}
}
}
if (config.isAutoLoadModuleInfo()) {
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
package io.ebeaninternal.server.querydefn;
import io.ebean.EbeanServer;
import io.ebean.Database;
import io.ebean.Update;
import io.ebeaninternal.api.BindParams;
import io.ebeaninternal.api.SpiUpdate;
@@ -14,7 +14,7 @@ public final class DefaultOrmUpdate<T> implements SpiUpdate<T>, Serializable {
private static final long serialVersionUID = -8791423602246515438L;
private transient final EbeanServer server;
private transient final Database server;
private final Class<?> beanType;
private final String name;
private String label;
@@ -35,7 +35,7 @@ public final class DefaultOrmUpdate<T> implements SpiUpdate<T>, Serializable {
* Create with a specific server. This means you can use the
* UpdateSql.execute() method.
*/
public DefaultOrmUpdate(Class<?> beanType, EbeanServer server, String baseTable, String updateStatement) {
public DefaultOrmUpdate(Class<?> beanType, Database server, String baseTable, String updateStatement) {
this.beanType = beanType;
this.server = server;
this.baseTable = baseTable;
@@ -4,7 +4,6 @@ module io.ebean.core {
uses io.ebean.cache.ServerCachePlugin;
uses io.ebean.cache.ServerCacheNotifyPlugin;
uses io.ebean.config.DatabaseConfigProvider;
uses io.ebean.config.ServerConfigProvider;
uses io.ebean.config.ModuleInfoLoader;
uses io.ebean.config.dbplatform.DatabasePlatformProvider;
uses io.ebean.datasource.DataSourceAlertFactory;
@@ -6,8 +6,7 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class DefaultServerCacheConfigTest {
class DefaultServerCacheConfigTest {
private DefaultServerCacheConfig create(int maxSize, int maxIdleSecs, int maxSecsToLive, int trimFreq) {
ServerCacheOptions options = new ServerCacheOptions();
@@ -20,33 +19,45 @@ public class DefaultServerCacheConfigTest {
}
@Test
public void trimFreq_halfIdle() {
void trimFreq_halfIdle() {
assertEquals(create(10000,10,20, 0).determineTrimFrequency(), 4);
}
@Test
public void trimFreq_halfIdle_withRounding() {
void trimFreq_halfIdle_withRounding() {
assertEquals(create(10000,11,20, 0).determineTrimFrequency(), 4);
}
@Test
public void trimFreq_halfTTL() {
void trimFreq_halfTTL() {
assertEquals(create(10000,0,20, 0).determineTrimFrequency(), 9);
}
@Test
public void trimFreq_halfTTL_withRounding() {
void trimFreq_halfTTL_withRounding() {
assertEquals(create(10000,0,21, 0).determineTrimFrequency(), 9);
}
@Test
public void trimFreq_explicit() {
void trimFreq_explicit() {
assertEquals(create(10000,10,20, 42).determineTrimFrequency(), 42);
}
@Test
void trimOnPut_default() {
assertEquals(create(0,0,0, 0).determineTrimOnPut(), 1_000);
}
@Test
void trimOnPut_tenPercent() {
assertEquals(create(10_000,0,0, 0).determineTrimOnPut(), 1_000);
assertEquals(create(9_000,0,0, 0).determineTrimOnPut(), 900);
assertEquals(create(100,0,0, 0).determineTrimOnPut(), 10);
}
@Test
void trimOnPut_roundDown() {
assertEquals(create(9010,0,0, 0).determineTrimOnPut(), 901);
assertEquals(create(9009,0,0, 0).determineTrimOnPut(), 900);
}
}
@@ -10,16 +10,14 @@ import org.junit.jupiter.api.Test;
import java.util.Random;
public class DefaultServerCache_RunEvictionTest {
class DefaultServerCache_RunEvictionTest {
private DefaultServerCache createCache() {
ServerCacheOptions cacheOptions = new ServerCacheOptions();
cacheOptions.setMaxSize(10000);
cacheOptions.setMaxSize(300);
cacheOptions.setMaxIdleSecs(1);
cacheOptions.setMaxSecsToLive(2);
cacheOptions.setTrimFrequency(1);
cacheOptions.setTrimFrequency(5);
ServerCacheConfig con = new ServerCacheConfig(ServerCacheType.BEAN, "foo", "foo", cacheOptions, null, null);
return new DefaultServerCache(new DefaultServerCacheConfig(con));
@@ -35,8 +33,7 @@ public class DefaultServerCache_RunEvictionTest {
@Disabled("test takes long time")
@Test
public void runEvict() throws InterruptedException {
void runEvict() throws InterruptedException {
for (int i = 0; i < 15; i++) {
doStuff();
cache.runEviction();
@@ -47,12 +44,10 @@ public class DefaultServerCache_RunEvictionTest {
}
private void doStuff() {
for (int i = 0; i < 500; i++) {
for (int i = 0; i < 5000; i++) {
String key = "" + random.nextInt(20000);
int mode = random.nextInt(10);
if (mode < 8) {
if (mode < 7) {
cache.get(key);
} else {
cache.put(key, key + "-" + System.currentTimeMillis());
@@ -1,6 +1,5 @@
package io.ebean.test.config.platform;
import io.ebean.docker.commands.ElasticConfig;
import io.ebean.docker.commands.ElasticContainer;
import java.util.Properties;
@@ -19,27 +18,18 @@ class ElasticSearchSetup {
}
void run() {
ElasticConfig elasticConfig = readConfig();
if (elasticConfig != null) {
new ElasticContainer(elasticConfig).start();
}
}
ElasticConfig readConfig() {
String version = read("version", null);
if (version == null) {
// we need an explicit version to run
return null;
if (version != null) {
Properties properties = populateDockerProperties(version);
ElasticContainer.newBuilder(version)
.properties(properties)
.build()
.start();
}
return new ElasticConfig(version, populateDockerProperties(version));
}
private Properties populateDockerProperties(String version) {
PropertiesBuilder properties = new PropertiesBuilder();
String mode = config.getProperty("ebean.test.shutdown");
if (mode != null) {
properties.set("shutdown", mode);
@@ -63,7 +53,7 @@ class ElasticSearchSetup {
private static class PropertiesBuilder {
private Properties dockerProperties = new Properties();
private final Properties dockerProperties = new Properties();
private void set(String key, String val) {
dockerProperties.setProperty("elastic." + key, val);
@@ -1,6 +1,5 @@
package io.ebean.test.config.platform;
import io.ebean.docker.commands.RedisConfig;
import io.ebean.docker.commands.RedisContainer;
import java.util.Properties;
@@ -16,9 +15,10 @@ class RedisSetup {
String host = dockerHost.dockerHost(properties.getProperty("ebean.test.dockerHost"));
properties.setProperty("redis.host", host);
}
RedisConfig redisConfig = new RedisConfig(version, properties);
RedisContainer container = new RedisContainer(redisConfig);
container.start();
RedisContainer.newBuilder(version)
.properties(properties)
.build()
.start();
}
}
}
@@ -1,7 +1,7 @@
package io.ebean.xtest.internal.server.cluster.binarymessage;
import io.ebean.Database;
import io.ebean.xtest.BaseTestCase;
import io.ebean.EbeanServer;
import io.ebean.xtest.internal.api.TDSpiEbeanServer;
import io.ebeaninternal.api.TransactionEventTable;
import io.ebeaninternal.server.cache.RemoteCacheEvent;
@@ -94,7 +94,7 @@ public class BinaryTransactionEventReadWriteTest extends BaseTestCase {
class TDServerLookup implements ServerLookup {
@Override
public EbeanServer getServer(String name) {
public Database getServer(String name) {
return mockEbeanServer;
}
}
@@ -1,16 +1,13 @@
package main;
import io.ebean.docker.commands.CockroachConfig;
import io.ebean.docker.commands.CockroachContainer;
public class StartCockroach {
public static void main(String[] args) {
CockroachConfig config = new CockroachConfig("v21.2.4");
config.setDbName("unit");
CockroachContainer container = new CockroachContainer(config);
container.start();
CockroachContainer.newBuilder("v21.2.4")
.dbName("unit")
.build()
.start();
}
}
+9 -13
View File
@@ -1,22 +1,18 @@
package main;
import io.ebean.docker.commands.Db2Config;
import io.ebean.docker.commands.Db2Container;
public class StartDb2 {
public static void main(String[] args) {
Db2Config config = new Db2Config("11.5.6.0a");
config.setDbName("unit");
config.setUser("unit");
config.setPassword("unit");
// to change collation, charset and other parameters like pagesize:
config.setCreateOptions("USING CODESET UTF-8 TERRITORY DE COLLATE USING IDENTITY PAGESIZE 32768");
config.setConfigOptions("USING STRING_UNITS CODEUNITS32");
Db2Container container = new Db2Container(config);
container.startWithDropCreate();
Db2Container.newBuilder("11.5.6.0a")
.dbName("unit")
.user("unit")
.password("unit")
// to change collation, charset and other parameters like pagesize:
.configOptions("USING CODESET UTF-8 TERRITORY DE COLLATE USING IDENTITY PAGESIZE 32768")
.configOptions("USING STRING_UNITS CODEUNITS32")
.build()
.startWithDropCreate();
}
}
@@ -1,18 +1,15 @@
package main;
import io.ebean.docker.commands.MariaDBConfig;
import io.ebean.docker.commands.MariaDBContainer;
public class StartMariaDb {
public static void main(String[] args) {
MariaDBConfig config = new MariaDBConfig("10.5");
config.setDbName("unit");
config.setUser("unit");
config.setPassword("unit");
MariaDBContainer container = new MariaDBContainer(config);
container.startWithDropCreate();
MariaDBContainer.newBuilder("10.5")
.dbName("unit")
.user("unit")
.password("unit")
.build()
.startWithDropCreate();
}
}
@@ -1,16 +1,17 @@
package main;
import io.ebean.docker.commands.MySqlConfig;
import io.ebean.docker.commands.MySqlContainer;
public class StartMySql {
public static void main(String[] args) {
MySqlConfig config = new MySqlConfig("8.0");
config.setDbName("unit");
config.setUser("unit");
config.setPassword("unit");
MySqlContainer.newBuilder("8.0")
.dbName("unit")
.user("unit")
.password("unit")
.build()
.startWithDropCreate();
// by default this mysql docker collation is case sensitive
// using utf8mb4_bin
@@ -22,7 +23,5 @@ public class StartMySql {
// config.setCollation("utf8mb4_unicode_ci");
// config.setCharacterSet("utf8mb4");
MySqlContainer container = new MySqlContainer(config);
container.startWithDropCreate();
}
}
@@ -1,16 +1,14 @@
package main;
import io.ebean.docker.commands.NuoDBConfig;
import io.ebean.docker.commands.NuoDBContainer;
public class StartNuoDB {
public static void main(String[] args) {
NuoDBContainer container = NuoDBContainer.newBuilder("4.0")
.schema("test_user")
.build();
NuoDBConfig config = new NuoDBConfig();
config.setSchema("test_user");
NuoDBContainer container = new NuoDBContainer(config);
container.stopRemove();
container.startWithDropCreate();
}
@@ -1,16 +1,13 @@
package main;
import io.ebean.docker.commands.OracleConfig;
import io.ebean.docker.commands.OracleContainer;
public class StartOracle {
public static void main(String[] args) {
OracleConfig config = new OracleConfig();
config.setUser("test_ebean");
OracleContainer container = new OracleContainer(config);
container.startWithDropCreate();
OracleContainer.newBuilder("latest")
.user("test_ebean")
.build()
.startWithDropCreate();
}
}
@@ -1,21 +1,18 @@
package main;
import io.ebean.docker.commands.PostgresConfig;
import io.ebean.docker.commands.PostgresContainer;
public class StartPostgres {
public static void main(String[] args) {
PostgresConfig config = new PostgresConfig("13");
config.setPort(5432);
config.setDbName("unit");
config.setUser("unit");
config.setPassword("unit");
config.setContainerName("pg13x");
config.setExtensions("hstore,pgcrypto");
PostgresContainer container = new PostgresContainer(config);
container.startWithDropCreate();
PostgresContainer.newBuilder("13")
.port(5432)
.dbName("unit")
.user("unit")
.password("unit")
.containerName("pg13x")
.extensions("hstore,pgcrypto")
.build()
.startWithDropCreate();
}
}
@@ -1,15 +1,15 @@
package main;
import io.ebean.docker.commands.SqlServerConfig;
import io.ebean.docker.commands.SqlServerContainer;
public class StartSqlServer {
public static void main(String[] args) {
SqlServerConfig config = new SqlServerConfig("2019-GA-ubuntu-16.04");
config.setDbName("test_ebean");
config.setUser("test_ebean");
SqlServerContainer.newBuilder("2019-GA-ubuntu-16.04")
.dbName("test_ebean")
.user("test_ebean")
.build()
.start();
// by default this sqlserver docker collation is case sensitive
// using MSSQL_COLLATION=Latin1_General_100_BIN2
@@ -20,8 +20,5 @@ public class StartSqlServer {
//config.setCollation("default");
//config.setCollation("Latin1_General_100_CI");
SqlServerContainer container = new SqlServerContainer(config);
container.start();
}
}
@@ -1,20 +1,16 @@
package main;
import io.ebean.docker.commands.YugabyteConfig;
import io.ebean.docker.commands.YugabyteContainer;
public class StartYugabyte {
public static void main(String[] args) {
// Check add extensions ?
YugabyteConfig config = new YugabyteConfig("2.11.2.0-b89");
config.setDbName("unit");
config.setUser("unit");
config.setExtensions("pgcrypto");
YugabyteContainer container = new YugabyteContainer(config);
container.startWithDropCreate();
YugabyteContainer.newBuilder("2.11.2.0-b89")
.dbName("unit")
.user("unit")
.extensions("pgcrypto")
.build()
.startWithDropCreate();
// Run container ut_yugabyte with host:localhost port:6433 db:unit user:unit/test shutdown:None
// docker run -d --name ut_yugabyte -p 6433:5433 -p 7000:7000 -p 9000:9000 -p 9042:9042 yugabytedb/yugabyte:2.11.2.0-b89 bin/yugabyted start --daemon=false
+1 -1
View File
@@ -44,7 +44,7 @@
<ebean-ddl-runner.version>1.3</ebean-ddl-runner.version>
<ebean-migration-auto.version>1.2</ebean-migration-auto.version>
<ebean-migration.version>13.0.0</ebean-migration.version>
<ebean-test-docker.version>4.9</ebean-test-docker.version>
<ebean-test-docker.version>5.0</ebean-test-docker.version>
<ebean-datasource.version>7.5</ebean-datasource.version>
<ebean-agent.version>13.5.0</ebean-agent.version>
<ebean-maven-plugin.version>13.5.0</ebean-maven-plugin.version>