@neo-one/server
Version:
NEO•ONE Server that NEO•ONE CLI and other clients connect to.
130 lines (128 loc) • 16.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const http_1 = require("@neo-one/http");
const monitor_1 = require("@neo-one/monitor");
const koa_compose_1 = tslib_1.__importDefault(require("koa-compose"));
const koa_compress_1 = tslib_1.__importDefault(require("koa-compress"));
const RPC_METHODS = {
executeTaskList: 'executeTaskList',
request: 'request',
ready: 'ready',
UNKNOWN: 'UNKNOWN',
INVALID: 'INVALID',
};
const rpcLabelNames = [monitor_1.KnownLabel.RPC_METHOD];
const rpcLabels = Object.values(RPC_METHODS).map((method) => ({
[monitor_1.KnownLabel.RPC_METHOD]: method,
}));
const SINGLE_REQUESTS_HISTOGRAM = monitor_1.metrics.createHistogram({
name: 'http_rpc_server_single_request_duration_seconds',
labelNames: rpcLabelNames,
labels: rpcLabels,
});
const SINGLE_REQUEST_ERRORS_COUNTER = monitor_1.metrics.createCounter({
name: 'http_rpc_server_single_request_failures_total',
labelNames: rpcLabelNames,
labels: rpcLabels,
});
exports.rpc = ({ server }) => {
const validateRequest = (request) => {
if (request !== undefined &&
typeof request === 'object' &&
request.method !== undefined &&
typeof request.method === 'string') {
return request;
}
throw new Error('Invalid Request');
};
const handleSingleRequest = async (monitor, requestIn) => monitor.captureSpanLog(async (span) => {
let request;
try {
request = validateRequest(requestIn);
}
finally {
let method = RPC_METHODS.UNKNOWN;
if (request !== undefined) {
({ method } = request);
}
else if (typeof requestIn === 'object') {
({ method } = requestIn);
}
if (RPC_METHODS[method] === undefined) {
method = RPC_METHODS.INVALID;
}
span.setLabels({ [span.labels.RPC_METHOD]: method });
}
let result;
switch (request.method) {
case 'executeTaskList':
await server.pluginManager
.getPlugin({ plugin: request.plugin })
.executeTaskList(server.pluginManager, JSON.stringify(request.options))
.toPromise();
result = { type: 'ok', message: 'Success!' };
break;
case 'request':
const response = await server.pluginManager
.getPlugin({ plugin: request.plugin })
.request(server.pluginManager, JSON.stringify(request.options));
result = { type: 'ok', response };
break;
case 'ready':
result = { type: 'ok' };
break;
default:
throw new Error('Method not found');
}
return result;
}, {
name: 'http_rpc_server_single_request',
metric: {
total: SINGLE_REQUESTS_HISTOGRAM,
error: SINGLE_REQUEST_ERRORS_COUNTER,
},
level: { log: 'verbose', span: 'info' },
});
const handleRequest = (monitor, request) => {
if (Array.isArray(request)) {
return Promise.all(request.map(async (batchRequest) => handleSingleRequest(monitor, batchRequest)));
}
return handleSingleRequest(monitor, request);
};
const handleRequestSafe = async (monitor, request) => {
try {
const result = await monitor.captureSpanLog(async (span) => handleRequest(span, request), {
name: 'http_rpc_server_request',
level: { log: 'verbose', span: 'info' },
error: {},
});
return result;
}
catch (error) {
return {
type: 'error',
message: error.message,
};
}
};
return {
name: 'rpc',
path: '/rpc',
middleware: koa_compose_1.default([
koa_compress_1.default(),
http_1.bodyParser(),
async (ctx) => {
if (!ctx.is('application/json')) {
return ctx.throw(415);
}
const { body } = ctx.request;
const monitor = http_1.getMonitor(ctx);
const result = await handleRequestSafe(monitor.withLabels({ [monitor.labels.RPC_TYPE]: 'http' }), body);
ctx.status = 200;
ctx.body = result;
},
]),
};
};
//# sourceMappingURL=data:application/json;charset=utf8;base64,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R0FBRyxDQUFDLENBQUM7Z0JBQ2hDLE1BQU0sTUFBTSxHQUFHLE1BQU0saUJBQWlCLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUV4RyxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztnQkFDakIsR0FBRyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7WUFDcEIsQ0FBQztTQUNGLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyxDQUFDIiwiZmlsZSI6Im5lby1vbmUtc2VydmVyL3NyYy9taWRkbGV3YXJlL3JwYy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGJvZHlQYXJzZXIsIGdldE1vbml0b3IgfSBmcm9tICdAbmVvLW9uZS9odHRwJztcbmltcG9ydCB7IEtub3duTGFiZWwsIG1ldHJpY3MsIE1vbml0b3IgfSBmcm9tICdAbmVvLW9uZS9tb25pdG9yJztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICdrb2EnO1xuaW1wb3J0IGNvbXBvc2UgZnJvbSAna29hLWNvbXBvc2UnO1xuaW1wb3J0IGtvYUNvbXByZXNzIGZyb20gJ2tvYS1jb21wcmVzcyc7XG5pbXBvcnQgeyBTZXJ2ZXIgfSBmcm9tICcuLi9TZXJ2ZXInO1xuXG5jb25zdCBSUENfTUVUSE9EUzogeyByZWFkb25seSBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgZXhlY3V0ZVRhc2tMaXN0OiAnZXhlY3V0ZVRhc2tMaXN0JyxcbiAgcmVxdWVzdDogJ3JlcXVlc3QnLFxuICByZWFkeTogJ3JlYWR5JyxcbiAgVU5LTk9XTjogJ1VOS05PV04nLFxuICBJTlZBTElEOiAnSU5WQUxJRCcsXG59O1xuXG5jb25zdCBycGNMYWJlbE5hbWVzOiByZWFkb25seSBzdHJpbmdbXSA9IFtLbm93bkxhYmVsLlJQQ19NRVRIT0RdO1xuY29uc3QgcnBjTGFiZWxzID0gT2JqZWN0LnZhbHVlcyhSUENfTUVUSE9EUykubWFwKChtZXRob2QpID0+ICh7XG4gIFtLbm93bkxhYmVsLlJQQ19NRVRIT0RdOiBtZXRob2QsXG59KSk7XG5cbmNvbnN0IFNJTkdMRV9SRVFVRVNUU19ISVNUT0dSQU0gPSBtZXRyaWNzLmNyZWF0ZUhpc3RvZ3JhbSh7XG4gIG5hbWU6ICdodHRwX3JwY19zZXJ2ZXJfc2luZ2xlX3JlcXVlc3RfZHVyYXRpb25fc2Vjb25kcycsXG4gIGxhYmVsTmFtZXM6IHJwY0xhYmVsTmFtZXMsXG4gIGxhYmVsczogcnBjTGFiZWxzLFxufSk7XG5cbmNvbnN0IFNJTkdMRV9SRVFVRVNUX0VSUk9SU19DT1VOVEVSID0gbWV0cmljcy5jcmVhdGVDb3VudGVyKHtcbiAgbmFtZTogJ2h0dHBfcnBjX3NlcnZlcl9zaW5nbGVfcmVxdWVzdF9mYWlsdXJlc190b3RhbCcsXG4gIGxhYmVsTmFtZXM6IHJwY0xhYmVsTmFtZXMsXG4gIGxhYmVsczogcnBjTGFiZWxzLFxufSk7XG5cbmludGVyZmFjZSBSUENSZXF1ZXN0IHtcbiAgcmVhZG9ubHkgbWV0aG9kOiBzdHJpbmc7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hbnlcbiAgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5pbnRlcmZhY2UgUlBDUmVzdWx0IHtcbiAgcmVhZG9ubHkgdHlwZTogJ29rJyB8ICdlcnJvcic7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hbnlcbiAgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5leHBvcnQgY29uc3QgcnBjID0gKHsgc2VydmVyIH06IHsgcmVhZG9ubHkgc2VydmVyOiBTZXJ2ZXIgfSkgPT4ge1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gIGNvbnN0IHZhbGlkYXRlUmVxdWVzdCA9IChyZXF1ZXN0OiBhbnkpOiBSUENSZXF1ZXN0ID0+IHtcbiAgICBpZiAoXG4gICAgICByZXF1ZXN0ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHR5cGVvZiByZXF1ZXN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgcmVxdWVzdC5tZXRob2QgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgdHlwZW9mIHJlcXVlc3QubWV0aG9kID09PSAnc3RyaW5nJ1xuICAgICkge1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFJlcXVlc3QnKTtcbiAgfTtcblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gIGNvbnN0IGhhbmRsZVNpbmdsZVJlcXVlc3QgPSBhc3luYyAobW9uaXRvcjogTW9uaXRvciwgcmVxdWVzdEluOiBhbnkpID0+XG4gICAgbW9uaXRvci5jYXB0dXJlU3BhbkxvZyhcbiAgICAgIGFzeW5jIChzcGFuKSA9PiB7XG4gICAgICAgIGxldCByZXF1ZXN0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlcXVlc3QgPSB2YWxpZGF0ZVJlcXVlc3QocmVxdWVzdEluKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBsZXQgbWV0aG9kID0gUlBDX01FVEhPRFMuVU5LTk9XTjtcbiAgICAgICAgICBpZiAocmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAoeyBtZXRob2QgfSA9IHJlcXVlc3QpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlcXVlc3RJbiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICh7IG1ldGhvZCB9ID0gcmVxdWVzdEluKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoKFJQQ19NRVRIT0RTW21ldGhvZF0gYXMgc3RyaW5nIHwgdW5kZWZpbmVkKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBtZXRob2QgPSBSUENfTUVUSE9EUy5JTlZBTElEO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNwYW4uc2V0TGFiZWxzKHsgW3NwYW4ubGFiZWxzLlJQQ19NRVRIT0RdOiBtZXRob2QgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmVzdWx0OiBSUENSZXN1bHQ7XG4gICAgICAgIHN3aXRjaCAocmVxdWVzdC5tZXRob2QpIHtcbiAgICAgICAgICBjYXNlICdleGVjdXRlVGFza0xpc3QnOlxuICAgICAgICAgICAgYXdhaXQgc2VydmVyLnBsdWdpbk1hbmFnZXJcbiAgICAgICAgICAgICAgLmdldFBsdWdpbih7IHBsdWdpbjogcmVxdWVzdC5wbHVnaW4gfSlcbiAgICAgICAgICAgICAgLmV4ZWN1dGVUYXNrTGlzdChzZXJ2ZXIucGx1Z2luTWFuYWdlciwgSlNPTi5zdHJpbmdpZnkocmVxdWVzdC5vcHRpb25zKSlcbiAgICAgICAgICAgICAgLnRvUHJvbWlzZSgpO1xuICAgICAgICAgICAgcmVzdWx0ID0geyB0eXBlOiAnb2snLCBtZXNzYWdlOiAnU3VjY2VzcyEnIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdyZXF1ZXN0JzpcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VydmVyLnBsdWdpbk1hbmFnZXJcbiAgICAgICAgICAgICAgLmdldFBsdWdpbih7IHBsdWdpbjogcmVxdWVzdC5wbHVnaW4gfSlcbiAgICAgICAgICAgICAgLnJlcXVlc3Qoc2VydmVyLnBsdWdpbk1hbmFnZXIsIEpTT04uc3RyaW5naWZ5KHJlcXVlc3Qub3B0aW9ucykpO1xuICAgICAgICAgICAgcmVzdWx0ID0geyB0eXBlOiAnb2snLCByZXNwb25zZSB9O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAncmVhZHknOlxuICAgICAgICAgICAgcmVzdWx0ID0geyB0eXBlOiAnb2snIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGZvdW5kJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ2h0dHBfcnBjX3NlcnZlcl9zaW5nbGVfcmVxdWVzdCcsXG4gICAgICAgIG1ldHJpYzoge1xuICAgICAgICAgIHRvdGFsOiBTSU5HTEVfUkVRVUVTVFNfSElTVE9HUkFNLFxuICAgICAgICAgIGVycm9yOiBTSU5HTEVfUkVRVUVTVF9FUlJPUlNfQ09VTlRFUixcbiAgICAgICAgfSxcblxuICAgICAgICBsZXZlbDogeyBsb2c6ICd2ZXJib3NlJywgc3BhbjogJ2luZm8nIH0sXG4gICAgICB9LFxuICAgICk7XG5cbiAgY29uc3QgaGFuZGxlUmVxdWVzdCA9IChtb25pdG9yOiBNb25pdG9yLCByZXF1ZXN0OiB7fSkgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHJlcXVlc3QpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwocmVxdWVzdC5tYXAoYXN5bmMgKGJhdGNoUmVxdWVzdCkgPT4gaGFuZGxlU2luZ2xlUmVxdWVzdChtb25pdG9yLCBiYXRjaFJlcXVlc3QpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhbmRsZVNpbmdsZVJlcXVlc3QobW9uaXRvciwgcmVxdWVzdCk7XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlUmVxdWVzdFNhZmUgPSBhc3luYyAobW9uaXRvcjogTW9uaXRvciwgcmVxdWVzdDoge30pOiBQcm9taXNlPG9iamVjdCB8IG9iamVjdFtdPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBwcmVmZXItaW1tZWRpYXRlLXJldHVyblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbW9uaXRvci5jYXB0dXJlU3BhbkxvZyhhc3luYyAoc3BhbikgPT4gaGFuZGxlUmVxdWVzdChzcGFuLCByZXF1ZXN0KSwge1xuICAgICAgICBuYW1lOiAnaHR0cF9ycGNfc2VydmVyX3JlcXVlc3QnLFxuICAgICAgICBsZXZlbDogeyBsb2c6ICd2ZXJib3NlJywgc3BhbjogJ2luZm8nIH0sXG4gICAgICAgIGVycm9yOiB7fSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tdmFyLWJlZm9yZS1yZXR1cm5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICB9O1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6ICdycGMnLFxuICAgIHBhdGg6ICcvcnBjJyxcbiAgICBtaWRkbGV3YXJlOiBjb21wb3NlKFtcbiAgICAgIGtvYUNvbXByZXNzKCksXG4gICAgICBib2R5UGFyc2VyKCksXG4gICAgICBhc3luYyAoY3R4OiBDb250ZXh0KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGlmICghY3R4LmlzKCdhcHBsaWNhdGlvbi9qc29uJykpIHtcbiAgICAgICAgICByZXR1cm4gY3R4LnRocm93KDQxNSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gICAgICAgIGNvbnN0IHsgYm9keSB9ID0gY3R4LnJlcXVlc3QgYXMgYW55O1xuICAgICAgICBjb25zdCBtb25pdG9yID0gZ2V0TW9uaXRvcihjdHgpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVSZXF1ZXN0U2FmZShtb25pdG9yLndpdGhMYWJlbHMoeyBbbW9uaXRvci5sYWJlbHMuUlBDX1RZUEVdOiAnaHR0cCcgfSksIGJvZHkpO1xuXG4gICAgICAgIGN0eC5zdGF0dXMgPSAyMDA7XG4gICAgICAgIGN0eC5ib2R5ID0gcmVzdWx0O1xuICAgICAgfSxcbiAgICBdKSxcbiAgfTtcbn07XG4iXX0=