// core-node.js // Copyright (C) 2022 DTP Technologies, LLC // License: Apache-2.0 'use strict'; const uuidv4 = require('uuid').v4; const mongoose = require('mongoose'); const fetch = require('node-fetch'); // jshint ignore:line const CoreNode = mongoose.model('CoreNode'); const CoreNodeRequest = mongoose.model('CoreNodeRequest'); const { SiteService, SiteError } = require('../../lib/site-lib'); class CoreNodeService extends SiteService { constructor (dtp) { super(dtp, module.exports); } async create (coreDefinition) { const core = new CoreNode(); core.created = new Date(); core.address = { }; if (!coreDefinition.host) { throw new SiteError(406, 'Must provide Core Node host address'); } core.address.host = coreDefinition.host.trim(); if (!coreDefinition.port) { throw new SiteError(406, 'Must provide Core Node TCP port number'); } coreDefinition.port = parseInt(coreDefinition.port, 10); if (coreDefinition.port < 1 || coreDefinition.port > 65535) { throw new SiteError(406, 'Core Node port number out of range'); } await core.save(); return core.toObject(); } async broadcast (request) { const results = [ ]; await CoreNode .find() .cursor() .eachAsync(async (core) => { try { const response = await this.sendRequest(core, request); results.push({ coreId: core._id, request, response }); } catch (error) { this.log.error('failed to send Core Node request', { core: core._id, request: request.url, error }); } }); return results; } async sendRequest (core, request) { const requestUrl = `https://${core.address.host}:${core.address.port}${request.url}`; const req = new CoreNodeRequest(); req.created = new Date(); req.core = core._id; req.token = { value: uuidv4(), claimed: false, }; req.url = request.url; await req.save(); try { const response = await fetch(requestUrl, { method: request.method, body: request.body, }); const json = await response.json(); return { request: req.toObject(), response: json }; } catch (error) { this.log.error('failed to send Core Node request', { core: core._id, request: request.url, error }); throw error; } return req.toObject(); } } module.exports = { slug: 'core-node', name: 'coreNode', create: (dtp) => { return new CoreNodeService(dtp); }, };