diff --git a/build.gradle b/build.gradle index 28e9640..0d7c939 100644 --- a/build.gradle +++ b/build.gradle @@ -4,14 +4,15 @@ buildscript { } dependencies { classpath "io.ratpack:ratpack-gradle:1.5.1" + classpath 'se.transmode.gradle:gradle-docker:1.2' } } plugins { id 'idea' id 'groovy' - id "io.ratpack.ratpack-groovy" version "1.5.1" - id "org.flywaydb.flyway" version "5.0.7" + id "io.ratpack.ratpack-groovy" version "1.5.1" apply false + id "org.flywaydb.flyway" version "5.0.7" apply false } allprojects { @@ -21,3 +22,7 @@ allprojects { jcenter() } } + +task wrapper(type: Wrapper) { + gradleVersion = '4.7' +} \ No newline at end of file diff --git a/dbt-core/src/main/groovy/com/devsoap/dbt/DBTModule.groovy b/dbt-core/src/main/groovy/com/devsoap/dbt/DBTModule.groovy index ebfe2b5..6079c20 100644 --- a/dbt-core/src/main/groovy/com/devsoap/dbt/DBTModule.groovy +++ b/dbt-core/src/main/groovy/com/devsoap/dbt/DBTModule.groovy @@ -27,6 +27,7 @@ import com.devsoap.dbt.services.LedgerService import com.devsoap.dbt.services.TransactionManagerService import com.fasterxml.jackson.databind.ObjectMapper import com.google.inject.multibindings.Multibinder +import groovy.json.JsonBuilder import groovy.util.logging.Slf4j import ratpack.guice.ConfigurableModule import ratpack.handling.HandlerDecorator @@ -48,7 +49,6 @@ class DBTModule extends ConfigurableModule { bind(ExecutorHandler) bind(LedgerData) - bind(LedgerService) bind(TransactionManagerService) @@ -70,7 +70,7 @@ class DBTModule extends ConfigurableModule { config.executor.remoteUrl = "http://localhost:${serverConfig.port}/${config.executor.path}" } if(!config.ledger.remoteUrl) { - config.executor.remoteUrl = "http://localhost:${serverConfig.port}/${config.ledger.path}" + config.ledger.remoteUrl = "http://localhost:${serverConfig.port}/${config.ledger.path}" } } } \ No newline at end of file diff --git a/dbt-core/src/main/groovy/com/devsoap/dbt/actions/ExecutorChainAction.groovy b/dbt-core/src/main/groovy/com/devsoap/dbt/actions/ExecutorChainAction.groovy index 797814e..1e734a9 100644 --- a/dbt-core/src/main/groovy/com/devsoap/dbt/actions/ExecutorChainAction.groovy +++ b/dbt-core/src/main/groovy/com/devsoap/dbt/actions/ExecutorChainAction.groovy @@ -25,15 +25,19 @@ import ratpack.groovy.handling.GroovyChainAction class ExecutorChainAction extends GroovyChainAction { private final String executorPath + private final boolean enabled @Inject ExecutorChainAction(DBTConfig config) { executorPath = config.executor.path + enabled = config.executor.enabled } @Override void execute() throws Exception { - log.info("Registering executor at $executorPath") + if(!enabled) return + + log.info("Registering executor at /$executorPath") path(executorPath, ExecutorHandler) } } diff --git a/dbt-core/src/main/groovy/com/devsoap/dbt/actions/LedgerChainAction.groovy b/dbt-core/src/main/groovy/com/devsoap/dbt/actions/LedgerChainAction.groovy index eb06f0a..e3cbadb 100644 --- a/dbt-core/src/main/groovy/com/devsoap/dbt/actions/LedgerChainAction.groovy +++ b/dbt-core/src/main/groovy/com/devsoap/dbt/actions/LedgerChainAction.groovy @@ -28,15 +28,19 @@ import ratpack.handling.Handlers class LedgerChainAction extends GroovyChainAction { private final String ledgerPath + private final boolean enabled @Inject LedgerChainAction(DBTConfig config) { ledgerPath = config.ledger.path + enabled = config.ledger.enabled } @Override void execute() throws Exception { - log.info("Registering ledger at $ledgerPath") + if(!enabled) return + + log.info("Registering ledger at /$ledgerPath") path(ledgerPath, Handlers.chain( registry.get(LedgerGetTransactionHandler), registry.get(LedgerUpdateTransactionHandler), diff --git a/dbt-core/src/main/groovy/com/devsoap/dbt/config/ExecutorConfig.groovy b/dbt-core/src/main/groovy/com/devsoap/dbt/config/ExecutorConfig.groovy index 833ed76..81a2a76 100644 --- a/dbt-core/src/main/groovy/com/devsoap/dbt/config/ExecutorConfig.groovy +++ b/dbt-core/src/main/groovy/com/devsoap/dbt/config/ExecutorConfig.groovy @@ -16,6 +16,7 @@ package com.devsoap.dbt.config class ExecutorConfig { + boolean enabled = true String path = 'executor' String remoteUrl } diff --git a/dbt-core/src/main/groovy/com/devsoap/dbt/config/LedgerConfig.groovy b/dbt-core/src/main/groovy/com/devsoap/dbt/config/LedgerConfig.groovy index a73dc0f..e6392ab 100644 --- a/dbt-core/src/main/groovy/com/devsoap/dbt/config/LedgerConfig.groovy +++ b/dbt-core/src/main/groovy/com/devsoap/dbt/config/LedgerConfig.groovy @@ -16,6 +16,7 @@ package com.devsoap.dbt.config class LedgerConfig { + boolean enabled = true String path = 'ledger' String remoteUrl } diff --git a/dbt-core/src/main/groovy/com/devsoap/dbt/handlers/ExecutorHandler.groovy b/dbt-core/src/main/groovy/com/devsoap/dbt/handlers/ExecutorHandler.groovy index 3eaa30f..9550394 100644 --- a/dbt-core/src/main/groovy/com/devsoap/dbt/handlers/ExecutorHandler.groovy +++ b/dbt-core/src/main/groovy/com/devsoap/dbt/handlers/ExecutorHandler.groovy @@ -22,6 +22,7 @@ import groovy.util.logging.Slf4j import ratpack.exec.Promise import ratpack.handling.Context import ratpack.handling.Handler +import ratpack.http.HttpMethod import ratpack.http.Status import ratpack.http.client.HttpClient import ratpack.jdbctx.Transaction @@ -46,32 +47,36 @@ class ExecutorHandler implements Handler { @Override void handle(Context ctx) throws Exception { - ctx.request.body.then { body -> - def mapper = ctx.get(ObjectMapper) - def ds = ctx.get(DataSource) - def transaction = mapper.readValue(body.text, BlockTransaction) + if(ctx.request.method == HttpMethod.POST) { + ctx.request.body.then { body -> + def mapper = ctx.get(ObjectMapper) + def ds = ctx.get(DataSource) + def transaction = mapper.readValue(body.text, BlockTransaction) - if(!validateChain(transaction)) { - ctx.response.status(Status.of(400, 'Transaction chain invalid')) - return - } - - executeCommands(ds, transaction).onError { e -> - log.info("Sending rolled back transaction to ledger") - println mapper.writeValueAsString(transaction) - client.post(config.ledger.remoteUrl.toURI(), { spec -> - spec.body.text(mapper.writeValueAsString(transaction)) - }).then { - ctx.error(e) + if(!validateChain(transaction)) { + ctx.response.status(Status.of(400, 'Transaction chain invalid')) + return } - }.then { - log.info("Updating ledger with execution result") - client.post(config.ledger.remoteUrl.toURI(), { spec -> - spec.body.text(mapper.writeValueAsString(transaction)) - }).then { - ctx.response.send(mapper.writeValueAsString(transaction)) + + executeCommands(ds, transaction).onError { e -> + log.info("Sending rolled back transaction to ledger") + println mapper.writeValueAsString(transaction) + client.post(config.ledger.remoteUrl.toURI(), { spec -> + spec.body.text(mapper.writeValueAsString(transaction)) + }).then { + ctx.error(e) + } + }.then { + log.info("Updating ledger with execution result") + client.post(config.ledger.remoteUrl.toURI(), { spec -> + spec.body.text(mapper.writeValueAsString(transaction)) + }).then { + ctx.response.send(mapper.writeValueAsString(transaction)) + } } } + } else { + ctx.next() } } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9365cf4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '2' + +services: + executor: + image: com.devsoap/dbt-executor + container_name: dbt-executor + environment: + - dbt.ledger.url=http://ledger:5050 + ledger: + image: com.devsoap/dbt-ledger + container_name: dbt-ledger + environment: + - dbt.executor.url=http://executor:5050 \ No newline at end of file diff --git a/docker-executor/build.gradle b/docker-executor/build.gradle new file mode 100644 index 0000000..1db051d --- /dev/null +++ b/docker-executor/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'docker' + +group 'com.devsoap' + +dependencies { + compile project(':dbt-core') + runtime ratpack.dependency('h2') + runtime ratpack.dependency('jdbc-tx') + runtime 'org.slf4j:slf4j-simple:1.7.25' +} + +run { + environment('RATPACK_DBT__LEDGER__REMOTE_URL', findProperty('ledgerURL').toString() ?: "http://localhost:5050/ledger") + environment('RATPACK_DBT__LEDGER__ENABLED', false) +} + +distDocker { + registry = findProperty('dockerRegistry') + tagVersion = 'latest' + exposePort 5050 + run.environment.each {key,value -> setEnvironment(key.toString(), value.toString())} +} diff --git a/docker-executor/src/ratpack/Ratpack.groovy b/docker-executor/src/ratpack/Ratpack.groovy new file mode 100644 index 0000000..e783ffc --- /dev/null +++ b/docker-executor/src/ratpack/Ratpack.groovy @@ -0,0 +1,24 @@ +import com.devsoap.dbt.DBTModule +import org.h2.jdbcx.JdbcDataSource +import org.slf4j.LoggerFactory + +import javax.sql.DataSource + +import static ratpack.groovy.Groovy.ratpack + +def log = LoggerFactory.getLogger('dbt-executor') + +ratpack { + serverConfig { + env() + sysProps() + } + + bindings { + bindInstance(DataSource, new JdbcDataSource(url: 'jdbc:h2:mem:dbtdb;DB_CLOSE_DELAY=-1', user: '')) + module (DBTModule) { config -> + log.info "Executor available at $config.executor.remoteUrl" + log.info "Ledger available at $config.ledger.remoteUrl" + } + } +} diff --git a/docker-ledger/Ratpack.groovy b/docker-ledger/Ratpack.groovy new file mode 100644 index 0000000..669f971 --- /dev/null +++ b/docker-ledger/Ratpack.groovy @@ -0,0 +1,16 @@ +@Grapes([ + @Grab('io.ratpack:ratpack-groovy:1.5.4'), + @Grab('org.slf4j:slf4j-simple:1.7.25') +]) + +import com.devsoap.dbt.DBTModule + +import static ratpack.groovy.Groovy.ratpack + +ratpack { + bindings { + module (DBTModule) { config -> + config.executor.remoteUrl = System.properties.getProperty('dbt.executor.url') + } + } +} diff --git a/docker-ledger/build.gradle b/docker-ledger/build.gradle new file mode 100644 index 0000000..9c0012a --- /dev/null +++ b/docker-ledger/build.gradle @@ -0,0 +1,22 @@ +apply plugin: 'docker' + +group 'com.devsoap' + +dependencies { + compile project(':dbt-core') + runtime ratpack.dependency('h2') + runtime ratpack.dependency('jdbc-tx') + runtime 'org.slf4j:slf4j-simple:1.7.25' +} + +run { + environment('RATPACK_DBT__EXECUTOR__REMOTE_URL', findProperty('executorURL').toString() ?: "http://localhost:5050/executor") + environment('RATPACK_DBT__EXECUTOR__ENABLED', false) +} + +distDocker { + registry = findProperty('dockerRegistry') + tagVersion = 'latest' + exposePort 5050 + run.environment.each {key,value -> setEnvironment(key.toString(), value.toString())} +} diff --git a/docker-ledger/src/ratpack/Ratpack.groovy b/docker-ledger/src/ratpack/Ratpack.groovy new file mode 100644 index 0000000..e783ffc --- /dev/null +++ b/docker-ledger/src/ratpack/Ratpack.groovy @@ -0,0 +1,24 @@ +import com.devsoap.dbt.DBTModule +import org.h2.jdbcx.JdbcDataSource +import org.slf4j.LoggerFactory + +import javax.sql.DataSource + +import static ratpack.groovy.Groovy.ratpack + +def log = LoggerFactory.getLogger('dbt-executor') + +ratpack { + serverConfig { + env() + sysProps() + } + + bindings { + bindInstance(DataSource, new JdbcDataSource(url: 'jdbc:h2:mem:dbtdb;DB_CLOSE_DELAY=-1', user: '')) + module (DBTModule) { config -> + log.info "Executor available at $config.executor.remoteUrl" + log.info "Ledger available at $config.ledger.remoteUrl" + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 9411448..91ca28c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 35937d2..16d2805 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Feb 23 08:49:01 EET 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip diff --git a/gradlew b/gradlew index 9d82f78..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,42 +6,6 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -60,6 +24,46 @@ cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282..f955316 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/settings.gradle b/settings.gradle index 99a4aad..d83491a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,8 @@ include 'dbt-core' include 'dbt-test' include 'dbt-demo' +include 'docker-executor' +include 'docker-ledger' +project(':docker-executor').name = 'dbt-executor' +project(':docker-ledger').name = 'dbt-ledger'