1

Improve demo

This commit is contained in:
2018-05-05 09:20:04 +03:00
parent 76512ee32e
commit c2fda1ffaf
6 changed files with 145 additions and 38 deletions

View File

@@ -1,7 +1,5 @@
package com.devsoap.dbt.data
import com.fasterxml.jackson.annotation.JsonValue
import com.fasterxml.jackson.databind.JsonNode
import groovy.transform.ToString
import java.nio.charset.StandardCharsets
@@ -54,6 +52,7 @@ class BlockTransaction implements Serializable {
long timeStamp
Map<String, List> result
String resultError
Query() {
// For serialization

View File

@@ -82,17 +82,28 @@ class ExecutorHandler implements Handler {
def tx = Transaction.create { ds.connection }
tx.wrap {
Promise.sync {
try {
transaction.queries.each { block ->
log.info "Executing $block.query ..."
if(block.query.toLowerCase().startsWith("select")){
log.info('Saving result from Select query')
try{
def result = txDs.connection
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)
.executeQuery(block.query)
block.result = toMap(result)
log.info "Executing $block.query ..."
if(block.query.toLowerCase().startsWith("select")){
log.info('Saving result from Select query')
} else {
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
}

View File

@@ -55,13 +55,13 @@ class TransactionManagerService implements Service {
httpClient.get(config.ledger.remoteUrl.toURI(), { spec ->
spec.headers.add('X-Transaction-Id', transactionId)
}).flatMap { response ->
if(response.status == Status.of(404)) {
throw new RuntimeException("Transaction with id '$transactionId' could not be found")
}
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)
if(oldTransaction == null) {
throw new RuntimeException("Transaction with id $transactionId could not be found")
}
if(oldTransaction.completed) {
throw new RuntimeException("Cannot modify a completed transaction")
}

View File

@@ -3,6 +3,7 @@ apply plugin: "org.flywaydb.flyway"
dependencies {
compile project(':dbt-core')
runtime ratpack.dependency('handlebars')
runtime ratpack.dependency('h2')
runtime ratpack.dependency('jdbc-tx')

View File

@@ -3,10 +3,14 @@ import com.devsoap.dbt.config.DBTConfig
import com.devsoap.dbt.demo.DatabaseService
import com.devsoap.dbt.services.TransactionManagerService
import org.h2.jdbcx.JdbcDataSource
import ratpack.form.Form
import ratpack.handlebars.HandlebarsModule
import ratpack.http.Status
import javax.sql.DataSource
import static ratpack.groovy.Groovy.ratpack
import static ratpack.handlebars.Template.handlebarsTemplate
ratpack {
@@ -16,6 +20,8 @@ ratpack {
}
bindings {
module HandlebarsModule
module (DBTModule) {
it.ledger.remoteUrl = 'http://localhost:5050/ledger'
it.executor.remoteUrl = 'http://localhost:5050/executor'
@@ -27,31 +33,43 @@ ratpack {
handlers {
/**
* Consumer services
*/
get('') {
get(TransactionManagerService).execute { transaction ->
transaction.query("INSERT INTO LOGS(LOG_ID,LOG_VALUE) VALUES (${new Random().nextInt()}, 'HELLO')")
get {
render handlebarsTemplate('index.html')
}
post('addQueryToTransaction') {
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 {
redirect("/gateway/${it['id'].textValue()}")
response.send(it.toString())
}
} else {
transactionManager.execute {
it.query(query)
} .then {
response.send(it.toString())
}
}
}
}
get('gateway/:transactionId?') {
get(TransactionManagerService).execute(pathTokens.transactionId, { transaction ->
transaction.query("INSERT INTO LOGS(LOG_ID,LOG_VALUE) VALUES (${new Random().nextInt()}, 'WORLD')")
}).then {
redirect("/gateway2/${it['id'].textValue()}")
}
}
get('gateway2/:transactionId?') {
get(TransactionManagerService).execute(pathTokens.transactionId, { transaction ->
transaction.query("SELECT * FROM LOGS")
transaction.complete()
}).then {
redirect('/ledger')
post('executeTransaction') {
def transactionManager = get(TransactionManagerService)
parse(Form).then { Form form ->
def transactionId = form.get('transactionId')
transactionManager.execute(transactionId) {
it.complete()
}.onError {
response.status(Status.of(501))
response.send(it.message)
}.then {
response.send(it.toString())
}
}
}
}

View 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>