UNPKG

ibmapm-restclient

Version:
629 lines (586 loc) 19.6 kB
// Copyright IBM Corp. 2017. All Rights Reserved. // Node module: ibmapm // This file is licensed under the Apache License 2.0. // License text available at https://opensource.org/licenses/Apache-2.0 'use strict'; var fs = require('fs'); var sender = require('./sender-queue'); var pluginconfig = require('./config').pluginConfig; var logger = require('../plugins/logutil').getLogger('httpsender.js'); var k8sutil = require('../tools/k8sutil'); var logutil = require('../plugins/logutil'); var rcutil = require('../plugins/util'); pluginconfig.loadPluginsConf(__dirname + '/../../etc/config.json'); var queue; var cfg = { tenantID: 'tenantid-0000-0000-0000-000000000000', metrics: 'metric', AAR: 'aar/middleware', ADR: 'adr/middleware' }; var dcId; // string var resourceEntities = {}; // {<resourceid>:<entityid>, ...} var relationships = {}; // {<resourceid>:[{type:<linktype>,to:<toresourceid>}], ...} module.exports.getK8stool = function() { return k8sutil; }; module.exports.getLogUtil = function() { return logutil; }; module.exports.getRestclientUtil = function() { return rcutil; }; module.exports.checkReadyStatus = function(callback) { pluginconfig.consumerInsts.forEach(function(inst) { var name = inst.Name(); inst.checkReadyStatus(function(initialized_status) { logger.debug(name + ' initialized = ' + initialized_status); if (initialized_status) { callback(); } }); }); return; }; module.exports.stop = function() { sender.stopQueue(); }; module.exports.updateLoglevel = function(level) { var logutil = require('../plugins/logutil.js'); logutil.updateLogLevel(level); }; module.exports.setConfiguration = function(fileName, callback) { var tempCfg; logger.debug('Load configuration files: ', fileName); var file = process.env.KNJ_CONFIG_FILE || fileName; try { if (fs.existsSync(file)) { var confString = fs.readFileSync(file, 'utf8'); tempCfg = JSON.parse(confString); cfg = tempCfg; if (!cfg.metrics) { cfg.metrics = 'metric'; } if (!cfg.AAR) { cfg.AAR = 'aar/middleware'; } if (!cfg.ADR) { cfg.ADR = 'adr/middleware'; } if (cfg.proxy) { process.env.KNJ_PROXY = cfg.proxy; } } else { logger.debug('No configuration file is set by KNJ_CONFIG_FILE'); } } catch (e) { logger.error('register_topology set cofniguration failed.'); logger.error(e); } if (process.env.IBAM_TENANT_ID) { cfg.tenantID = process.env.IBAM_TENANT_ID; } logger.debug('Configuration loaded ', cfg); if (callback && !global.AM_SERVICE_BOUND) { logger.debug('No backend BAM service, call the callback ', callback.name); callback(); } }; module.exports.getConfiguration = function() { return cfg; }; module.exports._writeRegistryToFile = function() { try { var filename = './' + dcId + '.json'; var fileContent = JSON.stringify({ resourceEntities: resourceEntities, relationships: relationships }); fs.writeFileSync(filename, fileContent, 'utf8'); } catch (e) { logger.error('write registry to file failed'); logger.error(e); } }; module.exports._readRegistryFromFile = function() { try { var filename = './' + dcId + '.json'; var fileContent = fs.readFileSync(filename, 'utf8'); var jsonContent = JSON.parse(fileContent); resourceEntities = jsonContent.resourceEntities; relationships = jsonContent.relationships; return jsonContent; } catch (e) { logger.error('read registry to file failed'); logger.error(e); } }; module.exports.getDC = function(id, callback) { logger.debug('getDC'); if (!queue) { queue = sender.getQueue('bam'); } queue.addTask({ keyIndexName: id, type: 'queryDc:', callback: callback }); }; module.exports.getResource = function(obj, callback) { logger.debug('getResource'); if (!queue) { queue = sender.getQueue('bam'); } queue.addTask({ uid: obj.id, type: 'queryResource:', callback: callback }); }; module.exports.queryRelationship = function(id, callback) { logger.debug('queryRelationship'); if (!queue) { queue = sender.getQueue('bam'); } queue.addTask({ id: id, type: 'queryRelationship:', callback: callback }); }; module.exports.getConfiguration = function(callback) { logger.debug('getConfiguration'); if (!queue) { queue = sender.getQueue('bam'); } queue.addTask({ keyIndexName: dcId, type: 'queryConfiguration:', callback: callback }); }; module.exports.registerDC = function(obj, callback) { logger.debug('registerDC', obj); if (!queue) { queue = sender.getQueue('bam'); } var payload = { keyIndexName: obj.id, entityTypes: obj.type, startedTime: obj.startTime || (new Date()).toISOString(), // '2016-05-27T03:21:25.432Z' deployment: obj.deployment }; if (obj.references && obj.references.length > 0) { var references = []; for (var ref in obj.references) { var item = obj.references[ref]; var ref_item = { _edgeType: item.type }; ref_item['_' + item.direction + 'Uid'] = item.id; references.push(ref_item); } payload['_references'] = references; } for (var prop in obj.properties) { // merge properties payload[prop] = obj.properties[prop]; } dcId = obj.id; queue.addTask({ payload: payload, type: 'dc:', callback: callback }); }; function genRef(refs) { let references = []; for (var ref in refs) { var item = refs[ref]; var ref_item = { _edgeType: item.type }; if (item.matchTokens) { ref_item.matchTokens = item.matchTokens; } if (item.id) { ref_item['_' + item.direction + 'Uid'] = item.id; } if (item.pid) { ref_item['_' + item.direction + 'Id'] = item.pid; } references.push(ref_item); } return references; } module.exports.registerAppResource = function(obj, callback) { logger.debug('register Application Resource ', obj); if (!obj.type || !obj.id || !obj.properties) { logger.error('registerResource payload is not complete, must have: ' + 'id, type and properties'); return; } if (!queue) { queue = sender.getQueue('bam'); } var payload = { // merge public attributes uid: obj.id, entityTypes: obj.type, // type: obj.type[0], deployment: obj.deployment }; if (obj.references && obj.references.length > 0) { payload['_references'] = genRef(obj.references); } for (var prop in obj.properties) { // merge properties payload[prop] = obj.properties[prop]; } queue.addTask({ payload: payload, type: 'resources: ' + payload.entityTypes, callback: callback }); }; module.exports.registerResource = function(obj, callback) { logger.debug('register Resource ', obj); if (!obj.type || !obj.id || !obj.properties) { logger.error('registerResource payload is not complete, must have: ' + 'id, type and properties'); return; } if (!queue) { queue = sender.getQueue('bam'); } var payload = { // merge public attributes uid: obj.id, entityTypes: obj.type, // type: obj.type[0], deployment: obj.deployment }; if (obj.VersionDependencies) { payload['VersionDependencies'] = obj.VersionDependencies; } if (obj.references && obj.references.length > 0) { payload['_references'] = genRef(obj.references); } for (var prop in obj.properties) { // merge properties payload[prop] = obj.properties[prop]; } queue.addTask({ payload: payload, callback: callback, type: 'resources: ' + payload.entityTypes }); }; module.exports.updateResource = function(obj, loc, callback) { logger.debug('update Resource ', obj); if (!obj.type || !obj.id || !obj.properties || !loc) { logger.error('updateResource payload is not complete, must have: ' + 'location, id, type and properties'); return; } if (!queue) { queue = sender.getQueue('bam'); } var payload = { // merge public attributes entityTypes: obj.type, deployment: obj.deployment }; if (obj.VersionDependencies) { payload['VersionDependencies'] = obj.VersionDependencies; } if (obj.references && obj.references.length > 0) { payload['_references'] = genRef(obj.references); } for (var prop in obj.properties) { // merge properties payload[prop] = obj.properties[prop]; } queue.addTask({ location: loc, payload: payload, callback: callback, type: 'updateResources: ' + payload.entityTypes }); }; module.exports.postDCConfiguration = function(payload, type, callback) { queue.addTask({ payload: payload, type: 'dcconfig: ', entityType: type, additionalHeader: { version: global.DC_VERSION, providerUniqueId: dcId, entityType: type }, callback: callback }); }; module.exports.postSituationConfiguration = function(payload, callback) { queue.addTask({ payload: payload, type: 'situation: ', callback: callback }); }; module.exports.sendMetrics = function(payload, callback) { logger.debug('sendMetrics ', JSON.stringify(payload)); if (!queue) { queue = sender.getQueue('bam'); } if (payload instanceof Array) { var timestamp = (new Date()).toISOString(); for (var index = 0; index < payload.length; index++) { if (payload[index].hasOwnProperty('APP_NAME')) { continue; // ignore checking for additional items for BI payload } if (process.env.UA_LWDC_LISTENER_URL) { if (!payload[index].measurement || !payload[index].tags || !payload[index].fields) { logger.warn('sendMetrics payload is not complete, must have: ' + 'measurement, tags and fields'); return; } for (const key in payload[index].fields) { if (payload[index].fields[key] === null || payload[index].fields[key] === undefined) { logger.debug(key, 'The metric value is ', payload[index].fields[key], ', will skip this.'); return; } } for (const key in payload[index].tags) { if (payload[index].tags[key].includes('undefined')) { logger.debug(key, 'The tags value is ', payload[index].tags[key], ' contains undefined string, will skip this.'); return; } } } else { if (!payload[index].resourceID || !payload[index].tags || !payload[index].metrics) { logger.warn('sendMetrics payload is not complete, must have: ' + 'resourceID, tags and metrics'); return; } for (const key in payload[index].metrics) { if (payload[index].metrics[key] === null || payload[index].metrics[key] === undefined) { logger.debug(key, 'The metric value is ', payload[index].metrics[key], ', will skip this.'); return; } } } if (!payload[index].timestamp) { payload[index].timestamp = timestamp; } } } else { if (process.env.UA_LWDC_LISTENER_URL) { if (!payload.measurement || !payload.tags || !payload.fields) { logger.warn('sendMetrics payload is not complete, must have: ' + 'measurement, tags and fields'); return; } for (const key in payload.fields) { if (payload.fields.hasOwnProperty(key)) { if (payload.fields[key] === null || payload.fields[key] === undefined) { logger.debug(key, 'The metric value is ', payload.fields[key], ', will skip this.'); return; } } } for (const key in payload.tags) { if (payload.tags.hasOwnProperty(key)) { if (payload.tags[key].includes('undefined')) { logger.debug(key, 'The tags value is ', payload.tags[key], ' contains undefined string, will skip this.'); return; } } } } else { if (!payload.resourceID || !payload.tags || !payload.metrics) { logger.warn('sendMetrics payload is not complete, must have: ' + 'resourceID, tags and metrics'); return; } for (const key in payload.metrics) { if (payload.metrics.hasOwnProperty(key)) { if (payload.metrics[key] === null || payload.metrics[key] === undefined) { logger.debug(key, 'The metric value is ', payload.metrics[key], ', will skip this.'); return; } } } } if (!payload.timestamp) { payload.timestamp = (new Date()).toISOString(); } } queue.addTask({ payload: payload, type: 'metrics: ', callback: callback }); }; var aarBatch = { payload: [], committed: false }; module.exports.sendAAR = function(payload, callback, batched) { logger.debug('sendAAR', JSON.stringify(payload)); if (!payload.properties || !payload.metrics) { logger.error('sendAAR payload is not complete, must have: properties and metrics'); return; } if (!dcId) { callback({message: 'dcId is not ready'}); return; } if (!queue) { queue = sender.getQueue('bam'); } if (!batched) { queue.addTask({ payload: payload, type: 'aar:', callback: callback }); return; } if (payload.properties.originID) { delete payload.properties.originID; } payload.properties['tenantID'] = cfg.tenantID; // Meet Patch Condition KNJ_AAR_BATCH_FREQ, then put into task queue if (aarBatch.payload.length === 0) { aarBatch.committed = false; let timeoutObj = setTimeout( function() { if (aarBatch.payload.length > 0) { queue.addTask({ payload: aarBatch.payload, type: 'aar: batched', callback: callback }); } aarBatch.payload = []; aarBatch.committed = true; }, global.KNJ_AAR_BATCH_FREQ * 1000 ); timeoutObj.unref(); } if (!aarBatch.committed) { aarBatch.payload.push(payload); } // Meet Patch Condition KNJ_AAR_BATCH_COUNT, then put into task queue if (aarBatch.payload.length >= global.KNJ_AAR_BATCH_COUNT) { queue.addTask({ payload: aarBatch.payload, type: 'aar: batched', callback: callback }); aarBatch.committed = true; aarBatch.payload = []; } }; var adrBatch = { payload: [], committed: false }; module.exports.sendADR = function(payload, callback) { logger.debug('sendADR', JSON.stringify(payload)); if (!payload.properties || !payload.statistics) { logger.error('sendADR payload is not complete, must have: properties and statistics'); return; } if (!dcId) { callback({message: 'dcId is not ready'}); } else { if (!queue) { queue = sender.getQueue('bam'); } payload.properties['originID'] = global.KNJ_BAM_ORIGINID; payload.properties['tenantID'] = cfg.tenantID; // Meet Patch Condition KNJ_ADR_BATCH_FREQ, then put into task queue if (adrBatch.payload.length === 0) { adrBatch.committed = false; let timeoutObj = setTimeout( function() { if (adrBatch.payload.length > 0) { queue.addTask({ payload: adrBatch.payload, type: 'adr: batched', callback: callback }); } adrBatch.payload = []; adrBatch.committed = true; }, global.KNJ_ADR_BATCH_FREQ * 1000 ); timeoutObj.unref(); } if (!adrBatch.committed) { adrBatch.payload.push(payload); } if (adrBatch.payload.length >= global.KNJ_ADR_BATCH_COUNT) { queue.addTask({ payload: adrBatch.payload, type: 'adr: batched', callback: callback }); adrBatch.payload = []; adrBatch.committed = true; } } }; module.exports.sendJSO = function(payload, callback) { logger.debug('sendJSO'); if (!queue) { queue = sender.getQueue('bam'); } queue.addTask({ payload: payload, type: 'jso: ', callback: callback }); }; // Deprecated: applicationMgmt has removed it module.exports.sendNotify = function(payload, callback) { queue.addTask({ payload: payload, type: 'rteNotify: ', keyIndexName: dcId, callback: callback }); }; // the type should be value of PluginConfig.prototype.queuetypes module.exports.send = function(payload, type, callback) { if (!queue) { queue = sender.getQueue('bam'); } if (type === pluginconfig.queuetypes.DC) { this.registerDC(payload, callback); } if (type === pluginconfig.queuetypes.RESOURCE) { this.registerResource(payload, callback); } if (type === pluginconfig.queuetypes.METRICS) { this.sendMetrics(payload, callback); } if (type === pluginconfig.queuetypes.AAR) { this.sendAAR(payload, callback); } if (type === pluginconfig.queuetypes.ADR) { this.sendADR(payload, callback); } if (type === pluginconfig.queuetypes.JSO) { this.sendJSO(payload, callback); } };