Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch scans by local or server Offset and GetPresetQueryId by queryVersionCode #31

Merged
merged 2 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Checkmarx.API.Tests/ScanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ public void GetScanResultsGroupedByPresetIdTest()
var res = clientV9.GetResultsForScan(18263);

var resByQueryId = res.GroupBy(x => x.QueryId).ToDictionary(x => x.Key, y => y.Count());
var resByPresetId = res.GroupBy(x => clientV9.GetPresetQueryId(x.QueryId)).ToDictionary(x => x.Key, y => y.Count());
var resByPresetId = res.GroupBy(x => clientV9.GetPresetQueryId(x.QueryVersionCode)).ToDictionary(x => x.Key, y => y.Count());
}

[TestMethod]
Expand Down Expand Up @@ -914,5 +914,19 @@ public void CompareSoapVsOdataScanResultsTest()
}
}
}

[TestMethod]
public void FetchScansByDateTest()
{
var filterDate = new DateTime(2024, 6, 23, 0, 3, 0);

var scanBefore = clientV93.GetScans(18096, true, scanKind: CxClient.ScanRetrieveKind.Last, maxScanDate: filterDate, includeGhostScans: false).SingleOrDefault();

Trace.WriteLine($"Scan Before: {scanBefore.Id}");

var scanAfter = clientV93.GetScans(18096, true, scanKind: CxClient.ScanRetrieveKind.First, minScanDate: filterDate, includeGhostScans: false).SingleOrDefault();

Trace.WriteLine($"Scan After: {scanAfter.Id}");
}
}
}
101 changes: 81 additions & 20 deletions Checkmarx.API/CxClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,26 @@ public List<CxDataRepository.Project> ProjectsOData
}
}

private TimeSpan? _serverDateTimeOffSet;
public TimeSpan ServerDateTimeOffSet
{
get
{
if (_serverDateTimeOffSet == null)
{
checkConnection();

var project = _oDataProjects.FirstOrDefault();
if (project == null)
throw new Exception("There are no conditions to get client DateTime Offset.");

_serverDateTimeOffSet = project.CreatedDate.Offset;
}

return _serverDateTimeOffSet.Value;
}
}

private global::Microsoft.OData.Client.DataServiceQuery<global::CxDataRepository.Scan> _oDataScans => _isV9 ? _oDataV9.Scans.Expand(x => x.ScannedLanguages) : _oData.Scans.Expand(x => x.ScannedLanguages);

private global::Microsoft.OData.Client.DataServiceQuery<global::CxDataRepository.Project> _oDataProjects => _isV9 ? _oDataV9.Projects : _oData.Projects;
Expand Down Expand Up @@ -2049,9 +2069,9 @@ public Scan GetFirstScan(long projectId)
return GetScans(projectId, true).FirstOrDefault();
}

public Scan GetLastScan(long projectId, bool fullScanOnly = false, bool onlyPublic = false, DateTime? maxScanDate = null, bool finished = true)
public Scan GetLastScan(long projectId, bool fullScanOnly = false, bool onlyPublic = false, DateTime? maxScanDate = null, bool finished = true, bool useServerTime = true)
{
var scans = GetScans(projectId, finished, onlyPublic: onlyPublic, maxScanDate: maxScanDate);
var scans = GetScans(projectId, finished, onlyPublic: onlyPublic, maxScanDate: maxScanDate, useServerTime: useServerTime);

// if there is no scans
if (!scans.Any())
Expand All @@ -2065,13 +2085,17 @@ public Scan GetLastScan(long projectId, bool fullScanOnly = false, bool onlyPubl
if (!finished)
return scans.OrderByDescending(x => x.DateAndTime.StartedOn).FirstOrDefault();

DateTimeOffset? filterMaxDate = null;
if (maxScanDate.HasValue)
filterMaxDate = useServerTime ? new DateTimeOffset(maxScanDate.Value, ServerDateTimeOffSet) : new DateTimeOffset(maxScanDate.Value);

// Prevent cases where the Id's counters of the scans where reinitiated.
long? scanId = _oDataV95.Projects.Expand(x => x.Scans)
.Where(p => p.Id == projectId).FirstOrDefault()?.Scans
.Where(x => (!fullScanOnly || !x.IsIncremental.Value)
&& (!onlyPublic || x.IsPublic)
&& (!finished || x.ScanType == 1)
&& (maxScanDate == null || x.ScanCompletedOn <= new DateTimeOffset(maxScanDate.Value))
&& (filterMaxDate == null || x.ScanCompletedOn <= filterMaxDate)
)
.OrderByDescending(x => x.ScanRequestedOn)
.FirstOrDefault()?.Id;
Expand All @@ -2083,9 +2107,9 @@ public Scan GetLastScan(long projectId, bool fullScanOnly = false, bool onlyPubl
return scans.LastOrDefault();
}

public Scan GetLastScanByVersion(long projectId, string version, bool onlyPublic = false, DateTime? maxScanDate = null)
public Scan GetLastScanByVersion(long projectId, string version, bool onlyPublic = false, DateTime? maxScanDate = null, bool useServerTime = true)
{
return GetScans(projectId, true, version: version, onlyPublic: onlyPublic, maxScanDate: maxScanDate).LastOrDefault();
return GetScans(projectId, true, version: version, onlyPublic: onlyPublic, maxScanDate: maxScanDate, useServerTime: useServerTime).LastOrDefault();
}

public Scan GetLastScanFinishOrFailed(long projectId)
Expand All @@ -2104,7 +2128,20 @@ public int GetScanCount()
return _oDataScans.Count();
}

public IEnumerable<Scan> GetScans(long projectId, bool finished, ScanRetrieveKind scanKind = ScanRetrieveKind.All, string version = null, bool onlyPublic = false, DateTime? minScanDate = null, DateTime? maxScanDate = null, bool includeGhostScans = true)
public IEnumerable<Scan> GetScans(long projectId, bool finished, ScanRetrieveKind scanKind = ScanRetrieveKind.All, string version = null, bool onlyPublic = false, DateTime? minScanDate = null, DateTime? maxScanDate = null, bool includeGhostScans = true, bool useServerTime = true)
{
DateTimeOffset? filterMaxDate = null;
if (maxScanDate.HasValue)
filterMaxDate = useServerTime ? new DateTimeOffset(maxScanDate.Value, ServerDateTimeOffSet) : new DateTimeOffset(maxScanDate.Value);

DateTimeOffset? filterMinDate = null;
if (minScanDate.HasValue)
filterMinDate = useServerTime ? new DateTimeOffset(minScanDate.Value, ServerDateTimeOffSet) : new DateTimeOffset(minScanDate.Value);

return GetODataScans(projectId, finished, scanKind, version, onlyPublic, filterMinDate, filterMaxDate, includeGhostScans);
}

public IEnumerable<Scan> GetODataScans(long projectId, bool finished, ScanRetrieveKind scanKind = ScanRetrieveKind.All, string version = null, bool onlyPublic = false, DateTimeOffset? minScanDateOffset = null, DateTimeOffset? maxScanDateOffset = null, bool includeGhostScans = true)
{
checkConnection();

Expand All @@ -2116,11 +2153,11 @@ public IEnumerable<Scan> GetScans(long projectId, bool finished, ScanRetrieveKin
if (version != null)
scans = scans.Where(x => version.StartsWith(x.ProductVersion));

if (minScanDate != null)
scans = scans.Where(x => x.ScanRequestedOn >= new DateTimeOffset(minScanDate.Value));
if (minScanDateOffset != null)
scans = scans.Where(x => x.ScanRequestedOn >= minScanDateOffset);

if (maxScanDate != null)
scans = scans.Where(x => x.ScanRequestedOn <= new DateTimeOffset(maxScanDate.Value));
if (maxScanDateOffset != null)
scans = scans.Where(x => x.ScanRequestedOn <= maxScanDateOffset);

if (!includeGhostScans)
scans = scans.Where(x => !(x.ScanType == 1 && x.EngineFinishedOn == null));
Expand Down Expand Up @@ -2727,24 +2764,22 @@ public long GetPresetQueryId(cxPortalWebService93.CxWSQueryGroup queryGroup, cxP
return query.QueryId;
}

private Dictionary<long, Tuple<cxPortalWebService93.CxWSQueryGroup, cxPortalWebService93.CxWSQuery>> _queryCache = null;

public long GetPresetQueryId(long overrideQueryId)
private Dictionary<long, Tuple<cxPortalWebService93.CxWSQueryGroup, cxPortalWebService93.CxWSQuery>> _queryVersionCache = null;
public long GetPresetQueryId(long queryVersionCode)
{
if (_queryCache == null)
if (_queryVersionCache == null)
{
_queryCache = new Dictionary<long, Tuple<cxPortalWebService93.CxWSQueryGroup, cxPortalWebService93.CxWSQuery>>();

foreach (var queryGroup in QueryGroups)
_queryVersionCache = new Dictionary<long, Tuple<cxPortalWebService93.CxWSQueryGroup, cxPortalWebService93.CxWSQuery>>();
foreach (var queryGroup in QueryGroupsByVersion)
{
foreach (var query in queryGroup.Queries)
{
_queryCache.Add(query.QueryId, new Tuple<cxPortalWebService93.CxWSQueryGroup, cxPortalWebService93.CxWSQuery>(queryGroup, query));
_queryVersionCache.Add(query.QueryVersionCode, new Tuple<cxPortalWebService93.CxWSQueryGroup, cxPortalWebService93.CxWSQuery>(queryGroup, query));
}
}
}

var pair = _queryCache[overrideQueryId];
var pair = _queryVersionCache[queryVersionCode];
return GetPresetQueryId(pair.Item1, pair.Item2);
}

Expand Down Expand Up @@ -3011,7 +3046,6 @@ public void AddQueriesToPreset(string presetName, params long[] cxQueryIds)
}

private IEnumerable<dynamic> _queryGroupsCache = null;

public IEnumerable<dynamic> QueryGroups
{
get
Expand All @@ -3038,6 +3072,33 @@ public IEnumerable<dynamic> QueryGroups
}
}

private IEnumerable<dynamic> _queryGroupsByVersionCache = null;
public IEnumerable<dynamic> QueryGroupsByVersion
{
get
{
if (_queryGroupsByVersionCache == null)
{
checkConnection();
dynamic response = null;
if (_isV9)
{
response = _cxPortalWebServiceSoapClientV9
.GetQueryCollectionWithInactiveAsync(_soapSessionId).Result;
}
else
{
response = _cxPortalWebServiceSoapClient
.GetQueryCollectionWithInactiveAsync(_soapSessionId).Result;

}
checkSoapResponse(response);
_queryGroupsByVersionCache = response.QueryGroups;
}
return _queryGroupsByVersionCache;
}
}

public IEnumerable<dynamic> GetProjectLevelQueries(long projectId)
{
if (_isV9)
Expand Down