From 4e7fa76c97b54001101d64dfab5912199b4c5e36 Mon Sep 17 00:00:00 2001 From: "d.baykov" Date: Fri, 30 Nov 2018 18:50:45 +0300 Subject: [PATCH] Maven plugin "PostgreSQL embended" ver.1.0 --- .gitignore | 83 ++++++++++ README.md | 111 +++++++++++++ pom.xml | 82 ++++++++++ .../pg_embedded_plugin/GeneralMojo.java | 23 +++ .../pg_embedded_plugin/StartPgServerMojo.java | 152 ++++++++++++++++++ .../pg_embedded_plugin/StopPgServerMojo.java | 38 +++++ 6 files changed, 489 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/GeneralMojo.java create mode 100644 src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StartPgServerMojo.java create mode 100644 src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StopPgServerMojo.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b2e2da2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,83 @@ +# Created by .ignore support plugin (hsz.mobi) +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/ +.idea/workspace.xml +.idea/tasks.xml +.idea/dictionaries +.idea/vcs.xml +.idea/jsLibraryMappings.xml + +# Sensitive or high-churn files: +.idea/dataSources.ids +.idea/dataSources.xml +.idea/dataSources.local.xml +.idea/sqlDataSources.xml +.idea/dynamic.xml +.idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +.idea/mongoSettings.xml + +## File-based project format: +*.iws +*.ipr +*.iml + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Java template +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +env.list + + +# OSX +*.DS_Store +.AppleDouble +.LSOverride + +# TestContainers +.testcontainers-* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ec4263 --- /dev/null +++ b/README.md @@ -0,0 +1,111 @@ +##pg embedded plugin + +This is a maven plugin for for starting a embedded postgresql server. + +You can use this example to start the server during maven initialization lifecicle. + + +#####Example: + + + com.rbkmoney.maven.plugins + pg-embedded-plugin + 1.0 + + port + database_name + + schema_name + + + + + PG_server_start + validate + + start + + + + PG_server_stop + compile + + stop + + + + + +#####Example for flyway and jooq: + + + org.flywaydb + flyway-maven-plugin + ${flyway.version} + + ${local.db.url} + ${local.db.user} + ${local.db.password} + + ${local.db.scheme} + + + + + migrate + initialize + + clean + migrate + + + + + + org.postgresql + postgresql + ${postgresql.jdbc.version} + + + + + org.jooq + jooq-codegen-maven + ${jooq.version} + + + org.postgresql.Driver + ${local.db.url} + ${local.db.user} + ${local.db.password} + + + + true + true + true + true + + + org.jooq.util.postgres.PostgresDatabase + .* + schema_version|.*func|get_adjustment.*|get_cashflow.*|get_payment.*|get_payout.*|get_refund.* + ${local.db.scheme} + + + target/generated-sources/db/ + + + + + + gen-src + generate-sources + + generate + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..84e6d1e --- /dev/null +++ b/pom.xml @@ -0,0 +1,82 @@ + + + 4.0.0 + + com.rbkmoney.maven.plugins + pg-embedded-plugin + maven-plugin + 1.0 + + pg-embedded-plugin Maven Mojo + The plugin starts the embedded PG server + + + Dmitrii Baikov <d.baykov@rbkmoney.com> + UTF-8 + 42.2.5 + + + + + org.apache.maven + maven-plugin-api + 3.0.5 + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.2 + provided + + + org.apache.maven + maven-settings + 3.0.5 + + + org.apache.commons + commons-lang3 + 3.1 + + + org.apache.commons + commons-collections4 + 4.1 + + + + com.opentable.components + otj-pg-embedded + 0.12.5 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + UTF-8 + + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.6.0 + + + default-descriptor + process-classes + + + + + + + diff --git a/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/GeneralMojo.java b/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/GeneralMojo.java new file mode 100644 index 0000000..e6d33ec --- /dev/null +++ b/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/GeneralMojo.java @@ -0,0 +1,23 @@ +package com.rbkmoney.maven.plugins.pg_embedded_plugin; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Parameter; + +public abstract class GeneralMojo extends AbstractMojo { + + @Parameter(defaultValue = "false") + private boolean skipGoal; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (skipGoal) { + getLog().debug("Goal was skipped"); + } else { + doExecute(); + } + } + + protected abstract void doExecute() throws MojoExecutionException, MojoFailureException; + +} diff --git a/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StartPgServerMojo.java b/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StartPgServerMojo.java new file mode 100644 index 0000000..ece0a17 --- /dev/null +++ b/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StartPgServerMojo.java @@ -0,0 +1,152 @@ +package com.rbkmoney.maven.plugins.pg_embedded_plugin; + +import com.opentable.db.postgres.embedded.EmbeddedPostgres; +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +/** + * Class to start the embedded server + * + * @author d.baykov + */ +@Mojo(name = "start", defaultPhase = LifecyclePhase.INITIALIZE) +public class StartPgServerMojo extends GeneralMojo { + + /** Directory where the project is located */ + @Parameter(defaultValue = "${project.build.directory}") + private String projectBuildDir; + + /** PostgreSQL version */ + @Parameter(property = "version") + private String version; + + /** Directory that will host the service files of postgresql */ + @Parameter(property = "dbDir") + private String dbDir; + + /** A port on which the instance will be raised */ + @Parameter(property = "port", defaultValue = "15432", required = true) + private int port; + + /** */ + @Parameter(property = "username", defaultValue = "postgres", required = true) + private String userName; + + /** */ + @Parameter(property = "password", defaultValue = "postgres") + private String password; + + /** */ + @Parameter(property = "dbName", required = true) + private String dbName; + + /** */ + @Parameter(property = "schemas", required = true) + private List schemas; + + /** Instance of the PostgreSQL */ + private static EmbeddedPostgres embeddedPostgres; + + /** Thread where the PostgreSQL server is running */ + private static Thread postgresThread; + + @Override + protected void doExecute() throws MojoExecutionException, MojoFailureException { + postgresThread = new Thread(() -> { + try { + startPgServer(); + createDatabase(); + createSchemas(); + } catch (IOException e) { + getLog().error("Errors occurred while starting the PG server:", e); + } catch (SQLException e) { + getLog().error("Errors occurred while creating objects:", e); + } + + }, "PG-embedded-server"); + postgresThread.start(); + try { + postgresThread.join(); + } catch (InterruptedException e) { + throw new RuntimeException("Embedded Postgres thread was interrupted", e); + } + } + + /** Method starts PG server */ + private void startPgServer() throws IOException { + if (embeddedPostgres == null) { + getLog().info("The PG server is starting..."); + EmbeddedPostgres.Builder builder = EmbeddedPostgres.builder(); + String dbDir = prepareDbDir(); + getLog().info("Dir for PG files: " + dbDir); + builder.setDataDirectory(dbDir); + builder.setPort(port); + //TODO: this can be implemented in the future... + //builder.setCleanDataDirectory(true); + //builder.setLocaleConfig(); + //builder.setServerConfig(); + //builder.setConnectConfig(); + embeddedPostgres = builder.start(); + getLog().info("The PG server was started!"); + } else { + getLog().warn("The PG server is already running!"); + } + } + + /** The method creates a new database */ + private void createDatabase() throws SQLException { + try (Connection conn = embeddedPostgres.getPostgresDatabase().getConnection()) { + Statement statement = conn.createStatement(); + statement.execute("CREATE DATABASE " + dbName); + statement.close(); + } catch (SQLException ex) { + getLog().error("An error occurred while creating the database "+ dbName); + throw ex; + } + } + + /** The method creates a new schema in the created database */ + private void createSchemas() throws SQLException { + DataSource database = embeddedPostgres.getDatabase(userName, dbName); + + try (Connection connection = database.getConnection()) { + Statement statement = connection.createStatement(); + for (String schema : schemas) { + statement.execute("CREATE SCHEMA " + schema); + } + statement.close(); + } catch (SQLException ex) { + getLog().error("An error occurred while creating the schemas " + schemas); + throw ex; + } + } + + /** The method sets the directory for placing postgre service files */ + private String prepareDbDir() { + if (StringUtils.isEmpty(dbDir)) { + return projectBuildDir + File.separator + "pgdata"; + } else { + return dbDir; + } + } + + public static EmbeddedPostgres getEmbeddedPostgres() { + return embeddedPostgres; + } + + public static Thread getPostgresThread() { + return postgresThread; + } +} diff --git a/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StopPgServerMojo.java b/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StopPgServerMojo.java new file mode 100644 index 0000000..e3bc2c7 --- /dev/null +++ b/src/main/java/com/rbkmoney/maven/plugins/pg_embedded_plugin/StopPgServerMojo.java @@ -0,0 +1,38 @@ +package com.rbkmoney.maven.plugins.pg_embedded_plugin; + +import com.opentable.db.postgres.embedded.EmbeddedPostgres; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; + +import java.io.IOException; + +/** + * Class to stop the embedded server + * + * @author d.baykov + */ +@Mojo(name = "stop", defaultPhase = LifecyclePhase.COMPILE, threadSafe = true) +public class StopPgServerMojo extends GeneralMojo { + + /** Instance of the PostgreSQL */ + private EmbeddedPostgres embeddedPostgres; + + @Override + protected void doExecute() throws MojoExecutionException, MojoFailureException { + embeddedPostgres = StartPgServerMojo.getEmbeddedPostgres(); + if (embeddedPostgres == null) { + getLog().info("The PG server wasn't started"); + } else { + try { + getLog().info("Stopping the PG server..."); + embeddedPostgres.close(); + getLog().info("The PG server stopped"); + } catch (IOException e) { + getLog().error("Error encountered while stopping the server ", e); + } + } + StartPgServerMojo.getPostgresThread().interrupt(); + } +} \ No newline at end of file