Improve demo
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
package com.devsoap.dbt.data
|
package com.devsoap.dbt.data
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonValue
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode
|
|
||||||
import groovy.transform.ToString
|
import groovy.transform.ToString
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
@@ -54,6 +52,7 @@ class BlockTransaction implements Serializable {
|
|||||||
long timeStamp
|
long timeStamp
|
||||||
|
|
||||||
Map<String, List> result
|
Map<String, List> result
|
||||||
|
String resultError
|
||||||
|
|
||||||
Query() {
|
Query() {
|
||||||
// For serialization
|
// For serialization
|
||||||
|
|||||||
@@ -82,17 +82,28 @@ class ExecutorHandler implements Handler {
|
|||||||
def tx = Transaction.create { ds.connection }
|
def tx = Transaction.create { ds.connection }
|
||||||
tx.wrap {
|
tx.wrap {
|
||||||
Promise.sync {
|
Promise.sync {
|
||||||
|
try {
|
||||||
transaction.queries.each { block ->
|
transaction.queries.each { block ->
|
||||||
log.info "Executing $block.query ..."
|
try{
|
||||||
if(block.query.toLowerCase().startsWith("select")){
|
|
||||||
log.info('Saving result from Select query')
|
|
||||||
def result = txDs.connection
|
def result = txDs.connection
|
||||||
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)
|
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)
|
||||||
.executeQuery(block.query)
|
.executeQuery(block.query)
|
||||||
block.result = toMap(result)
|
block.result = toMap(result)
|
||||||
|
log.info "Executing $block.query ..."
|
||||||
|
if(block.query.toLowerCase().startsWith("select")){
|
||||||
|
log.info('Saving result from Select query')
|
||||||
} else {
|
} else {
|
||||||
txDs.connection.createStatement().execute(block.query)
|
txDs.connection.createStatement().execute(block.query)
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
block.resultError = e.message
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to execute transaction $transaction.id, transaction rolled back", e)
|
||||||
|
tx.rollback()
|
||||||
|
transaction.rolledback = true
|
||||||
}
|
}
|
||||||
transaction
|
transaction
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ class TransactionManagerService implements Service {
|
|||||||
httpClient.get(config.ledger.remoteUrl.toURI(), { spec ->
|
httpClient.get(config.ledger.remoteUrl.toURI(), { spec ->
|
||||||
spec.headers.add('X-Transaction-Id', transactionId)
|
spec.headers.add('X-Transaction-Id', transactionId)
|
||||||
}).flatMap { response ->
|
}).flatMap { response ->
|
||||||
|
if(response.status == Status.of(404)) {
|
||||||
|
throw new RuntimeException("Transaction with id '$transactionId' could not be found")
|
||||||
|
}
|
||||||
if(response.status != Status.OK) {
|
if(response.status != Status.OK) {
|
||||||
throw new RuntimeException("Server returned ${response.statusCode} ${response.status.message}")
|
throw new RuntimeException("Ledger returned ${response.statusCode} ${response.status.message} for $transactionId")
|
||||||
}
|
}
|
||||||
def oldTransaction = mapper.readValue(response.body.text, BlockTransaction)
|
def oldTransaction = mapper.readValue(response.body.text, BlockTransaction)
|
||||||
if(oldTransaction == null) {
|
|
||||||
throw new RuntimeException("Transaction with id $transactionId could not be found")
|
|
||||||
}
|
|
||||||
if(oldTransaction.completed) {
|
if(oldTransaction.completed) {
|
||||||
throw new RuntimeException("Cannot modify a completed transaction")
|
throw new RuntimeException("Cannot modify a completed transaction")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ apply plugin: "org.flywaydb.flyway"
|
|||||||
dependencies {
|
dependencies {
|
||||||
compile project(':dbt-core')
|
compile project(':dbt-core')
|
||||||
|
|
||||||
|
runtime ratpack.dependency('handlebars')
|
||||||
runtime ratpack.dependency('h2')
|
runtime ratpack.dependency('h2')
|
||||||
runtime ratpack.dependency('jdbc-tx')
|
runtime ratpack.dependency('jdbc-tx')
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ import com.devsoap.dbt.config.DBTConfig
|
|||||||
import com.devsoap.dbt.demo.DatabaseService
|
import com.devsoap.dbt.demo.DatabaseService
|
||||||
import com.devsoap.dbt.services.TransactionManagerService
|
import com.devsoap.dbt.services.TransactionManagerService
|
||||||
import org.h2.jdbcx.JdbcDataSource
|
import org.h2.jdbcx.JdbcDataSource
|
||||||
|
import ratpack.form.Form
|
||||||
|
import ratpack.handlebars.HandlebarsModule
|
||||||
|
import ratpack.http.Status
|
||||||
|
|
||||||
import javax.sql.DataSource
|
import javax.sql.DataSource
|
||||||
|
|
||||||
import static ratpack.groovy.Groovy.ratpack
|
import static ratpack.groovy.Groovy.ratpack
|
||||||
|
import static ratpack.handlebars.Template.handlebarsTemplate
|
||||||
|
|
||||||
ratpack {
|
ratpack {
|
||||||
|
|
||||||
@@ -16,6 +20,8 @@ ratpack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bindings {
|
bindings {
|
||||||
|
module HandlebarsModule
|
||||||
|
|
||||||
module (DBTModule) {
|
module (DBTModule) {
|
||||||
it.ledger.remoteUrl = 'http://localhost:5050/ledger'
|
it.ledger.remoteUrl = 'http://localhost:5050/ledger'
|
||||||
it.executor.remoteUrl = 'http://localhost:5050/executor'
|
it.executor.remoteUrl = 'http://localhost:5050/executor'
|
||||||
@@ -27,31 +33,43 @@ ratpack {
|
|||||||
|
|
||||||
handlers {
|
handlers {
|
||||||
|
|
||||||
/**
|
get {
|
||||||
* Consumer services
|
render handlebarsTemplate('index.html')
|
||||||
*/
|
}
|
||||||
get('') {
|
|
||||||
get(TransactionManagerService).execute { transaction ->
|
post('addQueryToTransaction') {
|
||||||
transaction.query("INSERT INTO LOGS(LOG_ID,LOG_VALUE) VALUES (${new Random().nextInt()}, 'HELLO')")
|
def transactionManager = get(TransactionManagerService)
|
||||||
|
parse(Form).then { Form form ->
|
||||||
|
def query = form.get('query')
|
||||||
|
def transactionId = form.get('transactionId')
|
||||||
|
if(transactionId) {
|
||||||
|
transactionManager.execute(transactionId) {
|
||||||
|
it.query(query)
|
||||||
} .then {
|
} .then {
|
||||||
redirect("/gateway/${it['id'].textValue()}")
|
response.send(it.toString())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transactionManager.execute {
|
||||||
|
it.query(query)
|
||||||
|
} .then {
|
||||||
|
response.send(it.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get('gateway/:transactionId?') {
|
post('executeTransaction') {
|
||||||
get(TransactionManagerService).execute(pathTokens.transactionId, { transaction ->
|
def transactionManager = get(TransactionManagerService)
|
||||||
transaction.query("INSERT INTO LOGS(LOG_ID,LOG_VALUE) VALUES (${new Random().nextInt()}, 'WORLD')")
|
parse(Form).then { Form form ->
|
||||||
}).then {
|
def transactionId = form.get('transactionId')
|
||||||
redirect("/gateway2/${it['id'].textValue()}")
|
transactionManager.execute(transactionId) {
|
||||||
}
|
it.complete()
|
||||||
}
|
}.onError {
|
||||||
|
response.status(Status.of(501))
|
||||||
get('gateway2/:transactionId?') {
|
response.send(it.message)
|
||||||
get(TransactionManagerService).execute(pathTokens.transactionId, { transaction ->
|
}.then {
|
||||||
transaction.query("SELECT * FROM LOGS")
|
response.send(it.toString())
|
||||||
transaction.complete()
|
}
|
||||||
}).then {
|
|
||||||
redirect('/ledger')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
dbt-demo/src/ratpack/handlebars/index.html.hbs
Normal file
78
dbt-demo/src/ratpack/handlebars/index.html.hbs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="http://esironal.github.io/cmtouch/lib/codemirror.css">
|
||||||
|
<link rel="stylesheet" href="http://esironal.github.io/cmtouch/addon/hint/show-hint.css">
|
||||||
|
<script src="http://esironal.github.io/cmtouch/lib/codemirror.js"></script>
|
||||||
|
<script src="http://esironal.github.io/cmtouch/mode/javascript/javascript.js"></script>
|
||||||
|
<script src="http://esironal.github.io/cmtouch/mode/css/css.js"></script>
|
||||||
|
<script src="http://esironal.github.io/cmtouch/addon/selection/active-line.js"></script>
|
||||||
|
<script src="http://esironal.github.io/cmtouch/addon/edit/matchbrackets.js"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||||
|
<style type="text/css">.CodeMirror { font-size: 10px;width: 100%;height: 100%;}</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<main style="width:50%;height:100%;float:left">
|
||||||
|
<h2>Transactions</h2>
|
||||||
|
<form id="addQueryForm" action='/'>
|
||||||
|
<input type="hidden" name="transactionId" id="transactionId" />
|
||||||
|
<input name="query" style="width:300px" placeholder="Add query here..." />
|
||||||
|
<button type="submit">Submit Query</button>
|
||||||
|
</form>
|
||||||
|
<form id="executeTransactionForm" action='/'>
|
||||||
|
<input type="hidden" name="transactionId" id="transactionId" />
|
||||||
|
<button id='executeTransactionButton' type="submit">Execute Transaction</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<aside style="width:50%;height:100%;float:right" >
|
||||||
|
<h2>Ledger</h2>
|
||||||
|
<div id="ledger-content"></div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var editor = CodeMirror(document.getElementById("ledger-content"), {
|
||||||
|
mode: "application/json",
|
||||||
|
lineWrapping: true,
|
||||||
|
lineNumbers: true,
|
||||||
|
styleActiveLine: true,
|
||||||
|
matchBrackets: true
|
||||||
|
});
|
||||||
|
|
||||||
|
function refreshLedger() {
|
||||||
|
$.get('/ledger', function(data) {
|
||||||
|
editor.setValue(JSON.stringify(data, null, 2));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addQueryToTransaction(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var queryData = $('form#addQueryForm').serialize();
|
||||||
|
$.post( '/addQueryToTransaction', queryData, function(data) {
|
||||||
|
$('input#transactionId').val(data.id);
|
||||||
|
$('button#executeTransactionButton').show();
|
||||||
|
refreshLedger();
|
||||||
|
}, 'json');
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeTransaction(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var queryData = $('form#executeTransactionForm').serialize();
|
||||||
|
$.post( '/executeTransaction', queryData, function(data) {
|
||||||
|
$('input#transactionId').val(null);
|
||||||
|
$('button#executeTransactionButton').hide();
|
||||||
|
refreshLedger();
|
||||||
|
}, 'json').fail(function(response) {
|
||||||
|
alert(response.responseText);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$( "#addQueryForm" ).submit(addQueryToTransaction);
|
||||||
|
$( "#executeTransactionForm" ).submit(executeTransaction);
|
||||||
|
$('button#executeTransactionButton').hide();
|
||||||
|
window.onload = refreshLedger();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
Reference in New Issue
Block a user