mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2026-02-15 10:49:07 +00:00
Feature/centralized configs (#310)
* [snyk] fix vulnerabilities * move all process.env in one config * update log level in config * check envs * fix imports in tests for microsoft, soniox, deepgram * fix import in gather-test * fix missing imports --------- Co-authored-by: Markus Frindt <m.frindt@cognigy.com>
This commit is contained in:
48
app.js
48
app.js
@@ -1,22 +1,26 @@
|
|||||||
const assert = require('assert');
|
const {
|
||||||
assert.ok(process.env.JAMBONES_MYSQL_HOST &&
|
DRACHTIO_PORT,
|
||||||
process.env.JAMBONES_MYSQL_USER &&
|
DRACHTIO_HOST,
|
||||||
process.env.JAMBONES_MYSQL_PASSWORD &&
|
DRACHTIO_SECRET,
|
||||||
process.env.JAMBONES_MYSQL_DATABASE, 'missing JAMBONES_MYSQL_XXX env vars');
|
JAMBONES_OTEL_SERVICE_NAME,
|
||||||
assert.ok(process.env.DRACHTIO_PORT || process.env.DRACHTIO_HOST, 'missing DRACHTIO_PORT env var');
|
JAMBONES_LOGLEVEL,
|
||||||
assert.ok(process.env.DRACHTIO_SECRET, 'missing DRACHTIO_SECRET env var');
|
JAMBONES_CLUSTER_ID,
|
||||||
assert.ok(process.env.JAMBONES_FREESWITCH, 'missing JAMBONES_FREESWITCH env var');
|
JAMBONZ_CLEANUP_INTERVAL_MINS,
|
||||||
assert.ok(process.env.JAMBONES_REDIS_HOST, 'missing JAMBONES_REDIS_HOST env var');
|
getCleanupIntervalMins,
|
||||||
assert.ok(process.env.JAMBONES_NETWORK_CIDR || process.env.K8S, 'missing JAMBONES_SUBNET env var');
|
K8S,
|
||||||
assert.ok(process.env.ENCRYPTION_SECRET || process.env.JWT_SECRET, 'missing ENCRYPTION_SECRET env var');
|
NODE_ENV,
|
||||||
|
checkEnvs,
|
||||||
|
} = require('./lib/config');
|
||||||
|
|
||||||
|
checkEnvs();
|
||||||
|
|
||||||
const Srf = require('drachtio-srf');
|
const Srf = require('drachtio-srf');
|
||||||
const srf = new Srf();
|
const srf = new Srf();
|
||||||
const tracer = require('./tracer')(process.env.JAMBONES_OTEL_SERVICE_NAME || 'jambonz-feature-server');
|
const tracer = require('./tracer')(JAMBONES_OTEL_SERVICE_NAME);
|
||||||
const api = require('@opentelemetry/api');
|
const api = require('@opentelemetry/api');
|
||||||
srf.locals = {...srf.locals, otel: {tracer, api}};
|
srf.locals = {...srf.locals, otel: {tracer, api}};
|
||||||
|
|
||||||
const opts = {level: process.env.JAMBONES_LOGLEVEL || 'info'};
|
const opts = {level: JAMBONES_LOGLEVEL};
|
||||||
const pino = require('pino');
|
const pino = require('pino');
|
||||||
const logger = pino(opts, pino.destination({sync: false}));
|
const logger = pino(opts, pino.destination({sync: false}));
|
||||||
const {LifeCycleEvents, FS_UUID_SET_NAME} = require('./lib/utils/constants');
|
const {LifeCycleEvents, FS_UUID_SET_NAME} = require('./lib/utils/constants');
|
||||||
@@ -36,8 +40,8 @@ const {
|
|||||||
const InboundCallSession = require('./lib/session/inbound-call-session');
|
const InboundCallSession = require('./lib/session/inbound-call-session');
|
||||||
const SipRecCallSession = require('./lib/session/siprec-call-session');
|
const SipRecCallSession = require('./lib/session/siprec-call-session');
|
||||||
|
|
||||||
if (process.env.DRACHTIO_HOST) {
|
if (DRACHTIO_HOST) {
|
||||||
srf.connect({host: process.env.DRACHTIO_HOST, port: process.env.DRACHTIO_PORT, secret: process.env.DRACHTIO_SECRET });
|
srf.connect({host: DRACHTIO_HOST, port: DRACHTIO_PORT, secret: DRACHTIO_SECRET });
|
||||||
srf.on('connect', (err, hp) => {
|
srf.on('connect', (err, hp) => {
|
||||||
const arr = /^(.*)\/(.*)$/.exec(hp.split(',').pop());
|
const arr = /^(.*)\/(.*)$/.exec(hp.split(',').pop());
|
||||||
srf.locals.localSipAddress = `${arr[2]}`;
|
srf.locals.localSipAddress = `${arr[2]}`;
|
||||||
@@ -45,10 +49,10 @@ if (process.env.DRACHTIO_HOST) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.info(`listening for drachtio requests on port ${process.env.DRACHTIO_PORT}`);
|
logger.info(`listening for drachtio requests on port ${DRACHTIO_PORT}`);
|
||||||
srf.listen({port: process.env.DRACHTIO_PORT, secret: process.env.DRACHTIO_SECRET});
|
srf.listen({port: DRACHTIO_PORT, secret: DRACHTIO_SECRET});
|
||||||
}
|
}
|
||||||
if (process.env.NODE_ENV === 'test') {
|
if (NODE_ENV === 'test') {
|
||||||
srf.on('error', (err) => {
|
srf.on('error', (err) => {
|
||||||
logger.info(err, 'Error connecting to drachtio');
|
logger.info(err, 'Error connecting to drachtio');
|
||||||
});
|
});
|
||||||
@@ -113,13 +117,13 @@ function handle(signal) {
|
|||||||
const {removeFromSet} = srf.locals.dbHelpers;
|
const {removeFromSet} = srf.locals.dbHelpers;
|
||||||
srf.locals.disabled = true;
|
srf.locals.disabled = true;
|
||||||
logger.info(`got signal ${signal}`);
|
logger.info(`got signal ${signal}`);
|
||||||
const setName = `${(process.env.JAMBONES_CLUSTER_ID || 'default')}:active-fs`;
|
const setName = `${(JAMBONES_CLUSTER_ID || 'default')}:active-fs`;
|
||||||
if (setName && srf.locals.localSipAddress) {
|
if (setName && srf.locals.localSipAddress) {
|
||||||
logger.info(`got signal ${signal}, removing ${srf.locals.localSipAddress} from set ${setName}`);
|
logger.info(`got signal ${signal}, removing ${srf.locals.localSipAddress} from set ${setName}`);
|
||||||
removeFromSet(setName, srf.locals.localSipAddress);
|
removeFromSet(setName, srf.locals.localSipAddress);
|
||||||
}
|
}
|
||||||
removeFromSet(FS_UUID_SET_NAME, srf.locals.fsUUID);
|
removeFromSet(FS_UUID_SET_NAME, srf.locals.fsUUID);
|
||||||
if (process.env.K8S) {
|
if (K8S) {
|
||||||
srf.locals.lifecycleEmitter.operationalState = LifeCycleEvents.ScaleIn;
|
srf.locals.lifecycleEmitter.operationalState = LifeCycleEvents.ScaleIn;
|
||||||
}
|
}
|
||||||
if (getCount() === 0) {
|
if (getCount() === 0) {
|
||||||
@@ -128,7 +132,7 @@ function handle(signal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.JAMBONZ_CLEANUP_INTERVAL_MINS) {
|
if (JAMBONZ_CLEANUP_INTERVAL_MINS) {
|
||||||
const {clearFiles} = require('./lib/utils/cron-jobs');
|
const {clearFiles} = require('./lib/utils/cron-jobs');
|
||||||
|
|
||||||
/* cleanup orphaned files or channels every so often */
|
/* cleanup orphaned files or channels every so often */
|
||||||
@@ -138,7 +142,7 @@ if (process.env.JAMBONZ_CLEANUP_INTERVAL_MINS) {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error({err}, 'app.js: error clearing files');
|
logger.error({err}, 'app.js: error clearing files');
|
||||||
}
|
}
|
||||||
}, 1000 * 60 * (process.env.JAMBONZ_CLEANUP_INTERVAL_MINS || 60));
|
}, getCleanupIntervalMins());
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {srf, logger, disconnect};
|
module.exports = {srf, logger, disconnect};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const bent = require('bent');
|
const bent = require('bent');
|
||||||
const getJSON = bent('json');
|
const getJSON = bent('json');
|
||||||
const PORT = process.env.HTTP_PORT || 3000;
|
const {PORT} = require('../lib/config')
|
||||||
|
|
||||||
const sleep = (ms) => {
|
const sleep = (ms) => {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|||||||
193
lib/config.js
Normal file
193
lib/config.js
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const checkEnvs = () => {
|
||||||
|
assert.ok(process.env.JAMBONES_MYSQL_HOST &&
|
||||||
|
process.env.JAMBONES_MYSQL_USER &&
|
||||||
|
process.env.JAMBONES_MYSQL_PASSWORD &&
|
||||||
|
process.env.JAMBONES_MYSQL_DATABASE, 'missing JAMBONES_MYSQL_XXX env vars');
|
||||||
|
assert.ok(process.env.DRACHTIO_PORT || process.env.DRACHTIO_HOST, 'missing DRACHTIO_PORT env var');
|
||||||
|
assert.ok(process.env.DRACHTIO_SECRET, 'missing DRACHTIO_SECRET env var');
|
||||||
|
assert.ok(process.env.JAMBONES_FREESWITCH, 'missing JAMBONES_FREESWITCH env var');
|
||||||
|
assert.ok(process.env.JAMBONES_REDIS_HOST, 'missing JAMBONES_REDIS_HOST env var');
|
||||||
|
assert.ok(process.env.JAMBONES_NETWORK_CIDR || process.env.K8S, 'missing JAMBONES_SUBNET env var');
|
||||||
|
};
|
||||||
|
|
||||||
|
const NODE_ENV = process.env.NODE_ENV;
|
||||||
|
|
||||||
|
/* database mySQL */
|
||||||
|
const JAMBONES_MYSQL_HOST = process.env.JAMBONES_MYSQL_HOST;
|
||||||
|
const JAMBONES_MYSQL_USER = process.env.JAMBONES_MYSQL_USER;
|
||||||
|
const JAMBONES_MYSQL_PASSWORD = process.env.JAMBONES_MYSQL_PASSWORD;
|
||||||
|
const JAMBONES_MYSQL_DATABASE = process.env.JAMBONES_MYSQL_DATABASE;
|
||||||
|
const JAMBONES_MYSQL_PORT = parseInt(process.env.JAMBONES_MYSQL_PORT, 10) || 3306;
|
||||||
|
const JAMBONES_MYSQL_REFRESH_TTL = process.env.JAMBONES_MYSQL_REFRESH_TTL;
|
||||||
|
const JAMBONES_MYSQL_CONNECTION_LIMIT = parseInt(process.env.JAMBONES_MYSQL_CONNECTION_LIMIT, 10) || 10;
|
||||||
|
|
||||||
|
/* redis */
|
||||||
|
const JAMBONES_REDIS_HOST = process.env.JAMBONES_REDIS_HOST;
|
||||||
|
const JAMBONES_REDIS_PORT = parseInt(process.env.JAMBONES_REDIS_PORT, 10) || 6379;
|
||||||
|
|
||||||
|
/* gather and hints */
|
||||||
|
const JAMBONES_GATHER_EARLY_HINTS_MATCH = process.env.JAMBONES_GATHER_EARLY_HINTS_MATCH;
|
||||||
|
const JAMBONZ_GATHER_EARLY_HINTS_MATCH = process.env.JAMBONZ_GATHER_EARLY_HINTS_MATCH;
|
||||||
|
const JAMBONES_GATHER_CLEAR_GLOBAL_HINTS_ON_EMPTY_HINTS = process.env.JAMBONES_GATHER_CLEAR_GLOBAL_HINTS_ON_EMPTY_HINTS;
|
||||||
|
|
||||||
|
const SMPP_URL = process.env.SMPP_URL;
|
||||||
|
|
||||||
|
/* drachtio */
|
||||||
|
const DRACHTIO_PORT = process.env.DRACHTIO_PORT;
|
||||||
|
const DRACHTIO_HOST = process.env.DRACHTIO_HOST;
|
||||||
|
const DRACHTIO_SECRET = process.env.DRACHTIO_SECRET;
|
||||||
|
|
||||||
|
/* freeswitch */
|
||||||
|
const JAMBONES_API_BASE_URL = process.env.JAMBONES_API_BASE_URL;
|
||||||
|
const JAMBONES_FREESWITCH = process.env.JAMBONES_FREESWITCH;
|
||||||
|
const JAMBONES_FREESWITCH_MAX_CALL_DURATION_MINS = parseInt(process.env.JAMBONES_FREESWITCH_MAX_CALL_DURATION_MINS, 10)
|
||||||
|
|| 180;
|
||||||
|
|
||||||
|
|
||||||
|
const JAMBONES_SBCS = process.env.JAMBONES_SBCS;
|
||||||
|
|
||||||
|
/* websockets */
|
||||||
|
const JAMBONES_WS_HANDSHAKE_TIMEOUT_MS = parseInt(process.env.JAMBONES_WS_HANDSHAKE_TIMEOUT_MS, 10) || 1500;
|
||||||
|
const JAMBONES_WS_MAX_PAYLOAD = parseInt(process.env.JAMBONES_WS_MAX_PAYLOAD, 10) || 24 * 1024;
|
||||||
|
|
||||||
|
const MAX_RECONNECTS = 5;
|
||||||
|
const RESPONSE_TIMEOUT_MS = parseInt(process.env.JAMBONES_WS_API_MSG_RESPONSE_TIMEOUT, 10) || 5000;
|
||||||
|
|
||||||
|
const JAMBONES_NETWORK_CIDR = process.env.JAMBONES_NETWORK_CIDR;
|
||||||
|
const JAMBONES_TIME_SERIES_HOST = process.env.JAMBONES_TIME_SERIES_HOST;
|
||||||
|
const JAMBONES_CLUSTER_ID = process.env.JAMBONES_CLUSTER_ID || 'default';
|
||||||
|
const JAMBONES_ESL_LISTEN_ADDRESS = process.env.JAMBONES_ESL_LISTEN_ADDRESS;
|
||||||
|
|
||||||
|
/* tracing */
|
||||||
|
const JAMBONES_OTEL_ENABLED = process.env.JAMBONES_OTEL_ENABLED;
|
||||||
|
const JAMBONES_OTEL_SERVICE_NAME = process.env.JAMBONES_OTEL_SERVICE_NAME || 'jambonz-feature-server';
|
||||||
|
const OTEL_EXPORTER_JAEGER_AGENT_HOST = process.env.OTEL_EXPORTER_JAEGER_AGENT_HOST;
|
||||||
|
const OTEL_EXPORTER_ZIPKIN_URL = process.env.OTEL_EXPORTER_ZIPKIN_URL;
|
||||||
|
const OTEL_EXPORTER_COLLECTOR_URL = process.env.OTEL_EXPORTER_COLLECTOR_URL;
|
||||||
|
|
||||||
|
const JAMBONES_LOGLEVEL = process.env.JAMBONES_LOGLEVEL || 'info';
|
||||||
|
const JAMBONES_INJECT_CONTENT = process.env.JAMBONES_INJECT_CONTENT;
|
||||||
|
|
||||||
|
const PORT = parseInt(process.env.HTTP_PORT, 10) || 3000;
|
||||||
|
const HTTP_PORT_MAX = parseInt(process.env.HTTP_PORT_MAX, 10);
|
||||||
|
|
||||||
|
const K8S = process.env.K8S;
|
||||||
|
const K8S_SBC_SIP_SERVICE_NAME = process.env.K8S_SBC_SIP_SERVICE_NAME;
|
||||||
|
|
||||||
|
const JAMBONES_SUBNET = process.env.JAMBONES_SUBNET;
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
const JAMBONZ_CLEANUP_INTERVAL_MINS = process.env.JAMBONZ_CLEANUP_INTERVAL_MINS;
|
||||||
|
const getCleanupIntervalMins = () => {
|
||||||
|
const interval = parseInt(JAMBONZ_CLEANUP_INTERVAL_MINS, 10) || 60;
|
||||||
|
return 1000 * 60 * interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* speech vendors */
|
||||||
|
const AWS_REGION = process.env.AWS_REGION;
|
||||||
|
const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
|
||||||
|
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
|
||||||
|
const AWS_SNS_PORT = parseInt(process.env.AWS_SNS_PORT, 10) || 3001;
|
||||||
|
const AWS_SNS_TOPIC_ARM = process.env.AWS_SNS_TOPIC_ARM;
|
||||||
|
const AWS_SNS_PORT_MAX = parseInt(process.env.AWS_SNS_PORT_MAX, 10) || 3005;
|
||||||
|
|
||||||
|
const GCP_JSON_KEY = process.env.GCP_JSON_KEY;
|
||||||
|
|
||||||
|
const MICROSOFT_REGION = process.env.MICROSOFT_REGION;
|
||||||
|
const MICROSOFT_API_KEY = process.env.MICROSOFT_API_KEY;
|
||||||
|
|
||||||
|
const SONIOX_API_KEY = process.env.SONIOX_API_KEY;
|
||||||
|
|
||||||
|
const DEEPGRAM_API_KEY = process.env.DEEPGRAM_API_KEY;
|
||||||
|
|
||||||
|
const ANCHOR_MEDIA_ALWAYS = process.env.ANCHOR_MEDIA_ALWAYS;
|
||||||
|
const VMD_HINTS_FILE = process.env.VMD_HINTS_FILE;
|
||||||
|
|
||||||
|
/* security, secrets */
|
||||||
|
const LEGACY_CRYPTO = !!process.env.LEGACY_CRYPTO;
|
||||||
|
const JWT_SECRET = process.env.JWT_SECRET;
|
||||||
|
const ENCRYPTION_SECRET = process.env.ENCRYPTION_SECRET;
|
||||||
|
|
||||||
|
/* HTTP/1 pool dispatcher */
|
||||||
|
const HTTP_POOL = process.env.HTTP_POOL && parseInt(process.env.HTTP_POOL);
|
||||||
|
const HTTP_POOLSIZE = parseInt(process.env.HTTP_POOLSIZE, 10) || 10;
|
||||||
|
const HTTP_PIPELINING = parseInt(process.env.HTTP_PIPELINING, 10) || 1;
|
||||||
|
const HTTP_TIMEOUT = 10000;
|
||||||
|
|
||||||
|
const OPTIONS_PING_INTERVAL = parseInt(process.env.OPTIONS_PING_INTERVAL, 10) || 30000;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
JAMBONES_MYSQL_HOST,
|
||||||
|
JAMBONES_MYSQL_USER,
|
||||||
|
JAMBONES_MYSQL_PASSWORD,
|
||||||
|
JAMBONES_MYSQL_DATABASE,
|
||||||
|
JAMBONES_MYSQL_REFRESH_TTL,
|
||||||
|
JAMBONES_MYSQL_CONNECTION_LIMIT,
|
||||||
|
JAMBONES_MYSQL_PORT,
|
||||||
|
|
||||||
|
DRACHTIO_PORT,
|
||||||
|
DRACHTIO_HOST,
|
||||||
|
DRACHTIO_SECRET,
|
||||||
|
|
||||||
|
JAMBONES_GATHER_EARLY_HINTS_MATCH,
|
||||||
|
JAMBONZ_GATHER_EARLY_HINTS_MATCH,
|
||||||
|
JAMBONES_GATHER_CLEAR_GLOBAL_HINTS_ON_EMPTY_HINTS,
|
||||||
|
JAMBONES_FREESWITCH,
|
||||||
|
JAMBONES_REDIS_HOST,
|
||||||
|
JAMBONES_REDIS_PORT,
|
||||||
|
SMPP_URL,
|
||||||
|
JAMBONES_NETWORK_CIDR,
|
||||||
|
JAMBONES_API_BASE_URL,
|
||||||
|
JAMBONES_TIME_SERIES_HOST,
|
||||||
|
JAMBONES_INJECT_CONTENT,
|
||||||
|
JAMBONES_ESL_LISTEN_ADDRESS,
|
||||||
|
JAMBONES_SBCS,
|
||||||
|
JAMBONES_OTEL_ENABLED,
|
||||||
|
JAMBONES_OTEL_SERVICE_NAME,
|
||||||
|
OTEL_EXPORTER_JAEGER_AGENT_HOST,
|
||||||
|
OTEL_EXPORTER_ZIPKIN_URL,
|
||||||
|
OTEL_EXPORTER_COLLECTOR_URL,
|
||||||
|
|
||||||
|
JAMBONES_LOGLEVEL,
|
||||||
|
JAMBONES_CLUSTER_ID,
|
||||||
|
PORT,
|
||||||
|
HTTP_PORT_MAX,
|
||||||
|
K8S,
|
||||||
|
K8S_SBC_SIP_SERVICE_NAME,
|
||||||
|
JAMBONES_SUBNET,
|
||||||
|
NODE_ENV,
|
||||||
|
JAMBONZ_CLEANUP_INTERVAL_MINS,
|
||||||
|
getCleanupIntervalMins,
|
||||||
|
checkEnvs,
|
||||||
|
|
||||||
|
AWS_REGION,
|
||||||
|
AWS_ACCESS_KEY_ID,
|
||||||
|
AWS_SECRET_ACCESS_KEY,
|
||||||
|
AWS_SNS_PORT,
|
||||||
|
AWS_SNS_TOPIC_ARM,
|
||||||
|
AWS_SNS_PORT_MAX,
|
||||||
|
|
||||||
|
ANCHOR_MEDIA_ALWAYS,
|
||||||
|
VMD_HINTS_FILE,
|
||||||
|
JAMBONES_FREESWITCH_MAX_CALL_DURATION_MINS,
|
||||||
|
|
||||||
|
LEGACY_CRYPTO,
|
||||||
|
JWT_SECRET,
|
||||||
|
ENCRYPTION_SECRET,
|
||||||
|
HTTP_POOL,
|
||||||
|
HTTP_POOLSIZE,
|
||||||
|
HTTP_PIPELINING,
|
||||||
|
HTTP_TIMEOUT,
|
||||||
|
OPTIONS_PING_INTERVAL,
|
||||||
|
RESPONSE_TIMEOUT_MS,
|
||||||
|
JAMBONES_WS_HANDSHAKE_TIMEOUT_MS,
|
||||||
|
JAMBONES_WS_MAX_PAYLOAD,
|
||||||
|
MAX_RECONNECTS,
|
||||||
|
GCP_JSON_KEY,
|
||||||
|
MICROSOFT_REGION,
|
||||||
|
MICROSOFT_API_KEY,
|
||||||
|
SONIOX_API_KEY,
|
||||||
|
DEEPGRAM_API_KEY
|
||||||
|
};
|
||||||
@@ -10,6 +10,9 @@ const { normalizeJambones } = require('@jambonz/verb-specifications');
|
|||||||
const dbUtils = require('./utils/db-utils');
|
const dbUtils = require('./utils/db-utils');
|
||||||
const RootSpan = require('./utils/call-tracer');
|
const RootSpan = require('./utils/call-tracer');
|
||||||
const listTaskNames = require('./utils/summarize-tasks');
|
const listTaskNames = require('./utils/summarize-tasks');
|
||||||
|
const {
|
||||||
|
JAMBONES_MYSQL_REFRESH_TTL,
|
||||||
|
} = require('./config');
|
||||||
|
|
||||||
module.exports = function(srf, logger) {
|
module.exports = function(srf, logger) {
|
||||||
const {
|
const {
|
||||||
@@ -242,7 +245,7 @@ module.exports = function(srf, logger) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* allow for caching data - when caching treat retrieved data as immutable */
|
/* allow for caching data - when caching treat retrieved data as immutable */
|
||||||
const app2 = process.env.JAMBONES_MYSQL_REFRESH_TTL ? JSON.parse(JSON.stringify(app)) : app;
|
const app2 = JAMBONES_MYSQL_REFRESH_TTL ? JSON.parse(JSON.stringify(app)) : app;
|
||||||
if ('WS' === app.call_hook?.method ||
|
if ('WS' === app.call_hook?.method ||
|
||||||
app.call_hook?.url.startsWith('ws://') || app.call_hook?.url.startsWith('wss://')) {
|
app.call_hook?.url.startsWith('ws://') || app.call_hook?.url.startsWith('wss://')) {
|
||||||
app2.requestor = new WsRequestor(logger, account_sid, app.call_hook, accountInfo.account.webhook_secret) ;
|
app2.requestor = new WsRequestor(logger, account_sid, app.call_hook, accountInfo.account.webhook_secret) ;
|
||||||
@@ -285,7 +288,7 @@ module.exports = function(srf, logger) {
|
|||||||
const {rootSpan, siprec, application:app} = req.locals;
|
const {rootSpan, siprec, application:app} = req.locals;
|
||||||
let span;
|
let span;
|
||||||
try {
|
try {
|
||||||
if (app.tasks && !process.env.JAMBONES_MYSQL_REFRESH_TTL) {
|
if (app.tasks && !JAMBONES_MYSQL_REFRESH_TTL) {
|
||||||
app.tasks = normalizeJambones(logger, app.tasks).map((tdata) => makeTask(logger, tdata));
|
app.tasks = normalizeJambones(logger, app.tasks).map((tdata) => makeTask(logger, tdata));
|
||||||
if (0 === app.tasks.length) throw new Error('no application provided');
|
if (0 === app.tasks.length) throw new Error('no application provided');
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const {CallDirection, CallStatus} = require('../utils/constants');
|
const {CallDirection, CallStatus} = require('../utils/constants');
|
||||||
const parseUri = require('drachtio-srf').parseUri;
|
const parseUri = require('drachtio-srf').parseUri;
|
||||||
const uuidv4 = require('uuid-random');
|
const uuidv4 = require('uuid-random');
|
||||||
|
const {JAMBONES_API_BASE_URL} = require('../config');
|
||||||
/**
|
/**
|
||||||
* @classdesc Represents the common information for all calls
|
* @classdesc Represents the common information for all calls
|
||||||
* that is provided in call status webhooks
|
* that is provided in call status webhooks
|
||||||
@@ -146,8 +147,8 @@ class CallInfo {
|
|||||||
Object.assign(obj, {customerData: this._customerData});
|
Object.assign(obj, {customerData: this._customerData});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.JAMBONES_API_BASE_URL) {
|
if (JAMBONES_API_BASE_URL) {
|
||||||
Object.assign(obj, {apiBaseUrl: process.env.JAMBONES_API_BASE_URL});
|
Object.assign(obj, {apiBaseUrl: JAMBONES_API_BASE_URL});
|
||||||
}
|
}
|
||||||
if (this.publicIp) {
|
if (this.publicIp) {
|
||||||
Object.assign(obj, {fsPublicIp: this.publicIp});
|
Object.assign(obj, {fsPublicIp: this.publicIp});
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ const { normalizeJambones } = require('@jambonz/verb-specifications');
|
|||||||
const listTaskNames = require('../utils/summarize-tasks');
|
const listTaskNames = require('../utils/summarize-tasks');
|
||||||
const HttpRequestor = require('../utils/http-requestor');
|
const HttpRequestor = require('../utils/http-requestor');
|
||||||
const WsRequestor = require('../utils/ws-requestor');
|
const WsRequestor = require('../utils/ws-requestor');
|
||||||
|
const {
|
||||||
|
JAMBONES_INJECT_CONTENT,
|
||||||
|
AWS_REGION
|
||||||
|
} = require('../config');
|
||||||
const BADPRECONDITIONS = 'preconditions not met';
|
const BADPRECONDITIONS = 'preconditions not met';
|
||||||
const CALLER_CANCELLED_ERR_MSG = 'Response not sent due to unknown transaction';
|
const CALLER_CANCELLED_ERR_MSG = 'Response not sent due to unknown transaction';
|
||||||
|
|
||||||
@@ -626,7 +630,7 @@ class CallSession extends Emitter {
|
|||||||
speech_credential_sid: credential.speech_credential_sid,
|
speech_credential_sid: credential.speech_credential_sid,
|
||||||
accessKeyId: credential.access_key_id,
|
accessKeyId: credential.access_key_id,
|
||||||
secretAccessKey: credential.secret_access_key,
|
secretAccessKey: credential.secret_access_key,
|
||||||
region: credential.aws_region || process.env.AWS_REGION
|
region: credential.aws_region || AWS_REGION
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if ('microsoft' === vendor) {
|
else if ('microsoft' === vendor) {
|
||||||
@@ -1199,7 +1203,7 @@ class CallSession extends Emitter {
|
|||||||
this.logger.info({tasks: listTaskNames(t)}, 'CallSession:_onCommand new task list');
|
this.logger.info({tasks: listTaskNames(t)}, 'CallSession:_onCommand new task list');
|
||||||
this.replaceApplication(t);
|
this.replaceApplication(t);
|
||||||
}
|
}
|
||||||
else if (process.env.JAMBONES_INJECT_CONTENT) {
|
else if (JAMBONES_INJECT_CONTENT) {
|
||||||
this._injectTasks(t);
|
this._injectTasks(t);
|
||||||
this.logger.info({tasks: listTaskNames(this.tasks)}, 'CallSession:_onCommand - updated task list');
|
this.logger.info({tasks: listTaskNames(this.tasks)}, 'CallSession:_onCommand - updated task list');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const DtmfCollector = require('../utils/dtmf-collector');
|
|||||||
const dbUtils = require('../utils/db-utils');
|
const dbUtils = require('../utils/db-utils');
|
||||||
const debug = require('debug')('jambonz:feature-server');
|
const debug = require('debug')('jambonz:feature-server');
|
||||||
const {parseUri} = require('drachtio-srf');
|
const {parseUri} = require('drachtio-srf');
|
||||||
|
const {ANCHOR_MEDIA_ALWAYS} = require('../config');
|
||||||
|
|
||||||
function parseDtmfOptions(logger, dtmfCapture) {
|
function parseDtmfOptions(logger, dtmfCapture) {
|
||||||
let parentDtmfCollector, childDtmfCollector;
|
let parentDtmfCollector, childDtmfCollector;
|
||||||
@@ -135,7 +136,7 @@ class TaskDial extends Task {
|
|||||||
|
|
||||||
get canReleaseMedia() {
|
get canReleaseMedia() {
|
||||||
const keepAnchor = this.data.anchorMedia ||
|
const keepAnchor = this.data.anchorMedia ||
|
||||||
process.env.ANCHOR_MEDIA_ALWAYS ||
|
ANCHOR_MEDIA_ALWAYS ||
|
||||||
this.listenTask ||
|
this.listenTask ||
|
||||||
this.transcribeTask ||
|
this.transcribeTask ||
|
||||||
this.startAmd;
|
this.startAmd;
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ const {
|
|||||||
NvidiaTranscriptionEvents,
|
NvidiaTranscriptionEvents,
|
||||||
JambonzTranscriptionEvents
|
JambonzTranscriptionEvents
|
||||||
} = require('../utils/constants');
|
} = require('../utils/constants');
|
||||||
|
const {
|
||||||
|
JAMBONES_GATHER_EARLY_HINTS_MATCH,
|
||||||
|
JAMBONZ_GATHER_EARLY_HINTS_MATCH,
|
||||||
|
JAMBONES_GATHER_CLEAR_GLOBAL_HINTS_ON_EMPTY_HINTS,
|
||||||
|
} = require('../config');
|
||||||
const makeTask = require('./make_task');
|
const makeTask = require('./make_task');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
@@ -71,7 +75,7 @@ class TaskGather extends Task {
|
|||||||
this.isContinuousAsr = this.asrTimeout > 0;
|
this.isContinuousAsr = this.asrTimeout > 0;
|
||||||
|
|
||||||
if (Array.isArray(this.data.recognizer.hints) &&
|
if (Array.isArray(this.data.recognizer.hints) &&
|
||||||
0 == this.data.recognizer.hints.length && process.env.JAMBONES_GATHER_CLEAR_GLOBAL_HINTS_ON_EMPTY_HINTS) {
|
0 == this.data.recognizer.hints.length && JAMBONES_GATHER_CLEAR_GLOBAL_HINTS_ON_EMPTY_HINTS) {
|
||||||
logger.debug('Gather: an empty hints array was supplied, so we will mask global hints');
|
logger.debug('Gather: an empty hints array was supplied, so we will mask global hints');
|
||||||
this.maskGlobalSttHints = true;
|
this.maskGlobalSttHints = true;
|
||||||
}
|
}
|
||||||
@@ -162,7 +166,7 @@ class TaskGather extends Task {
|
|||||||
asrDtmfTerminationDigit: this.asrDtmfTerminationDigit
|
asrDtmfTerminationDigit: this.asrDtmfTerminationDigit
|
||||||
}, 'Gather:exec - enabling continuous ASR since it is turned on for the session');
|
}, 'Gather:exec - enabling continuous ASR since it is turned on for the session');
|
||||||
}
|
}
|
||||||
const {JAMBONZ_GATHER_EARLY_HINTS_MATCH, JAMBONES_GATHER_EARLY_HINTS_MATCH} = process.env;
|
|
||||||
if ((JAMBONZ_GATHER_EARLY_HINTS_MATCH || JAMBONES_GATHER_EARLY_HINTS_MATCH) && this.needsStt &&
|
if ((JAMBONZ_GATHER_EARLY_HINTS_MATCH || JAMBONES_GATHER_EARLY_HINTS_MATCH) && this.needsStt &&
|
||||||
!this.isContinuousAsr &&
|
!this.isContinuousAsr &&
|
||||||
this.data.recognizer?.hints?.length > 0 && this.data.recognizer?.hints?.length <= 10) {
|
this.data.recognizer?.hints?.length > 0 && this.data.recognizer?.hints?.length <= 10) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const Task = require('./task');
|
|||||||
const {TaskName, TaskPreconditions} = require('../utils/constants');
|
const {TaskName, TaskPreconditions} = require('../utils/constants');
|
||||||
const bent = require('bent');
|
const bent = require('bent');
|
||||||
const uuidv4 = require('uuid-random');
|
const uuidv4 = require('uuid-random');
|
||||||
|
const {K8S} = require('../config');
|
||||||
class TaskMessage extends Task {
|
class TaskMessage extends Task {
|
||||||
constructor(logger, opts) {
|
constructor(logger, opts) {
|
||||||
super(logger, opts);
|
super(logger, opts);
|
||||||
@@ -42,7 +42,7 @@ class TaskMessage extends Task {
|
|||||||
}
|
}
|
||||||
if (gw) {
|
if (gw) {
|
||||||
this.logger.info({gw, accountSid}, 'Message:exec - using smpp to send message');
|
this.logger.info({gw, accountSid}, 'Message:exec - using smpp to send message');
|
||||||
url = process.env.K8S ? 'http://smpp' : getSmpp();
|
url = K8S ? 'http://smpp' : getSmpp();
|
||||||
relativeUrl = '/sms';
|
relativeUrl = '/sms';
|
||||||
payload = {
|
payload = {
|
||||||
...payload,
|
...payload,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const {
|
|||||||
AvmdEvents
|
AvmdEvents
|
||||||
} = require('./constants');
|
} = require('./constants');
|
||||||
const bugname = 'amd_bug';
|
const bugname = 'amd_bug';
|
||||||
const {VMD_HINTS_FILE} = process.env;
|
const {VMD_HINTS_FILE} = require('../config');
|
||||||
let voicemailHints = [];
|
let voicemailHints = [];
|
||||||
|
|
||||||
const updateHints = async(file, callback) => {
|
const updateHints = async(file, callback) => {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
const Emitter = require('events');
|
const Emitter = require('events');
|
||||||
const bent = require('bent');
|
const bent = require('bent');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const PORT = process.env.AWS_SNS_PORT || 3010;
|
const {
|
||||||
|
AWS_REGION,
|
||||||
|
AWS_SNS_PORT: PORT,
|
||||||
|
AWS_SNS_TOPIC_ARM,
|
||||||
|
AWS_SNS_PORT_MAX,
|
||||||
|
} = require('../config');
|
||||||
const {LifeCycleEvents} = require('./constants');
|
const {LifeCycleEvents} = require('./constants');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -13,7 +18,7 @@ const {Parser} = require('xml2js');
|
|||||||
const parser = new Parser();
|
const parser = new Parser();
|
||||||
const {validatePayload} = require('verify-aws-sns-signature');
|
const {validatePayload} = require('verify-aws-sns-signature');
|
||||||
|
|
||||||
AWS.config.update({region: process.env.AWS_REGION});
|
AWS.config.update({region: AWS_REGION});
|
||||||
|
|
||||||
class SnsNotifier extends Emitter {
|
class SnsNotifier extends Emitter {
|
||||||
constructor(logger) {
|
constructor(logger) {
|
||||||
@@ -31,8 +36,8 @@ class SnsNotifier extends Emitter {
|
|||||||
|
|
||||||
_handleErrors(logger, app, resolve, reject, e) {
|
_handleErrors(logger, app, resolve, reject, e) {
|
||||||
if (e.code === 'EADDRINUSE' &&
|
if (e.code === 'EADDRINUSE' &&
|
||||||
process.env.AWS_SNS_PORT_MAX &&
|
AWS_SNS_PORT_MAX &&
|
||||||
e.port < process.env.AWS_SNS_PORT_MAX) {
|
e.port < AWS_SNS_PORT_MAX) {
|
||||||
|
|
||||||
logger.info(`SNS lifecycle server failed to bind port on ${e.port}, will try next port`);
|
logger.info(`SNS lifecycle server failed to bind port on ${e.port}, will try next port`);
|
||||||
const server = this._doListen(logger, app, ++e.port, resolve);
|
const server = this._doListen(logger, app, ++e.port, resolve);
|
||||||
@@ -132,12 +137,12 @@ class SnsNotifier extends Emitter {
|
|||||||
try {
|
try {
|
||||||
const response = await sns.subscribe({
|
const response = await sns.subscribe({
|
||||||
Protocol: 'http',
|
Protocol: 'http',
|
||||||
TopicArn: process.env.AWS_SNS_TOPIC_ARM,
|
TopicArn: AWS_SNS_TOPIC_ARM,
|
||||||
Endpoint: this.snsEndpoint
|
Endpoint: this.snsEndpoint
|
||||||
}).promise();
|
}).promise();
|
||||||
this.logger.info({response}, `response to SNS subscribe to ${process.env.AWS_SNS_TOPIC_ARM}`);
|
this.logger.info({response}, `response to SNS subscribe to ${AWS_SNS_TOPIC_ARM}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error({err}, `Error subscribing to SNS topic arn ${process.env.AWS_SNS_TOPIC_ARM}`);
|
this.logger.error({err}, `Error subscribing to SNS topic arn ${AWS_SNS_TOPIC_ARM}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,9 +152,9 @@ class SnsNotifier extends Emitter {
|
|||||||
const response = await sns.unsubscribe({
|
const response = await sns.unsubscribe({
|
||||||
SubscriptionArn: this.subscriptionArn
|
SubscriptionArn: this.subscriptionArn
|
||||||
}).promise();
|
}).promise();
|
||||||
this.logger.info({response}, `response to SNS unsubscribe to ${process.env.AWS_SNS_TOPIC_ARM}`);
|
this.logger.info({response}, `response to SNS unsubscribe to ${AWS_SNS_TOPIC_ARM}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error({err}, `Error unsubscribing to SNS topic arn ${process.env.AWS_SNS_TOPIC_ARM}`);
|
this.logger.error({err}, `Error unsubscribing to SNS topic arn ${AWS_SNS_TOPIC_ARM}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const assert = require('assert');
|
|||||||
const Emitter = require('events');
|
const Emitter = require('events');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const timeSeries = require('@jambonz/time-series');
|
const timeSeries = require('@jambonz/time-series');
|
||||||
|
const {NODE_ENV, JAMBONES_TIME_SERIES_HOST} = require('../config');
|
||||||
let alerter ;
|
let alerter ;
|
||||||
|
|
||||||
class BaseRequestor extends Emitter {
|
class BaseRequestor extends Emitter {
|
||||||
@@ -22,9 +23,9 @@ class BaseRequestor extends Emitter {
|
|||||||
|
|
||||||
if (!alerter) {
|
if (!alerter) {
|
||||||
alerter = timeSeries(logger, {
|
alerter = timeSeries(logger, {
|
||||||
host: process.env.JAMBONES_TIME_SERIES_HOST,
|
host: JAMBONES_TIME_SERIES_HOST,
|
||||||
commitSize: 50,
|
commitSize: 50,
|
||||||
commitInterval: 'test' === process.env.NODE_ENV ? 7 : 20
|
commitInterval: 'test' === NODE_ENV ? 7 : 20
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,24 @@
|
|||||||
const {execSync} = require('child_process');
|
const {execSync} = require('child_process');
|
||||||
|
const {
|
||||||
|
JAMBONES_FREESWITCH,
|
||||||
|
NODE_ENV,
|
||||||
|
JAMBONES_FREESWITCH_MAX_CALL_DURATION_MINS,
|
||||||
|
} = require('../config');
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const fsInventory = process.env.JAMBONES_FREESWITCH
|
const fsInventory = JAMBONES_FREESWITCH
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((fs) => {
|
.map((fs) => {
|
||||||
const arr = /^([^:]*):([^:]*):([^:]*)(?::([^:]*))?/.exec(fs);
|
const arr = /^([^:]*):([^:]*):([^:]*)(?::([^:]*))?/.exec(fs);
|
||||||
const opts = {address: arr[1], port: arr[2], secret: arr[3]};
|
const opts = {address: arr[1], port: arr[2], secret: arr[3]};
|
||||||
if (arr.length > 4) opts.advertisedAddress = arr[4];
|
if (arr.length > 4) opts.advertisedAddress = arr[4];
|
||||||
if (process.env.NODE_ENV === 'test') opts.listenAddress = '0.0.0.0';
|
if (NODE_ENV === 'test') opts.listenAddress = '0.0.0.0';
|
||||||
return opts;
|
return opts;
|
||||||
});
|
});
|
||||||
|
|
||||||
const clearChannels = () => {
|
const clearChannels = () => {
|
||||||
const {logger} = require('../..');
|
const {logger} = require('../..');
|
||||||
const pwd = fsInventory[0].secret;
|
const pwd = fsInventory[0].secret;
|
||||||
const maxDurationMins = process.env.JAMBONES_FREESWITCH_MAX_CALL_DURATION_MINS || 180;
|
const maxDurationMins = JAMBONES_FREESWITCH_MAX_CALL_DURATION_MINS;
|
||||||
|
|
||||||
const calls = execSync(`/usr/local/freeswitch/bin/fs_cli -p ${pwd} -x "show calls"`, {encoding: 'utf8'})
|
const calls = execSync(`/usr/local/freeswitch/bin/fs_cli -p ${pwd} -x "show calls"`, {encoding: 'utf8'})
|
||||||
.split('\n')
|
.split('\n')
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const algorithm = process.env.LEGACY_CRYPTO ? 'aes-256-ctr' : 'aes-256-cbc';
|
const {LEGACY_CRYPTO, ENCRYPTION_SECRET, JWT_SECRET} = require('../config');
|
||||||
|
const algorithm = LEGACY_CRYPTO ? 'aes-256-ctr' : 'aes-256-cbc';
|
||||||
const iv = crypto.randomBytes(16);
|
const iv = crypto.randomBytes(16);
|
||||||
const secretKey = crypto.createHash('sha256')
|
const secretKey = crypto.createHash('sha256')
|
||||||
.update(process.env.ENCRYPTION_SECRET || process.env.JWT_SECRET)
|
.update(ENCRYPTION_SECRET || JWT_SECRET)
|
||||||
.digest('base64')
|
.digest('base64')
|
||||||
.substring(0, 32);
|
.substring(0, 32);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const httpRoutes = require('../http-routes');
|
const httpRoutes = require('../http-routes');
|
||||||
const PORT = process.env.HTTP_PORT || 3000;
|
const {PORT, HTTP_PORT_MAX} = require('../config');
|
||||||
|
|
||||||
const doListen = (logger, app, port, resolve) => {
|
const doListen = (logger, app, port, resolve) => {
|
||||||
const server = app.listen(port, () => {
|
const server = app.listen(port, () => {
|
||||||
@@ -13,8 +13,8 @@ const doListen = (logger, app, port, resolve) => {
|
|||||||
};
|
};
|
||||||
const handleErrors = (logger, app, resolve, reject, e) => {
|
const handleErrors = (logger, app, resolve, reject, e) => {
|
||||||
if (e.code === 'EADDRINUSE' &&
|
if (e.code === 'EADDRINUSE' &&
|
||||||
process.env.HTTP_PORT_MAX &&
|
HTTP_PORT_MAX &&
|
||||||
e.port < process.env.HTTP_PORT_MAX) {
|
e.port < HTTP_PORT_MAX) {
|
||||||
|
|
||||||
logger.info(`HTTP server failed to bind port on ${e.port}, will try next port`);
|
logger.info(`HTTP server failed to bind port on ${e.port}, will try next port`);
|
||||||
const server = doListen(logger, app, ++e.port, resolve);
|
const server = doListen(logger, app, ++e.port, resolve);
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ const BaseRequestor = require('./base-requestor');
|
|||||||
const {HookMsgTypes} = require('./constants.json');
|
const {HookMsgTypes} = require('./constants.json');
|
||||||
const snakeCaseKeys = require('./snakecase-keys');
|
const snakeCaseKeys = require('./snakecase-keys');
|
||||||
const pools = new Map();
|
const pools = new Map();
|
||||||
const HTTP_TIMEOUT = 10000;
|
const {
|
||||||
|
HTTP_POOL,
|
||||||
|
HTTP_POOLSIZE,
|
||||||
|
HTTP_PIPELINING,
|
||||||
|
HTTP_TIMEOUT,
|
||||||
|
} = require('../config');
|
||||||
|
|
||||||
const toBase64 = (str) => Buffer.from(str || '', 'utf8').toString('base64');
|
const toBase64 = (str) => Buffer.from(str || '', 'utf8').toString('base64');
|
||||||
|
|
||||||
@@ -34,15 +39,15 @@ class HttpRequestor extends BaseRequestor {
|
|||||||
this._resource = u.resource;
|
this._resource = u.resource;
|
||||||
this._port = u.port;
|
this._port = u.port;
|
||||||
this._search = u.search;
|
this._search = u.search;
|
||||||
this._usePools = process.env.HTTP_POOL && parseInt(process.env.HTTP_POOL);
|
this._usePools = HTTP_POOL && parseInt(HTTP_POOL);
|
||||||
|
|
||||||
if (this._usePools) {
|
if (this._usePools) {
|
||||||
if (pools.has(this._baseUrl)) {
|
if (pools.has(this._baseUrl)) {
|
||||||
this.client = pools.get(this._baseUrl);
|
this.client = pools.get(this._baseUrl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const connections = process.env.HTTP_POOLSIZE ? parseInt(process.env.HTTP_POOLSIZE) : 10;
|
const connections = HTTP_POOLSIZE ? parseInt(HTTP_POOLSIZE) : 10;
|
||||||
const pipelining = process.env.HTTP_PIPELINING ? parseInt(process.env.HTTP_PIPELINING) : 1;
|
const pipelining = HTTP_PIPELINING ? parseInt(HTTP_PIPELINING) : 1;
|
||||||
const pool = this.client = new Pool(this._baseUrl, {
|
const pool = this.client = new Pool(this._baseUrl, {
|
||||||
connections,
|
connections,
|
||||||
pipelining
|
pipelining
|
||||||
|
|||||||
@@ -1,6 +1,21 @@
|
|||||||
const Mrf = require('drachtio-fsmrf');
|
const Mrf = require('drachtio-fsmrf');
|
||||||
const ip = require('ip');
|
const ip = require('ip');
|
||||||
const PORT = process.env.HTTP_PORT || 3000;
|
const {
|
||||||
|
JAMBONES_MYSQL_HOST,
|
||||||
|
JAMBONES_MYSQL_USER,
|
||||||
|
JAMBONES_MYSQL_PASSWORD,
|
||||||
|
JAMBONES_MYSQL_DATABASE,
|
||||||
|
JAMBONES_MYSQL_CONNECTION_LIMIT,
|
||||||
|
JAMBONES_MYSQL_PORT,
|
||||||
|
JAMBONES_FREESWITCH,
|
||||||
|
JAMBONES_REDIS_HOST,
|
||||||
|
JAMBONES_REDIS_PORT,
|
||||||
|
SMPP_URL,
|
||||||
|
JAMBONES_TIME_SERIES_HOST,
|
||||||
|
JAMBONES_ESL_LISTEN_ADDRESS,
|
||||||
|
PORT,
|
||||||
|
NODE_ENV,
|
||||||
|
} = require('../config');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
function initMS(logger, wrapper, ms) {
|
function initMS(logger, wrapper, ms) {
|
||||||
@@ -42,18 +57,18 @@ function installSrfLocals(srf, logger) {
|
|||||||
let idxStart = 0;
|
let idxStart = 0;
|
||||||
|
|
||||||
(async function() {
|
(async function() {
|
||||||
const fsInventory = process.env.JAMBONES_FREESWITCH
|
const fsInventory = JAMBONES_FREESWITCH
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((fs) => {
|
.map((fs) => {
|
||||||
const arr = /^([^:]*):([^:]*):([^:]*)(?::([^:]*))?/.exec(fs);
|
const arr = /^([^:]*):([^:]*):([^:]*)(?::([^:]*))?/.exec(fs);
|
||||||
assert.ok(arr, `Invalid syntax JAMBONES_FREESWITCH: ${process.env.JAMBONES_FREESWITCH}`);
|
assert.ok(arr, `Invalid syntax JAMBONES_FREESWITCH: ${JAMBONES_FREESWITCH}`);
|
||||||
const opts = {address: arr[1], port: arr[2], secret: arr[3]};
|
const opts = {address: arr[1], port: arr[2], secret: arr[3]};
|
||||||
if (arr.length > 4) opts.advertisedAddress = arr[4];
|
if (arr.length > 4) opts.advertisedAddress = arr[4];
|
||||||
/* NB: originally for testing only, but for now all jambonz deployments
|
/* NB: originally for testing only, but for now all jambonz deployments
|
||||||
have freeswitch installed locally alongside this app
|
have freeswitch installed locally alongside this app
|
||||||
*/
|
*/
|
||||||
if (process.env.NODE_ENV === 'test') opts.listenAddress = '0.0.0.0';
|
if (NODE_ENV === 'test') opts.listenAddress = '0.0.0.0';
|
||||||
else if (process.env.JAMBONES_ESL_LISTEN_ADDRESS) opts.listenAddress = process.env.JAMBONES_ESL_LISTEN_ADDRESS;
|
else if (JAMBONES_ESL_LISTEN_ADDRESS) opts.listenAddress = JAMBONES_ESL_LISTEN_ADDRESS;
|
||||||
return opts;
|
return opts;
|
||||||
});
|
});
|
||||||
logger.info({fsInventory}, 'freeswitch inventory');
|
logger.info({fsInventory}, 'freeswitch inventory');
|
||||||
@@ -125,12 +140,12 @@ function installSrfLocals(srf, logger) {
|
|||||||
lookupAccountCapacitiesBySid,
|
lookupAccountCapacitiesBySid,
|
||||||
lookupSmppGateways
|
lookupSmppGateways
|
||||||
} = require('@jambonz/db-helpers')({
|
} = require('@jambonz/db-helpers')({
|
||||||
host: process.env.JAMBONES_MYSQL_HOST,
|
host: JAMBONES_MYSQL_HOST,
|
||||||
user: process.env.JAMBONES_MYSQL_USER,
|
user: JAMBONES_MYSQL_USER,
|
||||||
port: process.env.JAMBONES_MYSQL_PORT || 3306,
|
port: JAMBONES_MYSQL_PORT || 3306,
|
||||||
password: process.env.JAMBONES_MYSQL_PASSWORD,
|
password: JAMBONES_MYSQL_PASSWORD,
|
||||||
database: process.env.JAMBONES_MYSQL_DATABASE,
|
database: JAMBONES_MYSQL_DATABASE,
|
||||||
connectionLimit: process.env.JAMBONES_MYSQL_CONNECTION_LIMIT || 10
|
connectionLimit: JAMBONES_MYSQL_CONNECTION_LIMIT || 10
|
||||||
}, logger, tracer);
|
}, logger, tracer);
|
||||||
const {
|
const {
|
||||||
client,
|
client,
|
||||||
@@ -153,24 +168,24 @@ function installSrfLocals(srf, logger) {
|
|||||||
getListPosition,
|
getListPosition,
|
||||||
lengthOfList,
|
lengthOfList,
|
||||||
} = require('@jambonz/realtimedb-helpers')({
|
} = require('@jambonz/realtimedb-helpers')({
|
||||||
host: process.env.JAMBONES_REDIS_HOST,
|
host: JAMBONES_REDIS_HOST,
|
||||||
port: process.env.JAMBONES_REDIS_PORT || 6379
|
port: JAMBONES_REDIS_PORT || 6379
|
||||||
}, logger, tracer);
|
}, logger, tracer);
|
||||||
const {
|
const {
|
||||||
synthAudio,
|
synthAudio,
|
||||||
getNuanceAccessToken,
|
getNuanceAccessToken,
|
||||||
getIbmAccessToken,
|
getIbmAccessToken,
|
||||||
} = require('@jambonz/speech-utils')({
|
} = require('@jambonz/speech-utils')({
|
||||||
host: process.env.JAMBONES_REDIS_HOST,
|
host: JAMBONES_REDIS_HOST,
|
||||||
port: process.env.JAMBONES_REDIS_PORT || 6379
|
port: JAMBONES_REDIS_PORT || 6379
|
||||||
}, logger, tracer);
|
}, logger, tracer);
|
||||||
const {
|
const {
|
||||||
writeAlerts,
|
writeAlerts,
|
||||||
AlertType
|
AlertType
|
||||||
} = require('@jambonz/time-series')(logger, {
|
} = require('@jambonz/time-series')(logger, {
|
||||||
host: process.env.JAMBONES_TIME_SERIES_HOST,
|
host: JAMBONES_TIME_SERIES_HOST,
|
||||||
commitSize: 50,
|
commitSize: 50,
|
||||||
commitInterval: 'test' === process.env.NODE_ENV ? 7 : 20
|
commitInterval: 'test' === NODE_ENV ? 7 : 20
|
||||||
});
|
});
|
||||||
|
|
||||||
let localIp;
|
let localIp;
|
||||||
@@ -218,7 +233,7 @@ function installSrfLocals(srf, logger) {
|
|||||||
parentLogger: logger,
|
parentLogger: logger,
|
||||||
getSBC,
|
getSBC,
|
||||||
getSmpp: () => {
|
getSmpp: () => {
|
||||||
return process.env.SMPP_URL;
|
return SMPP_URL;
|
||||||
},
|
},
|
||||||
lifecycleEmitter,
|
lifecycleEmitter,
|
||||||
getFreeswitch,
|
getFreeswitch,
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const timeSeries = require('@jambonz/time-series');
|
const timeSeries = require('@jambonz/time-series');
|
||||||
|
const {
|
||||||
|
NODE_ENV,
|
||||||
|
JAMBONES_TIME_SERIES_HOST
|
||||||
|
} = require('../config');
|
||||||
let alerter ;
|
let alerter ;
|
||||||
|
|
||||||
function isAbsoluteUrl(u) {
|
function isAbsoluteUrl(u) {
|
||||||
@@ -28,9 +32,9 @@ class Requestor {
|
|||||||
|
|
||||||
if (!alerter) {
|
if (!alerter) {
|
||||||
alerter = timeSeries(logger, {
|
alerter = timeSeries(logger, {
|
||||||
host: process.env.JAMBONES_TIME_SERIES_HOST,
|
host: JAMBONES_TIME_SERIES_HOST,
|
||||||
commitSize: 50,
|
commitSize: 50,
|
||||||
commitInterval: 'test' === process.env.NODE_ENV ? 7 : 20
|
commitInterval: 'test' === NODE_ENV ? 7 : 20
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,9 +42,9 @@ class Requestor {
|
|||||||
get Alerter() {
|
get Alerter() {
|
||||||
if (!alerter) {
|
if (!alerter) {
|
||||||
alerter = timeSeries(this.logger, {
|
alerter = timeSeries(this.logger, {
|
||||||
host: process.env.JAMBONES_TIME_SERIES_HOST,
|
host: JAMBONES_TIME_SERIES_HOST,
|
||||||
commitSize: 50,
|
commitSize: 50,
|
||||||
commitInterval: 'test' === process.env.NODE_ENV ? 7 : 20
|
commitInterval: 'test' === NODE_ENV ? 7 : 20
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return alerter;
|
return alerter;
|
||||||
|
|||||||
@@ -4,28 +4,38 @@ const {LifeCycleEvents, FS_UUID_SET_NAME} = require('./constants');
|
|||||||
const Emitter = require('events');
|
const Emitter = require('events');
|
||||||
const debug = require('debug')('jambonz:feature-server');
|
const debug = require('debug')('jambonz:feature-server');
|
||||||
const noopLogger = {info: () => {}, error: () => {}};
|
const noopLogger = {info: () => {}, error: () => {}};
|
||||||
|
const {
|
||||||
|
JAMBONES_SBCS,
|
||||||
|
K8S,
|
||||||
|
K8S_SBC_SIP_SERVICE_NAME,
|
||||||
|
AWS_SNS_TOPIC_ARM,
|
||||||
|
OPTIONS_PING_INTERVAL,
|
||||||
|
AWS_REGION,
|
||||||
|
NODE_ENV,
|
||||||
|
JAMBONES_CLUSTER_ID,
|
||||||
|
} = require('../config');
|
||||||
|
|
||||||
module.exports = (logger) => {
|
module.exports = (logger) => {
|
||||||
logger = logger || noopLogger;
|
logger = logger || noopLogger;
|
||||||
let idxSbc = 0;
|
let idxSbc = 0;
|
||||||
let sbcs = [];
|
let sbcs = [];
|
||||||
|
|
||||||
if (process.env.JAMBONES_SBCS) {
|
if (JAMBONES_SBCS) {
|
||||||
sbcs = process.env.JAMBONES_SBCS
|
sbcs = JAMBONES_SBCS
|
||||||
.split(',')
|
.split(',')
|
||||||
.map((sbc) => sbc.trim());
|
.map((sbc) => sbc.trim());
|
||||||
assert.ok(sbcs.length, 'JAMBONES_SBCS env var is empty or misconfigured');
|
assert.ok(sbcs.length, 'JAMBONES_SBCS env var is empty or misconfigured');
|
||||||
logger.info({sbcs}, 'SBC inventory');
|
logger.info({sbcs}, 'SBC inventory');
|
||||||
}
|
}
|
||||||
else if (process.env.K8S && process.env.K8S_SBC_SIP_SERVICE_NAME) {
|
else if (K8S && K8S_SBC_SIP_SERVICE_NAME) {
|
||||||
sbcs = [`${process.env.K8S_SBC_SIP_SERVICE_NAME}:5060`];
|
sbcs = [`${K8S_SBC_SIP_SERVICE_NAME}:5060`];
|
||||||
logger.info({sbcs}, 'SBC inventory');
|
logger.info({sbcs}, 'SBC inventory');
|
||||||
}
|
}
|
||||||
|
|
||||||
// listen for SNS lifecycle changes
|
// listen for SNS lifecycle changes
|
||||||
let lifecycleEmitter = new Emitter();
|
let lifecycleEmitter = new Emitter();
|
||||||
let dryUpCalls = false;
|
let dryUpCalls = false;
|
||||||
if (process.env.AWS_SNS_TOPIC_ARM && process.env.AWS_REGION) {
|
if (AWS_SNS_TOPIC_ARM && AWS_REGION) {
|
||||||
|
|
||||||
(async function() {
|
(async function() {
|
||||||
try {
|
try {
|
||||||
@@ -75,13 +85,13 @@ module.exports = (logger) => {
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
else if (process.env.K8S) {
|
else if (K8S) {
|
||||||
lifecycleEmitter.scaleIn = () => process.exit(0);
|
lifecycleEmitter.scaleIn = () => process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function pingProxies(srf) {
|
async function pingProxies(srf) {
|
||||||
if (process.env.NODE_ENV === 'test') return;
|
if (NODE_ENV === 'test') return;
|
||||||
|
|
||||||
for (const sbc of sbcs) {
|
for (const sbc of sbcs) {
|
||||||
try {
|
try {
|
||||||
@@ -102,7 +112,7 @@ module.exports = (logger) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (process.env.K8S) {
|
if (K8S) {
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
logger.info('disabling OPTIONS pings since we are running as a kubernetes service');
|
logger.info('disabling OPTIONS pings since we are running as a kubernetes service');
|
||||||
const {srf} = require('../..');
|
const {srf} = require('../..');
|
||||||
@@ -123,16 +133,16 @@ module.exports = (logger) => {
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const {srf} = require('../..');
|
const {srf} = require('../..');
|
||||||
pingProxies(srf);
|
pingProxies(srf);
|
||||||
}, process.env.OPTIONS_PING_INTERVAL || 30000);
|
}, OPTIONS_PING_INTERVAL);
|
||||||
|
|
||||||
// initial ping once we are up
|
// initial ping once we are up
|
||||||
setTimeout(async() => {
|
setTimeout(async() => {
|
||||||
|
|
||||||
// if SBCs are auto-scaling, monitor them as they come and go
|
// if SBCs are auto-scaling, monitor them as they come and go
|
||||||
const {srf} = require('../..');
|
const {srf} = require('../..');
|
||||||
if (!process.env.JAMBONES_SBCS) {
|
if (!JAMBONES_SBCS) {
|
||||||
const {monitorSet} = srf.locals.dbHelpers;
|
const {monitorSet} = srf.locals.dbHelpers;
|
||||||
const setName = `${(process.env.JAMBONES_CLUSTER_ID || 'default')}:active-sip`;
|
const setName = `${(JAMBONES_CLUSTER_ID || 'default')}:active-sip`;
|
||||||
await monitorSet(setName, 10, (members) => {
|
await monitorSet(setName, 10, (members) => {
|
||||||
sbcs = members;
|
sbcs = members;
|
||||||
logger.info(`sbc-pinger: SBC roster has changed, list of active SBCs is now ${sbcs}`);
|
logger.info(`sbc-pinger: SBC roster has changed, list of active SBCs is now ${sbcs}`);
|
||||||
|
|||||||
@@ -4,8 +4,12 @@ const short = require('short-uuid');
|
|||||||
const {HookMsgTypes} = require('./constants.json');
|
const {HookMsgTypes} = require('./constants.json');
|
||||||
const Websocket = require('ws');
|
const Websocket = require('ws');
|
||||||
const snakeCaseKeys = require('./snakecase-keys');
|
const snakeCaseKeys = require('./snakecase-keys');
|
||||||
const MAX_RECONNECTS = 5;
|
const {
|
||||||
const RESPONSE_TIMEOUT_MS = process.env.JAMBONES_WS_API_MSG_RESPONSE_TIMEOUT || 5000;
|
RESPONSE_TIMEOUT_MS,
|
||||||
|
MAX_RECONNECTS,
|
||||||
|
JAMBONES_WS_HANDSHAKE_TIMEOUT_MS,
|
||||||
|
JAMBONES_WS_MAX_PAYLOAD
|
||||||
|
} = require('../config');
|
||||||
|
|
||||||
class WsRequestor extends BaseRequestor {
|
class WsRequestor extends BaseRequestor {
|
||||||
constructor(logger, account_sid, hook, secret) {
|
constructor(logger, account_sid, hook, secret) {
|
||||||
@@ -192,14 +196,14 @@ class WsRequestor extends BaseRequestor {
|
|||||||
_connect() {
|
_connect() {
|
||||||
assert(!this.ws);
|
assert(!this.ws);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const handshakeTimeout = process.env.JAMBONES_WS_HANDSHAKE_TIMEOUT_MS ?
|
const handshakeTimeout = JAMBONES_WS_HANDSHAKE_TIMEOUT_MS ?
|
||||||
parseInt(process.env.JAMBONES_WS_HANDSHAKE_TIMEOUT_MS) :
|
parseInt(JAMBONES_WS_HANDSHAKE_TIMEOUT_MS) :
|
||||||
1500;
|
1500;
|
||||||
let opts = {
|
let opts = {
|
||||||
followRedirects: true,
|
followRedirects: true,
|
||||||
maxRedirects: 2,
|
maxRedirects: 2,
|
||||||
handshakeTimeout,
|
handshakeTimeout,
|
||||||
maxPayload: process.env.JAMBONES_WS_MAX_PAYLOAD ? parseInt(process.env.JAMBONES_WS_MAX_PAYLOAD) : 24 * 1024,
|
maxPayload: JAMBONES_WS_MAX_PAYLOAD ? parseInt(JAMBONES_WS_MAX_PAYLOAD) : 24 * 1024,
|
||||||
};
|
};
|
||||||
if (this.username && this.password) opts = {...opts, auth: `${this.username}:${this.password}`};
|
if (this.username && this.password) opts = {...opts, auth: `${this.username}:${this.password}`};
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
"start": "node app",
|
"start": "node app",
|
||||||
"test": "NODE_ENV=test JAMBONES_HOSTING=1 HTTP_POOL=1 ENCRYPTION_SECRET=foobar DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 DRACHTIO_SECRET=cymru JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=127.0.0.1 JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error ENABLE_METRICS=0 HTTP_PORT=3000 JAMBONES_SBCS=172.38.0.10 JAMBONES_FREESWITCH=127.0.0.1:8022:JambonzR0ck$:docker-host JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_NETWORK_CIDR=172.38.0.0/16 node test/ ",
|
"test": "NODE_ENV=test JAMBONES_HOSTING=1 HTTP_POOL=1 ENCRYPTION_SECRET=foobar DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 DRACHTIO_SECRET=cymru JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_PORT=3360 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=127.0.0.1 JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error ENABLE_METRICS=0 HTTP_PORT=3000 JAMBONES_SBCS=172.38.0.10 JAMBONES_FREESWITCH=127.0.0.1:8022:JambonzR0ck$:docker-host JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_NETWORK_CIDR=172.38.0.0/16 node test/ ",
|
||||||
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
|
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
|
||||||
"jslint": "eslint app.js lib"
|
"jslint": "eslint app.js lib",
|
||||||
|
"jslint:fix": "eslint app.js lib --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jambonz/db-helpers": "^0.7.4",
|
"@jambonz/db-helpers": "^0.7.4",
|
||||||
|
|||||||
@@ -2,6 +2,14 @@ const test = require('tape') ;
|
|||||||
const exec = require('child_process').exec ;
|
const exec = require('child_process').exec ;
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const {encrypt} = require('../lib/utils/encrypt-decrypt');
|
const {encrypt} = require('../lib/utils/encrypt-decrypt');
|
||||||
|
const {
|
||||||
|
GCP_JSON_KEY,
|
||||||
|
AWS_ACCESS_KEY_ID,
|
||||||
|
AWS_SECRET_ACCESS_KEY,
|
||||||
|
AWS_REGION,
|
||||||
|
MICROSOFT_REGION,
|
||||||
|
MICROSOFT_API_KEY,
|
||||||
|
} = require('../lib/config');
|
||||||
|
|
||||||
test('creating jambones_test database', (t) => {
|
test('creating jambones_test database', (t) => {
|
||||||
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 < ${__dirname}/db/create_test_db.sql`, (err, stdout, stderr) => {
|
exec(`mysql -h 127.0.0.1 -u root --protocol=tcp --port=3360 < ${__dirname}/db/create_test_db.sql`, (err, stdout, stderr) => {
|
||||||
@@ -19,24 +27,24 @@ test('creating schema', (t) => {
|
|||||||
t.pass('schema and test data successfully created');
|
t.pass('schema and test data successfully created');
|
||||||
|
|
||||||
const sql = [];
|
const sql = [];
|
||||||
if (process.env.GCP_JSON_KEY) {
|
if (GCP_JSON_KEY) {
|
||||||
const google_credential = encrypt(process.env.GCP_JSON_KEY);
|
const google_credential = encrypt(GCP_JSON_KEY);
|
||||||
t.pass('adding google credentials');
|
t.pass('adding google credentials');
|
||||||
sql.push(`UPDATE speech_credentials SET credential='${google_credential}' WHERE vendor='google';`);
|
sql.push(`UPDATE speech_credentials SET credential='${google_credential}' WHERE vendor='google';`);
|
||||||
}
|
}
|
||||||
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
|
if (AWS_ACCESS_KEY_ID && AWS_SECRET_ACCESS_KEY) {
|
||||||
const aws_credential = encrypt(JSON.stringify({
|
const aws_credential = encrypt(JSON.stringify({
|
||||||
access_key_id: process.env.AWS_ACCESS_KEY_ID,
|
access_key_id: AWS_ACCESS_KEY_ID,
|
||||||
secret_access_key: process.env.AWS_SECRET_ACCESS_KEY,
|
secret_access_key: AWS_SECRET_ACCESS_KEY,
|
||||||
aws_region: process.env.AWS_REGION
|
aws_region: AWS_REGION
|
||||||
}));
|
}));
|
||||||
t.pass('adding aws credentials');
|
t.pass('adding aws credentials');
|
||||||
sql.push(`UPDATE speech_credentials SET credential='${aws_credential}' WHERE vendor='aws';`);
|
sql.push(`UPDATE speech_credentials SET credential='${aws_credential}' WHERE vendor='aws';`);
|
||||||
}
|
}
|
||||||
if (process.env.MICROSOFT_REGION && process.env.MICROSOFT_API_KEY) {
|
if (MICROSOFT_REGION && MICROSOFT_API_KEY) {
|
||||||
const microsoft_credential = encrypt(JSON.stringify({
|
const microsoft_credential = encrypt(JSON.stringify({
|
||||||
region: process.env.MICROSOFT_REGION,
|
region: MICROSOFT_REGION,
|
||||||
api_key: process.env.MICROSOFT_API_KEY
|
api_key: MICROSOFT_API_KEY
|
||||||
}));
|
}));
|
||||||
t.pass('adding microsoft credentials');
|
t.pass('adding microsoft credentials');
|
||||||
sql.push(`UPDATE speech_credentials SET credential='${microsoft_credential}' WHERE vendor='microsoft';`);
|
sql.push(`UPDATE speech_credentials SET credential='${microsoft_credential}' WHERE vendor='microsoft';`);
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ const bent = require('bent');
|
|||||||
const getJSON = bent('json')
|
const getJSON = bent('json')
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
const {provisionCallHook} = require('./utils')
|
const {provisionCallHook} = require('./utils')
|
||||||
|
const {
|
||||||
|
GCP_JSON_KEY,
|
||||||
|
AWS_ACCESS_KEY_ID,
|
||||||
|
AWS_SECRET_ACCESS_KEY,
|
||||||
|
SONIOX_API_KEY,
|
||||||
|
DEEPGRAM_API_KEY,
|
||||||
|
MICROSOFT_REGION,
|
||||||
|
MICROSOFT_API_KEY,
|
||||||
|
} = require('../lib/config');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
@@ -18,7 +27,7 @@ function connect(connectable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('\'gather\' test - google', async(t) => {
|
test('\'gather\' test - google', async(t) => {
|
||||||
if (!process.env.GCP_JSON_KEY) {
|
if (!GCP_JSON_KEY) {
|
||||||
t.pass('skipping google tests');
|
t.pass('skipping google tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -58,7 +67,7 @@ test('\'gather\' test - google', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'gather\' test - default (google)', async(t) => {
|
test('\'gather\' test - default (google)', async(t) => {
|
||||||
if (!process.env.GCP_JSON_KEY) {
|
if (!GCP_JSON_KEY) {
|
||||||
t.pass('skipping google tests');
|
t.pass('skipping google tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -94,7 +103,7 @@ test('\'gather\' test - default (google)', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'gather\' test - microsoft', async(t) => {
|
test('\'gather\' test - microsoft', async(t) => {
|
||||||
if (!process.env.MICROSOFT_REGION || !process.env.MICROSOFT_API_KEY) {
|
if (!MICROSOFT_REGION || !MICROSOFT_API_KEY) {
|
||||||
t.pass('skipping microsoft tests');
|
t.pass('skipping microsoft tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -134,7 +143,7 @@ test('\'gather\' test - microsoft', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'gather\' test - aws', async(t) => {
|
test('\'gather\' test - aws', async(t) => {
|
||||||
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) {
|
if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY) {
|
||||||
t.pass('skipping aws tests');
|
t.pass('skipping aws tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -174,7 +183,7 @@ test('\'gather\' test - aws', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'gather\' test - deepgram', async(t) => {
|
test('\'gather\' test - deepgram', async(t) => {
|
||||||
if (!process.env.DEEPGRAM_API_KEY ) {
|
if (!DEEPGRAM_API_KEY ) {
|
||||||
t.pass('skipping deepgram tests');
|
t.pass('skipping deepgram tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -192,7 +201,7 @@ test('\'gather\' test - deepgram', async(t) => {
|
|||||||
"vendor": "deepgram",
|
"vendor": "deepgram",
|
||||||
"hints": ["customer support", "sales", "human resources", "HR"],
|
"hints": ["customer support", "sales", "human resources", "HR"],
|
||||||
"deepgramOptions": {
|
"deepgramOptions": {
|
||||||
"apiKey": process.env.DEEPGRAM_API_KEY
|
"apiKey": DEEPGRAM_API_KEY
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"timeout": 10,
|
"timeout": 10,
|
||||||
@@ -216,7 +225,7 @@ test('\'gather\' test - deepgram', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'gather\' test - soniox', async(t) => {
|
test('\'gather\' test - soniox', async(t) => {
|
||||||
if (!process.env.SONIOX_API_KEY ) {
|
if (!SONIOX_API_KEY ) {
|
||||||
t.pass('skipping soniox tests');
|
t.pass('skipping soniox tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -234,7 +243,7 @@ test('\'gather\' test - soniox', async(t) => {
|
|||||||
"vendor": "deepgram",
|
"vendor": "deepgram",
|
||||||
"hints": ["customer support", "sales", "human resources", "HR"],
|
"hints": ["customer support", "sales", "human resources", "HR"],
|
||||||
"deepgramOptions": {
|
"deepgramOptions": {
|
||||||
"apiKey": process.env.SONIOX_API_KEY
|
"apiKey": SONIOX_API_KEY
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"timeout": 10,
|
"timeout": 10,
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ const bent = require('bent');
|
|||||||
const getJSON = bent('json')
|
const getJSON = bent('json')
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
const {provisionCallHook} = require('./utils')
|
const {provisionCallHook} = require('./utils')
|
||||||
|
const {
|
||||||
|
GCP_JSON_KEY,
|
||||||
|
AWS_ACCESS_KEY_ID,
|
||||||
|
AWS_SECRET_ACCESS_KEY,
|
||||||
|
MICROSOFT_REGION,
|
||||||
|
MICROSOFT_API_KEY,
|
||||||
|
SONIOX_API_KEY,
|
||||||
|
DEEPGRAM_API_KEY,
|
||||||
|
} = require('../lib/config');
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||||
@@ -18,7 +27,7 @@ function connect(connectable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('\'transcribe\' test - google', async(t) => {
|
test('\'transcribe\' test - google', async(t) => {
|
||||||
if (!process.env.GCP_JSON_KEY) {
|
if (!GCP_JSON_KEY) {
|
||||||
t.pass('skipping google tests');
|
t.pass('skipping google tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -55,7 +64,7 @@ test('\'transcribe\' test - google', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'transcribe\' test - microsoft', async(t) => {
|
test('\'transcribe\' test - microsoft', async(t) => {
|
||||||
if (!process.env.MICROSOFT_REGION || !process.env.MICROSOFT_API_KEY) {
|
if (!MICROSOFT_REGION || !MICROSOFT_API_KEY) {
|
||||||
t.pass('skipping microsoft tests');
|
t.pass('skipping microsoft tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -92,7 +101,7 @@ test('\'transcribe\' test - microsoft', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'transcribe\' test - aws', async(t) => {
|
test('\'transcribe\' test - aws', async(t) => {
|
||||||
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) {
|
if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY) {
|
||||||
t.pass('skipping aws tests');
|
t.pass('skipping aws tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -129,7 +138,7 @@ test('\'transcribe\' test - aws', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'transcribe\' test - deepgram', async(t) => {
|
test('\'transcribe\' test - deepgram', async(t) => {
|
||||||
if (!process.env.DEEPGRAM_API_KEY ) {
|
if (!DEEPGRAM_API_KEY ) {
|
||||||
t.pass('skipping deepgram tests');
|
t.pass('skipping deepgram tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -146,7 +155,7 @@ test('\'transcribe\' test - deepgram', async(t) => {
|
|||||||
"vendor": "deepgram",
|
"vendor": "deepgram",
|
||||||
"hints": ["customer support", "sales", "human resources", "HR"],
|
"hints": ["customer support", "sales", "human resources", "HR"],
|
||||||
"deepgramOptions": {
|
"deepgramOptions": {
|
||||||
"apiKey": process.env.DEEPGRAM_API_KEY
|
"apiKey": DEEPGRAM_API_KEY
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"transcriptionHook": "/transcriptionHook"
|
"transcriptionHook": "/transcriptionHook"
|
||||||
@@ -169,7 +178,7 @@ test('\'transcribe\' test - deepgram', async(t) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('\'transcribe\' test - soniox', async(t) => {
|
test('\'transcribe\' test - soniox', async(t) => {
|
||||||
if (!process.env.SONIOX_API_KEY ) {
|
if (!SONIOX_API_KEY ) {
|
||||||
t.pass('skipping soniox tests');
|
t.pass('skipping soniox tests');
|
||||||
return t.end();
|
return t.end();
|
||||||
}
|
}
|
||||||
@@ -186,7 +195,7 @@ test('\'transcribe\' test - soniox', async(t) => {
|
|||||||
"vendor": "soniox",
|
"vendor": "soniox",
|
||||||
"hints": ["customer support", "sales", "human resources", "HR"],
|
"hints": ["customer support", "sales", "human resources", "HR"],
|
||||||
"deepgramOptions": {
|
"deepgramOptions": {
|
||||||
"apiKey": process.env.SONIOX_API_KEY
|
"apiKey": SONIOX_API_KEY
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"transcriptionHook": "/transcriptionHook"
|
"transcriptionHook": "/transcriptionHook"
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const app = express();
|
const app = express();
|
||||||
const Websocket = require('ws');
|
const Websocket = require('ws');
|
||||||
const listenPort = process.env.HTTP_PORT || 3000;
|
const {PORT} = require('../../lib/config');
|
||||||
|
const listenPort = PORT;
|
||||||
let json_mapping = new Map();
|
let json_mapping = new Map();
|
||||||
let hook_mapping = new Map();
|
let hook_mapping = new Map();
|
||||||
let ws_packet_count = new Map();
|
let ws_packet_count = new Map();
|
||||||
|
|||||||
@@ -2,13 +2,17 @@ const test = require('tape');
|
|||||||
const { sippUac } = require('./sipp')('test_fs');
|
const { sippUac } = require('./sipp')('test_fs');
|
||||||
const clearModule = require('clear-module');
|
const clearModule = require('clear-module');
|
||||||
const {provisionCallHook} = require('./utils')
|
const {provisionCallHook} = require('./utils')
|
||||||
|
const {
|
||||||
|
JAMBONES_LOGLEVEL,
|
||||||
|
JAMBONES_TIME_SERIES_HOST
|
||||||
|
} = require('../lib/config');
|
||||||
const opts = {
|
const opts = {
|
||||||
timestamp: () => {return `, "time": "${new Date().toISOString()}"`;},
|
timestamp: () => {return `, "time": "${new Date().toISOString()}"`;},
|
||||||
level: process.env.JAMBONES_LOGLEVEL || 'info'
|
level: JAMBONES_LOGLEVEL
|
||||||
};
|
};
|
||||||
const logger = require('pino')(opts);
|
const logger = require('pino')(opts);
|
||||||
const { queryAlerts } = require('@jambonz/time-series')(
|
const { queryAlerts } = require('@jambonz/time-series')(
|
||||||
logger, process.env.JAMBONES_TIME_SERIES_HOST
|
logger, JAMBONES_TIME_SERIES_HOST
|
||||||
);
|
);
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, p) => {
|
process.on('unhandledRejection', (reason, p) => {
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ const sinon = require('sinon');
|
|||||||
const proxyquire = require("proxyquire");
|
const proxyquire = require("proxyquire");
|
||||||
proxyquire.noCallThru();
|
proxyquire.noCallThru();
|
||||||
const MockWebsocket = require('./ws-mock')
|
const MockWebsocket = require('./ws-mock')
|
||||||
const logger = require('pino')({level: process.env.JAMBONES_LOGLEVEL || 'error'});
|
const {
|
||||||
|
JAMBONES_LOGLEVEL,
|
||||||
|
} = require('../lib/config');
|
||||||
|
const logger = require('pino')({level: JAMBONES_LOGLEVEL});
|
||||||
|
|
||||||
const BaseRequestor = proxyquire(
|
const BaseRequestor = proxyquire(
|
||||||
"../lib/utils/base-requestor",
|
"../lib/utils/base-requestor",
|
||||||
|
|||||||
16
tracer.js
16
tracer.js
@@ -7,12 +7,14 @@ const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
|
|||||||
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
|
||||||
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
|
||||||
const { OTLPTraceExporter } = require ('@opentelemetry/exporter-trace-otlp-http');
|
const { OTLPTraceExporter } = require ('@opentelemetry/exporter-trace-otlp-http');
|
||||||
//const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
|
const {
|
||||||
//const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
|
JAMBONES_OTEL_ENABLED,
|
||||||
//const { PinoInstrumentation } = require('@opentelemetry/instrumentation-pino');
|
OTEL_EXPORTER_JAEGER_AGENT_HOST,
|
||||||
|
OTEL_EXPORTER_ZIPKIN_URL,
|
||||||
|
} = require('./lib/config');
|
||||||
|
|
||||||
module.exports = (serviceName) => {
|
module.exports = (serviceName) => {
|
||||||
if (process.env.JAMBONES_OTEL_ENABLED) {
|
if (JAMBONES_OTEL_ENABLED) {
|
||||||
const {version} = require('./package.json');
|
const {version} = require('./package.json');
|
||||||
const provider = new NodeTracerProvider({
|
const provider = new NodeTracerProvider({
|
||||||
resource: new Resource({
|
resource: new Resource({
|
||||||
@@ -22,11 +24,11 @@ module.exports = (serviceName) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let exporter;
|
let exporter;
|
||||||
if (process.env.OTEL_EXPORTER_JAEGER_AGENT_HOST || process.env.OTEL_EXPORTER_JAEGER_ENDPOINT) {
|
if (OTEL_EXPORTER_JAEGER_AGENT_HOST || OTEL_EXPORTER_JAEGER_ENDPOINT) {
|
||||||
exporter = new JaegerExporter();
|
exporter = new JaegerExporter();
|
||||||
}
|
}
|
||||||
else if (process.env.OTEL_EXPORTER_ZIPKIN_URL) {
|
else if (OTEL_EXPORTER_ZIPKIN_URL) {
|
||||||
exporter = new ZipkinExporter({url:process.env.OTEL_EXPORTER_ZIPKIN_URL});
|
exporter = new ZipkinExporter({url:OTEL_EXPORTER_ZIPKIN_URL});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exporter = new OTLPTraceExporter({
|
exporter = new OTLPTraceExporter({
|
||||||
|
|||||||
Reference in New Issue
Block a user