Everyday you see people (or yourself) doing some mundane task and you wonder how can you help them automate that process. So this article highlights something I did a few months back to help a friend who used to spend considerable amount of time fetching data from ALM (Earlier know as QC) formatting it and putting in some other database.
I always wanted to use node.js in something useful, so I decided to set up a server to get data from ALM server and push it to other database. Until this point I had no idea if ALM had exposed any API’s. Luckily they had opened up access to ALM 11.00 and higher version via their REST API. I wanted everything on server side and there was no UI involved.
So I was able to come up with a small script which authenticates the user into ALM and then get all the defect related to a release. I have provided the comments where ever necessary in the below code. I am still a noob in node.js so please excuse me if I have made any mistake
var https = require('https'), fs = require('fs'), config = JSON.parse(fs.readFileSync('config.json'));//this refers to a file where I have all my config like host, userName, password Etc //this is added to avoid the TLS error. Uncomment if you get a TLS error while authenticating. //process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; //set the correct options for the call. var options = { host : config.host, path : "/qcbin/authentication-point/authenticate", method: "GET", headers : {'Authorization': 'Basic '+new Buffer(config.alm_userName + ':' + config.alm_password).toString('base64')} }; //authenticating the user into ALM ALMConnect(options, 'header','', function(status, data){ if(status){ //get the LWSSO_Cookie from the header. This is the session cookie which will be used in all callouts to ALM. if(data.headers["set-cookie"] != undefined ) { extractDefects(data.headers["set-cookie"]); }else{ console.log('Dagnabbit!! ERROR: Unable to login, check your username/password/serverURL.'); } }else{ console.log('Dagnabbit!! ERROR: ' + JSON.stringify(data)); } }); //Function to extract the defects for analysis. function extractDefects(LWSSO_Cookie){ var queryParam = "{"; //add Release queryParam += "detected-in-rel["+config.release+"];"; //add all your request parameters here. Its a little complicated initially, but you will get a hang of it. // Make sure to use encodeURIComponents() for all the values in the query parameters. queryParam+="}"; //get all the fields that you want to query. Lesser the fields smaller the XML returned, faster is the call. var fields = config.defectFieldMapping.fieldArray.join(','); var opt = { host: config.host, path: "/qcbin/rest/domains/"+config.domain+"/projects/"+config.project+"/defects?query="+queryParam+"&fields="+fields+"&page-size=max", method:"GET", headers: {"Cookie":LWSSO_Cookie} }; ALMConnect(opt, 'data','',function(status,data){ if(status){ //write the defects to an XML file in local drive. fs.writeFileSync('newDefect.xml',data); //once you get the defectXML you can parse it into JSON and push it other databases like SFDC etc.. }else{ console.log('Dagnabbit!! ERROR: ' + JSON.stringify(data)); } }); } function ALMConnect(opt, responseType,requestBody, callback){ var request = https.request(opt, function(res){ res.setEncoding('utf8'); var XMLoutput=''; res.on('data',function(chunk){ XMLoutput+=chunk; }); res.on('end',function(){ if(responseType=='data'){ callback(true,XMLoutput); }else { callback(true, res); } }); }); request.on('error',function(e){ callback(false,e); }); if(opt.method=='POST' || opt.method == 'PUT'){ request.write(requestBody); } request.end(); }