Files
2020-03-18 00:47:40 -03:00

133 lines
4.5 KiB
TypeScript

import {hLog} from "../helpers/common_functions";
import {ConfigurationModule} from "../modules/config";
import {ConnectionManager} from "../connections/manager.class";
import {HyperionConfig} from "../interfaces/hyperionConfig";
import {IncomingMessage, Server, ServerResponse} from "http";
import * as Fastify from 'fastify';
import * as Redis from 'ioredis';
import {registerPlugins} from "./plugins";
import {AddressInfo} from "net";
import {registerRoutes} from "./routes";
import {generateOpenApiConfig} from "./config/open_api";
import {createWriteStream} from "fs";
import {SocketManager} from "./socketManager";
class HyperionApiServer {
private conf: HyperionConfig;
private readonly manager: ConnectionManager;
private readonly fastify: Fastify.FastifyInstance<Server, IncomingMessage, ServerResponse>;
private readonly chain: string;
socketManager: SocketManager;
constructor() {
const cm = new ConfigurationModule();
this.conf = cm.config;
this.chain = this.conf.settings.chain;
process.title = `hyp-${this.chain}-api`;
this.manager = new ConnectionManager(cm);
this.manager.calculateServerHash();
this.manager.getHyperionVersion();
const logStream = createWriteStream('./logs/' + this.chain + '/api.access.log');
this.fastify = Fastify({
ignoreTrailingSlash: false, trustProxy: true, logger: this.conf.api.access_log ? {
stream: logStream,
redact: ['req.headers.authorization'],
level: 'info',
serializers: {
res: (res) => {
return {
status: res.statusCode
};
},
req: (req) => {
return {
method: req.method,
url: req.url,
ip: req.headers['x-real-ip']
}
}
}
} : false
});
this.fastify.decorate('manager', this.manager);
const ioRedisClient = new Redis(this.manager.conn.redis);
const api_rate_limit = {
max: 1000,
whitelist: [],
timeWindow: '1 minute',
redis: ioRedisClient
};
if (this.conf.features.streaming.enable) {
this.activateStreaming();
}
registerPlugins(this.fastify, {
fastify_elasticsearch: {
client: this.manager.elasticsearchClient
},
fastify_oas: generateOpenApiConfig(this.manager.config),
fastify_rate_limit: api_rate_limit,
fastify_redis: this.manager.conn.redis,
fastify_eosjs: this.manager,
});
registerRoutes(this.fastify);
this.addGenericTypeParsing();
this.fastify.ready().then(async () => {
await this.fastify.oas();
console.log(this.chain + ' api ready!');
}, (err) => {
console.log('an error happened', err)
});
}
activateStreaming() {
console.log('Importing stream module');
import('./socketManager').then((mod) => {
const connOpts = this.manager.conn.chains[this.chain];
this.socketManager = new mod.SocketManager(
this.fastify,
`http://${connOpts['WS_ROUTER_HOST']}:${connOpts['WS_ROUTER_PORT']}`,
this.manager.conn.redis
);
this.socketManager.startRelay();
});
}
private addGenericTypeParsing() {
this.fastify.addContentTypeParser('*', (req, done) => {
let data = '';
req.on('data', chunk => {
data += chunk;
});
req.on('end', () => {
done(null, data);
});
req.on('error', (err) => {
console.log('---- Content Parsing Error -----');
console.log(err);
});
});
}
async init() {
try {
await this.fastify.listen({
host: this.conf.api.server_addr,
port: this.conf.api.server_port
});
console.log(`server listening on ${(this.fastify.server.address() as AddressInfo).port}`);
} catch (err) {
this.fastify.log.error(err);
process.exit(1)
}
}
}
const server = new HyperionApiServer();
server.init().catch(hLog);