blob: 6dde27b9920f80c516775912fa66d82a3b6f8933 [file] [log] [blame]
var log4js = require('log4js');
var http = require('http');
var async = require('async');
var properties = require(process.env.SDNC_CONFIG_DIR + '/netdb-updater.json');
var admProperties = require(process.env.SDNC_CONFIG_DIR + '/admportal.json');
var csvtojson = require('csvtojson');
var mysql = require('mysql');
var moment = require('moment');
var os = require('os');
var fs = require('fs.extra');
// Check to make sure SDNC_CONFIG_DIR is set
var sdnc_config_dir = process.env.SDNC_CONFIG_DIR;
if ( typeof sdnc_config_dir == 'undefined' )
{
console.log('ERROR the SDNC_CONFIG_DIR environmental variable is not set.');
return;
}
// SETUP LOGGER
log4js.configure(process.env.SDNC_CONFIG_DIR + '/netdb.log4js.json');
var logger = log4js.getLogger('netdb');
logger.setLevel(properties.netdbLogLevel);
var yargs = require('yargs')
.usage("\nUsage: node netdb_updater -t link_master|router_master")
.demand('t')
.alias('t', 'table')
.example("Example: node netdb_updater -t link_master","Update SDNC LINK_MASTER table from NetDB.")
.argv;
var dbTable = yargs.table;
var debug = properties.netdbDebug;
var env = properties.netdbEnv;
var retSuccess = false;
// DB Setup
var currentDB = '';
var dbConnection = '';
var db01 = '';
var db02 = '';
var count = 0;
var errorMsg = [];
var dbtasks = [];
dbtasks.push( function(callback) { checkParams(callback); } );
dbtasks.push( function(callback) { dbConnect(callback); } );
//dbtasks.push( function(callback) { netdb(callback); } );
logger.debug('\n\n********** START PROCESSING - Env=' + env + ' Debug=' + debug + ' **********');
async.series(dbtasks, function(err,result){
if(err) {
logger.error(err + ' COUNT: ' + count);
}
else {
if ( errorMsg.length > 0 ){
logger.error(errorMsg);
}
}
});
function checkParams(scb){
if ( dbTable != 'link_master' && dbTable != 'router_master' ){
scb("Invalid parameter passed in '" + dbTable + " ' exiting.'");
}
else{
scb(null);
}
}
async.whilst(
function () { return count < properties.netdbRetryInterval },
function (callback) {
if ( dbTable == 'link_master' ){
getLinkMaster(callback);
}
else if (dbTable == 'router_master'){
getRouterMaster(callback);
}
else{ // should never hit this condition
logger.debug("Invalid parameter passed in '" + dbTable + " ' exiting.'");
}
},
function (err) {
logger.debug('whilst err function errorMsg = ' + errorMsg);
// report error
if ( errorMsg.length > 0 ){
logger.debug(errorMsg + ' COUNT: ' + count);
process.exit(1);
}
else{
logger.debug('success');
process.exit(0);
}
}
);
function returnError(emsg, cb){
retSuccess=false;
errorMsg.push(emsg);
if ( count == properties.netdbRetryInterval ) { logger.error(errorMsg); }
setTimeout( function(){
cb(null);
}, properties.netdbWaitTime);
}
function returnSuccess(cb){
logger.debug('inside returnSuccess');
errorMsg = '';
//var cnt = properties.netdbRetryInterval;
//logger.debug('b4 inc returnSuccess count=' + count);
//count = ++cnt;
//logger.debug('after inc returnSuccess count=' + count);
//cb(null);
retSuccess=true;
process.exit(0);
}
function getRouterMaster(cb){
logger.info('getRouterMaster debug=' + debug + ' count=' + count);
// setup connection
var netdbEnv = properties.netdbEnv;
var auth_param = '';
if ( netdbEnv == 'e2e' || netdbEnv == 'prod' ){
// conexus network
auth_param = '?auth=' + admProperties['ip-addresses']['eth2'] + ';'
}else{
// app network
auth_param = '?auth=' + admProperties['ip-addresses']['eth1:0'] + ';'
}
var username = properties.netdbUser;;
var password = properties.netdbPassword;
var date = moment().format('YYYYMMDD');
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var host = properties.netdbHost;
var port = properties.netdbPort;
var path = '/' + properties.netdbPath
+ '/' + properties.netdbNetwork
+ '/' + properties.netdbApiName
+ auth_param
+ 'client=' + properties.netdbClientName + ';'
+ 'date=' + date + ';'
+ 'reportName=' + dbTable + ';'
+ 'type=' + properties.netdbType;
var header = { 'Content-Type': 'text/csv' };
//var header = {'Host': host, 'Authorization': auth, 'Content-Type': 'text/csv' };
var options = {
method : "GET",
path : path,
host : host,
port : port,
headers : header
};
logger.debug('options:\n' + JSON.stringify(options,null,2));
var request = http.request(options, function(response) {
var response_str = '';
if ( retSuccess == true ){
var cnt = properties.netdbRetryInterval;
count = ++cnt;
}
else{
count++;
}
logger.debug('STATUS: ' + response.statusCode + ' content-type=' + response.headers['content-type']);
// Read the response from ODL side
response.on('data', function(chunk) {
response_str += chunk;
});
response.on('end', function() {
logger.debug('HEADERS:' + JSON.stringify(response.headers));
if(response.statusCode == 200){
if(response_str.length > 0){
// save the upload
try{
fs.writeFileSync('/sdncvar/sdnc/files/netdb-updater/' + moment().unix() + ".netdb." + dbTable + '.csv', response_str);
}
catch(e){
// this is not in reqs, if it fails keep on going.
logger.error('Error writing NetDB file:' + e);
}
if (response.headers['content-type'].indexOf('html') > 0){
returnError('Error:Unexpected content-type:' + response.headers['content-type'] + ' returned.\n', cb);
return;
}
// need to parse csv file
var Converter=csvtojson.Converter;
var csvConverter = new Converter({
noheader:true
});
var routerMasterSQL = '';
// end_parsed will be emitted once parsing is finished
csvConverter.on("end_parsed", function(respObj){
routerMasterSQL = routerMasterSQL.concat("INSERT INTO ROUTER_MASTER (crs_name, loopback_ip)");
for ( var x=0; x < respObj.length; x++ ){
if ( respObj[x].field1.length == 0 ){
returnError('Required field [crs_name] is null.', cb);
}
if (x!=0){
routerMasterSQL = routerMasterSQL.concat(' union ');
}
routerMasterSQL = routerMasterSQL.concat(" SELECT "
+ "'" + respObj[x].field1 + "',"
+ "'" + respObj[x].field2 + "' FROM DUAL ");
}
//logger.debug('SQL: ' + routerMasterSQL);
if (debug != 'debug' && env != 'dev'){
var tasks = [];
tasks.push( function(callback) { updateRouterMaster(routerMasterSQL,callback); } );
async.series(tasks, function(err,result){
if(err) {
returnError(err,cb);
return;
}
else {
logger.info('*** Router Master Table Replaced ***');
returnSuccess(cb);
return;
}
});
}
else{
logger.debug('*** debug ***');
returnSuccess(cb);
return;
}
});
csvConverter.on("error",function(errMsg,errData){
returnError(errMsg,cb);
return;
});
csvConverter.fromString(response_str, function(err,result){
if(err){
returnError(err,cb);
return;
}
});
}
else{
//logger.debug("no data");
returnError('no data',cb);
return;
}
}
else if(response.statusCode == 404){
returnError('Router Master Table for ' + date + ' is not Available.',cb);
return;
}
else {
returnError('Status Code:' + response.statudCode + ' returned for Router Master Table query.',cb);
return;
}
});
});
request.on('error', function(e) {
if ( retSuccess == true ){
var cnt = properties.netdbRetryInterval;
count = ++cnt;
}
else{
count++;
}
returnError(e,cb);
return;
});
request.end();
}
function getLinkMaster(cb){
logger.info('getLinkMaster debug=' + debug + ' count=' + count);
// setup connection
var netdbEnv = properties.netdbEnv;
var auth_param = '';
if ( netdbEnv == 'e2e' || netdbEnv == 'prod' ){
// conexus network
auth_param = '?auth=' + admProperties['ip-addresses']['eth2'] + ';'
}else{
// app network
auth_param = '?auth=' + admProperties['ip-addresses']['eth1:0'] + ';'
}
var username = properties.netdbUser;;
var password = properties.netdbPassword;
var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var host = properties.netdbHost;
var port = properties.netdbPort;
var date = moment().format('YYYYMMDD');
var path = '/' + properties.netdbPath
+ '/' + properties.netdbNetwork
+ '/' + properties.netdbApiName
+ auth_param
+ 'client=' + properties.netdbClientName + ';'
+ 'date=' + date + ';'
+ 'reportName=' + dbTable + ';'
+ 'type=' + properties.netdbType;
var header = { 'Content-Type': 'text/csv' };
//var header = {'Host': host, 'Authorization': auth, 'Content-Type': 'text/csv' };
var options = {
method : "GET",
path : path,
host : host,
port : port,
headers : header
};
logger.debug('options:\n' + JSON.stringify(options,null,2));
var request = http.request(options, function(response) {
logger.debug('STATUS: ' + response.statusCode + ' content-type=' + response.headers['content-type']);
if ( retSuccess == true ){
var cnt = properties.netdbRetryInterval;
count = ++cnt;
}
else{
count++
}
var response_str = '';
// Read the response from ODL side
response.on('data', function(chunk) {
response_str += chunk;
});
response.on('end', function() {
logger.debug('HEADERS:' + JSON.stringify(response.headers));
if(response.statusCode == 200){
if(response_str.length > 0){
//logger.debug('response_str=' + response_str);
// save the upload
try{
fs.writeFileSync('/sdncvar/sdnc/files/netdb-updater/' + moment().unix() + ".netdb." + dbTable + '.csv', response_str);
}
catch(e){
// this is not in reqs, if it fails keep on going.
logger.error('Error writing NetDB file:' + e);
}
if (response.headers['content-type'].indexOf('html') > 0){
returnError('Error:Unexpected content-type:' + response.headers['content-type'] + ' returned.\n', cb);
return;
}
// need to parse csv file
var Converter=csvtojson.Converter;
var csvConverter = new Converter({
noheader:true
});
var linkMasterSQL = '';
// end_parsed will be emitted once parsing is finished
csvConverter.on("end_parsed", function(jsonObj){
linkMasterSQL = linkMasterSQL.concat("INSERT INTO LINK_MASTER (link_interface_ip, source_crs_name, destination_crs_name, link_speed, default_cost, bundle_name, shutdown)");
for ( var x=0; x < jsonObj.length; x++ ){
if ( jsonObj[x].field1.length == 0 ){
returnError('Required field [link_interface_ip] is null.', cb);
return;
}
if ( jsonObj[x].field2.length == 0 ){
returnError('Required field [source_crs_name] is null.', cb);
return;
}
if ( jsonObj[x].field3.length == 0 ){
returnError('Required field [destination_crs_name] is null.', cb);
return;
}
if (x!=0){
linkMasterSQL = linkMasterSQL.concat(' union ');
}
linkMasterSQL = linkMasterSQL.concat(" SELECT "
+ "'" + jsonObj[x].field1 + "',"
+ "'" + jsonObj[x].field2 + "',"
+ "'" + jsonObj[x].field3 + "',"
+ jsonObj[x].field4 + ","
+ jsonObj[x].field5 + ","
+ "'" + jsonObj[x].field6 + "',"
+ "'" + jsonObj[x].field7 + "' FROM DUAL");
}
//logger.debug('SQL: ' + linkMasterSQL);
if (debug != 'debug' && env != 'dev'){
// update db
var tasks = [];
tasks.push( function(callback) { updateLinkMaster(linkMasterSQL,callback); } );
async.series(tasks, function(err,result){
if(err)
{
returnError(err,cb);
return;
}
else
{
logger.info('*** Link Master Table Replaced ***');
returnSuccess(cb);
return;
}
});
}
else{
returnSuccess(cb);
return;
}
});
csvConverter.on("error",function(errMsg,errData){
returnError(errMsg,cb);
return;
});
csvConverter.fromString(response_str, function(err,result){
if(err){
returnError(errMsg,cb);
return;
}
});
}
else{
returnError('no data',cb);
return;
}
}
else if(response.statusCode == 404){
returnError('Link Master Table for ' + date + ' is not Available.',cb);
return;
}
else {
returnError('Status Code:' + response.statudCode + ' returned for Link Master Table query.',cb);
return;
}
});
});
request.on('error', function(e) {
if ( retSuccess == true ){
var cnt = properties.netdbRetryInterval;
count = ++cnt;
}
else{
count++
}
returnError(e,cb);
return;
});
request.end();
}
function dbConnect(callback){
var l_db01 = admProperties['databases']['0'];
var db01Array = l_db01.split("|");
db01 = db01Array[0];
var l_db02 = admProperties['databases']['1'];
var db02Array = l_db02.split("|");
db02 = db02Array[0];
if ( admProperties.dbFabric == 'true' )
{
logger.debug('connectFabric()');
// testing
var fabric_connection = mysql.createConnection({
host : admProperties.dbFabricServer,
user : admProperties.dbFabricUser,
password : admProperties.dbFabricPassword,
database : admProperties.dbFabricDB,
port : admProperties.dbFabricPort
});
fabric_connection.connect( function(err) {
if (err) {
callback(err);
return;
}
fabric_connection.query('CALL dump.servers()', function(err,rows) {
var masterDB = '';
if (err) {
callback(err);
return;
}
fabric_connection.end();
logger.debug('rows: ' + JSON.stringify(rows,null,2));
// fabric servers
for ( var x=0; x<rows.length; x++)
{
// database servers
for ( var y=0; y<rows[x].length; y++)
{
var row = rows[x][y];
if (row.group_id == admProperties.dbFabricGroupId)
{
if (row.status == '3' && row.mode == '3'){
masterDB = row.host;
}
}
}
}
logger.debug('currentDB: ' + currentDB);
logger.debug('masterDB: ' + masterDB);
if (masterDB.length <=0)
{
logger.debug('no writable master db');
callback('no writable master db');
return;
}
if ( currentDB != masterDB )
{
currentDB = masterDB;
dbConnection = mysql.createConnection({
connectionLimit : admProperties.dbConnLimit,
host : currentDB,
user : admProperties.dbUser,
password : admProperties.dbPassword,
database : admProperties.dbName,
multipleStatements: true,
debug : false
});
}
logger.debug('new currentDB: ' + currentDB);
logger.debug('new masterDB: ' + masterDB);
callback(null);
return;
});
fabric_connection.on('error', function(err){
logger.debug(err.code);
callback(err);
return;
});
});
}
else
{
currentDB = db01;
var dbConn = mysql.createConnection({
connectionLimit : admProperties.dbConnLimit,
host : currentDB,
user : admProperties.dbUser,
password : admProperties.dbPassword,
database : admProperties.dbName,
multipleStatements: true,
debug : false
});
logger.debug('initDB currentDB=' + currentDB);
dbConn.connect(function(err,connection){
if(err){
logger.debug( String(err) ); // ALARM
callback(err);
return;
}
var sql = 'select @@read_only';
dbConn.query(sql, function(err,result){
dbConn.end();
// @@read_only=0 means db is writable
logger.debug('@@read_only=' + result[0]['@@read_only']);
if ( result[0]['@@read_only'] != '0' )
{
if (currentDB == db01)
{
currentDB = db02;
}
else
{
currentDB = db01;
}
logger.debug('initDB reconnect to currentDB '+ currentDB);
var newConnection = mysql.createConnection({
connectionLimit : admProperties.dbConnLimit,
host : currentDB,
user : admProperties.dbUser,
password : admProperties.dbPassword,
database : admProperties.dbName,
multipleStatements: true,
debug : false
}); // end create
dbConnection = newConnection;
callback(null);
return;
}
dbConnection = dbConn;
callback(null);
return;
});
});
}
}
function updateLinkMaster(linkMasterSQL,callback){
logger.debug('updateLinkMaster');
dbConnection.connect(function(err,connection)
{
if(err){
logger.debug( String(err) ); // ALARM
callback(err, 'Unable to get database connection.');
return;
}
}); // end connection
dbConnection.beginTransaction(function(err) {
if(err){
//dbConnection.release();
callback(err,String(err));
return;
}
var sql = "DELETE FROM LINK_MASTER";
dbConnection.query(sql,function(err,result)
{
if(err){
//dbConnection.release();
dbConnection.rollback( {rollback: 'NO RELEASE'},function(){
callback(err,String(err));
return;
});
}
dbConnection.query(linkMasterSQL,function(err,result)
{
if(err){
//dbConnection.release();
dbConnection.rollback( {rollback: 'NO RELEASE'},function(){
callback(err,String(err));
return;
});
}
dbConnection.commit(function(err){
if(err){
//dbConnection.release();
dbConnection.rollback( {rollback: 'NO RELEASE'},function(){
callback(err,String(err));
return;
});
}
//dbConnection.release();
callback(null);
});
})
});
}); // end transaction
}
function updateRouterMaster(routerMasterSQL,callback){
logger.debug('updateRouterMaster');
dbConnection.connect(function(err,connection)
{
if(err){
logger.debug( String(err) ); // ALARM
callback(err, 'Unable to get database connection.');
return;
}
}); // end connection
dbConnection.beginTransaction(function(err) {
if(err){
//dbConnection.release();
callback(err,String(err));
return;
}
var sql = "DELETE FROM ROUTER_MASTER";
dbConnection.query(sql,function(err,result)
{
if(err){
//dbConnection.release();
dbConnection.rollback( function(){
callback(err,String(err));
return;
});
}
dbConnection.query(routerMasterSQL,function(err,result)
{
if(err){
//dbConnection.release();
dbConnection.rollback( function(){
callback(err,String(err));
return;
});
}
dbConnection.commit(function(err){
if(err){
//dbConnection.release();
dbConnection.rollback( function(){
callback(err,String(err));
return;
});
}
//dbConnection.release();
callback(null);
});
})
});
}); // end transaction
}
/*
logger.debug('getLinkMaster - count=' + count);
if ( true ) {
//fail
setTimeout( function(){
cb(null);}, properties.netdbWaitTime);
return;
}
// success
count = 10;
cb(null);
}
*/