update idempotentcy
This commit is contained in:
parent
9c57b1de87
commit
06ff037189
3 changed files with 65 additions and 115 deletions
|
|
@ -128,10 +128,6 @@ function loadPlugin (name, config) {
|
||||||
return plugin
|
return plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
function pp (o) {
|
|
||||||
console.log(require('util').inspect(o, {depth: null}))
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCode, config, accounts, options,
|
function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCode, config, accounts, options,
|
||||||
onChangeCallback) {
|
onChangeCallback) {
|
||||||
const currentName = config.cryptoServices[pluginType]
|
const currentName = config.cryptoServices[pluginType]
|
||||||
|
|
@ -689,11 +685,21 @@ function executeTrades (cryptoCode) {
|
||||||
* ID Verifier functions
|
* ID Verifier functions
|
||||||
*/
|
*/
|
||||||
exports.verifyUser = function verifyUser (data, cb) {
|
exports.verifyUser = function verifyUser (data, cb) {
|
||||||
idVerifierPlugin.verifyUser(data, cb)
|
return new Promise((resolve, reject) => {
|
||||||
|
idVerifierPlugin.verifyUser(data, (err, res) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
return resolve(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.verifyTx = function verifyTx (data, cb) {
|
exports.verifyTx = function verifyTx (data, cb) {
|
||||||
idVerifierPlugin.verifyTransaction(data, cb)
|
return new Promise((resolve, reject) => {
|
||||||
|
idVerifierPlugin.verifyTransaction(data, (err, res) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
return resolve(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendMessage (rec) {
|
function sendMessage (rec) {
|
||||||
|
|
|
||||||
156
lib/routes.js
156
lib/routes.js
|
|
@ -5,8 +5,6 @@ const logger = require('./logger')
|
||||||
const configManager = require('./config-manager')
|
const configManager = require('./config-manager')
|
||||||
const db = require('./db')
|
const db = require('./db')
|
||||||
|
|
||||||
let mock = false
|
|
||||||
|
|
||||||
let plugins
|
let plugins
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
@ -127,19 +125,12 @@ function trade (req, res, next) {
|
||||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||||
|
|
||||||
plugins.trade(getDeviceId(req), tx)
|
plugins.trade(getDeviceId(req), tx)
|
||||||
.then(() => {
|
.then(() => cacheAndRespond(req, res))
|
||||||
updateCachedAction(req, {}, 201)
|
|
||||||
res.status(201).json({})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateChange (req, res) {
|
function stateChange (req, res) {
|
||||||
plugins.stateChange(getDeviceId(req), getDeviceTime(req), req.body)
|
plugins.stateChange(getDeviceId(req), getDeviceTime(req), req.body)
|
||||||
.then(() => res.json({success: true}))
|
.then(() => cacheAndRespond(req, res))
|
||||||
.catch(err => {
|
|
||||||
console.error(err)
|
|
||||||
res.json({success: false})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function send (req, res) {
|
function send (req, res) {
|
||||||
|
|
@ -149,8 +140,7 @@ function send (req, res) {
|
||||||
return plugins.sendCoins(getDeviceId(req), tx)
|
return plugins.sendCoins(getDeviceId(req), tx)
|
||||||
.then(status => {
|
.then(status => {
|
||||||
const body = {txId: status && status.txId}
|
const body = {txId: status && status.txId}
|
||||||
updateCachedAction(req, body, 200)
|
return cacheAndRespond(req, res, body)
|
||||||
.then(() => res.json(body))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,50 +150,27 @@ function cashOut (req, res) {
|
||||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||||
|
|
||||||
return plugins.cashOut(getDeviceId(req), tx)
|
return plugins.cashOut(getDeviceId(req), tx)
|
||||||
.then(cryptoAddress => res.json({toAddress: cryptoAddress}))
|
.then(cryptoAddress => cacheAndRespond(req, res, {toAddress: cryptoAddress}))
|
||||||
.catch(err => {
|
|
||||||
res.json({
|
|
||||||
err: err.message,
|
|
||||||
errType: err.name
|
|
||||||
})
|
|
||||||
logger.error(err)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function dispenseAck (req, res) {
|
function dispenseAck (req, res) {
|
||||||
plugins.dispenseAck(getDeviceId(req), req.body.tx)
|
plugins.dispenseAck(getDeviceId(req), req.body.tx)
|
||||||
res.json({success: true})
|
.then(() => cacheAndRespond(req, res))
|
||||||
}
|
}
|
||||||
|
|
||||||
function deviceEvent (req, res) {
|
function deviceEvent (req, res) {
|
||||||
plugins.logEvent(getDeviceId(req), req.body)
|
plugins.logEvent(getDeviceId(req), req.body)
|
||||||
res.json({err: null})
|
.then(() => cacheAndRespond(req, res))
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyUser (req, res) {
|
function verifyUser (req, res) {
|
||||||
if (mock) return res.json({success: true})
|
plugins.verifyUser(req.body)
|
||||||
|
.then(idResult => cacheAndRespond(req, res, idResult))
|
||||||
plugins.verifyUser(req.body, (err, idResult) => {
|
|
||||||
if (err) {
|
|
||||||
logger.error(err)
|
|
||||||
return res.json({err: 'Verification failed'})
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(idResult)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function verifyTx (req, res) {
|
function verifyTx (req, res) {
|
||||||
if (mock) return res.json({success: true})
|
plugins.verifyTransaction(req.body)
|
||||||
|
.then(idResult => cacheAndRespond(req, res, idResult))
|
||||||
plugins.verifyTx(req.body, (err, idResult) => {
|
|
||||||
if (err) {
|
|
||||||
logger.error(err)
|
|
||||||
return res.json({err: 'Verification failed'})
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(idResult)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ca (req, res) {
|
function ca (req, res) {
|
||||||
|
|
@ -223,14 +190,8 @@ function pair (req, res) {
|
||||||
|
|
||||||
return pair.pair(token, deviceId)
|
return pair.pair(token, deviceId)
|
||||||
.then(valid => {
|
.then(valid => {
|
||||||
updateCachedAction(req, {})
|
if (valid) return cacheAndRespond(req, res)
|
||||||
if (valid) {
|
throw httpError('Invalid token', 408)
|
||||||
updateCachedAction(req, {}, 200)
|
|
||||||
return res.json({})
|
|
||||||
}
|
|
||||||
|
|
||||||
updateCachedAction(req, {}, 408)
|
|
||||||
return res.status(408).json({})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,13 +199,13 @@ function phoneCode (req, res) {
|
||||||
const phone = req.body.phone
|
const phone = req.body.phone
|
||||||
|
|
||||||
logger.debug('Phone code requested for: ' + phone)
|
logger.debug('Phone code requested for: ' + phone)
|
||||||
|
|
||||||
return plugins.getPhoneCode(phone)
|
return plugins.getPhoneCode(phone)
|
||||||
.then(code => res.json({code}))
|
.then(code => cacheAndRespond(req, res, {code}))
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error(err)
|
if (err.name === 'BadNumberError') throw httpError('Bad number', 410)
|
||||||
if (err.name === 'BadNumberError') return res.sendStatus(410)
|
throw err
|
||||||
return res.sendStatus(500)
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePhone (req, res) {
|
function updatePhone (req, res) {
|
||||||
|
|
@ -252,11 +213,7 @@ function updatePhone (req, res) {
|
||||||
const tx = req.body
|
const tx = req.body
|
||||||
|
|
||||||
return plugins.updatePhone(tx, notified)
|
return plugins.updatePhone(tx, notified)
|
||||||
.then(r => res.json(r))
|
.then(r => cacheAndRespond(req, res, r))
|
||||||
.catch(err => {
|
|
||||||
logger.error(err)
|
|
||||||
res.sendStatus(500)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchPhoneTx (req, res) {
|
function fetchPhoneTx (req, res) {
|
||||||
|
|
@ -271,11 +228,7 @@ function fetchPhoneTx (req, res) {
|
||||||
function registerRedeem (req, res) {
|
function registerRedeem (req, res) {
|
||||||
const txId = req.params.txId
|
const txId = req.params.txId
|
||||||
return plugins.registerRedeem(txId)
|
return plugins.registerRedeem(txId)
|
||||||
.then(() => res.json({success: true}))
|
.then(() => cacheAndRespond(req, res))
|
||||||
.catch(err => {
|
|
||||||
logger.error(err)
|
|
||||||
res.sendStatus(500)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function waitForDispense (req, res) {
|
function waitForDispense (req, res) {
|
||||||
|
|
@ -296,38 +249,9 @@ function waitForDispense (req, res) {
|
||||||
|
|
||||||
function dispense (req, res) {
|
function dispense (req, res) {
|
||||||
const tx = req.body.tx
|
const tx = req.body.tx
|
||||||
const txId = tx.id
|
|
||||||
const deviceId = getDeviceId(req)
|
|
||||||
|
|
||||||
console.log('DEBUG17')
|
return plugins.requestDispense(tx)
|
||||||
|
.then(dispenseRec => cacheAndRespond(req, res, dispenseRec))
|
||||||
return cachedResponse(deviceId, txId, req)
|
|
||||||
.then(cached => {
|
|
||||||
console.log('DEBUG18: %j', cached)
|
|
||||||
|
|
||||||
// Cache hit
|
|
||||||
if (cached && cached.pendingRequest) return res.sendStatus(409)
|
|
||||||
console.log('DEBUG18.5')
|
|
||||||
if (cached) res.json(cached)
|
|
||||||
|
|
||||||
console.log('DEBUG19')
|
|
||||||
|
|
||||||
// No cache hit
|
|
||||||
return plugins.requestDispense(tx)
|
|
||||||
.then(dispenseRec => {
|
|
||||||
console.log('DEBUG20: %j', dispenseRec)
|
|
||||||
|
|
||||||
return cacheResponse(deviceId, txId, req, dispenseRec)
|
|
||||||
.then(() => res.json(dispenseRec))
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log('DEBUG21')
|
|
||||||
|
|
||||||
logger.error(err)
|
|
||||||
res.sendStatus(500)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(err => logger.error(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isUniqueViolation (err) {
|
function isUniqueViolation (err) {
|
||||||
|
|
@ -355,22 +279,42 @@ function cacheAction (req, res, next) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function cachedActionError (req, err, status) {
|
|
||||||
return updateCachedAction(req, {error: err}, status || 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateCachedAction (req, body, status) {
|
function updateCachedAction (req, body, status) {
|
||||||
const sql = 'update idempotents set body=$1, status=$2, pending=$3 where request_id=$4 and device_id=$5'
|
const sql = `update idempotents set body=$1, status=$2, pending=$3
|
||||||
|
where request_id=$4 and device_id=$5 and pending=$6`
|
||||||
|
|
||||||
const requestId = req.headers['request-id']
|
const requestId = req.headers['request-id']
|
||||||
const deviceId = getDeviceId(req)
|
const deviceId = getDeviceId(req)
|
||||||
|
|
||||||
return db.none(sql, [body, status, false, requestId, deviceId])
|
return db.none(sql, [body, status, false, requestId, deviceId, true])
|
||||||
|
}
|
||||||
|
|
||||||
|
function postErrorHandler (err, req, res, next) {
|
||||||
|
const statusCode = err.code || 500
|
||||||
|
const json = {error: err.message}
|
||||||
|
|
||||||
|
return updateCachedAction(req, json, statusCode)
|
||||||
|
.then(() => res.status(statusCode).json({}))
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheAndRespond (req, res, _body, _status) {
|
||||||
|
const status = _status || 200
|
||||||
|
const body = _body || {}
|
||||||
|
|
||||||
|
return updateCachedAction(req, body, status)
|
||||||
|
.then(() => res.status(status).json(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
function httpError (msg, code) {
|
||||||
|
const err = new Error(msg)
|
||||||
|
err.name = 'HTTPError'
|
||||||
|
err.code = code || 500
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
function init (opts) {
|
function init (opts) {
|
||||||
plugins = opts.plugins
|
plugins = opts.plugins
|
||||||
mock = opts.mock
|
|
||||||
|
|
||||||
const authMiddleware = opts.authMiddleware
|
const authMiddleware = opts.authMiddleware
|
||||||
const app = opts.app
|
const app = opts.app
|
||||||
|
|
@ -400,7 +344,7 @@ function init (opts) {
|
||||||
app.get('/await_dispense/:txId', authMiddleware, waitForDispense)
|
app.get('/await_dispense/:txId', authMiddleware, waitForDispense)
|
||||||
app.post('/dispense', authMiddleware, dispense)
|
app.post('/dispense', authMiddleware, dispense)
|
||||||
|
|
||||||
app.post('*', updateCachedAction)
|
app.post('*', postErrorHandler)
|
||||||
|
|
||||||
localApp.get('/pid', (req, res) => {
|
localApp.get('/pid', (req, res) => {
|
||||||
const deviceId = req.query.device_id
|
const deviceId = req.query.device_id
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -111,6 +111,6 @@ v need to create CA: http://stackoverflow.com/questions/19665863/how-do-i-use-a-
|
||||||
|
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
- consistent error handling
|
v consistent error handling
|
||||||
- usage of http status codes (good for got)
|
v usage of http status codes (good for got)
|
||||||
- finish idempotency for all calls
|
v finish idempotency for all calls
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue