vulcain-corejs
Version:
Vulcain micro-service framework
120 lines (118 loc) • 4.97 kB
JavaScript
"use strict";
const http = require('http');
const actions_1 = require('../pipeline/actions');
const query_1 = require('../pipeline/query');
const vulcain_configurationsjs_1 = require('vulcain-configurationsjs');
const annotations_1 = require('../di/annotations');
class AbstractAdapter {
constructor(domainName, container) {
this.domainName = domainName;
this.container = container;
this.commandManager = new actions_1.CommandManager(container);
this.queryManager = new query_1.QueryManager(container);
this.testUser = container.get(annotations_1.DefaultServiceNames.TestUser, true);
this.domain = container.get(annotations_1.DefaultServiceNames.Domain);
this.metrics = container.get(annotations_1.DefaultServiceNames.Metrics);
}
calcDelayInMs(begin) {
// ts = [seconds, nanoseconds]
const ts = process.hrtime(begin);
// convert seconds to miliseconds and nanoseconds to miliseconds as well
return (ts[0] * 1000) + (ts[1] / 1000000);
}
startRequest(command) {
// util.log("Request : " + JSON.stringify(command)); // TODO remove sensible data
return process.hrtime();
}
endRequest(begin, response, ctx, e) {
const ms = this.calcDelayInMs(begin);
let prefix = "";
if (response.value.schema)
prefix = response.value.schema + '.';
prefix += response.value.action + ".";
this.metrics.timing(prefix + "responseTime", ms);
this.metrics.increment(prefix + "total");
this.metrics.timing("allRequests.responseTime", ms);
this.metrics.increment("allRequests.total");
if (!response.error) {
this.metrics.increment(prefix + "success");
this.metrics.increment("allRequests.success");
}
else {
this.metrics.increment(prefix + "failure");
this.metrics.increment("allRequests.failure");
}
let trace = {
duration: ms,
info: Object.assign({}, response.value)
};
delete trace.info.value;
if (e) {
trace.stackTrace = e.stack;
trace.message = e.message;
}
vulcain_configurationsjs_1.System.log.write(ctx, trace);
}
executeQueryRequest(query, ctx) {
return this.executeRequestInternal(this.queryManager, query, ctx);
}
executeCommandRequest(command, ctx) {
return this.executeRequestInternal(this.commandManager, command, ctx);
}
executeRequestInternal(manager, command, ctx) {
let self = this;
return new Promise((resolve, reject) => {
let headers = new Map();
if (!command || !command.domain) {
resolve({ value: "domain is required.", code: 400, headers: headers });
return;
}
if (command.domain.toLowerCase() !== self.domainName.toLowerCase()) {
resolve({ value: "this service doesn't belong to domain " + self.domainName, code: 400, headers: headers });
return;
}
try {
// Check if handler exists
let metadata = manager.getMetadata(command);
if (!ctx.user && this.testUser) {
ctx.user = this.testUser;
ctx.user.tenant = ctx.tenant;
}
// Verify authorization
if (metadata.scope && !ctx.hasScope(metadata.scope)) {
resolve({ code: 403, status: "Unauthorized", value: { error: { message: http.STATUS_CODES[403] } } });
return;
}
}
catch (e) {
reject(e);
return;
}
// Execute handler
manager.runAsync(command, ctx)
.then(result => {
if (command.correlationId)
headers.set("X-VULCAIN-CORRELATION-ID", command.correlationId);
if (result)
delete result.userContext;
// TODO https://github.com/phretaddin/schemapack
resolve({ value: result, headers: headers });
ctx.dispose();
})
.catch(result => {
// Normalize error
if (result instanceof vulcain_configurationsjs_1.BadRequestError) {
resolve({ code: 400, value: { status: "Error", error: { message: result.message } }, headers: headers });
return;
}
else if (result instanceof Error) {
result = { status: "Error", error: { message: result.message } };
}
resolve({ code: 500, value: result, headers: headers });
ctx.dispose();
});
});
}
}
exports.AbstractAdapter = AbstractAdapter;
//# sourceMappingURL=abstractAdapter.js.map