From 2393a392da875e39da9aee400e5b1c16004c4da0 Mon Sep 17 00:00:00 2001 From: rzen Date: Wed, 5 Jan 2022 22:47:13 -0500 Subject: [PATCH] initial commit --- .env | 1 + .gitignore | 5 + db/.gitignore | 1 + db/Dockerfile | 5 + db/pom.xml | 56 ++++++++ db/src/main/java/test/DbApp.java | 24 ++++ db/src/main/java/test/DbAppProvider.java | 12 ++ .../services/io.bootique.BQModuleProvider | 1 + db/src/main/resources/init.sql | 38 +++++ db/src/main/resources/master.yaml | 3 + db/src/main/resources/test/db/default.yaml | 23 +++ db/src/main/resources/test/db/local.yaml | 3 + docker-compose.yaml | 101 ++++++++++++++ model/.gitignore | 1 + model/pom.xml | 72 ++++++++++ model/src/main/java/test/cayenne/E1.java | 9 ++ model/src/main/java/test/cayenne/E2.java | 9 ++ .../src/main/java/test/cayenne/auto/_E1.java | 131 ++++++++++++++++++ .../src/main/java/test/cayenne/auto/_E2.java | 131 ++++++++++++++++++ .../src/main/resources/test/cayenne-test.xml | 11 ++ model/src/main/resources/test/test.map.xml | 40 ++++++ pom.xml | 131 ++++++++++++++++++ run-test.sh | 10 ++ test/.gitignore | 1 + test/Dockerfile | 5 + test/pom.xml | 66 +++++++++ test/src/main/java/test/FailCommand.java | 33 +++++ test/src/main/java/test/HappyCommand.java | 32 +++++ test/src/main/java/test/TestApp.java | 31 +++++ test/src/main/java/test/TestAppProvider.java | 13 ++ test/src/main/java/test/TestCase.java | 30 ++++ .../services/io.bootique.BQModuleProvider | 1 + test/src/main/resources/test/default.yaml | 22 +++ test/src/main/resources/test/local.yaml | 3 + 34 files changed, 1055 insertions(+) create mode 100644 .env create mode 100644 .gitignore create mode 100644 db/.gitignore create mode 100644 db/Dockerfile create mode 100644 db/pom.xml create mode 100644 db/src/main/java/test/DbApp.java create mode 100644 db/src/main/java/test/DbAppProvider.java create mode 100644 db/src/main/resources/META-INF/services/io.bootique.BQModuleProvider create mode 100644 db/src/main/resources/init.sql create mode 100644 db/src/main/resources/master.yaml create mode 100644 db/src/main/resources/test/db/default.yaml create mode 100644 db/src/main/resources/test/db/local.yaml create mode 100644 docker-compose.yaml create mode 100644 model/.gitignore create mode 100644 model/pom.xml create mode 100644 model/src/main/java/test/cayenne/E1.java create mode 100644 model/src/main/java/test/cayenne/E2.java create mode 100644 model/src/main/java/test/cayenne/auto/_E1.java create mode 100644 model/src/main/java/test/cayenne/auto/_E2.java create mode 100644 model/src/main/resources/test/cayenne-test.xml create mode 100644 model/src/main/resources/test/test.map.xml create mode 100644 pom.xml create mode 100755 run-test.sh create mode 100644 test/.gitignore create mode 100644 test/Dockerfile create mode 100644 test/pom.xml create mode 100644 test/src/main/java/test/FailCommand.java create mode 100644 test/src/main/java/test/HappyCommand.java create mode 100644 test/src/main/java/test/TestApp.java create mode 100644 test/src/main/java/test/TestAppProvider.java create mode 100644 test/src/main/java/test/TestCase.java create mode 100644 test/src/main/resources/META-INF/services/io.bootique.BQModuleProvider create mode 100644 test/src/main/resources/test/default.yaml create mode 100644 test/src/main/resources/test/local.yaml diff --git a/.env b/.env new file mode 100644 index 0000000..a3b61e7 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VERSION=1.0-SNAPSHOT \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4a9715 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/**/*.iml +/**/.idea +/**/target +/**/dependency-reduced-pom.xml +/target \ No newline at end of file diff --git a/db/.gitignore b/db/.gitignore new file mode 100644 index 0000000..c41cc9e --- /dev/null +++ b/db/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/db/Dockerfile b/db/Dockerfile new file mode 100644 index 0000000..4b0afca --- /dev/null +++ b/db/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:11 + +ARG version +ADD target/test-db-${version}.jar /test-db.jar +ENTRYPOINT ["java", "-jar", "/test-db.jar"] \ No newline at end of file diff --git a/db/pom.xml b/db/pom.xml new file mode 100644 index 0000000..65b3698 --- /dev/null +++ b/db/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + + test + parent + ${revision}${sha1}${changelist} + + + test-db + jar + DB + + + test.DbApp + + + + + test + test-model + + + + + io.bootique.liquibase + bootique-liquibase + + + io.bootique.logback + bootique-logback + + + io.bootique.jdbc + bootique-jdbc-hikaricp-instrumented + + + mysql + mysql-connector-java + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + diff --git a/db/src/main/java/test/DbApp.java b/db/src/main/java/test/DbApp.java new file mode 100644 index 0000000..ce0f0ec --- /dev/null +++ b/db/src/main/java/test/DbApp.java @@ -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") + ; + } +} diff --git a/db/src/main/java/test/DbAppProvider.java b/db/src/main/java/test/DbAppProvider.java new file mode 100644 index 0000000..4ad6b02 --- /dev/null +++ b/db/src/main/java/test/DbAppProvider.java @@ -0,0 +1,12 @@ +package test; + +import io.bootique.BQModuleProvider; + +public class DbAppProvider implements BQModuleProvider { + public DbAppProvider() {} + + @Override + public DbApp module() { + return new DbApp(); + } +} diff --git a/db/src/main/resources/META-INF/services/io.bootique.BQModuleProvider b/db/src/main/resources/META-INF/services/io.bootique.BQModuleProvider new file mode 100644 index 0000000..f4ca80c --- /dev/null +++ b/db/src/main/resources/META-INF/services/io.bootique.BQModuleProvider @@ -0,0 +1 @@ +test.DbAppProvider \ No newline at end of file diff --git a/db/src/main/resources/init.sql b/db/src/main/resources/init.sql new file mode 100644 index 0000000..4da21bd --- /dev/null +++ b/db/src/main/resources/init.sql @@ -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; diff --git a/db/src/main/resources/master.yaml b/db/src/main/resources/master.yaml new file mode 100644 index 0000000..447a00e --- /dev/null +++ b/db/src/main/resources/master.yaml @@ -0,0 +1,3 @@ +databaseChangeLog: + - include: + file: classpath:init.sql diff --git a/db/src/main/resources/test/db/default.yaml b/db/src/main/resources/test/db/default.yaml new file mode 100644 index 0000000..8843459 --- /dev/null +++ b/db/src/main/resources/test/db/default.yaml @@ -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' diff --git a/db/src/main/resources/test/db/local.yaml b/db/src/main/resources/test/db/local.yaml new file mode 100644 index 0000000..f8ebfab --- /dev/null +++ b/db/src/main/resources/test/db/local.yaml @@ -0,0 +1,3 @@ +jdbc: + test: + jdbcUrl: "jdbc:mysql://192.168.10.64:33006/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8" diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..4275ec9 --- /dev/null +++ b/docker-compose.yaml @@ -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 diff --git a/model/.gitignore b/model/.gitignore new file mode 100644 index 0000000..c41cc9e --- /dev/null +++ b/model/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/model/pom.xml b/model/pom.xml new file mode 100644 index 0000000..0b868f9 --- /dev/null +++ b/model/pom.xml @@ -0,0 +1,72 @@ + + + 4.0.0 + + + test + parent + ${revision}${sha1}${changelist} + + + test-model + + + + org.apache.cayenne + cayenne-lifecycle + ${cayenne.version} + + + + + + + + org.apache.cayenne.plugins + cayenne-maven-plugin + ${cayenne.version} + + ${project.basedir}/src/main/resources/test/test.map.xml + test.cayenne.auto + + com.mysql.cj.jdbc.Driver + ${env.JDBC_TEST_JDBCURL} + root + test + + + test.cayenne + + test + databasechangelog.* + + + true + true + + + + default-cli + + + + + cgen + + + + + + + mysql + mysql-connector-java + ${mysql.version} + + + + + + + \ No newline at end of file diff --git a/model/src/main/java/test/cayenne/E1.java b/model/src/main/java/test/cayenne/E1.java new file mode 100644 index 0000000..a40cc39 --- /dev/null +++ b/model/src/main/java/test/cayenne/E1.java @@ -0,0 +1,9 @@ +package test.cayenne; + +import test.cayenne.auto._E1; + +public class E1 extends _E1 { + + private static final long serialVersionUID = 1L; + +} diff --git a/model/src/main/java/test/cayenne/E2.java b/model/src/main/java/test/cayenne/E2.java new file mode 100644 index 0000000..6ba99b3 --- /dev/null +++ b/model/src/main/java/test/cayenne/E2.java @@ -0,0 +1,9 @@ +package test.cayenne; + +import test.cayenne.auto._E2; + +public class E2 extends _E2 { + + private static final long serialVersionUID = 1L; + +} diff --git a/model/src/main/java/test/cayenne/auto/_E1.java b/model/src/main/java/test/cayenne/auto/_E1.java new file mode 100644 index 0000000..312251c --- /dev/null +++ b/model/src/main/java/test/cayenne/auto/_E1.java @@ -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 TEXT = PropertyFactory.createString("text", String.class); + public static final EntityProperty E2 = PropertyFactory.createEntity("e2", E2.class); + public static final ListProperty 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 getE2s() { + return (List)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(); + } + +} diff --git a/model/src/main/java/test/cayenne/auto/_E2.java b/model/src/main/java/test/cayenne/auto/_E2.java new file mode 100644 index 0000000..da12542 --- /dev/null +++ b/model/src/main/java/test/cayenne/auto/_E2.java @@ -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 TEXT = PropertyFactory.createString("text", String.class); + public static final EntityProperty E1 = PropertyFactory.createEntity("e1", E1.class); + public static final ListProperty 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 getE1s() { + return (List)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(); + } + +} diff --git a/model/src/main/resources/test/cayenne-test.xml b/model/src/main/resources/test/cayenne-test.xml new file mode 100644 index 0000000..e792124 --- /dev/null +++ b/model/src/main/resources/test/cayenne-test.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/model/src/main/resources/test/test.map.xml b/model/src/main/resources/test/test.map.xml new file mode 100644 index 0000000..33e6ede --- /dev/null +++ b/model/src/main/resources/test/test.map.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..ec7d400 --- /dev/null +++ b/pom.xml @@ -0,0 +1,131 @@ + + 4.0.0 + + parent + test + ${revision}${sha1}${changelist} + + Parent + + pom + + + 1.0 + + -SNAPSHOT + + 2.0.M1 + + + 8.0.22 + 3.0.2-rc + 4.2.B1 + + 8 + 8 + UTF-8 + UTF-8 + + Dummy + + + + db + model + test + + + + + + test + test-model + ${project.version} + + + + + io.bootique.bom + bootique-bom + ${bootique.version} + pom + import + + + + + org.apache.cayenne + cayenne-server + ${cayenne.version} + + + + + mysql + mysql-connector-java + ${mysql.version} + + + org.mariadb.jdbc + mariadb-java-client + ${mariadb.version} + + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + true + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + package + + shade + + + + + + ${main.class} + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + true + + + + + + + + + diff --git a/run-test.sh b/run-test.sh new file mode 100755 index 0000000..26285fe --- /dev/null +++ b/run-test.sh @@ -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 \ No newline at end of file diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..c41cc9e --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/test/Dockerfile b/test/Dockerfile new file mode 100644 index 0000000..6a84c6e --- /dev/null +++ b/test/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:11 + +ARG version +ADD target/test-test-${version}.jar /test-test.jar +ENTRYPOINT ["java", "-jar", "/test-test.jar"] \ No newline at end of file diff --git a/test/pom.xml b/test/pom.xml new file mode 100644 index 0000000..f70becb --- /dev/null +++ b/test/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + + test + parent + ${revision}${sha1}${changelist} + + + test-test + + + test.TestApp + + + + + test + test-model + + + + io.bootique.cayenne + bootique-cayenne + + + io.bootique.agrest + bootique-agrest + + + io.agrest + agrest-engine + 4.7 + + + io.bootique.jdbc + bootique-jdbc-hikaricp + + + io.bootique.logback + bootique-logback + + + + mysql + mysql-connector-java + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + + + \ No newline at end of file diff --git a/test/src/main/java/test/FailCommand.java b/test/src/main/java/test/FailCommand.java new file mode 100644 index 0000000..495924b --- /dev/null +++ b/test/src/main/java/test/FailCommand.java @@ -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 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(); + } +} \ No newline at end of file diff --git a/test/src/main/java/test/HappyCommand.java b/test/src/main/java/test/HappyCommand.java new file mode 100644 index 0000000..b571d38 --- /dev/null +++ b/test/src/main/java/test/HappyCommand.java @@ -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 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(); + } +} diff --git a/test/src/main/java/test/TestApp.java b/test/src/main/java/test/TestApp.java new file mode 100644 index 0000000..ce4b9cf --- /dev/null +++ b/test/src/main/java/test/TestApp.java @@ -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") + + ; + } +} diff --git a/test/src/main/java/test/TestAppProvider.java b/test/src/main/java/test/TestAppProvider.java new file mode 100644 index 0000000..0636b74 --- /dev/null +++ b/test/src/main/java/test/TestAppProvider.java @@ -0,0 +1,13 @@ +package test; + +import io.bootique.BQModuleProvider; + +public class TestAppProvider implements BQModuleProvider { + + public TestAppProvider() {} + + @Override + public TestApp module() { + return new TestApp(); + } +} diff --git a/test/src/main/java/test/TestCase.java b/test/src/main/java/test/TestCase.java new file mode 100644 index 0000000..8ead80b --- /dev/null +++ b/test/src/main/java/test/TestCase.java @@ -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(); + } + } +} diff --git a/test/src/main/resources/META-INF/services/io.bootique.BQModuleProvider b/test/src/main/resources/META-INF/services/io.bootique.BQModuleProvider new file mode 100644 index 0000000..2c41f77 --- /dev/null +++ b/test/src/main/resources/META-INF/services/io.bootique.BQModuleProvider @@ -0,0 +1 @@ +test.TestAppProvider \ No newline at end of file diff --git a/test/src/main/resources/test/default.yaml b/test/src/main/resources/test/default.yaml new file mode 100644 index 0000000..2733b31 --- /dev/null +++ b/test/src/main/resources/test/default.yaml @@ -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' diff --git a/test/src/main/resources/test/local.yaml b/test/src/main/resources/test/local.yaml new file mode 100644 index 0000000..8185afc --- /dev/null +++ b/test/src/main/resources/test/local.yaml @@ -0,0 +1,3 @@ +jdbc: + test: + jdbcUrl: "jdbc:mysql://localhost:33006/test?connectTimeout=0&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"