mirror of
https://github.com/jambonz/sbc-inbound.git
synced 2026-01-24 22:37:51 +00:00
Feature/app call count tracking (#51)
* add call count tracking at the app level (optional) * add histogram for rtt to rtpengine commands * update time-series * update rtpengine-utils
This commit is contained in:
2
app.js
2
app.js
@@ -16,6 +16,7 @@ const logger = require('pino')(opts);
|
||||
const {
|
||||
writeCallCount,
|
||||
writeCallCountSP,
|
||||
writeCallCountApp,
|
||||
queryCdrs,
|
||||
writeCdrs,
|
||||
writeAlerts,
|
||||
@@ -74,6 +75,7 @@ srf.locals = {...srf.locals,
|
||||
stats,
|
||||
writeCallCount,
|
||||
writeCallCountSP,
|
||||
writeCallCountApp,
|
||||
queryCdrs,
|
||||
writeCdrs,
|
||||
writeAlerts,
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
const Emitter = require('events');
|
||||
const SrsClient = require('@jambonz/siprec-client-utils');
|
||||
const {makeRtpEngineOpts, SdpWantsSrtp, makeAccountCallCountKey, makeSPCallCountKey} = require('./utils');
|
||||
const {
|
||||
makeRtpEngineOpts,
|
||||
SdpWantsSrtp,
|
||||
nudgeCallCounts,
|
||||
roundTripTime,
|
||||
parseConnectionIp
|
||||
} = require('./utils');
|
||||
|
||||
const {forwardInDialogRequests} = require('drachtio-fn-b2b-sugar');
|
||||
const {parseUri, stringifyUri, SipError} = require('drachtio-srf');
|
||||
const debug = require('debug')('jambonz:sbc-inbound');
|
||||
@@ -49,9 +56,11 @@ class CallSession extends Emitter {
|
||||
this.activeCallIds = this.srf.locals.activeCallIds;
|
||||
|
||||
this.decrKey = req.srf.locals.realtimeDbHelpers.decrKey;
|
||||
this.callCountKey = makeAccountCallCountKey(req.locals.account_sid);
|
||||
this.callCountKeySP = makeSPCallCountKey(req.locals.service_provider_sid);
|
||||
this._mediaReleased = false;
|
||||
|
||||
this.application_sid = req.locals.application_sid;
|
||||
this.account_sid = req.locals.account_sid;
|
||||
this.service_provider_sid = req.locals.service_provider_sid;
|
||||
}
|
||||
|
||||
get isFromMSTeams() {
|
||||
@@ -147,8 +156,13 @@ class CallSession extends Emitter {
|
||||
direction: ['public', 'private'],
|
||||
sdp
|
||||
};
|
||||
const startAt = process.hrtime();
|
||||
const response = await this.offer(opts);
|
||||
this.logger.debug({opts, response}, 'response from rtpengine to offer');
|
||||
this.rtpengineIp = opts.sdp ? parseConnectionIp(opts.sdp) : 'undefined';
|
||||
const rtt = roundTripTime(startAt);
|
||||
this.stats.histogram('app.rtpengine.response_time', rtt, [
|
||||
'direction:inbound', 'command:offer', `rtpengine:${this.rtpengineIp}`]);
|
||||
this.logger.debug({opts, response, rtt, rtpengine: this.rtpengineIp}, 'response from rtpengine to offer');
|
||||
if ('ok' !== response.result) {
|
||||
this.logger.error({}, `rtpengine offer failed with ${JSON.stringify(response)}`);
|
||||
throw new Error('rtpengine failed: answer');
|
||||
@@ -223,7 +237,11 @@ class CallSession extends Emitter {
|
||||
'to-tag': this.rtpEngineOpts.uac.tag,
|
||||
sdp
|
||||
};
|
||||
const startAt = process.hrtime();
|
||||
const response = await this.answer(opts);
|
||||
const rtt = roundTripTime(startAt);
|
||||
this.stats.histogram('app.rtpengine.response_time', rtt, [
|
||||
'direction:inbound', 'command:answer', `rtpengine:${this.rtpengineIp}`]);
|
||||
if ('ok' !== response.result) {
|
||||
this.logger.error(`rtpengine answer failed with ${JSON.stringify(response)}`);
|
||||
throw new Error('rtpengine failed: answer');
|
||||
@@ -285,7 +303,7 @@ class CallSession extends Emitter {
|
||||
this.stats.increment('sbc.terminations', tags);
|
||||
this.activeCallIds.set(this.req.get('Call-ID'), this);
|
||||
const call_sid = uac.res?.get('X-Call-Sid');
|
||||
const application_sid = uac.res?.get('X-Application-Sid');
|
||||
const application_sid = this.application_sid || uac.res?.get('X-Application-Sid');
|
||||
if (this.req.locals.cdr) {
|
||||
this.req.locals.cdr = {
|
||||
...this.req.locals.cdr,
|
||||
@@ -307,24 +325,19 @@ class CallSession extends Emitter {
|
||||
await other.destroy();
|
||||
} catch (err) {}
|
||||
this.unsubscribeDTMF(this.logger, this.req.get('Call-ID'), this.rtpEngineOpts.uas.tag);
|
||||
if (process.env.JAMBONES_HOSTING || process.env.JAMBONES_TRACK_ACCOUNT_CALLS) {
|
||||
const {account_sid, service_provider_sid} = this.req.locals;
|
||||
const {writeCallCount, writeCallCountSP} = this.req.srf.locals;
|
||||
|
||||
Promise.all([
|
||||
this.decrKey(this.callCountKey),
|
||||
this.decrKey(this.callCountKeySP)
|
||||
])
|
||||
.then(([calls, callsSP]) => {
|
||||
this.logger.info({calls, callsSP}, 'decremented call counts after call completion');
|
||||
return Promise.all([
|
||||
writeCallCount(account_sid, calls),
|
||||
writeCallCountSP(service_provider_sid, callsSP)
|
||||
]);
|
||||
})
|
||||
.catch((err) => {
|
||||
this.logger.error({err}, 'error decrementing call counts after call completion');
|
||||
});
|
||||
const trackingOn = process.env.JAMBONES_TRACK_ACCOUNT_CALLS ||
|
||||
process.env.JAMBONES_TRACK_SP_CALLS ||
|
||||
process.env.JAMBONES_TRACK_APP_CALLS;
|
||||
|
||||
if (process.env.JAMBONES_HOSTING || trackingOn) {
|
||||
const {writeCallCount, writeCallCountSP, writeCallCountApp} = this.req.srf.locals;
|
||||
await nudgeCallCounts(this.logger, {
|
||||
service_provider_sid: this.service_provider_sid,
|
||||
account_sid: this.account_sid,
|
||||
application_sid: this.application_sid
|
||||
}, this.decrKey, {writeCallCountSP, writeCallCount, writeCallCountApp})
|
||||
.catch((err) => this.logger.error(err, 'Error decrementing call counts'));
|
||||
}
|
||||
|
||||
/* write cdr for connected call */
|
||||
|
||||
@@ -2,7 +2,7 @@ const debug = require('debug')('jambonz:sbc-inbound');
|
||||
const assert = require('assert');
|
||||
const Emitter = require('events');
|
||||
const parseUri = require('drachtio-srf').parseUri;
|
||||
const {makeAccountCallCountKey, makeSPCallCountKey} = require('./utils');
|
||||
const {nudgeCallCounts} = require('./utils');
|
||||
const msProxyIps = process.env.MS_TEAMS_SIP_PROXY_IPS ?
|
||||
process.env.MS_TEAMS_SIP_PROXY_IPS.split(',').map((i) => i.trim()) :
|
||||
[];
|
||||
@@ -226,6 +226,7 @@ module.exports = function(srf, logger) {
|
||||
service_provider_sid: account.service_provider_sid,
|
||||
account_sid: account.account_sid,
|
||||
account,
|
||||
application_sid: account.device_calling_application_sid,
|
||||
webhook_secret: account.webhook_secret,
|
||||
...req.locals
|
||||
};
|
||||
@@ -264,38 +265,36 @@ module.exports = function(srf, logger) {
|
||||
};
|
||||
|
||||
const checkLimits = async(req, res, next) => {
|
||||
if (!process.env.JAMBONES_HOSTING && !process.env.JAMBONES_TRACK_ACCOUNT_CALLS) return next(); // skip
|
||||
const trackingOn = process.env.JAMBONES_TRACK_ACCOUNT_CALLS ||
|
||||
process.env.JAMBONES_TRACK_SP_CALLS ||
|
||||
process.env.JAMBONES_TRACK_APP_CALLS;
|
||||
if (!process.env.JAMBONES_HOSTING && !trackingOn) return next(); // skip
|
||||
|
||||
const {incrKey, decrKey} = req.srf.locals.realtimeDbHelpers;
|
||||
const {logger, account_sid, account, service_provider_sid} = req.locals;
|
||||
const {writeCallCount, writeCallCountSP, writeAlerts, AlertType} = req.srf.locals;
|
||||
const {logger, account_sid, account, service_provider_sid, application_sid} = req.locals;
|
||||
const {writeCallCount, writeCallCountSP, writeCallCountApp, writeAlerts, AlertType} = req.srf.locals;
|
||||
assert(account_sid);
|
||||
assert(service_provider_sid);
|
||||
const keyAccount = makeAccountCallCountKey(account_sid);
|
||||
const keySP = makeSPCallCountKey(service_provider_sid);
|
||||
|
||||
/* decrement count if INVITE is later rejected */
|
||||
res.once('end', async({status}) => {
|
||||
if (status > 200) {
|
||||
try {
|
||||
const [calls, callsSP] = await Promise.all([decrKey(keyAccount), decrKey(keySP)]);
|
||||
logger.info({calls, callsSP}, `decremented call counts after ${status} response`);
|
||||
} catch (err) {
|
||||
logger.info({err}, 'Error decrementing call count');
|
||||
}
|
||||
nudgeCallCounts(logger, {
|
||||
service_provider_sid,
|
||||
account_sid,
|
||||
application_sid
|
||||
}, decrKey, {writeCallCountSP, writeCallCount, writeCallCountApp})
|
||||
.catch((err) => logger.error(err, 'Error decrementing call counts'));
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
/* increment the call count */
|
||||
const [calls, callsSP] = await Promise.all([incrKey(keyAccount), incrKey(keySP)]);
|
||||
logger.info({calls, callsSP}, 'incremented call counts');
|
||||
|
||||
/* write the call counts to the database for both account and service provider */
|
||||
Promise.all([
|
||||
writeCallCount(account_sid, calls),
|
||||
writeCallCountSP(service_provider_sid, callsSP)
|
||||
]).catch((err) => logger.error({err}, 'Error writing call counts'));
|
||||
const {callsSP, calls} = await nudgeCallCounts(logger, {
|
||||
service_provider_sid,
|
||||
account_sid,
|
||||
application_sid
|
||||
}, incrKey, {writeCallCountSP, writeCallCount, writeCallCountApp});
|
||||
|
||||
/* compare to account's limit, though avoid db hit when call count is low */
|
||||
const minLimit = process.env.MIN_CALL_LIMIT ?
|
||||
@@ -324,7 +323,7 @@ module.exports = function(srf, logger) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (process.env.JAMBONES_TRACK_ACCOUNT_CALLS || process.env.JAMBONES_TRACK_SP_CALLS) {
|
||||
else if (trackingOn) {
|
||||
const {account_limit, sp_limit} = await queryCallLimits(service_provider_sid, account_sid);
|
||||
if (process.env.JAMBONES_TRACK_ACCOUNT_CALLS && account_limit > 0 && calls > account_limit) {
|
||||
logger.info({calls, account_limit}, 'checkLimits: account limits exceeded');
|
||||
|
||||
82
lib/utils.js
82
lib/utils.js
@@ -43,8 +43,9 @@ const SdpWantsSrtp = (sdp) => {
|
||||
return /m=audio.*SAVP/.test(sdp);
|
||||
};
|
||||
|
||||
const makeAccountCallCountKey = (sid) => `${sid}:incalls:account`;
|
||||
const makeSPCallCountKey = (sid) => `${sid}:incalls:sp`;
|
||||
const makeAccountCallCountKey = (sid) => `incalls:account:${sid}`;
|
||||
const makeSPCallCountKey = (sid) => `incalls:sp:${sid}:`;
|
||||
const makeAppCallCountKey = (sid) => `incalls:app${sid}:`;
|
||||
|
||||
const normalizeDID = (tel) => {
|
||||
const regex = /^\+(\d+)$/;
|
||||
@@ -83,6 +84,77 @@ const createHealthCheckApp = (port, logger) => {
|
||||
});
|
||||
};
|
||||
|
||||
const nudgeCallCounts = async(logger, sids, nudgeOperator, writers) => {
|
||||
const {service_provider_sid, account_sid, application_sid} = sids;
|
||||
const {writeCallCount, writeCallCountSP, writeCallCountApp} = writers;
|
||||
const nudges = [];
|
||||
const writes = [];
|
||||
|
||||
if (process.env.JAMBONES_TRACK_SP_CALLS) {
|
||||
const key = makeSPCallCountKey(service_provider_sid);
|
||||
nudges.push(nudgeOperator(key));
|
||||
}
|
||||
else {
|
||||
nudges.push(() => Promise.resolve(null));
|
||||
}
|
||||
|
||||
if (process.env.JAMBONES_TRACK_ACCOUNT_CALLS || process.env.JAMBONES_HOSTING) {
|
||||
const key = makeAccountCallCountKey(account_sid);
|
||||
nudges.push(nudgeOperator(key));
|
||||
}
|
||||
else {
|
||||
nudges.push(() => Promise.resolve(null));
|
||||
}
|
||||
|
||||
if (process.env.JAMBONES_TRACK_APP_CALLS && application_sid) {
|
||||
const key = makeAppCallCountKey(application_sid);
|
||||
nudges.push(nudgeOperator(key));
|
||||
}
|
||||
else {
|
||||
nudges.push(() => Promise.resolve(null));
|
||||
}
|
||||
|
||||
try {
|
||||
const [callsSP, calls, callsApp] = await Promise.all(nudges);
|
||||
logger.debug({
|
||||
calls, callsSP, callsApp,
|
||||
service_provider_sid, account_sid, application_sid}, 'call counts after adjustment');
|
||||
if (process.env.JAMBONES_TRACK_SP_CALLS) {
|
||||
writes.push(writeCallCountSP({service_provider_sid, calls_in_progress: callsSP}));
|
||||
}
|
||||
|
||||
if (process.env.JAMBONES_TRACK_ACCOUNT_CALLS || process.env.JAMBONES_HOSTING) {
|
||||
writes.push(writeCallCount({service_provider_sid, account_sid, calls_in_progress: calls}));
|
||||
}
|
||||
|
||||
if (process.env.JAMBONES_TRACK_APP_CALLS && application_sid) {
|
||||
writes.push(writeCallCountApp({service_provider_sid, account_sid, application_sid, calls_in_progress: callsApp}));
|
||||
}
|
||||
|
||||
/* write the call counts to the database */
|
||||
Promise.all(writes).catch((err) => logger.error({err}, 'Error writing call counts'));
|
||||
|
||||
return {callsSP, calls, callsApp};
|
||||
} catch (err) {
|
||||
logger.error(err, 'error incrementing call counts');
|
||||
}
|
||||
|
||||
return {callsSP: null, calls: null, callsApp: null};
|
||||
};
|
||||
|
||||
const roundTripTime = (startAt) => {
|
||||
const diff = process.hrtime(startAt);
|
||||
const time = diff[0] * 1e3 + diff[1] * 1e-6;
|
||||
return time.toFixed(0);
|
||||
};
|
||||
|
||||
const parseConnectionIp = (sdp) => {
|
||||
const regex = /c=IN IP4 ([0-9.]+)/;
|
||||
const arr = regex.exec(sdp);
|
||||
return arr ? arr[1] : null;
|
||||
};
|
||||
|
||||
|
||||
module.exports = {
|
||||
isWSS,
|
||||
SdpWantsSrtp,
|
||||
@@ -90,8 +162,12 @@ module.exports = {
|
||||
makeRtpEngineOpts,
|
||||
makeAccountCallCountKey,
|
||||
makeSPCallCountKey,
|
||||
makeAppCallCountKey,
|
||||
normalizeDID,
|
||||
equalsIgnoreOrder,
|
||||
systemHealth,
|
||||
createHealthCheckApp
|
||||
createHealthCheckApp,
|
||||
nudgeCallCounts,
|
||||
roundTripTime,
|
||||
parseConnectionIp
|
||||
};
|
||||
|
||||
118
package-lock.json
generated
118
package-lock.json
generated
@@ -13,10 +13,10 @@
|
||||
"@jambonz/http-authenticator": "^0.2.2",
|
||||
"@jambonz/http-health-check": "^0.0.1",
|
||||
"@jambonz/realtimedb-helpers": "^0.4.29",
|
||||
"@jambonz/rtpengine-utils": "^0.3.1",
|
||||
"@jambonz/rtpengine-utils": "^0.3.4",
|
||||
"@jambonz/siprec-client-utils": "^0.1.4",
|
||||
"@jambonz/stats-collector": "^0.1.6",
|
||||
"@jambonz/time-series": "^0.2.2",
|
||||
"@jambonz/time-series": "^0.2.4",
|
||||
"aws-sdk": "^2.1152.0",
|
||||
"bent": "^7.3.12",
|
||||
"cidr-matcher": "^2.1.1",
|
||||
@@ -632,45 +632,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/rtpengine-utils": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/rtpengine-utils/-/rtpengine-utils-0.3.1.tgz",
|
||||
"integrity": "sha512-vf0TedWgDhOvlsbGcjrHmSDwyz/85fZ8TjxE50AjD4ueSw/zULwl7wezn3wTz70oTwbzAPYYHnjhyQJns9cwPg==",
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/rtpengine-utils/-/rtpengine-utils-0.3.4.tgz",
|
||||
"integrity": "sha512-7I7Q7O/TuWgk8Z0OX/qGrQZczeDt9pDLnGSwy88NTv5lAbrOYmPyNTC/8VJGfbHISfvBaPYT88+wQn2RIpXRPg==",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.1",
|
||||
"rtpengine-client": "^0.3.2",
|
||||
"rtpengine-client": "^0.3.6",
|
||||
"ws": "^8.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/rtpengine-utils/node_modules/rtpengine-client": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/rtpengine-client/-/rtpengine-client-0.3.2.tgz",
|
||||
"integrity": "sha512-RbttcmoQxtYU7VCHZR2RHE3eMFShZqq8cMRfPAGw42o4TDdET4Ih4OC0NicVyVRpzlRlzfysTvFWQNXVth03wQ==",
|
||||
"dependencies": {
|
||||
"bencode": "^2.0.1",
|
||||
"uuid": "^8.2.0",
|
||||
"ws": "^7.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/rtpengine-utils/node_modules/rtpengine-client/node_modules/ws": {
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
|
||||
"integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==",
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/rtpengine-utils/node_modules/ws": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
|
||||
@@ -710,9 +680,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jambonz/time-series": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.2.tgz",
|
||||
"integrity": "sha512-QGljKP25R93nDenkuX7bXr7tZfsrRpHTK4ygUWzpRWIe44trY2wUcaTc+HevBSjCSshbOkB/Nn9Tzz19JTzO3w==",
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.4.tgz",
|
||||
"integrity": "sha512-0rvELi9V/qdyPpM/2LidTd2EDN34iCU6U8ccuLUgqV05FaH/EW0qN0RFaVXVlFK6wCDZqEOBynd7x05De3dncw==",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.1",
|
||||
"influx": "^5.9.3"
|
||||
@@ -1083,12 +1053,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/bencode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.1.tgz",
|
||||
"integrity": "sha512-2uhEl8FdjSBUyb69qDTgOEeeqDTa+n3yMQzLW0cOzNf1Ow5bwcg3idf+qsWisIKRH8Bk8oC7UXL8irRcPA8ZEQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz",
|
||||
"integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w=="
|
||||
},
|
||||
"node_modules/bent": {
|
||||
"version": "7.3.12",
|
||||
@@ -4371,6 +4338,16 @@
|
||||
"node": "6.* || >= 7.*"
|
||||
}
|
||||
},
|
||||
"node_modules/rtpengine-client": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/rtpengine-client/-/rtpengine-client-0.3.6.tgz",
|
||||
"integrity": "sha512-V+o1j0F1bQekFifvkdB9LwdvRX8neMQ6HlG6TG6jFYFCvT1iMrh6BXaKIvn8JvJ4KcwHwTMJGJQSXpLmwa8KsQ==",
|
||||
"dependencies": {
|
||||
"bencode": "^2.0.1",
|
||||
"uuid": "^8.2.0",
|
||||
"ws": "^7.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
@@ -5805,33 +5782,15 @@
|
||||
}
|
||||
},
|
||||
"@jambonz/rtpengine-utils": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/rtpengine-utils/-/rtpengine-utils-0.3.1.tgz",
|
||||
"integrity": "sha512-vf0TedWgDhOvlsbGcjrHmSDwyz/85fZ8TjxE50AjD4ueSw/zULwl7wezn3wTz70oTwbzAPYYHnjhyQJns9cwPg==",
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/rtpengine-utils/-/rtpengine-utils-0.3.4.tgz",
|
||||
"integrity": "sha512-7I7Q7O/TuWgk8Z0OX/qGrQZczeDt9pDLnGSwy88NTv5lAbrOYmPyNTC/8VJGfbHISfvBaPYT88+wQn2RIpXRPg==",
|
||||
"requires": {
|
||||
"debug": "^4.3.1",
|
||||
"rtpengine-client": "^0.3.2",
|
||||
"rtpengine-client": "^0.3.6",
|
||||
"ws": "^8.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"rtpengine-client": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/rtpengine-client/-/rtpengine-client-0.3.2.tgz",
|
||||
"integrity": "sha512-RbttcmoQxtYU7VCHZR2RHE3eMFShZqq8cMRfPAGw42o4TDdET4Ih4OC0NicVyVRpzlRlzfysTvFWQNXVth03wQ==",
|
||||
"requires": {
|
||||
"bencode": "^2.0.1",
|
||||
"uuid": "^8.2.0",
|
||||
"ws": "^7.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
|
||||
"integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==",
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
|
||||
@@ -5859,9 +5818,9 @@
|
||||
}
|
||||
},
|
||||
"@jambonz/time-series": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.2.tgz",
|
||||
"integrity": "sha512-QGljKP25R93nDenkuX7bXr7tZfsrRpHTK4ygUWzpRWIe44trY2wUcaTc+HevBSjCSshbOkB/Nn9Tzz19JTzO3w==",
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.2.4.tgz",
|
||||
"integrity": "sha512-0rvELi9V/qdyPpM/2LidTd2EDN34iCU6U8ccuLUgqV05FaH/EW0qN0RFaVXVlFK6wCDZqEOBynd7x05De3dncw==",
|
||||
"requires": {
|
||||
"debug": "^4.3.1",
|
||||
"influx": "^5.9.3"
|
||||
@@ -6154,12 +6113,9 @@
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"bencode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.1.tgz",
|
||||
"integrity": "sha512-2uhEl8FdjSBUyb69qDTgOEeeqDTa+n3yMQzLW0cOzNf1Ow5bwcg3idf+qsWisIKRH8Bk8oC7UXL8irRcPA8ZEQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz",
|
||||
"integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w=="
|
||||
},
|
||||
"bent": {
|
||||
"version": "7.3.12",
|
||||
@@ -8672,6 +8628,16 @@
|
||||
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
|
||||
"integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA=="
|
||||
},
|
||||
"rtpengine-client": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/rtpengine-client/-/rtpengine-client-0.3.6.tgz",
|
||||
"integrity": "sha512-V+o1j0F1bQekFifvkdB9LwdvRX8neMQ6HlG6TG6jFYFCvT1iMrh6BXaKIvn8JvJ4KcwHwTMJGJQSXpLmwa8KsQ==",
|
||||
"requires": {
|
||||
"bencode": "^2.0.1",
|
||||
"uuid": "^8.2.0",
|
||||
"ws": "^7.4.4"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node app",
|
||||
"test": "NODE_ENV=test HTTP_PORT=3050 JAMBONES_NETWORK_CIDR='127.0.0.1/32' JAMBONES_HOSTING=1 SBC_ACCOUNT_SID=ed649e33-e771-403a-8c99-1780eabbc803 JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=error DRACHTIO_SECRET=cymru DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 JAMBONES_RTPENGINES=127.0.0.1:12222 JAMBONES_FEATURE_SERVERS=172.38.0.11 node test/ ",
|
||||
"test": "NODE_ENV=test HTTP_PORT=3050 JAMBONES_NETWORK_CIDR='127.0.0.1/32' JAMBONES_HOSTING=1 SBC_ACCOUNT_SID=ed649e33-e771-403a-8c99-1780eabbc803 JAMBONES_TIME_SERIES_HOST=127.0.0.1 JAMBONES_MYSQL_HOST=127.0.0.1 JAMBONES_MYSQL_USER=jambones_test JAMBONES_MYSQL_PASSWORD=jambones_test JAMBONES_MYSQL_DATABASE=jambones_test JAMBONES_REDIS_HOST=localhost JAMBONES_REDIS_PORT=16379 JAMBONES_LOGLEVEL=debug DRACHTIO_SECRET=cymru DRACHTIO_HOST=127.0.0.1 DRACHTIO_PORT=9060 JAMBONES_RTPENGINES=127.0.0.1:12222 JAMBONES_FEATURE_SERVERS=172.38.0.11 node test/ ",
|
||||
"coverage": "./node_modules/.bin/nyc --reporter html --report-dir ./coverage npm run test",
|
||||
"jslint": "eslint app.js lib"
|
||||
},
|
||||
@@ -29,10 +29,10 @@
|
||||
"@jambonz/http-authenticator": "^0.2.2",
|
||||
"@jambonz/http-health-check": "^0.0.1",
|
||||
"@jambonz/realtimedb-helpers": "^0.4.29",
|
||||
"@jambonz/rtpengine-utils": "^0.3.1",
|
||||
"@jambonz/rtpengine-utils": "^0.3.4",
|
||||
"@jambonz/siprec-client-utils": "^0.1.4",
|
||||
"@jambonz/stats-collector": "^0.1.6",
|
||||
"@jambonz/time-series": "^0.2.2",
|
||||
"@jambonz/time-series": "^0.2.4",
|
||||
"aws-sdk": "^2.1152.0",
|
||||
"bent": "^7.3.12",
|
||||
"cidr-matcher": "^2.1.1",
|
||||
|
||||
Reference in New Issue
Block a user