initial commit
This commit is contained in:
commit
2393a392da
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/**/*.iml
|
||||
/**/.idea
|
||||
/**/target
|
||||
/**/dependency-reduced-pom.xml
|
||||
/target
|
1
db/.gitignore
vendored
Normal file
1
db/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
5
db/Dockerfile
Normal file
5
db/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM openjdk:11
|
||||
|
||||
ARG version
|
||||
ADD target/test-db-${version}.jar /test-db.jar
|
||||
ENTRYPOINT ["java", "-jar", "/test-db.jar"]
|
56
db/pom.xml
Normal file
56
db/pom.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>${revision}${sha1}${changelist}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>test-db</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>DB</name>
|
||||
|
||||
<properties>
|
||||
<main.class>test.DbApp</main.class>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test-model</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--BQ deps-->
|
||||
<dependency>
|
||||
<groupId>io.bootique.liquibase</groupId>
|
||||
<artifactId>bootique-liquibase</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique.logback</groupId>
|
||||
<artifactId>bootique-logback</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique.jdbc</groupId>
|
||||
<artifactId>bootique-jdbc-hikaricp-instrumented</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
24
db/src/main/java/test/DbApp.java
Normal file
24
db/src/main/java/test/DbApp.java
Normal file
@ -0,0 +1,24 @@
|
||||
package test;
|
||||
|
||||
import io.bootique.BQCoreModule;
|
||||
import io.bootique.BaseModule;
|
||||
import io.bootique.Bootique;
|
||||
import io.bootique.di.Binder;
|
||||
import io.bootique.meta.application.OptionMetadata;
|
||||
|
||||
public class DbApp extends BaseModule {
|
||||
public static void main(String[] args) {
|
||||
Bootique.main(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder) {
|
||||
BQCoreModule.extend(binder)
|
||||
.addConfig("classpath:test/db/default.yaml")
|
||||
|
||||
// --local
|
||||
.addOption(OptionMetadata.builder("local", "Load configuration for local environment.").build())
|
||||
.mapConfigResource("local", "classpath:test/db/local.yaml")
|
||||
;
|
||||
}
|
||||
}
|
12
db/src/main/java/test/DbAppProvider.java
Normal file
12
db/src/main/java/test/DbAppProvider.java
Normal file
@ -0,0 +1,12 @@
|
||||
package test;
|
||||
|
||||
import io.bootique.BQModuleProvider;
|
||||
|
||||
public class DbAppProvider implements BQModuleProvider {
|
||||
public DbAppProvider() {}
|
||||
|
||||
@Override
|
||||
public DbApp module() {
|
||||
return new DbApp();
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
test.DbAppProvider
|
38
db/src/main/resources/init.sql
Normal file
38
db/src/main/resources/init.sql
Normal file
@ -0,0 +1,38 @@
|
||||
-- liquibase formatted sql
|
||||
-- changeset rzen:1
|
||||
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `test`.`e1` (
|
||||
`id` INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`text` TEXT NULL DEFAULT NULL,
|
||||
`e2_id` INT(5) UNSIGNED NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `fk_e2_idx` (`e2_id` ASC) VISIBLE,
|
||||
CONSTRAINT `fk_e2`
|
||||
FOREIGN KEY (`e2_id`)
|
||||
REFERENCES `test`.`e2` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `test`.`e2` (
|
||||
`id` INT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`text` TEXT NULL DEFAULT NULL,
|
||||
`e1_id` INT(5) UNSIGNED NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `fk_e1_idx` (`e1_id` ASC) VISIBLE,
|
||||
CONSTRAINT `fk_e1`
|
||||
FOREIGN KEY (`e1_id`)
|
||||
REFERENCES `test`.`e1` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = utf8;
|
||||
|
||||
SET SQL_MODE=@OLD_SQL_MODE;
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
3
db/src/main/resources/master.yaml
Normal file
3
db/src/main/resources/master.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
databaseChangeLog:
|
||||
- include:
|
||||
file: classpath:init.sql
|
23
db/src/main/resources/test/db/default.yaml
Normal file
23
db/src/main/resources/test/db/default.yaml
Normal file
@ -0,0 +1,23 @@
|
||||
jdbc:
|
||||
test:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
jdbcUrl: "jdbc:mysql://db:3306/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
|
||||
username: root
|
||||
password: test
|
||||
minimumIdle: 1
|
||||
maximumPoolSize: 20
|
||||
connectionTestQuery: "select 1"
|
||||
autoCommit: false
|
||||
|
||||
# Liquibase Migrations Config
|
||||
liquibase:
|
||||
datasource: test
|
||||
changeLogs:
|
||||
- classpath:master.yaml
|
||||
|
||||
# Logging
|
||||
log:
|
||||
level: info
|
||||
appenders:
|
||||
- type: console
|
||||
logFormat: '[%d{"dd/MMM/yyyy:HH:mm:ss,SSS"}] %t %X %-5p %c{1}: %m%n%ex'
|
3
db/src/main/resources/test/db/local.yaml
Normal file
3
db/src/main/resources/test/db/local.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
jdbc:
|
||||
test:
|
||||
jdbcUrl: "jdbc:mysql://192.168.10.64:33006/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
|
101
docker-compose.yaml
Normal file
101
docker-compose.yaml
Normal file
@ -0,0 +1,101 @@
|
||||
version: '3.4'
|
||||
|
||||
volumes:
|
||||
test-m2:
|
||||
external: true
|
||||
|
||||
networks:
|
||||
backend:
|
||||
|
||||
x-jdbc-env:
|
||||
&jdbc-env
|
||||
JDBC_TEST_JDBCURL: jdbc:mysql://db:3306/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
|
||||
JDBC_TEST_USERNAME: root
|
||||
JDBC_TEST_PASSWORD: test
|
||||
|
||||
services:
|
||||
|
||||
mvn-build:
|
||||
image: maven:3-openjdk-11
|
||||
working_dir: /usr/src/maven
|
||||
volumes:
|
||||
- .:/usr/src/maven
|
||||
- test-m2:/root/.m2
|
||||
entrypoint: mvn clean package
|
||||
|
||||
db:
|
||||
image: mariadb:10
|
||||
networks:
|
||||
- backend
|
||||
ports:
|
||||
- "33006:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: test
|
||||
labels:
|
||||
traefik.enable: 'false'
|
||||
|
||||
liquibase:
|
||||
image: test-db:1.0-SNAPSHOT
|
||||
build:
|
||||
context: db
|
||||
args:
|
||||
version: ${VERSION}
|
||||
networks:
|
||||
- backend
|
||||
command: --lb-update
|
||||
|
||||
|
||||
# cayenne helpers
|
||||
|
||||
cdbimport:
|
||||
image: maven:3-openjdk-11
|
||||
networks:
|
||||
- backend
|
||||
volumes:
|
||||
- test-m2:/root/.m2
|
||||
- .:/usr/src/maven
|
||||
working_dir: /usr/src/maven
|
||||
environment:
|
||||
<<: *jdbc-env
|
||||
command: mvn -f model cayenne:cdbimport
|
||||
|
||||
cgen:
|
||||
image: maven:3-openjdk-11
|
||||
volumes:
|
||||
- test-m2:/root/.m2
|
||||
- .:/usr/src/maven
|
||||
working_dir: /usr/src/maven
|
||||
environment:
|
||||
<<: *jdbc-env
|
||||
command: mvn -f model cayenne:cgen
|
||||
|
||||
|
||||
# app services
|
||||
|
||||
# this shows a fail scenario
|
||||
fail:
|
||||
image: test-test:${VERSION}
|
||||
build:
|
||||
context: test
|
||||
args:
|
||||
version: ${VERSION}
|
||||
networks:
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- liquibase
|
||||
command: --fail
|
||||
|
||||
# this shows off a workaround
|
||||
happy:
|
||||
image: test-test:${VERSION}
|
||||
build:
|
||||
context: test
|
||||
args:
|
||||
version: ${VERSION}
|
||||
networks:
|
||||
- backend
|
||||
depends_on:
|
||||
- db
|
||||
- liquibase
|
||||
command: --happy
|
1
model/.gitignore
vendored
Normal file
1
model/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
72
model/pom.xml
Normal file
72
model/pom.xml
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>${revision}${sha1}${changelist}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>test-model</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cayenne</groupId>
|
||||
<artifactId>cayenne-lifecycle</artifactId>
|
||||
<version>${cayenne.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cayenne.plugins</groupId>
|
||||
<artifactId>cayenne-maven-plugin</artifactId>
|
||||
<version>${cayenne.version}</version>
|
||||
<configuration>
|
||||
<map>${project.basedir}/src/main/resources/test/test.map.xml</map>
|
||||
<superPkg>test.cayenne.auto</superPkg>
|
||||
<dataSource>
|
||||
<driver>com.mysql.cj.jdbc.Driver</driver>
|
||||
<url>${env.JDBC_TEST_JDBCURL}</url>
|
||||
<username>root</username>
|
||||
<password>test</password>
|
||||
</dataSource>
|
||||
<dbImport>
|
||||
<defaultPackage>test.cayenne</defaultPackage>
|
||||
<catalog>
|
||||
<name>test</name>
|
||||
<excludeTable>databasechangelog.*</excludeTable>
|
||||
</catalog>
|
||||
</dbImport>
|
||||
<overwriteExisting>true</overwriteExisting>
|
||||
<meaningfulPk>true</meaningfulPk>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-cli</id>
|
||||
<goals>
|
||||
<!-- To perform reverse engineering, explicitly run 'mvn cayenne:cdbimport' -->
|
||||
<!-- To perform class generation, explicitly run 'mvn cayenne:cgen' -->
|
||||
<!-- Start up the modeler from the command-line 'mvn cayenne-modeler:run' -->
|
||||
<goal>cgen</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<!-- 3rdParty deps-->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
</project>
|
9
model/src/main/java/test/cayenne/E1.java
Normal file
9
model/src/main/java/test/cayenne/E1.java
Normal file
@ -0,0 +1,9 @@
|
||||
package test.cayenne;
|
||||
|
||||
import test.cayenne.auto._E1;
|
||||
|
||||
public class E1 extends _E1 {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
9
model/src/main/java/test/cayenne/E2.java
Normal file
9
model/src/main/java/test/cayenne/E2.java
Normal file
@ -0,0 +1,9 @@
|
||||
package test.cayenne;
|
||||
|
||||
import test.cayenne.auto._E2;
|
||||
|
||||
public class E2 extends _E2 {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
131
model/src/main/java/test/cayenne/auto/_E1.java
Normal file
131
model/src/main/java/test/cayenne/auto/_E1.java
Normal file
@ -0,0 +1,131 @@
|
||||
package test.cayenne.auto;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cayenne.BaseDataObject;
|
||||
import org.apache.cayenne.exp.property.EntityProperty;
|
||||
import org.apache.cayenne.exp.property.ListProperty;
|
||||
import org.apache.cayenne.exp.property.PropertyFactory;
|
||||
import org.apache.cayenne.exp.property.StringProperty;
|
||||
|
||||
import test.cayenne.E2;
|
||||
|
||||
/**
|
||||
* Class _E1 was generated by Cayenne.
|
||||
* It is probably a good idea to avoid changing this class manually,
|
||||
* since it may be overwritten next time code is regenerated.
|
||||
* If you need to make any customizations, please use subclass.
|
||||
*/
|
||||
public abstract class _E1 extends BaseDataObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String ID_PK_COLUMN = "id";
|
||||
|
||||
public static final StringProperty<String> TEXT = PropertyFactory.createString("text", String.class);
|
||||
public static final EntityProperty<E2> E2 = PropertyFactory.createEntity("e2", E2.class);
|
||||
public static final ListProperty<E2> E2S = PropertyFactory.createList("e2s", E2.class);
|
||||
|
||||
protected String text;
|
||||
|
||||
protected Object e2;
|
||||
protected Object e2s;
|
||||
|
||||
public void setText(String text) {
|
||||
beforePropertyWrite("text", this.text, text);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
beforePropertyRead("text");
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public void setE2(E2 e2) {
|
||||
setToOneTarget("e2", e2, true);
|
||||
}
|
||||
|
||||
public E2 getE2() {
|
||||
return (E2)readProperty("e2");
|
||||
}
|
||||
|
||||
public void addToE2s(E2 obj) {
|
||||
addToManyTarget("e2s", obj, true);
|
||||
}
|
||||
|
||||
public void removeFromE2s(E2 obj) {
|
||||
removeToManyTarget("e2s", obj, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<E2> getE2s() {
|
||||
return (List<E2>)readProperty("e2s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readPropertyDirectly(String propName) {
|
||||
if(propName == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch(propName) {
|
||||
case "text":
|
||||
return this.text;
|
||||
case "e2":
|
||||
return this.e2;
|
||||
case "e2s":
|
||||
return this.e2s;
|
||||
default:
|
||||
return super.readPropertyDirectly(propName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePropertyDirectly(String propName, Object val) {
|
||||
if(propName == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (propName) {
|
||||
case "text":
|
||||
this.text = (String)val;
|
||||
break;
|
||||
case "e2":
|
||||
this.e2 = val;
|
||||
break;
|
||||
case "e2s":
|
||||
this.e2s = val;
|
||||
break;
|
||||
default:
|
||||
super.writePropertyDirectly(propName, val);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
writeSerialized(out);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
readSerialized(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeState(ObjectOutputStream out) throws IOException {
|
||||
super.writeState(out);
|
||||
out.writeObject(this.text);
|
||||
out.writeObject(this.e2);
|
||||
out.writeObject(this.e2s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
super.readState(in);
|
||||
this.text = (String)in.readObject();
|
||||
this.e2 = in.readObject();
|
||||
this.e2s = in.readObject();
|
||||
}
|
||||
|
||||
}
|
131
model/src/main/java/test/cayenne/auto/_E2.java
Normal file
131
model/src/main/java/test/cayenne/auto/_E2.java
Normal file
@ -0,0 +1,131 @@
|
||||
package test.cayenne.auto;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cayenne.BaseDataObject;
|
||||
import org.apache.cayenne.exp.property.EntityProperty;
|
||||
import org.apache.cayenne.exp.property.ListProperty;
|
||||
import org.apache.cayenne.exp.property.PropertyFactory;
|
||||
import org.apache.cayenne.exp.property.StringProperty;
|
||||
|
||||
import test.cayenne.E1;
|
||||
|
||||
/**
|
||||
* Class _E2 was generated by Cayenne.
|
||||
* It is probably a good idea to avoid changing this class manually,
|
||||
* since it may be overwritten next time code is regenerated.
|
||||
* If you need to make any customizations, please use subclass.
|
||||
*/
|
||||
public abstract class _E2 extends BaseDataObject {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String ID_PK_COLUMN = "id";
|
||||
|
||||
public static final StringProperty<String> TEXT = PropertyFactory.createString("text", String.class);
|
||||
public static final EntityProperty<E1> E1 = PropertyFactory.createEntity("e1", E1.class);
|
||||
public static final ListProperty<E1> E1S = PropertyFactory.createList("e1s", E1.class);
|
||||
|
||||
protected String text;
|
||||
|
||||
protected Object e1;
|
||||
protected Object e1s;
|
||||
|
||||
public void setText(String text) {
|
||||
beforePropertyWrite("text", this.text, text);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
beforePropertyRead("text");
|
||||
return this.text;
|
||||
}
|
||||
|
||||
public void setE1(E1 e1) {
|
||||
setToOneTarget("e1", e1, true);
|
||||
}
|
||||
|
||||
public E1 getE1() {
|
||||
return (E1)readProperty("e1");
|
||||
}
|
||||
|
||||
public void addToE1s(E1 obj) {
|
||||
addToManyTarget("e1s", obj, true);
|
||||
}
|
||||
|
||||
public void removeFromE1s(E1 obj) {
|
||||
removeToManyTarget("e1s", obj, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<E1> getE1s() {
|
||||
return (List<E1>)readProperty("e1s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readPropertyDirectly(String propName) {
|
||||
if(propName == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch(propName) {
|
||||
case "text":
|
||||
return this.text;
|
||||
case "e1":
|
||||
return this.e1;
|
||||
case "e1s":
|
||||
return this.e1s;
|
||||
default:
|
||||
return super.readPropertyDirectly(propName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePropertyDirectly(String propName, Object val) {
|
||||
if(propName == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (propName) {
|
||||
case "text":
|
||||
this.text = (String)val;
|
||||
break;
|
||||
case "e1":
|
||||
this.e1 = val;
|
||||
break;
|
||||
case "e1s":
|
||||
this.e1s = val;
|
||||
break;
|
||||
default:
|
||||
super.writePropertyDirectly(propName, val);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
writeSerialized(out);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
readSerialized(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeState(ObjectOutputStream out) throws IOException {
|
||||
super.writeState(out);
|
||||
out.writeObject(this.text);
|
||||
out.writeObject(this.e1);
|
||||
out.writeObject(this.e1s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readState(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
super.readState(in);
|
||||
this.text = (String)in.readObject();
|
||||
this.e1 = in.readObject();
|
||||
this.e1s = in.readObject();
|
||||
}
|
||||
|
||||
}
|
11
model/src/main/resources/test/cayenne-test.xml
Normal file
11
model/src/main/resources/test/cayenne-test.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<domain xmlns="http://cayenne.apache.org/schema/10/domain"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://cayenne.apache.org/schema/10/domain https://cayenne.apache.org/schema/10/domain.xsd"
|
||||
project-version="10">
|
||||
<map name="test"/>
|
||||
<node name="test-node"
|
||||
factory="org.apache.cayenne.configuration.server.JNDIDataSourceFactory" parameters="jdbc/mysql/test">
|
||||
<map-ref name="test"/>
|
||||
</node>
|
||||
</domain>
|
40
model/src/main/resources/test/test.map.xml
Normal file
40
model/src/main/resources/test/test.map.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<data-map xmlns="http://cayenne.apache.org/schema/10/modelMap"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://cayenne.apache.org/schema/10/modelMap https://cayenne.apache.org/schema/10/modelMap.xsd"
|
||||
project-version="10">
|
||||
<property name="defaultPackage" value="test.cayenne"/>
|
||||
<property name="defaultCatalog" value="test"/>
|
||||
<db-entity name="e1" catalog="test">
|
||||
<db-attribute name="e2_id" type="BIGINT" length="10"/>
|
||||
<db-attribute name="id" type="BIGINT" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
|
||||
<db-attribute name="text" type="LONGVARCHAR" length="65535"/>
|
||||
</db-entity>
|
||||
<db-entity name="e2" catalog="test">
|
||||
<db-attribute name="e1_id" type="BIGINT" length="10"/>
|
||||
<db-attribute name="id" type="BIGINT" isPrimaryKey="true" isGenerated="true" isMandatory="true" length="10"/>
|
||||
<db-attribute name="text" type="LONGVARCHAR" length="65535"/>
|
||||
</db-entity>
|
||||
<obj-entity name="E1" className="test.cayenne.E1" dbEntityName="e1">
|
||||
<obj-attribute name="text" type="java.lang.String" db-attribute-path="text"/>
|
||||
</obj-entity>
|
||||
<obj-entity name="E2" className="test.cayenne.E2" dbEntityName="e2">
|
||||
<obj-attribute name="text" type="java.lang.String" db-attribute-path="text"/>
|
||||
</obj-entity>
|
||||
<db-relationship name="e2" source="e1" target="e2">
|
||||
<db-attribute-pair source="e2_id" target="id"/>
|
||||
</db-relationship>
|
||||
<db-relationship name="e2s" source="e1" target="e2" toMany="true">
|
||||
<db-attribute-pair source="id" target="e1_id"/>
|
||||
</db-relationship>
|
||||
<db-relationship name="e1" source="e2" target="e1">
|
||||
<db-attribute-pair source="e1_id" target="id"/>
|
||||
</db-relationship>
|
||||
<db-relationship name="e1s" source="e2" target="e1" toMany="true">
|
||||
<db-attribute-pair source="id" target="e2_id"/>
|
||||
</db-relationship>
|
||||
<obj-relationship name="e2" source="E1" target="E2" deleteRule="Nullify" db-relationship-path="e2"/>
|
||||
<obj-relationship name="e2s" source="E1" target="E2" deleteRule="Deny" db-relationship-path="e2s"/>
|
||||
<obj-relationship name="e1" source="E2" target="E1" deleteRule="Nullify" db-relationship-path="e1"/>
|
||||
<obj-relationship name="e1s" source="E2" target="E1" deleteRule="Deny" db-relationship-path="e1s"/>
|
||||
</data-map>
|
131
pom.xml
Normal file
131
pom.xml
Normal file
@ -0,0 +1,131 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>test</groupId>
|
||||
<version>${revision}${sha1}${changelist}</version>
|
||||
|
||||
<name>Parent</name>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<revision>1.0</revision>
|
||||
<sha1/>
|
||||
<changelist>-SNAPSHOT</changelist>
|
||||
|
||||
<bootique.version>2.0.M1</bootique.version>
|
||||
<!-- must stay at 8.0.22 until bootique upgrades to liquibase 4.x -->
|
||||
<!-- see https://bugs.mysql.com/bug.php?id=102302 and https://github.com/liquibase/liquibase/blob/4.4.x/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java#L324 -->
|
||||
<mysql.version>8.0.22</mysql.version>
|
||||
<mariadb.version>3.0.2-rc</mariadb.version>
|
||||
<cayenne.version>4.2.B1</cayenne.version>
|
||||
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<main.class>Dummy</main.class>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>db</module>
|
||||
<module>model</module>
|
||||
<module>test</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test-model</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- bootique -->
|
||||
<dependency>
|
||||
<groupId>io.bootique.bom</groupId>
|
||||
<artifactId>bootique-bom</artifactId>
|
||||
<version>${bootique.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- cayenne -->
|
||||
<dependency>
|
||||
<groupId>org.apache.cayenne</groupId>
|
||||
<artifactId>cayenne-server</artifactId>
|
||||
<version>${cayenne.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mysql driver -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>${mariadb.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>${main.class}</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
</project>
|
10
run-test.sh
Executable file
10
run-test.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z `docker volume ls -q | grep -i test-m2` ]; then docker volume create test-m2; fi
|
||||
docker-compose up -d db
|
||||
sleep 30s
|
||||
docker-compose run --rm mvn-build
|
||||
docker-compose build
|
||||
docker-compose run --rm fail
|
||||
docker-compose run --rm happy
|
||||
docker-compose down
|
1
test/.gitignore
vendored
Normal file
1
test/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
5
test/Dockerfile
Normal file
5
test/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM openjdk:11
|
||||
|
||||
ARG version
|
||||
ADD target/test-test-${version}.jar /test-test.jar
|
||||
ENTRYPOINT ["java", "-jar", "/test-test.jar"]
|
66
test/pom.xml
Normal file
66
test/pom.xml
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>${revision}${sha1}${changelist}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>test-test</artifactId>
|
||||
|
||||
<properties>
|
||||
<main.class>test.TestApp</main.class>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>test</groupId>
|
||||
<artifactId>test-model</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.bootique.cayenne</groupId>
|
||||
<artifactId>bootique-cayenne</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique.agrest</groupId>
|
||||
<artifactId>bootique-agrest</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.agrest</groupId>
|
||||
<artifactId>agrest-engine</artifactId>
|
||||
<version>4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique.jdbc</groupId>
|
||||
<artifactId>bootique-jdbc-hikaricp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.bootique.logback</groupId>
|
||||
<artifactId>bootique-logback</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
33
test/src/main/java/test/FailCommand.java
Normal file
33
test/src/main/java/test/FailCommand.java
Normal file
@ -0,0 +1,33 @@
|
||||
package test;
|
||||
|
||||
import io.bootique.cli.Cli;
|
||||
import io.bootique.command.CommandOutcome;
|
||||
import io.bootique.command.CommandWithMetadata;
|
||||
import io.bootique.meta.application.CommandMetadata;
|
||||
import org.apache.cayenne.ObjectContext;
|
||||
import org.apache.cayenne.configuration.server.ServerRuntime;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
public class FailCommand extends CommandWithMetadata {
|
||||
|
||||
@Inject
|
||||
private Provider<ServerRuntime> cayenneRuntimeProvider;
|
||||
|
||||
@Inject
|
||||
public FailCommand(CommandMetadata.Builder metadataBuilder) {
|
||||
super(metadataBuilder
|
||||
.name("fail")
|
||||
.description("Demo of a possible issue with Cayenne.")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandOutcome run(Cli cli) {
|
||||
ObjectContext context = cayenneRuntimeProvider.get().newContext();
|
||||
TestCase.runTest(context, true);
|
||||
return CommandOutcome.succeeded();
|
||||
}
|
||||
}
|
32
test/src/main/java/test/HappyCommand.java
Normal file
32
test/src/main/java/test/HappyCommand.java
Normal file
@ -0,0 +1,32 @@
|
||||
package test;
|
||||
|
||||
import io.bootique.cli.Cli;
|
||||
import io.bootique.command.CommandOutcome;
|
||||
import io.bootique.command.CommandWithMetadata;
|
||||
import io.bootique.meta.application.CommandMetadata;
|
||||
import org.apache.cayenne.ObjectContext;
|
||||
import org.apache.cayenne.configuration.server.ServerRuntime;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
public class HappyCommand extends CommandWithMetadata {
|
||||
@Inject
|
||||
private Provider<ServerRuntime> cayenneRuntimeProvider;
|
||||
|
||||
@Inject
|
||||
public HappyCommand(CommandMetadata.Builder metadataBuilder) {
|
||||
super(metadataBuilder
|
||||
.name("happy")
|
||||
.description("Demo of a possible issue with Cayenne. This command shows a workaround.")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandOutcome run(Cli cli) {
|
||||
ObjectContext context = cayenneRuntimeProvider.get().newContext();
|
||||
TestCase.runTest(context, false);
|
||||
return CommandOutcome.succeeded();
|
||||
}
|
||||
}
|
31
test/src/main/java/test/TestApp.java
Normal file
31
test/src/main/java/test/TestApp.java
Normal file
@ -0,0 +1,31 @@
|
||||
package test;
|
||||
|
||||
import io.bootique.BQCoreModule;
|
||||
import io.bootique.BaseModule;
|
||||
import io.bootique.Bootique;
|
||||
import io.bootique.di.Binder;
|
||||
import io.bootique.meta.application.OptionMetadata;
|
||||
|
||||
public class TestApp extends BaseModule {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Bootique.app(args)
|
||||
.autoLoadModules()
|
||||
.exec()
|
||||
.exit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder) {
|
||||
BQCoreModule.extend(binder)
|
||||
.addConfig("classpath:test/default.yaml")
|
||||
.addCommand(FailCommand.class)
|
||||
.addCommand(HappyCommand.class)
|
||||
|
||||
// --local
|
||||
.addOption(OptionMetadata.builder("local", "Load configuration for local environment.").build())
|
||||
.mapConfigResource("local", "classpath:test/local.yaml")
|
||||
|
||||
;
|
||||
}
|
||||
}
|
13
test/src/main/java/test/TestAppProvider.java
Normal file
13
test/src/main/java/test/TestAppProvider.java
Normal file
@ -0,0 +1,13 @@
|
||||
package test;
|
||||
|
||||
import io.bootique.BQModuleProvider;
|
||||
|
||||
public class TestAppProvider implements BQModuleProvider {
|
||||
|
||||
public TestAppProvider() {}
|
||||
|
||||
@Override
|
||||
public TestApp module() {
|
||||
return new TestApp();
|
||||
}
|
||||
}
|
30
test/src/main/java/test/TestCase.java
Normal file
30
test/src/main/java/test/TestCase.java
Normal file
@ -0,0 +1,30 @@
|
||||
package test;
|
||||
|
||||
import org.apache.cayenne.ObjectContext;
|
||||
import test.cayenne.E1;
|
||||
import test.cayenne.E2;
|
||||
|
||||
public class TestCase {
|
||||
|
||||
public static void runTest (ObjectContext context, boolean doFail) {
|
||||
for (int i=100; i<110; ++i) {
|
||||
E1 e1 = context.newObject(E1.class);
|
||||
E2 e2 = context.newObject(E2.class);
|
||||
|
||||
e1.setText("e1 #" + i);
|
||||
e2.setText("e2 #" + i);
|
||||
|
||||
// executing this commit seems to
|
||||
// mitigate the issue
|
||||
|
||||
if (!doFail) {
|
||||
context.commitChanges();
|
||||
}
|
||||
|
||||
e1.setE2(e2);
|
||||
e2.setE1(e1);
|
||||
|
||||
context.commitChanges();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
test.TestAppProvider
|
22
test/src/main/resources/test/default.yaml
Normal file
22
test/src/main/resources/test/default.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
# JDBC config
|
||||
jdbc:
|
||||
test:
|
||||
driverClassName: com.mysql.cj.jdbc.Driver
|
||||
jdbcUrl: "jdbc:mysql://db:3306/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
|
||||
username: root
|
||||
password: test
|
||||
minimumIdle: 1
|
||||
maximumPoolSize: 20
|
||||
connectionTestQuery: "select 1"
|
||||
autoCommit: false
|
||||
|
||||
cayenne:
|
||||
configs:
|
||||
- test/cayenne-test.xml
|
||||
datasource: test
|
||||
|
||||
log:
|
||||
level: debug
|
||||
appenders:
|
||||
- type: console
|
||||
logFormat: '[%d{"dd/MMM/yyyy:HH:mm:ss,SSS"}] %t %X %-5p %c{1}: %m%n%ex'
|
3
test/src/main/resources/test/local.yaml
Normal file
3
test/src/main/resources/test/local.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
jdbc:
|
||||
test:
|
||||
jdbcUrl: "jdbc:mysql://localhost:33006/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"
|
Loading…
Reference in New Issue
Block a user