From e4d5c8aa335c357c1210d229bbb979e331c78d95 Mon Sep 17 00:00:00 2001 From: Hugo Mota Date: Tue, 10 Mar 2020 13:16:40 +0000 Subject: [PATCH] fix(scancompare): add the previous scan fetch add the previous scan fetch to compare with the last scan --- source/components/ScanSummary/ScanSummary.ts | 32 ++++++++++--------- source/components/ScanSummary/constants.ts | 14 ++++++++ .../XmlParsingService/XmlParsingService.ts | 1 + .../XmlParsingServiceImpl.ts | 26 ++++++++++++++- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/source/components/ScanSummary/ScanSummary.ts b/source/components/ScanSummary/ScanSummary.ts index c239773..719a805 100644 --- a/source/components/ScanSummary/ScanSummary.ts +++ b/source/components/ScanSummary/ScanSummary.ts @@ -1,8 +1,7 @@ import { format as formatString } from 'util'; +import { ConfigurationService, LoggerService, XmlParsingService } from '../../services'; import DataService from '../../services/DataService/DataService'; -import { IScanSummaryData } from './IScanSummaryData'; -import { LoggerService, XmlParsingService, ConfigurationService } from '../../services'; -import { QUERY_PROJECT_DETAILS, QUERY_PROJECT_STATUS, RESPONSE_TEMPLATE } from './constants'; +import { QUERY_PREVIOUS_SCAN_ID, QUERY_PROJECT_DETAILS, RESPONSE_TEMPLATE } from './constants'; import ScanSummaryError from './ScanSummaryError'; const cnf = ConfigurationService.getConfig(); @@ -13,7 +12,7 @@ const timeout = (ms: number) => { return new Promise(resolve => setTimeout(resolve, ms)); }; -const fetchData = async (scanId: number): Promise => { +const fetchData = async (projectId: number, scanId: number): Promise => { const ds = DataService.getInstance(); try { @@ -25,8 +24,12 @@ const fetchData = async (scanId: number): Promise => { if (!scanSummaryQueryResult.length) { throw new ScanSummaryError(ScanSummaryError.MISSING_SCAN_DETAILS, scanId); } - // const scanTotalsQueryResult = (await ds.executeQuery(formatString(QUERY_PROJECT_STATUS, scanId))) as any[]; - const scanTotalsQueryResult = (await ds.executeGetCompareScansSummary(scanId as number, scanId as number)) as any[]; + + const previousScanIdQueryResult = (await ds.executeQuery(formatString(QUERY_PREVIOUS_SCAN_ID, projectId, scanId))) as any[]; + const previousScanId: number = previousScanIdQueryResult.length ? previousScanIdQueryResult[0].scanId : scanId; + log.debug('retrieved previous scan id from database %s', previousScanId); + + const scanTotalsQueryResult = (await ds.executeGetCompareScansSummary(scanId as number, previousScanId as number)) as any[]; log.debug('retrieved from database %j', scanTotalsQueryResult); await ds.disconnect(); @@ -78,24 +81,22 @@ const fetchData = async (scanId: number): Promise => { } }; -const fetchDataRetry = async (scanId: number, retries: number): Promise => { +const fetchDataRetry = async (projectId: number, scanId: number, retries: number): Promise => { try { if (retries >= 0) { - log.info('Feching data for scanId=%s attempt #%s', scanId, retries); - const scanData = await fetchData(scanId); + log.info('Feching data for projectId=%s scanId=%s attempt #%s', projectId, scanId, retries); + const scanData = await fetchData(projectId, scanId); log.debug('Feching data for scanId=%s attempt #%s returned %j', scanId, retries, scanData); if (!scanData) { await timeout(2000); - return await fetchDataRetry(scanId, retries - 1); + return await fetchDataRetry(projectId, scanId, retries - 1); } return scanData; - } else { - throw Error('ABORTING'); } } catch (e) { if (retries > 0) { await timeout(2000); - return await fetchDataRetry(scanId, retries - 1); + return await fetchDataRetry(projectId, scanId, retries - 1); } else { log.error('Could not retrieve data for scanId=%s after several attempts', scanId); return undefined; @@ -109,11 +110,12 @@ const summaryReport = async (): Promise => { } const scanId = await xml.fetchScanIdAndQuit(cnf.project.xmlReport); - const scanData = await fetchDataRetry(scanId, 4); + const projectId = await xml.fetchProjectIdAndQuit(cnf.project.xmlReport); + const scanData = await fetchDataRetry(projectId, scanId, 4); log.debug('fetched scan details %j', scanData); if (scanData) { - log.info('finished retrieving data for scanId=%s projectName="%s"', scanId, scanData.projectName); + log.info('finished retrieving data for projectId=%s scanId=%s projectName="%s"', projectId, scanId, scanData.projectName); } return Promise.resolve(scanData); diff --git a/source/components/ScanSummary/constants.ts b/source/components/ScanSummary/constants.ts index 9c65ce8..12776bb 100644 --- a/source/components/ScanSummary/constants.ts +++ b/source/components/ScanSummary/constants.ts @@ -38,6 +38,20 @@ ORDER BY Query.Severity DESC; `; +export const QUERY_PREVIOUS_SCAN_ID = ` +SELECT + Id as scanId +FROM + [CxDB].[dbo].[TaskScans] +WHERE + ProjectId = %s + AND Id <= %s +ORDER BY + Id DESC +OFFSET 1 ROWS +FETCH NEXT 1 ROW ONLY +`; + export const RESPONSE_TEMPLATE: IScanSummaryData = { productVersion: '', projectId: 0, diff --git a/source/services/XmlParsingService/XmlParsingService.ts b/source/services/XmlParsingService/XmlParsingService.ts index 757035e..84d6ae0 100644 --- a/source/services/XmlParsingService/XmlParsingService.ts +++ b/source/services/XmlParsingService/XmlParsingService.ts @@ -2,6 +2,7 @@ import XmlParsingServiceImpl from './XmlParsingServiceImpl'; export interface IXmlParsingService { fetchScanIdAndQuit(xmlReportPath: string): Promise; + fetchProjectIdAndQuit(xmlReportPath: string): Promise; } let instance: IXmlParsingService; diff --git a/source/services/XmlParsingService/XmlParsingServiceImpl.ts b/source/services/XmlParsingService/XmlParsingServiceImpl.ts index a245545..09a0cb5 100644 --- a/source/services/XmlParsingService/XmlParsingServiceImpl.ts +++ b/source/services/XmlParsingService/XmlParsingServiceImpl.ts @@ -1,6 +1,6 @@ -import { IXmlParsingService } from './XmlParsingService'; import lineReader from 'line-reader'; import { LoggerService } from '../LoggerService'; +import { IXmlParsingService } from './XmlParsingService'; const log = LoggerService.getLogger('XmlParsingServiceImpl'); @@ -28,6 +28,22 @@ const getScanIdAndQuit = (path: string): Promise => { }); }; +const getProjectIdAndQuit = (path: string): Promise => { + return new Promise(resolve => { + lineReader.eachLine(path, line => { + if (line.includes('CxXMLResults')) { + const xmlProp = extractMatchFromString(/ProjectId=\"[0-9]*\"/g, line); + const xmlPropValue = extractMatchFromString(/\d+/g, xmlProp ? xmlProp : ''); + log.debug('fetched xmlProperty %s', xmlProp); + log.debug('fetched xmlPropertyValue %s', xmlPropValue); + resolve(xmlPropValue); + return false; + } + return true; + }); + }); +}; + export default class XmlParsingServiceImpl implements IXmlParsingService { public async fetchScanIdAndQuit(_xmlReportPath: string): Promise { const scanId = await getScanIdAndQuit(_xmlReportPath); @@ -36,4 +52,12 @@ export default class XmlParsingServiceImpl implements IXmlParsingService { return Promise.resolve(scanId ? scanId : 0); } + + public async fetchProjectIdAndQuit(_xmlReportPath: string): Promise { + const projectId = await getProjectIdAndQuit(_xmlReportPath); + + log.info('fetched projectId=%s from %s', projectId, _xmlReportPath); + + return Promise.resolve(projectId ? projectId : 0); + } }