1

Allow to select between in-memory ledger and mongo ledger

This commit is contained in:
2018-06-10 09:12:16 +03:00
parent 0f24c37ac5
commit feabe74942
10 changed files with 212 additions and 78 deletions

View File

@@ -19,9 +19,9 @@ import com.devsoap.dbt.config.DBTConfig
import com.devsoap.dbt.data.BlockTransaction
import com.devsoap.dbt.data.Query
import com.devsoap.dbt.services.LedgerService
import com.devsoap.dbt.services.MongoLedgerService
import com.fasterxml.jackson.databind.ObjectMapper
import groovy.util.logging.Slf4j
import ratpack.exec.Promise
import ratpack.handling.Context
import ratpack.handling.Handler
import ratpack.http.HttpMethod

View File

@@ -7,6 +7,8 @@ import com.google.inject.multibindings.Multibinder
import ratpack.handling.HandlerDecorator
import ratpack.server.ServerConfig
import javax.sql.DataSource
class DBTExecutorModule extends DBTModule {
@Override
@@ -16,6 +18,8 @@ class DBTExecutorModule extends DBTModule {
bind(ExecutorChainAction)
bind(ExecutorHandler)
requireBinding(DataSource)
Multibinder.newSetBinder(binder(), HandlerDecorator).addBinding()
.toInstance(HandlerDecorator.prependHandlers(ExecutorChainAction))
}

View File

@@ -20,7 +20,8 @@ class DBTLedgerModule extends DBTModule {
bind(LedgerGetTransactionHandler)
bind(LedgerListTransactionsHandler)
bind(LedgerUpdateTransactionHandler)
bind(LedgerService)
requireBinding(LedgerService)
Multibinder.newSetBinder(binder(), HandlerDecorator).addBinding()
.toInstance(HandlerDecorator.prependHandlers(LedgerChainAction))

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2018 Devsoap Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.devsoap.dbt.modules
import com.devsoap.dbt.config.DBTConfig
import com.devsoap.dbt.handlers.ConfigInfoHandler
import com.devsoap.dbt.handlers.JsonSchemaHandler
import com.devsoap.dbt.services.TransactionManagerService
import com.fasterxml.jackson.databind.ObjectMapper
import groovy.util.logging.Slf4j
import ratpack.guice.ConfigurableModule
import ratpack.server.ServerConfig
@Slf4j
class DBTModule extends ConfigurableModule<DBTConfig> {
@Override
protected void configure() {
bind(ObjectMapper)
bind(TransactionManagerService)
bind(ConfigInfoHandler)
bind(JsonSchemaHandler)
}
@Override
protected DBTConfig createConfig(ServerConfig serverConfig) {
(DBTConfig) serverConfig.getAsConfigObject('/dbt', DBTConfig)?.getObject() ?: super.createConfig(serverConfig)
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2018 Devsoap Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.devsoap.dbt.services
import com.devsoap.dbt.data.BlockTransaction
import groovy.util.logging.Slf4j
import ratpack.exec.Promise
@Slf4j
class InMemoryLedgerService implements LedgerService {
private static final LedgerData data = new LedgerData()
InMemoryLedgerService() {
log.warn('Using in-memory ledger service which will not store the ledger between restarts. Please consider ' +
'using the Mongo ledger service instead.')
}
@Override
Promise<Optional<BlockTransaction>> fetchTransaction(String transactionId) {
Promise.value(Optional.ofNullable(data.transactions.find {it.id == transactionId}))
}
@Override
Promise<List<BlockTransaction>> allTransactions() {
log.info("Found ${data.transactions.size()} transactions")
Promise.value(data.transactions)
}
@Override
Promise<String> newTransaction(BlockTransaction transaction) {
log.info("Adding new transaction $transaction.id")
data.transactions.add(transaction)
Promise.value(transaction.id)
}
@Override
Promise<String> updateTransaction(BlockTransaction transaction) {
log.info("Updating transaction $transaction.id")
data.transactions.removeAll {it.id == transaction.id}
data.transactions.add(transaction)
Promise.value(transaction.id)
}
private static class LedgerData {
final List<BlockTransaction> transactions = []
}
}

View File

@@ -15,72 +15,17 @@
*/
package com.devsoap.dbt.services
import com.devsoap.dbt.config.DBTConfig
import com.devsoap.dbt.data.BlockTransaction
import com.fasterxml.jackson.databind.ObjectMapper
import com.gmongo.GMongo
import com.mongodb.BasicDBObject
import com.mongodb.BasicDBObjectBuilder
import com.mongodb.DB
import com.mongodb.DBCollection
import com.mongodb.DBCursor
import com.mongodb.DBObject
import com.mongodb.MongoURI
import com.mongodb.util.JSON
import groovy.util.logging.Slf4j
import ratpack.exec.Promise
import ratpack.service.Service
import javax.inject.Inject
interface LedgerService extends Service {
@Slf4j
class LedgerService implements Service {
Promise<Optional<BlockTransaction>> fetchTransaction(String transactionId)
private final String dbUrl
private DB db
private final ObjectMapper mapper
Promise<List<BlockTransaction>> allTransactions()
@Inject
LedgerService(DBTConfig config, ObjectMapper mapper) {
dbUrl = config.ledger.databaseUrl
this.mapper = mapper
}
Promise<String> newTransaction(BlockTransaction transaction)
Promise<Optional<BlockTransaction>> fetchTransaction(String transactionId) {
BlockTransaction transaction = transactions.findOne(['id':transactionId])?.findAll { it.key != '_id' } as BlockTransaction
Promise.value(Optional.ofNullable(transaction))
}
Promise<List<BlockTransaction>> allTransactions() {
def cursor = transactions.find()
log.info("Found ${cursor.size()} transactions")
Promise.value(cursor.collect {it.findAll { it.key != '_id' } as BlockTransaction})
}
Promise<String> newTransaction(BlockTransaction transaction) {
log.info("Adding new transaction $transaction.id")
transactions << JSON.parse(mapper.writeValueAsString(transaction))
Promise.value(transaction.id)
}
Promise<String> updateTransaction(BlockTransaction transaction) {
log.info("Updating transaction $transaction.id")
transactions.findAndModify(
['id':transaction.id] as BasicDBObject,
JSON.parse(mapper.writeValueAsString(transaction)) as DBObject
)
Promise.value(transaction.id)
}
private DBCollection getTransactions() {
database.getCollection('transactions')
}
private DB getDatabase() {
if(!db) {
db = new GMongo(new MongoURI(dbUrl)).getDB('dbt')
}
db
}
}
Promise<String> updateTransaction(BlockTransaction transaction)
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2018 Devsoap Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.devsoap.dbt.services
import com.devsoap.dbt.config.DBTConfig
import com.devsoap.dbt.data.BlockTransaction
import com.fasterxml.jackson.databind.ObjectMapper
import com.gmongo.GMongo
import com.mongodb.*
import com.mongodb.util.JSON
import groovy.util.logging.Slf4j
import ratpack.exec.Promise
import javax.inject.Inject
@Slf4j
class MongoLedgerService implements LedgerService {
private final String dbUrl
private DB db
private final ObjectMapper mapper
@Inject
MongoLedgerService(DBTConfig config, ObjectMapper mapper) {
dbUrl = config.ledger.databaseUrl
this.mapper = mapper
}
@Override
Promise<Optional<BlockTransaction>> fetchTransaction(String transactionId) {
BlockTransaction transaction = transactions.findOne(['id':transactionId])?.findAll { it.key != '_id' } as BlockTransaction
Promise.value(Optional.ofNullable(transaction))
}
@Override
Promise<List<BlockTransaction>> allTransactions() {
def cursor = transactions.find()
log.info("Found ${cursor.size()} transactions")
Promise.value(cursor.collect {it.findAll { it.key != '_id' } as BlockTransaction})
}
@Override
Promise<String> newTransaction(BlockTransaction transaction) {
log.info("Adding new transaction $transaction.id")
transactions << JSON.parse(mapper.writeValueAsString(transaction))
Promise.value(transaction.id)
}
@Override
Promise<String> updateTransaction(BlockTransaction transaction) {
log.info("Updating transaction $transaction.id")
transactions.findAndModify(
['id':transaction.id] as BasicDBObject,
JSON.parse(mapper.writeValueAsString(transaction)) as DBObject
)
Promise.value(transaction.id)
}
private DBCollection getTransactions() {
database.getCollection('transactions')
}
private DB getDatabase() {
if(!db) {
db = new GMongo(new MongoURI(dbUrl)).getDB('dbt')
}
db
}
}