From c743d67f0d256e0d6b1d5e3d6cdcf73f56a1cb21 Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 23 May 2024 13:59:39 +0530 Subject: [PATCH 01/24] Updating SBOM with hashes MD5,SHA_1,SHA_256 --- src/LCT.Common/CycloneDXBomParser.cs | 41 +++++++++++++++++++- src/LCT.PackageIdentifier/AlpineProcesser.cs | 6 +-- src/LCT.PackageIdentifier/ConanProcessor.cs | 1 + src/LCT.PackageIdentifier/DebianProcessor.cs | 3 +- src/LCT.PackageIdentifier/MavenProcessor.cs | 1 + src/LCT.PackageIdentifier/NpmProcessor.cs | 4 +- src/LCT.PackageIdentifier/NugetProcessor.cs | 4 +- src/LCT.PackageIdentifier/PythonProcessor.cs | 5 ++- 8 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/LCT.Common/CycloneDXBomParser.cs b/src/LCT.Common/CycloneDXBomParser.cs index bd570cce..ced0018c 100644 --- a/src/LCT.Common/CycloneDXBomParser.cs +++ b/src/LCT.Common/CycloneDXBomParser.cs @@ -15,17 +15,21 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Security.Cryptography; +using System.Text; +using static CycloneDX.Models.Component; namespace LCT.Common { public class CycloneDXBomParser : ICycloneDXBomParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public ComponentScope Scope { get; set; } public Bom ParseCycloneDXBom(string filePath) { Bom bom = new Bom(); string json = string.Empty; - Logger.Logger.Log(null, Level.Notice, $"Consuming cyclonedx file data from "+ filePath + "...\n", null); + Logger.Logger.Log(null, Level.Notice, $"Consuming cyclonedx file data from " + filePath + "...\n", null); try { @@ -81,7 +85,7 @@ public static void CheckValidComponentsForProjectType(List bom, strin foreach (var component in bom.ToList()) { if (!string.IsNullOrEmpty(component.Name) && !string.IsNullOrEmpty(component.Version) - && !string.IsNullOrEmpty(component.Purl) && + && !string.IsNullOrEmpty(component.Purl) && component.Purl.Contains(Dataconstant.PurlCheck()[projectType.ToUpper()])) { //Taking Valid Components for perticular projects @@ -94,5 +98,38 @@ public static void CheckValidComponentsForProjectType(List bom, strin } } } + + public void AddComponentHashes(Bom bom) + { + foreach (var component in bom.Components) + { + string input = $"{component.Name}{component.Version}{Scope}{GetType()}"; + component.Hashes = new List + { + new Hash + { + Alg = Hash.HashAlgorithm.MD5, + Content = GetHashForComponent(input, MD5.Create()) + }, + new Hash + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = GetHashForComponent(input, SHA1.Create()) + }, + new Hash + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = GetHashForComponent(input, SHA256.Create()) + } + }; + } + + } + + public static string GetHashForComponent(string input, HashAlgorithm hashAlgorithm) + { + byte[] byteHash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input)); + return Convert.ToHexString(byteHash); + } } } diff --git a/src/LCT.PackageIdentifier/AlpineProcesser.cs b/src/LCT.PackageIdentifier/AlpineProcesser.cs index f9f3da2b..24067023 100644 --- a/src/LCT.PackageIdentifier/AlpineProcesser.cs +++ b/src/LCT.PackageIdentifier/AlpineProcesser.cs @@ -23,11 +23,10 @@ namespace LCT.PackageIdentifier /// /// The AlpineProcessor class /// - public class AlpineProcessor : IParser + public class AlpineProcessor : CycloneDXBomParser, IParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly ICycloneDXBomParser _cycloneDXBomParser; - public AlpineProcessor(ICycloneDXBomParser cycloneDXBomParser) { _cycloneDXBomParser = cycloneDXBomParser; @@ -58,7 +57,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) bom.Components = listComponentForBOM; bom.Dependencies = dependenciesForBOM; - + if (File.Exists(appSettings.CycloneDxSBomTemplatePath) && appSettings.CycloneDxSBomTemplatePath.EndsWith(FileConstant.SBOMTemplateFileExtension)) { Bom templateDetails; @@ -69,6 +68,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) } bom = RemoveExcludedComponents(appSettings, bom); + AddComponentHashes(bom); return bom; } diff --git a/src/LCT.PackageIdentifier/ConanProcessor.cs b/src/LCT.PackageIdentifier/ConanProcessor.cs index 1207dd38..cce2a271 100644 --- a/src/LCT.PackageIdentifier/ConanProcessor.cs +++ b/src/LCT.PackageIdentifier/ConanProcessor.cs @@ -68,6 +68,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) } bom.Components = componentsForBOM; + AddComponentHashes(bom); Logger.Debug($"ParsePackageFile():End"); return bom; } diff --git a/src/LCT.PackageIdentifier/DebianProcessor.cs b/src/LCT.PackageIdentifier/DebianProcessor.cs index b077b442..7f7600eb 100644 --- a/src/LCT.PackageIdentifier/DebianProcessor.cs +++ b/src/LCT.PackageIdentifier/DebianProcessor.cs @@ -25,7 +25,7 @@ namespace LCT.PackageIdentifier /// /// The DebianProcessor class /// - public class DebianProcessor : IParser + public class DebianProcessor : CycloneDXBomParser, IParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly ICycloneDXBomParser _cycloneDXBomParser; @@ -73,6 +73,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) } bom = RemoveExcludedComponents(appSettings, bom); + AddComponentHashes(bom); return bom; } diff --git a/src/LCT.PackageIdentifier/MavenProcessor.cs b/src/LCT.PackageIdentifier/MavenProcessor.cs index 248a7a62..68aa3008 100644 --- a/src/LCT.PackageIdentifier/MavenProcessor.cs +++ b/src/LCT.PackageIdentifier/MavenProcessor.cs @@ -96,6 +96,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) bom.Components = componentsForBOM; bom.Dependencies = dependenciesForBOM; + AddComponentHashes(bom); BomCreator.bomKpiData.ComponentsInComparisonBOM = bom.Components.Count; Logger.Debug($"ParsePackageFile():End"); return bom; diff --git a/src/LCT.PackageIdentifier/NpmProcessor.cs b/src/LCT.PackageIdentifier/NpmProcessor.cs index 7bf74d4d..9b1c9b85 100644 --- a/src/LCT.PackageIdentifier/NpmProcessor.cs +++ b/src/LCT.PackageIdentifier/NpmProcessor.cs @@ -39,7 +39,6 @@ public class NpmProcessor : CycloneDXBomParser, IParser private const string Version = "version"; private const string NotFoundInRepo = "Not Found in JFrogRepo"; private const string Requires = "requires"; - public NpmProcessor(ICycloneDXBomParser cycloneDXBomParser) { _cycloneDXBomParser = cycloneDXBomParser; @@ -68,12 +67,15 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) Logger.Warn($"Component Name : {item.Name}\nComponent Version : {item.Version}\nPackage Found in : {item.Description}\n"); } } + bom.Components = componentsForBOM; bom.Dependencies = dependencies; + AddComponentHashes(bom); Logger.Debug($"ParsePackageFile():End"); return bom; } + public List ParsePackageLockJson(string filepath, CommonAppSettings appSettings) { List bundledComponents = new List(); diff --git a/src/LCT.PackageIdentifier/NugetProcessor.cs b/src/LCT.PackageIdentifier/NugetProcessor.cs index 878697d0..1bc08ac5 100644 --- a/src/LCT.PackageIdentifier/NugetProcessor.cs +++ b/src/LCT.PackageIdentifier/NugetProcessor.cs @@ -27,7 +27,7 @@ namespace LCT.PackageIdentifier { - public class NugetProcessor : IParser + public class NugetProcessor : CycloneDXBomParser, IParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private const string NotFoundInRepo = "Not Found in JFrogRepo"; @@ -49,7 +49,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) var componentsWithMultipleVersions = bom.Components.GroupBy(s => s.Name).Where(g => g.Count() > 1).SelectMany(g => g).ToList(); CheckForMultipleVersions(appSettings, componentsWithMultipleVersions); - + AddComponentHashes(bom); Logger.Debug($"ParsePackageFile():End"); return bom; } diff --git a/src/LCT.PackageIdentifier/PythonProcessor.cs b/src/LCT.PackageIdentifier/PythonProcessor.cs index f1058ce2..ff248e0f 100644 --- a/src/LCT.PackageIdentifier/PythonProcessor.cs +++ b/src/LCT.PackageIdentifier/PythonProcessor.cs @@ -24,8 +24,8 @@ using Component = CycloneDX.Models.Component; namespace LCT.PackageIdentifier -{ - public class PythonProcessor : IParser +{ + public class PythonProcessor : CycloneDXBomParser, IParser { private const string NotFoundInRepo = "Not Found in JFrogRepo"; @@ -76,6 +76,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) //Adding Template Component Details & MetaData SbomTemplate.AddComponentDetails(bom.Components, templateDetails); bom = RemoveExcludedComponents(appSettings, bom); + AddComponentHashes(bom); return bom; } From 32632a1271ccbd984f44cc7b3e0d10428bca36fe Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 23 May 2024 14:14:02 +0530 Subject: [PATCH 02/24] UT update --- src/LCT.Common/CycloneDXBomParser.cs | 2 +- .../CycloneBomProcessorTests.cs | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/LCT.Common/CycloneDXBomParser.cs b/src/LCT.Common/CycloneDXBomParser.cs index ced0018c..4b0b9809 100644 --- a/src/LCT.Common/CycloneDXBomParser.cs +++ b/src/LCT.Common/CycloneDXBomParser.cs @@ -126,7 +126,7 @@ public void AddComponentHashes(Bom bom) } - public static string GetHashForComponent(string input, HashAlgorithm hashAlgorithm) + private static string GetHashForComponent(string input, HashAlgorithm hashAlgorithm) { byte[] byteHash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input)); return Convert.ToHexString(byteHash); diff --git a/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs b/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs index e7a5b757..cce2445e 100644 --- a/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs +++ b/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs @@ -11,6 +11,7 @@ using NUnit.Framework; using System.Collections.Generic; using System.IO; +using System.Security.Cryptography; namespace PackageIdentifier.UTest { @@ -210,5 +211,62 @@ public void ExtractSBOMDetailsFromTemplate_GivenBomTemplateWithoutComponents_Ret Assert.That(0,Is.EqualTo(files.Components.Count), "Returns Zero components in BOM"); } + [Test] + public void AddComponentHashes_ShouldCalculateHashesForAllComponents() + { + // Arrange + var parser = new CycloneDXBomParser(); + var bom = new Bom + { + Components = new List + { + new Component + { + Name = "Component1", + Version = "1.0.0" + }, + new Component + { + Name = "Component2", + Version = "2.0.0" + } + } + }; + + // Act + parser.AddComponentHashes(bom); + + // Assert + Assert.AreEqual(2, bom.Components.Count); + + foreach (var component in bom.Components) + { + Assert.IsNotNull(component.Hashes); + Assert.AreEqual(3, component.Hashes.Count); + + foreach (var hash in component.Hashes) + { + Assert.IsNotNull(hash.Content); + } + } + } + + [Test] + public void GetHashForComponent_ShouldReturnValidHash() + { + // Arrange + + var input = "Component1-1.0.0"; + + // Act + var md5Hash = CycloneDXBomParser.GetHashForComponent(input, MD5.Create()); + var sha1Hash = CycloneDXBomParser.GetHashForComponent(input, SHA1.Create()); + var sha256Hash = CycloneDXBomParser.GetHashForComponent(input, SHA256.Create()); + + // Assert + Assert.IsNotNull(md5Hash); + Assert.IsNotNull(sha1Hash); + Assert.IsNotNull(sha256Hash); + } } } From 042c2cbefded5e2726b8b1b2ec0f17b57647f5bd Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Thu, 23 May 2024 17:37:51 +0530 Subject: [PATCH 03/24] Initial --- .../SW360Apicommunication.cs | 26 +++++- .../ComponentCreator.cs | 6 +- src/LCT.SW360PackageCreator/CreatorHelper.cs | 90 ++++++++++--------- src/LCT.Services/Sw360Service.cs | 10 ++- 4 files changed, 82 insertions(+), 50 deletions(-) diff --git a/src/LCT.APICommunications/SW360Apicommunication.cs b/src/LCT.APICommunications/SW360Apicommunication.cs index 1722e900..05f9681d 100644 --- a/src/LCT.APICommunications/SW360Apicommunication.cs +++ b/src/LCT.APICommunications/SW360Apicommunication.cs @@ -127,12 +127,34 @@ public async Task GetReleases() var result = string.Empty; try { - return await httpClient.GetStringAsync(sw360ReleaseApi); + HttpResponseMessage responseMessage = await httpClient.GetAsync(sw360ReleaseApi); + if (responseMessage != null && responseMessage.StatusCode.Equals(HttpStatusCode.OK)) + { + return await responseMessage.Content.ReadAsStringAsync(); + } + else + { + Logger.Error("Sw360 server failed to fetch releases, StatusCode:" + + responseMessage?.StatusCode +" & ReasonPharse :"+ responseMessage?.ReasonPhrase); + Environment.Exit(-1); + } } catch (TaskCanceledException ex) { Logger.Debug($"{ex.Message}"); - Logger.Error("A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); + Logger.Error("GetReleases():TaskCanceledException:A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); + Environment.Exit(-1); + } + catch (HttpRequestException ex) + { + Logger.Debug($"{ex.Message}"); + Logger.Error("GetReleases():HttpRequestException:A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); + Environment.Exit(-1); + } + catch (InvalidOperationException ex) + { + Logger.Debug($"{ex.Message}"); + Logger.Error("GetReleases():InvalidOperationException:A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); Environment.Exit(-1); } return result; diff --git a/src/LCT.SW360PackageCreator/ComponentCreator.cs b/src/LCT.SW360PackageCreator/ComponentCreator.cs index 44ad18a0..b24f3332 100644 --- a/src/LCT.SW360PackageCreator/ComponentCreator.cs +++ b/src/LCT.SW360PackageCreator/ComponentCreator.cs @@ -86,7 +86,7 @@ private async Task> GetListOfBomData(List components Components component = await GetSourceUrl(componentsData.Name, componentsData.Version, componentsData.ProjectType, item.BomRef); componentsData.SourceUrl = component.SourceUrl; - + if (componentsData.ProjectType.ToUpperInvariant() == "ALPINE") { componentsData.AlpineSourceData = component.AlpineSourceData; @@ -202,7 +202,7 @@ private static async Task GetSourceUrl(string name, string version, componentsData.SourceUrl = await UrlHelper.Instance.GetSourceUrlForConanPackage(name, version); break; case "ALPINE": - Components alpComponentData = await UrlHelper.Instance.GetSourceUrlForAlpinePackage(name, version,bomRef); + Components alpComponentData = await UrlHelper.Instance.GetSourceUrlForAlpinePackage(name, version, bomRef); componentsData = alpComponentData; componentsData.ProjectType = projectType; break; @@ -276,7 +276,7 @@ private async Task CreateComponent(ICreatorHelper creatorHelper, await CreateComponentAndRealease(creatorHelper, sw360CreatorService, item, sw360Url, appSettings); } - if (appSettings.ProjectType.ToUpperInvariant()=="ALPINE") + if (appSettings.ProjectType.ToUpperInvariant() == "ALPINE") { string localPathforSourceRepo = UrlHelper.GetDownloadPathForAlpineRepo(); if (Directory.GetDirectories(localPathforSourceRepo).Length != 0) diff --git a/src/LCT.SW360PackageCreator/CreatorHelper.cs b/src/LCT.SW360PackageCreator/CreatorHelper.cs index 7ab2c659..7a65e365 100644 --- a/src/LCT.SW360PackageCreator/CreatorHelper.cs +++ b/src/LCT.SW360PackageCreator/CreatorHelper.cs @@ -205,53 +205,57 @@ public async Task> SetContentsForComparisonBOM(List 0) + { + ComparisonBomData mapper; + foreach (Components item in lstComponentForBOM) { - if ((string.IsNullOrEmpty(item.SourceUrl) || item.SourceUrl == Dataconstant.SourceUrlNotFound) && !string.IsNullOrEmpty(releasesInfo.SourceCodeDownloadUrl)) + mapper = new ComparisonBomData(); + ReleasesInfo releasesInfo = await GetReleaseInfoFromSw360(item, componentsAvailableInSw360, sw360Service); + IRepository repo = new Repository(); + + mapper.Name = item.Name; + mapper.Group = item.Group; + mapper.Version = item.Version; + mapper.ComponentExternalId = item.ComponentExternalId; + mapper.ReleaseExternalId = item.ReleaseExternalId; + mapper.SourceUrl = item.SourceUrl; + mapper.DownloadUrl = item.DownloadUrl; + mapper.ComponentStatus = GetComponentAvailabilityStatus(componentsAvailableInSw360, item); + mapper.ReleaseStatus = IsReleaseAvailable(item.Name, item.Version, item.ReleaseExternalId); + mapper.AlpineSource = item.AlpineSourceData; + if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["DEBIAN"])) { - // If not able to get source details from snapshot.org, try getting source URL from SW360 - mapper.SourceUrl = releasesInfo.SourceCodeDownloadUrl; - mapper.DownloadUrl = releasesInfo.SourceCodeDownloadUrl; + if ((string.IsNullOrEmpty(item.SourceUrl) || item.SourceUrl == Dataconstant.SourceUrlNotFound) && !string.IsNullOrEmpty(releasesInfo.SourceCodeDownloadUrl)) + { + // If not able to get source details from snapshot.org, try getting source URL from SW360 + mapper.SourceUrl = releasesInfo.SourceCodeDownloadUrl; + mapper.DownloadUrl = releasesInfo.SourceCodeDownloadUrl; + } + mapper.PatchURls = item.PatchURLs; } - mapper.PatchURls = item.PatchURLs; - } - else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["MAVEN"])) - { - mapper.DownloadUrl = GetMavenDownloadUrl(mapper, item, releasesInfo); - } - else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && - (item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["PYTHON"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["CONAN"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["ALPINE"]))) - { - mapper.DownloadUrl = mapper.SourceUrl; - } - else - { - mapper.DownloadUrl = GetComponentDownloadUrl(mapper, item, repo, releasesInfo); + else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["MAVEN"])) + { + mapper.DownloadUrl = GetMavenDownloadUrl(mapper, item, releasesInfo); + } + else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && + (item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["PYTHON"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["CONAN"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["ALPINE"]))) + { + mapper.DownloadUrl = mapper.SourceUrl; + } + else + { + mapper.DownloadUrl = GetComponentDownloadUrl(mapper, item, repo, releasesInfo); + } + mapper.ApprovedStatus = GetApprovedStatus(mapper.ComponentStatus, mapper.ReleaseStatus, releasesInfo); + mapper.IsComponentCreated = GetCreatedStatus(mapper.ComponentStatus); + mapper.IsReleaseCreated = GetCreatedStatus(mapper.ReleaseStatus); + mapper.FossologyUploadStatus = GetFossologyUploadStatus(mapper.ApprovedStatus); + mapper.ReleaseAttachmentLink = string.Empty; + mapper.ReleaseLink = GetReleaseLink(componentsAvailableInSw360, item.Name, item.Version); + comparisonBomData.Add(mapper); } - mapper.ApprovedStatus = GetApprovedStatus(mapper.ComponentStatus, mapper.ReleaseStatus, releasesInfo); - mapper.IsComponentCreated = GetCreatedStatus(mapper.ComponentStatus); - mapper.IsReleaseCreated = GetCreatedStatus(mapper.ReleaseStatus); - mapper.FossologyUploadStatus = GetFossologyUploadStatus(mapper.ApprovedStatus); - mapper.ReleaseAttachmentLink = string.Empty; - mapper.ReleaseLink = GetReleaseLink(componentsAvailableInSw360, item.Name, item.Version); - comparisonBomData.Add(mapper); } Logger.Debug($"SetContentsForComparisonBOM():End"); diff --git a/src/LCT.Services/Sw360Service.cs b/src/LCT.Services/Sw360Service.cs index e230d07e..91eddb9b 100644 --- a/src/LCT.Services/Sw360Service.cs +++ b/src/LCT.Services/Sw360Service.cs @@ -61,7 +61,8 @@ public async Task> GetAvailableReleasesInSw360(List string responseBody = await m_SW360ApiCommunicationFacade.GetReleases(); if (string.IsNullOrWhiteSpace(responseBody)) { - Logger.Warn("Available release list found empty from the SW360 Server!"); + Logger.Error("GetAvailableReleasesInSw360(): Release list from the SW360 Server found empty!!"); + Environment.Exit(-1); } Sw360ServiceStopWatch.Stop(); @@ -70,10 +71,15 @@ public async Task> GetAvailableReleasesInSw360(List var modelMappedObject = JsonConvert.DeserializeObject(responseBody); - if (modelMappedObject != null) + if (modelMappedObject != null && modelMappedObject.Embedded?.Sw360Releases.Count > 0) { availableComponentsList = await GetAvailableComponenentsList(modelMappedObject.Embedded?.Sw360Releases, listOfComponentsToBom); } + else + { + Logger.Error("Releases list found empty from the SW360 Server!!"); + Environment.Exit(-1); + } } catch (HttpRequestException ex) { From cdb574f2a8633943b1c9e2454946b638962122e1 Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Fri, 24 May 2024 17:27:06 +0530 Subject: [PATCH 04/24] Duplicate check --- src/LCT.Services/Sw360CreatorService.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/LCT.Services/Sw360CreatorService.cs b/src/LCT.Services/Sw360CreatorService.cs index 7d642184..7def038d 100644 --- a/src/LCT.Services/Sw360CreatorService.cs +++ b/src/LCT.Services/Sw360CreatorService.cs @@ -117,7 +117,7 @@ public async Task TriggerFossologyProcess(string releaseId, s } catch (HttpRequestException ex) { - ExceptionHandling.FossologyException(ex); + ExceptionHandling.FossologyException(ex); } @@ -270,13 +270,30 @@ public async Task LinkReleasesToProject(List releasesTobeLi var finalReleasesToBeLinked = manuallyLinkedReleases.Concat(releasesTobeLinked).Distinct().ToList(); Logger.Debug($"No of release Id's to link - {finalReleasesToBeLinked.Count}"); + Dictionary linkedReleasesUniqueDict = new Dictionary(); + foreach (var release in finalReleasesToBeLinked) + { + if (!linkedReleasesUniqueDict.ContainsKey(release.ReleaseId)) + { + linkedReleasesUniqueDict.Add(release.ReleaseId, release); + } + else + { + Logger.Warn("Duplicate entries found in finalReleasesToBeLinked: " + release.Name + ":" + release.ReleaseId + + " , with :" + linkedReleasesUniqueDict[release.ReleaseId].Name + ":" + linkedReleasesUniqueDict[release.ReleaseId].ReleaseId); + } + } + + // Assigning unique entries + finalReleasesToBeLinked = linkedReleasesUniqueDict.Values.ToList(); + Dictionary linkedReleasesDict = new Dictionary(); linkedReleasesDict = finalReleasesToBeLinked? .ToDictionary( releaseLinked => releaseLinked.ReleaseId, releaseLinked => new AddLinkedRelease() { - ReleaseRelation = string.IsNullOrEmpty(releaseLinked.Relation) ? Dataconstant.LinkedByCAToolReleaseRelation + ReleaseRelation = string.IsNullOrEmpty(releaseLinked.Relation) ? Dataconstant.LinkedByCAToolReleaseRelation : releaseLinked.Relation, Comment = manuallyLinkedReleases.Any(r => r.ReleaseId == releaseLinked.ReleaseId) ? releaseLinked.Comment : Dataconstant.LinkedByCATool }); From 03f5a70b171fcfae1b034fd92af02136aef99709 Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Fri, 24 May 2024 17:30:28 +0530 Subject: [PATCH 05/24] Unique entries --- src/LCT.Services/Sw360CreatorService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LCT.Services/Sw360CreatorService.cs b/src/LCT.Services/Sw360CreatorService.cs index 7def038d..a7251e7f 100644 --- a/src/LCT.Services/Sw360CreatorService.cs +++ b/src/LCT.Services/Sw360CreatorService.cs @@ -284,7 +284,7 @@ public async Task LinkReleasesToProject(List releasesTobeLi } } - // Assigning unique entries + // Assigning unique entries from the Dict finalReleasesToBeLinked = linkedReleasesUniqueDict.Values.ToList(); Dictionary linkedReleasesDict = new Dictionary(); From 14b6714d85f4da1a87aaedb72a7e6605b47ea200 Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Mon, 27 May 2024 14:29:41 +0530 Subject: [PATCH 06/24] UT Added --- .../CreatorHelperTest.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs b/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs index 4b54c79a..8af81103 100644 --- a/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs +++ b/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs @@ -19,6 +19,10 @@ using System.Diagnostics; using LCT.Common; using Castle.Core.Internal; +using LCT.Facade.Interfaces; +using System.Net.Http; +using System.Net; +using System.Text; namespace SW360ComponentCreator.UTest { @@ -169,6 +173,54 @@ public async Task SetContentsForComparisonBOM_ProvidedValidBomDetails_ReturnsLis Assert.That(data.Count > 0); } + [Test] + public async Task SetContentsForComparisonBOM_ProvidedValidBomDetailsWithSw360InvalidCred_ReturnsEmpty() + { + //Arrange + var debianPatcher = new Mock(); + IDictionary _packageDownloderList = new Dictionary + { + { "DEBIAN", new DebianPackageDownloader(debianPatcher.Object) } + }; + var creatorHelper = new CreatorHelper(_packageDownloderList); + + ReleasesInfo releasesInfo = new ReleasesInfo(); + releasesInfo.SourceCodeDownloadUrl = "https://snapshot.debian.org/archive/debian/20180915T211528Z/pool/main/a/adduser/adduser_3.118.tar.xz"; + + List componentsAvailableInSw360 = new List(); + List comparisonBomData = new List + { + new Components() + { + Name = "adduser", + Version = "3.118", + ComponentExternalId = "pkg:deb/debian/adduser?arch=source", + ReleaseExternalId = "pkg:deb/debian/adduser@3.118?arch=source", + SourceUrl = "https://snapshot.debian.org/archive/debian/20180915T211528Z/pool/main/a/adduser/adduser_3.118.tar.xz", + DownloadUrl = "https://snapshot.debian.org/archive/debian/20180915T211528Z/pool/main/a/adduser/adduser_3.118.tar.xz" + } + }; + var iSW360Service = new Mock(); + + //Mocking the Sw360 result as Empty with SuccessCode + HttpResponseMessage responseMessage = new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent("", Encoding.UTF8) + }; + var iSW360ApicommunicationFacade = new Mock(); + iSW360ApicommunicationFacade.Setup(x => x.GetReleases()).ReturnsAsync(await responseMessage.Content.ReadAsStringAsync()); + + iSW360Service.Setup(x => x.GetAvailableReleasesInSw360(comparisonBomData)).ReturnsAsync(componentsAvailableInSw360); + iSW360Service.Setup(x => x.GetReleaseDataOfComponent(comparisonBomData[0].ReleaseLink)).ReturnsAsync(releasesInfo); + + //Act + var data = await creatorHelper.SetContentsForComparisonBOM(comparisonBomData, iSW360Service.Object); + + //Assert + Assert.That(data.Count.Equals(0)); + } + [Test] public async Task GetUpdatedComponentsDetails_ProvidedValidBomDetails_ReturnsUpdatedBom() { From afa468c136b87d8b73cac0c95842c62c78c08ed9 Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Mon, 27 May 2024 14:35:00 +0530 Subject: [PATCH 07/24] UT Added --- src/LCT.SW360PackageCreator.UTest/ComponentCreatorTest.cs | 1 - src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs | 1 - src/LCT.Services/Sw360CreatorService.cs | 2 -- 3 files changed, 4 deletions(-) diff --git a/src/LCT.SW360PackageCreator.UTest/ComponentCreatorTest.cs b/src/LCT.SW360PackageCreator.UTest/ComponentCreatorTest.cs index 375dbd81..3f39eb8b 100644 --- a/src/LCT.SW360PackageCreator.UTest/ComponentCreatorTest.cs +++ b/src/LCT.SW360PackageCreator.UTest/ComponentCreatorTest.cs @@ -234,7 +234,6 @@ public async Task CycloneDxBomParser_PassingFilePath_ReturnsSuccess() Assert.That(list.Count > 0); } - [Test] public async Task CycloneDxBomParser_PassingFilePath_ReturnsComponentsExcludingDev() { diff --git a/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs b/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs index 8af81103..141d1823 100644 --- a/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs +++ b/src/LCT.SW360PackageCreator.UTest/CreatorHelperTest.cs @@ -210,7 +210,6 @@ public async Task SetContentsForComparisonBOM_ProvidedValidBomDetailsWithSw360In }; var iSW360ApicommunicationFacade = new Mock(); iSW360ApicommunicationFacade.Setup(x => x.GetReleases()).ReturnsAsync(await responseMessage.Content.ReadAsStringAsync()); - iSW360Service.Setup(x => x.GetAvailableReleasesInSw360(comparisonBomData)).ReturnsAsync(componentsAvailableInSw360); iSW360Service.Setup(x => x.GetReleaseDataOfComponent(comparisonBomData[0].ReleaseLink)).ReturnsAsync(releasesInfo); diff --git a/src/LCT.Services/Sw360CreatorService.cs b/src/LCT.Services/Sw360CreatorService.cs index a7251e7f..927ce70f 100644 --- a/src/LCT.Services/Sw360CreatorService.cs +++ b/src/LCT.Services/Sw360CreatorService.cs @@ -110,9 +110,7 @@ public async Task TriggerFossologyProcess(string releaseId, s FossTriggerStatus fossTriggerStatus = null; try { - string triggerStatus = await m_SW360ApiCommunicationFacade.TriggerFossologyProcess(releaseId, sw360link); - fossTriggerStatus = JsonConvert.DeserializeObject(triggerStatus); } catch (HttpRequestException ex) From dc255082c07b04038d04b4f716e2c132d7a55bbf Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Tue, 28 May 2024 09:32:20 +0530 Subject: [PATCH 08/24] Sonar Issues fixed --- src/LCT.PackageIdentifier/NpmProcessor.cs | 8 +- src/LCT.SW360PackageCreator/CreatorHelper.cs | 102 +++++++++--------- .../PackageDownloader.cs | 2 +- src/LCT.Services/Sw360CreatorService.cs | 6 +- 4 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/LCT.PackageIdentifier/NpmProcessor.cs b/src/LCT.PackageIdentifier/NpmProcessor.cs index 7bf74d4d..2479a7aa 100644 --- a/src/LCT.PackageIdentifier/NpmProcessor.cs +++ b/src/LCT.PackageIdentifier/NpmProcessor.cs @@ -74,7 +74,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) return bom; } - public List ParsePackageLockJson(string filepath, CommonAppSettings appSettings) + public static List ParsePackageLockJson(string filepath, CommonAppSettings appSettings) { List bundledComponents = new List(); List lstComponentForBOM = new List(); @@ -247,7 +247,7 @@ private static void GetComponentsForBom(string filepath, CommonAppSettings appSe components.Description = folderPath; components.Version = Convert.ToString(properties[Version]); - components.Author = prop?.Value[Requires]?.ToString(); + components.Author = prop.Value[Requires]?.ToString(); components.Purl = $"{ApiConstant.NPMExternalID}{componentName}@{components.Version}"; components.BomRef = $"{ApiConstant.NPMExternalID}{componentName}@{components.Version}"; components.Properties = new List(); @@ -399,7 +399,7 @@ public static void GetdependencyDetails(List componentsForBOM, List subDependencies = new(); - foreach (var item in (component?.Author?.Split(",")).Where(item => item.Contains(':'))) + foreach (var item in (component.Author?.Split(",")).Where(item => item.Contains(':'))) { var componentDetails = item.Split(":"); var name = StringFormat(componentDetails[0]); @@ -540,7 +540,7 @@ private static List GetExcludedComponentsList(List compone else { BomCreator.bomKpiData.ComponentsExcluded++; - Logger.Debug($"GetExcludedComponentsList():InvalidComponent For NPM : Component Details : {componentsInfo?.Name} @ {componentsInfo?.Version} @ {componentsInfo?.Purl}"); + Logger.Debug($"GetExcludedComponentsList():InvalidComponent For NPM : Component Details : {componentsInfo.Name} @ {componentsInfo.Version} @ {componentsInfo.Purl}"); } } return components; diff --git a/src/LCT.SW360PackageCreator/CreatorHelper.cs b/src/LCT.SW360PackageCreator/CreatorHelper.cs index 7a65e365..dcb4a18a 100644 --- a/src/LCT.SW360PackageCreator/CreatorHelper.cs +++ b/src/LCT.SW360PackageCreator/CreatorHelper.cs @@ -208,60 +208,66 @@ public async Task> SetContentsForComparisonBOM(List 0) { - ComparisonBomData mapper; - foreach (Components item in lstComponentForBOM) - { - mapper = new ComparisonBomData(); - ReleasesInfo releasesInfo = await GetReleaseInfoFromSw360(item, componentsAvailableInSw360, sw360Service); - IRepository repo = new Repository(); - - mapper.Name = item.Name; - mapper.Group = item.Group; - mapper.Version = item.Version; - mapper.ComponentExternalId = item.ComponentExternalId; - mapper.ReleaseExternalId = item.ReleaseExternalId; - mapper.SourceUrl = item.SourceUrl; - mapper.DownloadUrl = item.DownloadUrl; - mapper.ComponentStatus = GetComponentAvailabilityStatus(componentsAvailableInSw360, item); - mapper.ReleaseStatus = IsReleaseAvailable(item.Name, item.Version, item.ReleaseExternalId); - mapper.AlpineSource = item.AlpineSourceData; - if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["DEBIAN"])) - { - if ((string.IsNullOrEmpty(item.SourceUrl) || item.SourceUrl == Dataconstant.SourceUrlNotFound) && !string.IsNullOrEmpty(releasesInfo.SourceCodeDownloadUrl)) - { - // If not able to get source details from snapshot.org, try getting source URL from SW360 - mapper.SourceUrl = releasesInfo.SourceCodeDownloadUrl; - mapper.DownloadUrl = releasesInfo.SourceCodeDownloadUrl; - } - mapper.PatchURls = item.PatchURLs; - } - else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["MAVEN"])) - { - mapper.DownloadUrl = GetMavenDownloadUrl(mapper, item, releasesInfo); - } - else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && - (item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["PYTHON"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["CONAN"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["ALPINE"]))) - { - mapper.DownloadUrl = mapper.SourceUrl; - } - else - { - mapper.DownloadUrl = GetComponentDownloadUrl(mapper, item, repo, releasesInfo); - } - mapper.ApprovedStatus = GetApprovedStatus(mapper.ComponentStatus, mapper.ReleaseStatus, releasesInfo); - mapper.IsComponentCreated = GetCreatedStatus(mapper.ComponentStatus); - mapper.IsReleaseCreated = GetCreatedStatus(mapper.ReleaseStatus); - mapper.FossologyUploadStatus = GetFossologyUploadStatus(mapper.ApprovedStatus); - mapper.ReleaseAttachmentLink = string.Empty; - mapper.ReleaseLink = GetReleaseLink(componentsAvailableInSw360, item.Name, item.Version); - comparisonBomData.Add(mapper); - } + comparisonBomData.Add(await GetComparisionBomItems(lstComponentForBOM, sw360Service)); } Logger.Debug($"SetContentsForComparisonBOM():End"); return comparisonBomData; } + private async Task GetComparisionBomItems(List lstComponentForBOM, ISW360Service sw360Service) + { + ComparisonBomData mapper; + mapper = new ComparisonBomData(); + foreach (Components item in lstComponentForBOM) + { + ReleasesInfo releasesInfo = await GetReleaseInfoFromSw360(item, componentsAvailableInSw360, sw360Service); + IRepository repo = new Repository(); + + mapper.Name = item.Name; + mapper.Group = item.Group; + mapper.Version = item.Version; + mapper.ComponentExternalId = item.ComponentExternalId; + mapper.ReleaseExternalId = item.ReleaseExternalId; + mapper.SourceUrl = item.SourceUrl; + mapper.DownloadUrl = item.DownloadUrl; + mapper.ComponentStatus = GetComponentAvailabilityStatus(componentsAvailableInSw360, item); + mapper.ReleaseStatus = IsReleaseAvailable(item.Name, item.Version, item.ReleaseExternalId); + mapper.AlpineSource = item.AlpineSourceData; + if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["DEBIAN"])) + { + if ((string.IsNullOrEmpty(item.SourceUrl) || item.SourceUrl == Dataconstant.SourceUrlNotFound) && !string.IsNullOrEmpty(releasesInfo.SourceCodeDownloadUrl)) + { + // If not able to get source details from snapshot.org, try getting source URL from SW360 + mapper.SourceUrl = releasesInfo.SourceCodeDownloadUrl; + mapper.DownloadUrl = releasesInfo.SourceCodeDownloadUrl; + } + mapper.PatchURls = item.PatchURLs; + } + else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["MAVEN"])) + { + mapper.DownloadUrl = GetMavenDownloadUrl(mapper, item, releasesInfo); + } + else if (!string.IsNullOrEmpty(item.ReleaseExternalId) && + (item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["PYTHON"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["CONAN"]) || item.ReleaseExternalId.Contains(Dataconstant.PurlCheck()["ALPINE"]))) + { + mapper.DownloadUrl = mapper.SourceUrl; + } + else + { + mapper.DownloadUrl = GetComponentDownloadUrl(mapper, item, repo, releasesInfo); + } + mapper.ApprovedStatus = GetApprovedStatus(mapper.ComponentStatus, mapper.ReleaseStatus, releasesInfo); + mapper.IsComponentCreated = GetCreatedStatus(mapper.ComponentStatus); + mapper.IsReleaseCreated = GetCreatedStatus(mapper.ReleaseStatus); + mapper.FossologyUploadStatus = GetFossologyUploadStatus(mapper.ApprovedStatus); + mapper.ReleaseAttachmentLink = string.Empty; + mapper.ReleaseLink = GetReleaseLink(componentsAvailableInSw360, item.Name, item.Version); + + } + return mapper; + } + private static string GetMavenDownloadUrl(ComparisonBomData mapper, Components item, ReleasesInfo releasesInfo) { string sourceURL = string.Empty; diff --git a/src/LCT.SW360PackageCreator/PackageDownloader.cs b/src/LCT.SW360PackageCreator/PackageDownloader.cs index a37cefae..e06e290b 100644 --- a/src/LCT.SW360PackageCreator/PackageDownloader.cs +++ b/src/LCT.SW360PackageCreator/PackageDownloader.cs @@ -145,7 +145,7 @@ private static Result ListTagsOfComponent(ComparisonBomData component) const int timeOutMs = 200 * 60 * 1000; var processResult = ProcessAsyncHelper.RunAsync(p.StartInfo, timeOutMs); Result result = processResult?.Result ?? new Result(); - Logger.Debug($"GetCorrectVersion:{gitCommand}:{result.ExitCode}, output:{result?.StdOut}, Error:{result.StdErr}"); + Logger.Debug($"GetCorrectVersion:{gitCommand}:{result.ExitCode}, output:{result.StdOut}, Error:{result.StdErr}"); return result; } diff --git a/src/LCT.Services/Sw360CreatorService.cs b/src/LCT.Services/Sw360CreatorService.cs index 927ce70f..4fd58d78 100644 --- a/src/LCT.Services/Sw360CreatorService.cs +++ b/src/LCT.Services/Sw360CreatorService.cs @@ -285,15 +285,15 @@ public async Task LinkReleasesToProject(List releasesTobeLi // Assigning unique entries from the Dict finalReleasesToBeLinked = linkedReleasesUniqueDict.Values.ToList(); - Dictionary linkedReleasesDict = new Dictionary(); - linkedReleasesDict = finalReleasesToBeLinked? + Dictionary linkedReleasesDict; + linkedReleasesDict = finalReleasesToBeLinked .ToDictionary( releaseLinked => releaseLinked.ReleaseId, releaseLinked => new AddLinkedRelease() { ReleaseRelation = string.IsNullOrEmpty(releaseLinked.Relation) ? Dataconstant.LinkedByCAToolReleaseRelation : releaseLinked.Relation, - Comment = manuallyLinkedReleases.Any(r => r.ReleaseId == releaseLinked.ReleaseId) ? releaseLinked.Comment : Dataconstant.LinkedByCATool + Comment = manuallyLinkedReleases.Exists(r => r.ReleaseId == releaseLinked.ReleaseId) ? releaseLinked.Comment : Dataconstant.LinkedByCATool }); StringContent content = new StringContent(JsonConvert.SerializeObject(linkedReleasesDict), Encoding.UTF8, "application/json"); From d8e4f15e931c1bc2e05a9fa974a49c1b0ff0d05c Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Tue, 28 May 2024 10:06:37 +0530 Subject: [PATCH 09/24] Log added --- src/LCT.SW360PackageCreator/CreatorHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/LCT.SW360PackageCreator/CreatorHelper.cs b/src/LCT.SW360PackageCreator/CreatorHelper.cs index dcb4a18a..91379df1 100644 --- a/src/LCT.SW360PackageCreator/CreatorHelper.cs +++ b/src/LCT.SW360PackageCreator/CreatorHelper.cs @@ -263,7 +263,8 @@ private async Task GetComparisionBomItems(List ls mapper.FossologyUploadStatus = GetFossologyUploadStatus(mapper.ApprovedStatus); mapper.ReleaseAttachmentLink = string.Empty; mapper.ReleaseLink = GetReleaseLink(componentsAvailableInSw360, item.Name, item.Version); - + + Logger.Debug($"Sw360 avilability status for Name " + mapper.Name + ":" + mapper.ComponentStatus + "-Version " + mapper.Version + ":" + mapper.ReleaseStatus); } return mapper; } From 5b07e9e8bf9cfb0ac01c64829e35485a3625ff62 Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Tue, 28 May 2024 11:13:09 +0530 Subject: [PATCH 10/24] Review comments --- src/LCT.APICommunications/SW360Apicommunication.cs | 4 ++-- src/LCT.SW360PackageCreator/CreatorHelper.cs | 3 ++- src/LCT.Services/Sw360Service.cs | 9 ++------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/LCT.APICommunications/SW360Apicommunication.cs b/src/LCT.APICommunications/SW360Apicommunication.cs index 05f9681d..23d8188d 100644 --- a/src/LCT.APICommunications/SW360Apicommunication.cs +++ b/src/LCT.APICommunications/SW360Apicommunication.cs @@ -134,8 +134,8 @@ public async Task GetReleases() } else { - Logger.Error("Sw360 server failed to fetch releases, StatusCode:" - + responseMessage?.StatusCode +" & ReasonPharse :"+ responseMessage?.ReasonPhrase); + Logger.Error("SW360 server is not accessible while getting All Releases,Please wait for sometime and re run the pipeline again." + + " StatusCode:" + responseMessage?.StatusCode + " & ReasonPharse :" + responseMessage?.ReasonPhrase); Environment.Exit(-1); } } diff --git a/src/LCT.SW360PackageCreator/CreatorHelper.cs b/src/LCT.SW360PackageCreator/CreatorHelper.cs index 91379df1..6e8d9856 100644 --- a/src/LCT.SW360PackageCreator/CreatorHelper.cs +++ b/src/LCT.SW360PackageCreator/CreatorHelper.cs @@ -264,7 +264,8 @@ private async Task GetComparisionBomItems(List ls mapper.ReleaseAttachmentLink = string.Empty; mapper.ReleaseLink = GetReleaseLink(componentsAvailableInSw360, item.Name, item.Version); - Logger.Debug($"Sw360 avilability status for Name " + mapper.Name + ":" + mapper.ComponentStatus + "-Version " + mapper.Version + ":" + mapper.ReleaseStatus); + Logger.Debug($"Sw360 avilability status for Name " + mapper.Name + ":" + mapper.ComponentExternalId + "=" + mapper.ComponentStatus + + "-Version " + mapper.Version + ":" + mapper.ReleaseExternalId + "=" + mapper.ReleaseStatus); } return mapper; } diff --git a/src/LCT.Services/Sw360Service.cs b/src/LCT.Services/Sw360Service.cs index 91eddb9b..35bb31dd 100644 --- a/src/LCT.Services/Sw360Service.cs +++ b/src/LCT.Services/Sw360Service.cs @@ -59,12 +59,6 @@ public async Task> GetAvailableReleasesInSw360(List { Sw360ServiceStopWatch.Start(); string responseBody = await m_SW360ApiCommunicationFacade.GetReleases(); - if (string.IsNullOrWhiteSpace(responseBody)) - { - Logger.Error("GetAvailableReleasesInSw360(): Release list from the SW360 Server found empty!!"); - Environment.Exit(-1); - } - Sw360ServiceStopWatch.Stop(); Logger.Debug($"GetAvailableReleasesInSw360():Time taken to in GetReleases() call" + $"-{TimeSpan.FromMilliseconds(Sw360ServiceStopWatch.ElapsedMilliseconds).TotalSeconds}"); @@ -77,7 +71,8 @@ public async Task> GetAvailableReleasesInSw360(List } else { - Logger.Error("Releases list found empty from the SW360 Server!!"); + Logger.Debug("GetAvailableReleasesInSw360() : Releases list found empty from the SW360 Server !!"); + Logger.Error("SW360 server is not accessible while getting All Releases,Please wait for sometime and re run the pipeline again"); Environment.Exit(-1); } } From bb764bc5c6ef8602626ab7db3b6f4db9f80f6af4 Mon Sep 17 00:00:00 2001 From: sumanthkb44 <84563853+sumanthkb44@users.noreply.github.com> Date: Tue, 28 May 2024 16:32:53 +0530 Subject: [PATCH 11/24] Update CreatorHelper.cs --- src/LCT.SW360PackageCreator/CreatorHelper.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/LCT.SW360PackageCreator/CreatorHelper.cs b/src/LCT.SW360PackageCreator/CreatorHelper.cs index 6e8d9856..3f96207e 100644 --- a/src/LCT.SW360PackageCreator/CreatorHelper.cs +++ b/src/LCT.SW360PackageCreator/CreatorHelper.cs @@ -198,6 +198,7 @@ private static async Task GetAttachmentUrlList(ComparisonBomData compone return downloadPath; } + public async Task> SetContentsForComparisonBOM(List lstComponentForBOM, ISW360Service sw360Service) { Logger.Debug($"SetContentsForComparisonBOM():Start"); @@ -205,22 +206,23 @@ public async Task> SetContentsForComparisonBOM(List 0) { - comparisonBomData.Add(await GetComparisionBomItems(lstComponentForBOM, sw360Service)); + comparisonBomData = await GetComparisionBomItems(lstComponentForBOM, sw360Service); } Logger.Debug($"SetContentsForComparisonBOM():End"); return comparisonBomData; } - private async Task GetComparisionBomItems(List lstComponentForBOM, ISW360Service sw360Service) + private async Task> GetComparisionBomItems(List lstComponentForBOM, ISW360Service sw360Service) { + List comparisonBomData = new(); ComparisonBomData mapper; - mapper = new ComparisonBomData(); foreach (Components item in lstComponentForBOM) { + mapper = new ComparisonBomData(); ReleasesInfo releasesInfo = await GetReleaseInfoFromSw360(item, componentsAvailableInSw360, sw360Service); IRepository repo = new Repository(); @@ -266,8 +268,9 @@ private async Task GetComparisionBomItems(List ls Logger.Debug($"Sw360 avilability status for Name " + mapper.Name + ":" + mapper.ComponentExternalId + "=" + mapper.ComponentStatus + "-Version " + mapper.Version + ":" + mapper.ReleaseExternalId + "=" + mapper.ReleaseStatus); + comparisonBomData.Add(mapper); } - return mapper; + return comparisonBomData; } private static string GetMavenDownloadUrl(ComparisonBomData mapper, Components item, ReleasesInfo releasesInfo) From a1b414cd08675a2d3940eece21b8bee3c97c94bd Mon Sep 17 00:00:00 2001 From: Chalapala RaghavendraReddy Date: Wed, 29 May 2024 11:34:14 +0530 Subject: [PATCH 12/24] Added new Metadata tools and component name,version and type --- src/LCT.Common/FileOperations.cs | 11 +++-- .../BomValidatorUnitTests.cs | 13 +++--- .../CycloneBomProcessorTests.cs | 43 +++++++++++++++---- src/LCT.PackageIdentifier/BomCreator.cs | 6 ++- src/LCT.PackageIdentifier/BomValidator.cs | 5 ++- .../CycloneBomProcessor.cs | 31 +++++++++++-- .../Interface/IBomCreator.cs | 3 +- src/LCT.PackageIdentifier/Program.cs | 10 ++--- .../CreatorValidatorTest.cs | 13 +++--- .../CreatorValidator.cs | 5 ++- src/LCT.SW360PackageCreator/Program.cs | 4 +- .../Sw360ProjectServiceTest.cs | 12 +++--- src/LCT.Services.UTest/Sw360ServiceTest.cs | 2 +- .../Interface/ISw360ProjectService.cs | 2 +- src/LCT.Services/Sw360ProjectService.cs | 4 +- 15 files changed, 117 insertions(+), 47 deletions(-) diff --git a/src/LCT.Common/FileOperations.cs b/src/LCT.Common/FileOperations.cs index 3ec79012..7644e247 100644 --- a/src/LCT.Common/FileOperations.cs +++ b/src/LCT.Common/FileOperations.cs @@ -7,6 +7,7 @@ using CycloneDX.Models; using LCT.Common.Interface; using log4net; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -14,6 +15,9 @@ using System.Linq; using System.Reflection; using System.Security; +using System.Text.Json.Serialization; +using System.Text.Json; +using Newtonsoft.Json.Converters; namespace LCT.Common { @@ -49,10 +53,9 @@ public void ValidateFilePath(string filePath) public string WriteContentToFile(T dataToWrite, string folderPath, string fileNameWithExtension, string projectName) { try - { - Logger.Debug($"WriteContentToFile():folderpath-{folderPath},fileNameWithExtension-{fileNameWithExtension}," + - $"projectName-{projectName}"); - string jsonString = JsonConvert.SerializeObject(dataToWrite, Formatting.Indented); + { + Logger.Debug($"WriteContentToFile():folderpath-{folderPath},fileNameWithExtension-{fileNameWithExtension}," + $"projectName-{projectName}"); + string jsonString = JsonConvert.SerializeObject(dataToWrite, Formatting.Indented, new StringEnumConverter()); string fileName = $"{projectName}_{fileNameWithExtension}"; string filePath = Path.Combine(folderPath, fileName); diff --git a/src/LCT.PackageIdentifier.UTest/BomValidatorUnitTests.cs b/src/LCT.PackageIdentifier.UTest/BomValidatorUnitTests.cs index da6c7d0b..5ac8cf34 100644 --- a/src/LCT.PackageIdentifier.UTest/BomValidatorUnitTests.cs +++ b/src/LCT.PackageIdentifier.UTest/BomValidatorUnitTests.cs @@ -13,6 +13,7 @@ using System.IO; using System.Threading.Tasks; using LCT.Common; +using LCT.APICommunications.Model; namespace PackageIdentifier.UTest { @@ -28,11 +29,12 @@ public async Task ValidateAppSettings_ProvidedProjectID_ReturnsProjectName() { //Arrange string projectName = "Test"; + ProjectReleases projectReleases = new ProjectReleases(); var CommonAppSettings = new CommonAppSettings(mockIFolderAction.Object) { SW360ProjectName = "Test" }; - mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny())) + mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny(), projectReleases)) .ReturnsAsync(projectName); mockIFileOperations.Setup(x => x.ValidateFilePath(It.IsAny())) @@ -45,10 +47,10 @@ public async Task ValidateAppSettings_ProvidedProjectID_ReturnsProjectName() CommonAppSettings.PackageFilePath = ""; //Act - await BomValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object); + await BomValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object, projectReleases); //Assert - mockISw360ProjectService.Verify(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny()), Times.AtLeastOnce); + mockISw360ProjectService.Verify(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny(), projectReleases), Times.AtLeastOnce); } [TestCase] @@ -56,11 +58,12 @@ public Task ValidateAppSettings_ProvidedProjectID_ReturnsInvalidDataException() { //Arrange string projectName = null; + ProjectReleases projectReleases = new ProjectReleases(); var CommonAppSettings = new CommonAppSettings(mockIFolderAction.Object) { SW360ProjectName = "Test" }; - mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny())) + mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny(),projectReleases)) .ReturnsAsync(projectName); mockIFileOperations.Setup(x => x.ValidateFilePath(It.IsAny())) @@ -72,7 +75,7 @@ public Task ValidateAppSettings_ProvidedProjectID_ReturnsInvalidDataException() .Verifiable(); //Act && Assert - Assert.ThrowsAsync(async () => await BomValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object)); + Assert.ThrowsAsync(async () => await BomValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object, projectReleases)); return Task.CompletedTask; } } diff --git a/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs b/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs index e7a5b757..7e416b17 100644 --- a/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs +++ b/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs @@ -5,9 +5,12 @@ // -------------------------------------------------------------------------------------------------------------------- using CycloneDX.Models; +using LCT.APICommunications.Model; using LCT.Common; using LCT.Common.Constants; +using LCT.Common.Model; using LCT.PackageIdentifier; +using NuGet.ContentModel; using NUnit.Framework; using System.Collections.Generic; using System.IO; @@ -21,6 +24,7 @@ public class CycloneBomProcessorTests public void SetMetadataInComparisonBOM_GivenBOMWithEmptyMetadata_FillsInMetadataInfoInBOM() { //Arrange + ProjectReleases projectReleases = new ProjectReleases(); Bom bom = new Bom() { Metadata = null, @@ -35,23 +39,27 @@ public void SetMetadataInComparisonBOM_GivenBOMWithEmptyMetadata_FillsInMetadata CaVersion = "1.2.3" }; //Act - Bom files = CycloneBomProcessor.SetMetadataInComparisonBOM(bom, appSettings); + Bom files = CycloneBomProcessor.SetMetadataInComparisonBOM(bom, appSettings, projectReleases); //Assert - Assert.That(1, Is.EqualTo(files.Metadata.Tools.Count), "Returns bom with metadata "); + Assert.That(2, Is.EqualTo(files.Metadata.Tools.Count), "Returns bom with metadata "); } [Test] public void SetMetadataInComparisonBOM_GivenBOMWithMetadata_AddsNewMetadataInfoInBOM() { //Arrange + ProjectReleases projectReleases = new ProjectReleases(); + projectReleases.Version= "1.0"; + Bom bom = new Bom() { Metadata = new Metadata() { - Tools = new List(){ - new Tool(){ - Name = "Existing Data",Version = "1.0.",Vendor = "AG"} } + Tools = new List() { + new Tool() { + Name = "Existing Data", Version = "1.0.", Vendor = "AG" } }, + Component = new Component() }, Components = new List() { @@ -61,7 +69,8 @@ public void SetMetadataInComparisonBOM_GivenBOMWithMetadata_AddsNewMetadataInfoI }; CommonAppSettings appSettings = new CommonAppSettings() { - CaVersion = "1.2.3" + CaVersion = "1.2.3", + SW360ProjectName = "Test", }; Tool tools = new Tool() @@ -70,12 +79,28 @@ public void SetMetadataInComparisonBOM_GivenBOMWithMetadata_AddsNewMetadataInfoI Version = "1.0.17", Vendor = "Siemens AG" }; + Tool SiemensSBOM = new Tool + { + Name = "Siemens SBOM", + Version = "2.0.0", + Vendor = "Siemens AG", + }; + Component component = new Component + { + Name = appSettings.SW360ProjectName, + Version = projectReleases.Version, + Type = Component.Classification.Application + }; + //Act - Bom files = CycloneBomProcessor.SetMetadataInComparisonBOM(bom, appSettings); + Bom files = CycloneBomProcessor.SetMetadataInComparisonBOM(bom, appSettings, projectReleases); //Assert - Assert.That(tools.Name, Is.EqualTo(files.Metadata.Tools[1].Name), "Returns bom with metadata "); - + Assert.That(tools.Name, Is.EqualTo(files.Metadata.Tools[1].Name), "Returns bom with metadata tools"); + Assert.That(SiemensSBOM.Name, Is.EqualTo(files.Metadata.Tools[2].Name), "Returns bom with metadata tools"); + Assert.That(component.Name, Is.EqualTo(files.Metadata.Component.Name), "Returns bom with metadata component "); + Assert.That(component.Version, Is.EqualTo(files.Metadata.Component.Version), "Returns bom with metadata component "); + Assert.That(component.Type, Is.EqualTo(files.Metadata.Component.Type), "Returns bom with metadata component "); } [Test] public void SetProperties_GivenComponent_SetsPropertiesInBOM() diff --git a/src/LCT.PackageIdentifier/BomCreator.cs b/src/LCT.PackageIdentifier/BomCreator.cs index db59edd4..83976ca7 100644 --- a/src/LCT.PackageIdentifier/BomCreator.cs +++ b/src/LCT.PackageIdentifier/BomCreator.cs @@ -5,6 +5,7 @@ // -------------------------------------------------------------------------------------------------------------------- using CycloneDX.Models; +using LCT.APICommunications.Model; using LCT.Common; using LCT.Common.Constants; using LCT.Common.Interface; @@ -40,7 +41,7 @@ public BomCreator(ICycloneDXBomParser cycloneDXBomParser) CycloneDXBomParser = cycloneDXBomParser; } - public async Task GenerateBom(CommonAppSettings appSettings, IBomHelper bomHelper, IFileOperations fileOperations) + public async Task GenerateBom(CommonAppSettings appSettings, IBomHelper bomHelper, IFileOperations fileOperations, ProjectReleases projectReleases) { Logger.Debug($"GenerateBom():Start"); Bom listOfComponentsToBom; @@ -51,9 +52,10 @@ public async Task GenerateBom(CommonAppSettings appSettings, IBomHelper bomHelpe $"= {listOfComponentsToBom.Components.Count}", null); bomKpiData.ComponentsInComparisonBOM = listOfComponentsToBom.Components.Count; + //Get project details for metadata properties //sets metadata properties - listOfComponentsToBom = CycloneBomProcessor.SetMetadataInComparisonBOM(listOfComponentsToBom, appSettings); + listOfComponentsToBom = CycloneBomProcessor.SetMetadataInComparisonBOM(listOfComponentsToBom, appSettings,projectReleases); // Writes Comparison Bom Logger.Logger.Log(null, Level.Notice, $"Writing CycloneDX BOM..", null); diff --git a/src/LCT.PackageIdentifier/BomValidator.cs b/src/LCT.PackageIdentifier/BomValidator.cs index 29e69ed9..a4db211a 100644 --- a/src/LCT.PackageIdentifier/BomValidator.cs +++ b/src/LCT.PackageIdentifier/BomValidator.cs @@ -4,6 +4,7 @@ // SPDX-License-Identifier: MIT // -------------------------------------------------------------------------------------------------------------------- +using LCT.APICommunications.Model; using LCT.Common; using LCT.Services.Interface; using System.IO; @@ -16,9 +17,9 @@ namespace LCT.PackageIdentifier /// public static class BomValidator { - public static async Task ValidateAppSettings(CommonAppSettings appSettings, ISw360ProjectService bomService) + public static async Task ValidateAppSettings(CommonAppSettings appSettings, ISw360ProjectService bomService, ProjectReleases projectReleases) { - string sw360ProjectName = await bomService.GetProjectNameByProjectIDFromSW360(appSettings.SW360ProjectID, appSettings.SW360ProjectName); + string sw360ProjectName = await bomService.GetProjectNameByProjectIDFromSW360(appSettings.SW360ProjectID, appSettings.SW360ProjectName,projectReleases); if (string.IsNullOrEmpty(sw360ProjectName)) { diff --git a/src/LCT.PackageIdentifier/CycloneBomProcessor.cs b/src/LCT.PackageIdentifier/CycloneBomProcessor.cs index 10eabdd5..a1ae2558 100644 --- a/src/LCT.PackageIdentifier/CycloneBomProcessor.cs +++ b/src/LCT.PackageIdentifier/CycloneBomProcessor.cs @@ -5,11 +5,14 @@ // -------------------------------------------------------------------------------------------------------------------- using CycloneDX.Models; +using LCT.APICommunications.Model; using LCT.Common; using LCT.Common.Constants; using log4net; +using System; using System.Collections.Generic; using System.Reflection; +using System.Security.Policy; namespace LCT.PackageIdentifier { @@ -18,28 +21,50 @@ public static class CycloneBomProcessor private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public static Bom SetMetadataInComparisonBOM(Bom bom, CommonAppSettings appSettings) + public static Bom SetMetadataInComparisonBOM(Bom bom, CommonAppSettings appSettings, ProjectReleases projectReleases) { Logger.Debug("Starting to add metadata info into the BOM"); List tools = new List(); + List components = new List(); Tool tool = new Tool { Name = "Clearing Automation Tool", Version = appSettings.CaVersion, - Vendor = "Siemens AG" + Vendor = "Siemens AG", + ExternalReferences = new List() { new ExternalReference { Url = "https://github.com/siemens/continuous-clearing", Type = ExternalReference.ExternalReferenceType.Website } } + }; tools.Add(tool); + Tool SiemensSBOM = new Tool + { + Name = "Siemens SBOM", + Version = "2.0.0", + Vendor = "Siemens AG", + ExternalReferences = new List() { new ExternalReference { Url = "https://sbom.siemens.io/", Type = ExternalReference.ExternalReferenceType.Website } } + }; + tools.Add(SiemensSBOM); + Component component = new Component + { + Name = appSettings.SW360ProjectName, + Version = projectReleases.Version, + Type = Component.Classification.Application + }; + components.Add(component); if (bom.Metadata != null) { bom.Metadata.Tools.AddRange(tools); + bom.Metadata.Component.Name = component.Name; + bom.Metadata.Component.Version = component.Version; + bom.Metadata.Component.Type = component.Type; } else { bom.Metadata = new Metadata { - Tools = tools + Tools = tools, + Component = component }; } return bom; diff --git a/src/LCT.PackageIdentifier/Interface/IBomCreator.cs b/src/LCT.PackageIdentifier/Interface/IBomCreator.cs index 014cd55a..bc865d30 100644 --- a/src/LCT.PackageIdentifier/Interface/IBomCreator.cs +++ b/src/LCT.PackageIdentifier/Interface/IBomCreator.cs @@ -4,6 +4,7 @@ // SPDX-License-Identifier: MIT // -------------------------------------------------------------------------------------------------------------------- +using LCT.APICommunications.Model; using LCT.Common; using LCT.Common.Interface; using LCT.Services.Interface; @@ -20,7 +21,7 @@ public interface IBomCreator public IBomHelper BomHelper { get; set; } - public Task GenerateBom(CommonAppSettings appSettings, IBomHelper bomHelper, IFileOperations fileOperations); + public Task GenerateBom(CommonAppSettings appSettings, IBomHelper bomHelper, IFileOperations fileOperations, ProjectReleases projectReleases); public Task CheckJFrogConnection(); } diff --git a/src/LCT.PackageIdentifier/Program.cs b/src/LCT.PackageIdentifier/Program.cs index c74c6f73..24acd76d 100644 --- a/src/LCT.PackageIdentifier/Program.cs +++ b/src/LCT.PackageIdentifier/Program.cs @@ -47,7 +47,7 @@ static async Task Main(string[] args) m_Verbose = true; ISettingsManager settingsManager = new SettingsManager(); CommonAppSettings appSettings = settingsManager.ReadConfiguration(args, FileConstant.appSettingFileName); - + ProjectReleases projectReleases = new ProjectReleases(); string FolderPath = LogFolderInitialisation(appSettings); settingsManager.CheckRequiredArgsToRun(appSettings, "Identifer"); @@ -64,7 +64,7 @@ static async Task Main(string[] args) Logger.Logger.Log(null, Level.Alert, $"Package Identifier is running in TEST mode \n", null); // Validate application settings - await ValidateAppsettingsFile(appSettings); + await ValidateAppsettingsFile(appSettings,projectReleases); Logger.Logger.Log(null, Level.Notice, $"Input Parameters used in Package Identifier:\n\t" + $"PackageFilePath\t\t --> {appSettings.PackageFilePath}\n\t" + @@ -88,7 +88,7 @@ static async Task Main(string[] args) //Validating JFrog Settings if (await bomCreator.CheckJFrogConnection()) { - await bomCreator.GenerateBom(appSettings, new BomHelper(), new FileOperations()); + await bomCreator.GenerateBom(appSettings, new BomHelper(), new FileOperations(),projectReleases); } Logger.Logger.Log(null, Level.Notice, $"End of Package Identifier execution : {DateTime.Now}\n", null); } @@ -107,7 +107,7 @@ private static IJFrogService GetJfrogService(CommonAppSettings appSettings) return jFrogService; } - private static async Task ValidateAppsettingsFile(CommonAppSettings appSettings) + private static async Task ValidateAppsettingsFile(CommonAppSettings appSettings, ProjectReleases projectReleases) { SW360ConnectionSettings sw360ConnectionSettings = new SW360ConnectionSettings() { @@ -118,7 +118,7 @@ private static async Task ValidateAppsettingsFile(CommonAppSettings appSettings) Timeout = appSettings.TimeOut }; ISw360ProjectService sw360ProjectService = new Sw360ProjectService(new SW360ApicommunicationFacade(sw360ConnectionSettings)); - await BomValidator.ValidateAppSettings(appSettings, sw360ProjectService); + await BomValidator.ValidateAppSettings(appSettings, sw360ProjectService,projectReleases); } private static string LogFolderInitialisation(CommonAppSettings appSettings) diff --git a/src/LCT.SW360PackageCreator.UTest/CreatorValidatorTest.cs b/src/LCT.SW360PackageCreator.UTest/CreatorValidatorTest.cs index e00e73a1..d4910e8a 100644 --- a/src/LCT.SW360PackageCreator.UTest/CreatorValidatorTest.cs +++ b/src/LCT.SW360PackageCreator.UTest/CreatorValidatorTest.cs @@ -12,6 +12,7 @@ using System.IO; using LCT.Common; using System.Threading.Tasks; +using LCT.APICommunications.Model; namespace SW360ComponentCreator.UTest { @@ -29,16 +30,17 @@ public async Task ValidateAppSettings_TestPositive() { //Arrange string projectName = "Test"; + ProjectReleases projectReleases=new ProjectReleases(); var CommonAppSettings = new CommonAppSettings(); CommonAppSettings.SW360ProjectName = "Test"; - mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny())) + mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny(), projectReleases)) .ReturnsAsync(projectName); //Act - await CreatorValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object); + await CreatorValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object,projectReleases); //Assert - mockISw360ProjectService.Verify(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny()), Times.AtLeastOnce); + mockISw360ProjectService.Verify(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny(), projectReleases), Times.AtLeastOnce); } [TestCase] @@ -46,14 +48,15 @@ public void ValidateAppSettings_TestNegative() { //Arrange string projectName = null; + ProjectReleases projectReleases = new ProjectReleases(); var CommonAppSettings = new CommonAppSettings(); - mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny())) + mockISw360ProjectService.Setup(x => x.GetProjectNameByProjectIDFromSW360(It.IsAny(), It.IsAny(),projectReleases)) .ReturnsAsync(projectName); //Act //Assert - Assert.ThrowsAsync(() => CreatorValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object)); + Assert.ThrowsAsync(() => CreatorValidator.ValidateAppSettings(CommonAppSettings, mockISw360ProjectService.Object, projectReleases)); } diff --git a/src/LCT.SW360PackageCreator/CreatorValidator.cs b/src/LCT.SW360PackageCreator/CreatorValidator.cs index 007fe567..707b2391 100644 --- a/src/LCT.SW360PackageCreator/CreatorValidator.cs +++ b/src/LCT.SW360PackageCreator/CreatorValidator.cs @@ -8,6 +8,7 @@ using System.IO; using System.Threading.Tasks; using LCT.Common; +using LCT.APICommunications.Model; namespace LCT.SW360PackageCreator @@ -17,9 +18,9 @@ namespace LCT.SW360PackageCreator /// public static class CreatorValidator { - public static async Task ValidateAppSettings(CommonAppSettings appSettings, ISw360ProjectService sw360ProjectService) + public static async Task ValidateAppSettings(CommonAppSettings appSettings, ISw360ProjectService sw360ProjectService, ProjectReleases projectReleases) { - string sw360ProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360(appSettings.SW360ProjectID, appSettings.SW360ProjectName); + string sw360ProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360(appSettings.SW360ProjectID, appSettings.SW360ProjectName,projectReleases); if (string.IsNullOrEmpty(sw360ProjectName)) { diff --git a/src/LCT.SW360PackageCreator/Program.cs b/src/LCT.SW360PackageCreator/Program.cs index 82102429..3d3f84a4 100644 --- a/src/LCT.SW360PackageCreator/Program.cs +++ b/src/LCT.SW360PackageCreator/Program.cs @@ -4,6 +4,7 @@ // SPDX-License-Identifier: MIT // -------------------------------------------------------------------------------------------------------------------- +using LCT.APICommunications.Model; using LCT.Common; using LCT.Common.Constants; using LCT.Common.Interface; @@ -48,10 +49,11 @@ static async Task Main(string[] args) CommonAppSettings appSettings = settingsManager.ReadConfiguration(args, FileConstant.appSettingFileName); ISW360ApicommunicationFacade sW360ApicommunicationFacade; ISw360ProjectService sw360ProjectService= Getsw360ProjectServiceObject(appSettings, out sW360ApicommunicationFacade); + ProjectReleases projectReleases = new ProjectReleases(); string FolderPath = InitiateLogger(appSettings); settingsManager.CheckRequiredArgsToRun(appSettings, "Creator"); - await CreatorValidator.ValidateAppSettings(appSettings, sw360ProjectService); + await CreatorValidator.ValidateAppSettings(appSettings, sw360ProjectService, projectReleases); Logger.Logger.Log(null, Level.Notice, $"\n====================<<<<< Package creator >>>>>====================", null); Logger.Logger.Log(null, Level.Notice, $"\nStart of Package creator execution : {DateTime.Now}", null); diff --git a/src/LCT.Services.UTest/Sw360ProjectServiceTest.cs b/src/LCT.Services.UTest/Sw360ProjectServiceTest.cs index 11dbe3e3..d81d4df6 100644 --- a/src/LCT.Services.UTest/Sw360ProjectServiceTest.cs +++ b/src/LCT.Services.UTest/Sw360ProjectServiceTest.cs @@ -32,12 +32,13 @@ public void Setup() public async Task GetProjectNameByProjectIDFromSW360_InvalidSW360Credentials_HttpRequestException_ReturnsProjectNameAsEmpty() { // Arrange + ProjectReleases projectReleases=new ProjectReleases(); Mock sw360ApicommunicationFacadeMck = new Mock(); sw360ApicommunicationFacadeMck.Setup(x => x.GetProjectById(It.IsAny())).Throws(); ISw360ProjectService sw360ProjectService = new Sw360ProjectService(sw360ApicommunicationFacadeMck.Object); // Act - var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("shdjdkhsdfdkfhdhifsodo", "TestProject"); + var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("shdjdkhsdfdkfhdhifsodo", "TestProject",projectReleases); // Assert Assert.That(actualProjectName, Is.EqualTo(string.Empty), "GetProjectNameByProjectIDFromSW360 does not return empty on exception"); @@ -46,13 +47,14 @@ public async Task GetProjectNameByProjectIDFromSW360_InvalidSW360Credentials_Htt [Test] public async Task GetProjectNameByProjectIDFromSW360_InvalidSW360Credentials_AggregateException_ReturnsProjectNameAsEmpty() { - // Arrange + // Arrange + ProjectReleases projectReleases = new ProjectReleases(); Mock sw360ApicommunicationFacadeMck = new Mock(); sw360ApicommunicationFacadeMck.Setup(x => x.GetProjectById(It.IsAny())).Throws(); ISw360ProjectService sw360ProjectService = new Sw360ProjectService(sw360ApicommunicationFacadeMck.Object); // Act - var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("shdjdkhsdfdkfhdhifsodo", "TestProject"); + var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("shdjdkhsdfdkfhdhifsodo", "TestProject", projectReleases); // Assert Assert.That(actualProjectName, Is.EqualTo(string.Empty), "GetProjectNameByProjectIDFromSW360 does not return empty on exception"); @@ -70,7 +72,7 @@ public async Task GetProjectNameByProjectIDFromSW360_ValidProjectIdAndName_Retur ISw360ProjectService sw360ProjectService = new Sw360ProjectService(sw360ApicommunicationFacadeMck.Object); // Act - var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("shdjdkhsdfdkfhdhifsodo", "TestProject"); + var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("shdjdkhsdfdkfhdhifsodo", "TestProject",projectsMapper); // Assert Assert.That(actualProjectName, Is.EqualTo(string.Empty), "Project Id not exist"); @@ -93,7 +95,7 @@ public async Task GetProjectNameByProjectIDFromSW360_ValidProjectNameAndId_Retur ISw360ProjectService sw360ProjectService = new Sw360ProjectService(sw360ApicommunicationFacadeMck.Object); // Act - var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("2c0a03b6d4edaf1b2ccdf64d0d0004f7", "TestProject"); + var actualProjectName = await sw360ProjectService.GetProjectNameByProjectIDFromSW360("2c0a03b6d4edaf1b2ccdf64d0d0004f7", "TestProject",projectsMapper); // Assert Assert.That(actualProjectName, Is.EqualTo(expectedName), "Project Id not exist"); diff --git a/src/LCT.Services.UTest/Sw360ServiceTest.cs b/src/LCT.Services.UTest/Sw360ServiceTest.cs index 6ede5fc2..39e34c1a 100644 --- a/src/LCT.Services.UTest/Sw360ServiceTest.cs +++ b/src/LCT.Services.UTest/Sw360ServiceTest.cs @@ -42,7 +42,7 @@ public async Task GetProjectNameByProjectIDFromSW360_ProvidedProjectIdReturnsPro // Act ISw360ProjectService sw360Service = new Sw360ProjectService(swApiCommunicationFacade.Object); - string sw360ProjectName = await sw360Service.GetProjectNameByProjectIDFromSW360("4aa1165e2d23da3d383692eb9c000a43", "Test"); + string sw360ProjectName = await sw360Service.GetProjectNameByProjectIDFromSW360("4aa1165e2d23da3d383692eb9c000a43", "Test", projectsMapper); // Assert Assert.AreEqual("Test", sw360ProjectName); diff --git a/src/LCT.Services/Interface/ISw360ProjectService.cs b/src/LCT.Services/Interface/ISw360ProjectService.cs index b5eac164..3a3c24fe 100644 --- a/src/LCT.Services/Interface/ISw360ProjectService.cs +++ b/src/LCT.Services/Interface/ISw360ProjectService.cs @@ -21,7 +21,7 @@ public interface ISw360ProjectService /// projectId /// projectName /// string - Task GetProjectNameByProjectIDFromSW360(string projectId, string projectName); + Task GetProjectNameByProjectIDFromSW360(string projectId, string projectName, ProjectReleases projectReleases); Task> GetAlreadyLinkedReleasesByProjectId(string projectId); } diff --git a/src/LCT.Services/Sw360ProjectService.cs b/src/LCT.Services/Sw360ProjectService.cs index 0dd5b48d..fda2c5dd 100644 --- a/src/LCT.Services/Sw360ProjectService.cs +++ b/src/LCT.Services/Sw360ProjectService.cs @@ -39,7 +39,7 @@ public Sw360ProjectService(ISW360ApicommunicationFacade sw360ApiCommunicationFac /// projectId /// projectName /// string - public async Task GetProjectNameByProjectIDFromSW360(string projectId, string projectName) + public async Task GetProjectNameByProjectIDFromSW360(string projectId, string projectName, ProjectReleases projectReleases) { string sw360ProjectName = string.Empty; @@ -56,6 +56,8 @@ public async Task GetProjectNameByProjectIDFromSW360(string projectId, s { var projectInfo = JsonConvert.DeserializeObject(result); sw360ProjectName = projectInfo?.Name; + projectReleases.Name=projectInfo?.Name; + projectReleases.Version=projectInfo?.Version; } } From b45c5be8016d958bf970c95730f039dd67f9b269 Mon Sep 17 00:00:00 2001 From: Chalapala RaghavendraReddy Date: Wed, 29 May 2024 11:38:16 +0530 Subject: [PATCH 13/24] Remove unnessasary usings --- src/LCT.Common/FileOperations.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/LCT.Common/FileOperations.cs b/src/LCT.Common/FileOperations.cs index 7644e247..69fa79f1 100644 --- a/src/LCT.Common/FileOperations.cs +++ b/src/LCT.Common/FileOperations.cs @@ -7,7 +7,6 @@ using CycloneDX.Models; using LCT.Common.Interface; using log4net; -using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -15,8 +14,6 @@ using System.Linq; using System.Reflection; using System.Security; -using System.Text.Json.Serialization; -using System.Text.Json; using Newtonsoft.Json.Converters; namespace LCT.Common From 0d152e95dd11b6ea2626ae211b3ee96585a3768c Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Wed, 29 May 2024 12:35:04 +0530 Subject: [PATCH 14/24] Review comments --- src/LCT.APICommunications/SW360Apicommunication.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/LCT.APICommunications/SW360Apicommunication.cs b/src/LCT.APICommunications/SW360Apicommunication.cs index 23d8188d..7f7c6a0d 100644 --- a/src/LCT.APICommunications/SW360Apicommunication.cs +++ b/src/LCT.APICommunications/SW360Apicommunication.cs @@ -141,20 +141,20 @@ public async Task GetReleases() } catch (TaskCanceledException ex) { - Logger.Debug($"{ex.Message}"); - Logger.Error("GetReleases():TaskCanceledException:A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); + Logger.Debug($"GetReleases():TaskCanceledException Error : {ex.Message}", ex); + Logger.Error("TaskCanceledException error has error while getting all releases from the SW360 server,Please wait for sometime and re run the pipeline again. Error :" + ex.Message); Environment.Exit(-1); } catch (HttpRequestException ex) { - Logger.Debug($"{ex.Message}"); - Logger.Error("GetReleases():HttpRequestException:A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); + Logger.Debug($"GetReleases():HttpRequestException Error : {ex.Message}", ex); + Logger.Error("HttpRequestException error has error while getting all releases from the SW360 server,Please wait for sometime and re run the pipeline again. Error :" + ex.Message); Environment.Exit(-1); } catch (InvalidOperationException ex) { - Logger.Debug($"{ex.Message}"); - Logger.Error("GetReleases():InvalidOperationException:A timeout error is thrown from SW360 server,Please wait for sometime and re run the pipeline again"); + Logger.Debug($"GetReleases():InvalidOperationException Error : {ex.Message}", ex); + Logger.Error("InvalidOperationException error has error while getting all releases from the SW360 server,Please wait for sometime and re run the pipeline again. Error :" + ex.Message); Environment.Exit(-1); } return result; From 3aa1d20f91945ee30de5c06d8fb46e6207a09ca7 Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Wed, 29 May 2024 12:41:42 +0530 Subject: [PATCH 15/24] Nuspec update --- CA.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CA.nuspec b/CA.nuspec index e9fc6a7d..e1d7c404 100644 --- a/CA.nuspec +++ b/CA.nuspec @@ -4,7 +4,7 @@ continuous-clearing - 6.2.0 + 6.2.1 Siemens AG continuous-clearing contributors https://github.com/siemens/continuous-clearing From 031bc3c99ac314fe1c3bb7f045c23a4cbeca24ce Mon Sep 17 00:00:00 2001 From: Sumanth Kb Date: Thu, 30 May 2024 12:07:16 +0530 Subject: [PATCH 16/24] BuG fix --- src/LCT.Services/Sw360CreatorService.cs | 2 +- src/LCT.Services/Sw360Service.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LCT.Services/Sw360CreatorService.cs b/src/LCT.Services/Sw360CreatorService.cs index 4fd58d78..c35466e3 100644 --- a/src/LCT.Services/Sw360CreatorService.cs +++ b/src/LCT.Services/Sw360CreatorService.cs @@ -277,7 +277,7 @@ public async Task LinkReleasesToProject(List releasesTobeLi } else { - Logger.Warn("Duplicate entries found in finalReleasesToBeLinked: " + release.Name + ":" + release.ReleaseId + + Logger.Debug("Duplicate entries found in finalReleasesToBeLinked: " + release.Name + ":" + release.ReleaseId + " , with :" + linkedReleasesUniqueDict[release.ReleaseId].Name + ":" + linkedReleasesUniqueDict[release.ReleaseId].ReleaseId); } } diff --git a/src/LCT.Services/Sw360Service.cs b/src/LCT.Services/Sw360Service.cs index 35bb31dd..37a76859 100644 --- a/src/LCT.Services/Sw360Service.cs +++ b/src/LCT.Services/Sw360Service.cs @@ -65,7 +65,7 @@ public async Task> GetAvailableReleasesInSw360(List var modelMappedObject = JsonConvert.DeserializeObject(responseBody); - if (modelMappedObject != null && modelMappedObject.Embedded?.Sw360Releases.Count > 0) + if (modelMappedObject != null && modelMappedObject.Embedded?.Sw360Releases?.Count > 0) { availableComponentsList = await GetAvailableComponenentsList(modelMappedObject.Embedded?.Sw360Releases, listOfComponentsToBom); } From 27071a2834d8b785a199ae0890d453c0eef48317 Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 30 May 2024 17:18:17 +0530 Subject: [PATCH 17/24] Additon of component hashes --- .../JfrogAqlApiCommunication.cs | 2 +- .../Model/AQL/AqlResult.cs | 9 +++ src/LCT.Common/CycloneDXBomParser.cs | 35 +----------- .../CycloneBomProcessorTests.cs | 57 ------------------- src/LCT.PackageIdentifier/AlpineProcesser.cs | 3 +- src/LCT.PackageIdentifier/ConanProcessor.cs | 27 ++++++++- .../CycloneBomProcessor.cs | 1 + src/LCT.PackageIdentifier/DebianProcessor.cs | 29 +++++++++- src/LCT.PackageIdentifier/MavenProcessor.cs | 27 ++++++++- src/LCT.PackageIdentifier/NpmProcessor.cs | 25 +++++++- src/LCT.PackageIdentifier/NugetProcessor.cs | 33 +++++++++-- src/LCT.PackageIdentifier/PythonProcessor.cs | 27 ++++++++- 12 files changed, 168 insertions(+), 107 deletions(-) diff --git a/src/LCT.APICommunications/JfrogAqlApiCommunication.cs b/src/LCT.APICommunications/JfrogAqlApiCommunication.cs index adda574b..19f5f271 100644 --- a/src/LCT.APICommunications/JfrogAqlApiCommunication.cs +++ b/src/LCT.APICommunications/JfrogAqlApiCommunication.cs @@ -119,7 +119,7 @@ private static string BuildAqlQuery(string repoName, string packageName, string } StringBuilder query = new(); - query.Append($"items.find({{{string.Join(", ", queryList)}}}).include(\"repo\", \"path\", \"name\").limit(1)"); + query.Append($"items.find({{{string.Join(", ", queryList)}}}).include(\"repo\", \"path\", \"name\", \"actual_sha1\",\"actual_md5\",\"sha256\").limit(1)"); return query.ToString(); } diff --git a/src/LCT.APICommunications/Model/AQL/AqlResult.cs b/src/LCT.APICommunications/Model/AQL/AqlResult.cs index 278cd553..1a281969 100644 --- a/src/LCT.APICommunications/Model/AQL/AqlResult.cs +++ b/src/LCT.APICommunications/Model/AQL/AqlResult.cs @@ -22,5 +22,14 @@ public class AqlResult [JsonProperty("name")] public string Name { get; set; } + + [JsonProperty("actual_md5")] + public string MD5 { get; set; } + + [JsonProperty("actual_sha1")] + public string SHA1 { get; set; } + + [JsonProperty("sha256")] + public string SHA256 { get; set; } } } diff --git a/src/LCT.Common/CycloneDXBomParser.cs b/src/LCT.Common/CycloneDXBomParser.cs index 4b0b9809..48d27972 100644 --- a/src/LCT.Common/CycloneDXBomParser.cs +++ b/src/LCT.Common/CycloneDXBomParser.cs @@ -24,7 +24,6 @@ namespace LCT.Common public class CycloneDXBomParser : ICycloneDXBomParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public ComponentScope Scope { get; set; } public Bom ParseCycloneDXBom(string filePath) { Bom bom = new Bom(); @@ -98,38 +97,6 @@ public static void CheckValidComponentsForProjectType(List bom, strin } } } - - public void AddComponentHashes(Bom bom) - { - foreach (var component in bom.Components) - { - string input = $"{component.Name}{component.Version}{Scope}{GetType()}"; - component.Hashes = new List - { - new Hash - { - Alg = Hash.HashAlgorithm.MD5, - Content = GetHashForComponent(input, MD5.Create()) - }, - new Hash - { - Alg = Hash.HashAlgorithm.SHA_1, - Content = GetHashForComponent(input, SHA1.Create()) - }, - new Hash - { - Alg = Hash.HashAlgorithm.SHA_256, - Content = GetHashForComponent(input, SHA256.Create()) - } - }; - } - - } - - private static string GetHashForComponent(string input, HashAlgorithm hashAlgorithm) - { - byte[] byteHash = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(input)); - return Convert.ToHexString(byteHash); - } + } } diff --git a/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs b/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs index cce2445e..cae99b0c 100644 --- a/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs +++ b/src/LCT.PackageIdentifier.UTest/CycloneBomProcessorTests.cs @@ -211,62 +211,5 @@ public void ExtractSBOMDetailsFromTemplate_GivenBomTemplateWithoutComponents_Ret Assert.That(0,Is.EqualTo(files.Components.Count), "Returns Zero components in BOM"); } - [Test] - public void AddComponentHashes_ShouldCalculateHashesForAllComponents() - { - // Arrange - var parser = new CycloneDXBomParser(); - var bom = new Bom - { - Components = new List - { - new Component - { - Name = "Component1", - Version = "1.0.0" - }, - new Component - { - Name = "Component2", - Version = "2.0.0" - } - } - }; - - // Act - parser.AddComponentHashes(bom); - - // Assert - Assert.AreEqual(2, bom.Components.Count); - - foreach (var component in bom.Components) - { - Assert.IsNotNull(component.Hashes); - Assert.AreEqual(3, component.Hashes.Count); - - foreach (var hash in component.Hashes) - { - Assert.IsNotNull(hash.Content); - } - } - } - - [Test] - public void GetHashForComponent_ShouldReturnValidHash() - { - // Arrange - - var input = "Component1-1.0.0"; - - // Act - var md5Hash = CycloneDXBomParser.GetHashForComponent(input, MD5.Create()); - var sha1Hash = CycloneDXBomParser.GetHashForComponent(input, SHA1.Create()); - var sha256Hash = CycloneDXBomParser.GetHashForComponent(input, SHA256.Create()); - - // Assert - Assert.IsNotNull(md5Hash); - Assert.IsNotNull(sha1Hash); - Assert.IsNotNull(sha256Hash); - } } } diff --git a/src/LCT.PackageIdentifier/AlpineProcesser.cs b/src/LCT.PackageIdentifier/AlpineProcesser.cs index 24067023..179e85a4 100644 --- a/src/LCT.PackageIdentifier/AlpineProcesser.cs +++ b/src/LCT.PackageIdentifier/AlpineProcesser.cs @@ -23,7 +23,7 @@ namespace LCT.PackageIdentifier /// /// The AlpineProcessor class /// - public class AlpineProcessor : CycloneDXBomParser, IParser + public class AlpineProcessor : IParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly ICycloneDXBomParser _cycloneDXBomParser; @@ -68,7 +68,6 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) } bom = RemoveExcludedComponents(appSettings, bom); - AddComponentHashes(bom); return bom; } diff --git a/src/LCT.PackageIdentifier/ConanProcessor.cs b/src/LCT.PackageIdentifier/ConanProcessor.cs index cce2a271..bc9fe355 100644 --- a/src/LCT.PackageIdentifier/ConanProcessor.cs +++ b/src/LCT.PackageIdentifier/ConanProcessor.cs @@ -29,7 +29,7 @@ namespace LCT.PackageIdentifier /// /// Parses the Conan Packages /// - public class ConanProcessor : CycloneDXBomParser, IParser + public class ConanProcessor : CycloneDXBomParser,IParser { #region fields static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -68,7 +68,6 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) } bom.Components = componentsForBOM; - AddComponentHashes(bom); Logger.Debug($"ParsePackageFile():End"); return bom; } @@ -129,6 +128,8 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List x.Name == jfrogpackageName); Property artifactoryrepo = new() { Name = Dataconstant.Cdx_ArtifactoryRepoUrl, Value = repoName }; Component componentVal = component; @@ -139,7 +140,29 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List() + { + new() + { + Alg = Hash.HashAlgorithm.MD5, + Content = hashes.MD5 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = hashes.SHA1 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = hashes.SHA256 + } + }; + + } modifiedBOM.Add(componentVal); } diff --git a/src/LCT.PackageIdentifier/CycloneBomProcessor.cs b/src/LCT.PackageIdentifier/CycloneBomProcessor.cs index 10eabdd5..93e0dd72 100644 --- a/src/LCT.PackageIdentifier/CycloneBomProcessor.cs +++ b/src/LCT.PackageIdentifier/CycloneBomProcessor.cs @@ -10,6 +10,7 @@ using log4net; using System.Collections.Generic; using System.Reflection; +using static CycloneDX.Models.ExternalReference; namespace LCT.PackageIdentifier { diff --git a/src/LCT.PackageIdentifier/DebianProcessor.cs b/src/LCT.PackageIdentifier/DebianProcessor.cs index 7f7600eb..b23e1a68 100644 --- a/src/LCT.PackageIdentifier/DebianProcessor.cs +++ b/src/LCT.PackageIdentifier/DebianProcessor.cs @@ -5,6 +5,7 @@ // -------------------------------------------------------------------------------------------------------------------- using CycloneDX.Models; +using LCT.APICommunications; using LCT.APICommunications.Model.AQL; using LCT.Common; using LCT.Common.Constants; @@ -18,6 +19,7 @@ using System.Linq; using System.Net; using System.Reflection; +using System.Security.Cryptography; using System.Threading.Tasks; namespace LCT.PackageIdentifier @@ -25,7 +27,7 @@ namespace LCT.PackageIdentifier /// /// The DebianProcessor class /// - public class DebianProcessor : CycloneDXBomParser, IParser + public class DebianProcessor : IParser { static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly ICycloneDXBomParser _cycloneDXBomParser; @@ -73,7 +75,6 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) } bom = RemoveExcludedComponents(appSettings, bom); - AddComponentHashes(bom); return bom; } @@ -103,6 +104,8 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List x.Name == jfrogpackageName); Property artifactoryrepo = new() { Name = Dataconstant.Cdx_ArtifactoryRepoUrl, Value = repoName }; Component componentVal = component; @@ -113,7 +116,29 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List() + { + new() + { + Alg = Hash.HashAlgorithm.MD5, + Content = hashes.MD5 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = hashes.SHA1 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = hashes.SHA256 + } + }; + + } modifiedBOM.Add(componentVal); } diff --git a/src/LCT.PackageIdentifier/MavenProcessor.cs b/src/LCT.PackageIdentifier/MavenProcessor.cs index 68aa3008..74296075 100644 --- a/src/LCT.PackageIdentifier/MavenProcessor.cs +++ b/src/LCT.PackageIdentifier/MavenProcessor.cs @@ -4,6 +4,7 @@ // -------------------------------------------------------------------------------------------------------------------- using CycloneDX.Models; +using LCT.APICommunications; using LCT.APICommunications.Model.AQL; using LCT.Common; using LCT.Common.Constants; @@ -96,7 +97,6 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) bom.Components = componentsForBOM; bom.Dependencies = dependenciesForBOM; - AddComponentHashes(bom); BomCreator.bomKpiData.ComponentsInComparisonBOM = bom.Components.Count; Logger.Debug($"ParsePackageFile():End"); return bom; @@ -176,7 +176,10 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List x.Name == jfrogpackageName); Property artifactoryrepo = new() { Name = Dataconstant.Cdx_ArtifactoryRepoUrl, Value = repoName }; Component componentVal = component; if (componentVal.Properties?.Count == null || componentVal.Properties?.Count <= 0) @@ -186,7 +189,29 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List() + { + new() + { + Alg = Hash.HashAlgorithm.MD5, + Content = hashes.MD5 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = hashes.SHA1 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = hashes.SHA256 + } + }; + + } modifiedBOM.Add(componentVal); } diff --git a/src/LCT.PackageIdentifier/NpmProcessor.cs b/src/LCT.PackageIdentifier/NpmProcessor.cs index 9b1c9b85..b73a3ce6 100644 --- a/src/LCT.PackageIdentifier/NpmProcessor.cs +++ b/src/LCT.PackageIdentifier/NpmProcessor.cs @@ -70,7 +70,6 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) bom.Components = componentsForBOM; bom.Dependencies = dependencies; - AddComponentHashes(bom); Logger.Debug($"ParsePackageFile():End"); return bom; } @@ -314,7 +313,9 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List x.Name == jfrogpackageName); Property artifactoryrepo = new() { Name = Dataconstant.Cdx_ArtifactoryRepoUrl, Value = repoName }; Component componentVal = component; @@ -325,7 +326,29 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List() + { + new() + { + Alg = Hash.HashAlgorithm.MD5, + Content = hashes.MD5 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = hashes.SHA1 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = hashes.SHA256 + } + }; + + } modifiedBOM.Add(componentVal); } diff --git a/src/LCT.PackageIdentifier/NugetProcessor.cs b/src/LCT.PackageIdentifier/NugetProcessor.cs index 1bc08ac5..2cf17993 100644 --- a/src/LCT.PackageIdentifier/NugetProcessor.cs +++ b/src/LCT.PackageIdentifier/NugetProcessor.cs @@ -43,13 +43,12 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) { Logger.Debug($"ParsePackageFile():Start"); List listComponentForBOM = new List(); - Bom bom = new Bom(); + Bom bom = new Bom(); ParsingInputFileForBOM(appSettings, ref listComponentForBOM, ref bom); var componentsWithMultipleVersions = bom.Components.GroupBy(s => s.Name).Where(g => g.Count() > 1).SelectMany(g => g).ToList(); CheckForMultipleVersions(appSettings, componentsWithMultipleVersions); - AddComponentHashes(bom); Logger.Debug($"ParsePackageFile():End"); return bom; } @@ -220,7 +219,10 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List x.Name == jfrogpackageName); Property artifactoryrepo = new() { Name = Dataconstant.Cdx_ArtifactoryRepoUrl, Value = repoName }; Component componentVal = component; @@ -231,7 +233,28 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List() + { + new() + { + Alg = Hash.HashAlgorithm.MD5, + Content = hashes.MD5 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = hashes.SHA1 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = hashes.SHA256 + } + }; + } modifiedBOM.Add(componentVal); } return modifiedBOM; @@ -389,7 +412,7 @@ private void ParsingInputFileForBOM(CommonAppSettings appSettings, ref List listComponentForBOM, List listofComponents, List dependencies) diff --git a/src/LCT.PackageIdentifier/PythonProcessor.cs b/src/LCT.PackageIdentifier/PythonProcessor.cs index ff248e0f..5b5e6b96 100644 --- a/src/LCT.PackageIdentifier/PythonProcessor.cs +++ b/src/LCT.PackageIdentifier/PythonProcessor.cs @@ -25,7 +25,7 @@ namespace LCT.PackageIdentifier { - public class PythonProcessor : CycloneDXBomParser, IParser + public class PythonProcessor : IParser { private const string NotFoundInRepo = "Not Found in JFrogRepo"; @@ -76,7 +76,6 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) //Adding Template Component Details & MetaData SbomTemplate.AddComponentDetails(bom.Components, templateDetails); bom = RemoveExcludedComponents(appSettings, bom); - AddComponentHashes(bom); return bom; } @@ -354,6 +353,8 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List x.Name == jfrogpackageName); Property artifactoryrepo = new() { Name = Dataconstant.Cdx_ArtifactoryRepoUrl, Value = repoName }; Component componentVal = component; @@ -364,7 +365,29 @@ public async Task> GetJfrogRepoDetailsOfAComponent(List() + { + new() + { + Alg = Hash.HashAlgorithm.MD5, + Content = hashes.MD5 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_1, + Content = hashes.SHA1 + }, + new() + { + Alg = Hash.HashAlgorithm.SHA_256, + Content = hashes.SHA256 + } + }; + + } modifiedBOM.Add(componentVal); } return modifiedBOM; From 08ad099f52b68c64f18b9e70168fc96a0a81e244 Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 30 May 2024 18:00:47 +0530 Subject: [PATCH 18/24] bug fix --- src/LCT.APICommunications/JfrogAqlApiCommunication.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LCT.APICommunications/JfrogAqlApiCommunication.cs b/src/LCT.APICommunications/JfrogAqlApiCommunication.cs index 19f5f271..f8585ce6 100644 --- a/src/LCT.APICommunications/JfrogAqlApiCommunication.cs +++ b/src/LCT.APICommunications/JfrogAqlApiCommunication.cs @@ -58,7 +58,7 @@ public async Task GetInternalComponentDataByRepo(string rep StringBuilder query = new(); query.Append("items.find({\"repo\":\""); query.Append($"{repoName}"); - query.Append("\"}).include(\"repo\", \"path\", \"name\")"); + query.Append("\"}).include(\"repo\", \"path\", \"name\", \"actual_sha1\",\"actual_md5\",\"sha256\")"); string aqlQueryToBody = query.ToString(); string uri = $"{DomainName}{ApiConstant.JfrogArtifactoryApiSearchAql}"; @@ -119,7 +119,7 @@ private static string BuildAqlQuery(string repoName, string packageName, string } StringBuilder query = new(); - query.Append($"items.find({{{string.Join(", ", queryList)}}}).include(\"repo\", \"path\", \"name\", \"actual_sha1\",\"actual_md5\",\"sha256\").limit(1)"); + query.Append($"items.find({{{string.Join(", ", queryList)}}}).include(\"repo\", \"path\", \"name\").limit(1)"); return query.ToString(); } From 82a664a7e6f3ebcc0706365fe1e0fc875414d13a Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 30 May 2024 18:02:02 +0530 Subject: [PATCH 19/24] updated fileoperations --- src/LCT.Common/FileOperations.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/LCT.Common/FileOperations.cs b/src/LCT.Common/FileOperations.cs index 3ec79012..6e71d225 100644 --- a/src/LCT.Common/FileOperations.cs +++ b/src/LCT.Common/FileOperations.cs @@ -8,6 +8,7 @@ using LCT.Common.Interface; using log4net; using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using System; using System.Collections.Generic; using System.IO; @@ -52,7 +53,7 @@ public string WriteContentToFile(T dataToWrite, string folderPath, string fil { Logger.Debug($"WriteContentToFile():folderpath-{folderPath},fileNameWithExtension-{fileNameWithExtension}," + $"projectName-{projectName}"); - string jsonString = JsonConvert.SerializeObject(dataToWrite, Formatting.Indented); + string jsonString = JsonConvert.SerializeObject(dataToWrite, Formatting.Indented, new StringEnumConverter()); string fileName = $"{projectName}_{fileNameWithExtension}"; string filePath = Path.Combine(folderPath, fileName); From b9eea1e06b26c8857fe446b2f9e6c1232fe74b8e Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 30 May 2024 18:11:14 +0530 Subject: [PATCH 20/24] UT updation --- src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs b/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs index a5237c7e..c4adccb0 100644 --- a/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs +++ b/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs @@ -55,8 +55,11 @@ public async Task GetRepoDetails_GivenProjectTypeAsDebian_ReturnsListOFComponent new() { Path="test/test", - Name="compoenent", - Repo="remote" + Name="Test-1.debian", + Repo="remote", + MD5="7654345676543", + SHA256="65434567", + SHA1="765434567654" } }; mockIProcessor.Setup(x => x.GetJfrogArtifactoryRepoInfo(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(lstComponentForBOM); From ccfe8487acd7481f544149806b8306d01f47781e Mon Sep 17 00:00:00 2001 From: karthika Date: Thu, 30 May 2024 18:22:53 +0530 Subject: [PATCH 21/24] UT update --- .../BomHelperUnitTests.cs | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) diff --git a/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs b/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs index c4adccb0..7647ac39 100644 --- a/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs +++ b/src/LCT.PackageIdentifier.UTest/BomHelperUnitTests.cs @@ -76,7 +76,256 @@ public async Task GetRepoDetails_GivenProjectTypeAsDebian_ReturnsListOFComponent //Assert Assert.AreEqual(expected.Count, lstComponentForBOM.Count); } + [TestCase] + public async Task GetRepoDetails_GivenProjectTypeAsNpm_ReturnsListOFComponents() + { + + //Arrange + var lstComponentForBOM = new List() + { + new Component() + { + Name="Test", + Version="1", + } + }; + + CommonAppSettings appSettings = new CommonAppSettings() + { + ArtifactoryUploadApiKey = "testvalue", + ProjectType = "NPM", + Debian = new Config() + { + JfrogDebianRepoList = new string[] { "here" } + }, + JFrogApi = "https://jfrogapi" + }; + List aqlResultList = new() + { + new() + { + Path="test/test", + Name="Test-1.tgz", + Repo="remote", + MD5="7654345676543", + SHA256="65434567", + SHA1="765434567654" + } + }; + mockIProcessor.Setup(x => x.GetJfrogArtifactoryRepoInfo(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(lstComponentForBOM); + Mock cycloneDXBomParser = new Mock(); + + IParser parser = new DebianProcessor(cycloneDXBomParser.Object); + Mock jFrogService = new Mock(); + Mock bomHelper = new Mock(); + bomHelper.Setup(x => x.GetListOfComponentsFromRepo(It.IsAny(), It.IsAny())).ReturnsAsync(aqlResultList); + + //Act + var expected = await parser.GetJfrogRepoDetailsOfAComponent(lstComponentForBOM, appSettings, jFrogService.Object, bomHelper.Object); + + //Assert + Assert.AreEqual(expected.Count, lstComponentForBOM.Count); + } + [TestCase] + public async Task GetRepoDetails_GivenProjectTypeAsNuget_ReturnsListOFComponents() + { + + //Arrange + var lstComponentForBOM = new List() + { + new Component() + { + Name="Test", + Version="1", + } + }; + + CommonAppSettings appSettings = new CommonAppSettings() + { + ArtifactoryUploadApiKey = "testvalue", + ProjectType = "NUGET", + Debian = new Config() + { + JfrogDebianRepoList = new string[] { "here" } + }, + JFrogApi = "https://jfrogapi" + }; + List aqlResultList = new() + { + new() + { + Path="test/test", + Name="Test.1.nupkg", + Repo="remote", + MD5="7654345676543", + SHA256="65434567", + SHA1="765434567654" + } + }; + mockIProcessor.Setup(x => x.GetJfrogArtifactoryRepoInfo(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(lstComponentForBOM); + Mock cycloneDXBomParser = new Mock(); + + IParser parser = new DebianProcessor(cycloneDXBomParser.Object); + Mock jFrogService = new Mock(); + Mock bomHelper = new Mock(); + bomHelper.Setup(x => x.GetListOfComponentsFromRepo(It.IsAny(), It.IsAny())).ReturnsAsync(aqlResultList); + + //Act + var expected = await parser.GetJfrogRepoDetailsOfAComponent(lstComponentForBOM, appSettings, jFrogService.Object, bomHelper.Object); + + //Assert + Assert.AreEqual(expected.Count, lstComponentForBOM.Count); + } + [TestCase] + public async Task GetRepoDetails_GivenProjectTypeAsPython_ReturnsListOFComponents() + { + + //Arrange + var lstComponentForBOM = new List() + { + new Component() + { + Name="Test", + Version="1", + } + }; + + CommonAppSettings appSettings = new CommonAppSettings() + { + ArtifactoryUploadApiKey = "testvalue", + ProjectType = "PYTHON", + Debian = new Config() + { + JfrogDebianRepoList = new string[] { "here" } + }, + JFrogApi = "https://jfrogapi" + }; + List aqlResultList = new() + { + new() + { + Path="test/test", + Name="Test-1.whl", + Repo="remote", + MD5="7654345676543", + SHA256="65434567", + SHA1="765434567654" + } + }; + mockIProcessor.Setup(x => x.GetJfrogArtifactoryRepoInfo(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(lstComponentForBOM); + Mock cycloneDXBomParser = new Mock(); + + IParser parser = new DebianProcessor(cycloneDXBomParser.Object); + Mock jFrogService = new Mock(); + Mock bomHelper = new Mock(); + bomHelper.Setup(x => x.GetListOfComponentsFromRepo(It.IsAny(), It.IsAny())).ReturnsAsync(aqlResultList); + + //Act + var expected = await parser.GetJfrogRepoDetailsOfAComponent(lstComponentForBOM, appSettings, jFrogService.Object, bomHelper.Object); + + //Assert + Assert.AreEqual(expected.Count, lstComponentForBOM.Count); + } + [TestCase] + public async Task GetRepoDetails_GivenProjectTypeAsConan_ReturnsListOFComponents() + { + + //Arrange + var lstComponentForBOM = new List() + { + new Component() + { + Name="Test", + Version="1", + } + }; + + CommonAppSettings appSettings = new CommonAppSettings() + { + ArtifactoryUploadApiKey = "testvalue", + ProjectType = "Conan", + Debian = new Config() + { + JfrogDebianRepoList = new string[] { "here" } + }, + JFrogApi = "https://jfrogapi" + }; + List aqlResultList = new() + { + new() + { + Path="test/test", + Name="Test-1", + Repo="remote", + MD5="7654345676543", + SHA256="65434567", + SHA1="765434567654" + } + }; + mockIProcessor.Setup(x => x.GetJfrogArtifactoryRepoInfo(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(lstComponentForBOM); + Mock cycloneDXBomParser = new Mock(); + IParser parser = new DebianProcessor(cycloneDXBomParser.Object); + Mock jFrogService = new Mock(); + Mock bomHelper = new Mock(); + bomHelper.Setup(x => x.GetListOfComponentsFromRepo(It.IsAny(), It.IsAny())).ReturnsAsync(aqlResultList); + + //Act + var expected = await parser.GetJfrogRepoDetailsOfAComponent(lstComponentForBOM, appSettings, jFrogService.Object, bomHelper.Object); + + //Assert + Assert.AreEqual(expected.Count, lstComponentForBOM.Count); + } + [TestCase] + public async Task GetRepoDetails_GivenProjectTypeAsMaven_ReturnsListOFComponents() + { + + //Arrange + var lstComponentForBOM = new List() + { + new Component() + { + Name="Test", + Version="1", + } + }; + + CommonAppSettings appSettings = new CommonAppSettings() + { + ArtifactoryUploadApiKey = "testvalue", + ProjectType = "MAVEN", + Debian = new Config() + { + JfrogDebianRepoList = new string[] { "here" } + }, + JFrogApi = "https://jfrogapi" + }; + List aqlResultList = new() + { + new() + { + Path="test/test", + Name="Test-1-sources.jar", + Repo="remote", + MD5="7654345676543", + SHA256="65434567", + SHA1="765434567654" + } + }; + mockIProcessor.Setup(x => x.GetJfrogArtifactoryRepoInfo(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync(lstComponentForBOM); + Mock cycloneDXBomParser = new Mock(); + + IParser parser = new DebianProcessor(cycloneDXBomParser.Object); + Mock jFrogService = new Mock(); + Mock bomHelper = new Mock(); + bomHelper.Setup(x => x.GetListOfComponentsFromRepo(It.IsAny(), It.IsAny())).ReturnsAsync(aqlResultList); + + //Act + var expected = await parser.GetJfrogRepoDetailsOfAComponent(lstComponentForBOM, appSettings, jFrogService.Object, bomHelper.Object); + + //Assert + Assert.AreEqual(expected.Count, lstComponentForBOM.Count); + } [TestCase] public void Test_WriteBomKpiDataToConsole() From 35a27ed67e3b3912e80c9a272ab586251bd81a3e Mon Sep 17 00:00:00 2001 From: Chalapala RaghavendraReddy Date: Mon, 3 Jun 2024 16:23:20 +0530 Subject: [PATCH 22/24] Cli changes for 3 excs --- .../Model/DisplayPackagesInfo.cs | 29 +- .../PackageUploadHelper.cs | 285 ++++++++++++++++-- src/ArtifactoryUploader/PackageUploader.cs | 24 +- src/ArtifactoryUploader/Program.cs | 1 - src/LCT.Common/Constants/FileConstant.cs | 2 + src/LCT.Common/ExceptionHandling.cs | 4 +- src/LCT.Common/FileOperations.cs | 75 +++++ src/LCT.Common/Interface/IFileOperations.cs | 18 ++ src/LCT.Common/Model/MultipleVersionValues.cs | 30 ++ src/LCT.PackageIdentifier/ConanProcessor.cs | 52 +++- src/LCT.PackageIdentifier/NpmProcessor.cs | 53 +++- src/LCT.PackageIdentifier/NugetProcessor.cs | 56 +++- src/LCT.PackageIdentifier/Program.cs | 162 +++++++++- src/LCT.PackageIdentifier/Scanner.cs | 9 +- .../ComponentCreator.cs | 2 +- src/LCT.SW360PackageCreator/Program.cs | 1 - 16 files changed, 749 insertions(+), 54 deletions(-) create mode 100644 src/LCT.Common/Model/MultipleVersionValues.cs diff --git a/src/ArtifactoryUploader/Model/DisplayPackagesInfo.cs b/src/ArtifactoryUploader/Model/DisplayPackagesInfo.cs index 532813ea..912e76f8 100644 --- a/src/ArtifactoryUploader/Model/DisplayPackagesInfo.cs +++ b/src/ArtifactoryUploader/Model/DisplayPackagesInfo.cs @@ -4,13 +4,16 @@ // SPDX-License-Identifier: MIT // -------------------------------------------------------------------------------------------------------------------- using LCT.APICommunications.Model; +using Newtonsoft.Json; using System.Collections.Generic; namespace LCT.ArtifactoryUploader.Model { /// - /// The Model class for UnkmownPackagesAll + /// The Model class for DisplayPackagesInfo /// + + [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public class DisplayPackagesInfo { public List UnknownPackagesNpm { get; set; } @@ -39,4 +42,28 @@ public class DisplayPackagesInfo public List SuccessfullPackagesMaven { get; set; } } + public class ProjectResponse + { + [JsonProperty("npm")] + public List Npm { get; set; } + [JsonProperty("nuget")] + public List Nuget { get; set; } + [JsonProperty("conan")] + public List Conan { get; set; } + [JsonProperty("python")] + public List Python { get; set; } + [JsonProperty("debian")] + public List Debian { get; set; } + [JsonProperty("maven")] + public List Maven { get; set; } + + } + + public class JsonComponents + { + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("version")] + public string Version { get; set; } + } } diff --git a/src/ArtifactoryUploader/PackageUploadHelper.cs b/src/ArtifactoryUploader/PackageUploadHelper.cs index 0be43fea..bcbaaf88 100644 --- a/src/ArtifactoryUploader/PackageUploadHelper.cs +++ b/src/ArtifactoryUploader/PackageUploadHelper.cs @@ -12,6 +12,7 @@ using LCT.ArtifactoryUploader.Model; using LCT.Common; using LCT.Common.Constants; +using LCT.Common.Interface; using LCT.Services; using LCT.Services.Interface; using log4net; @@ -152,12 +153,12 @@ public static DisplayPackagesInfo GetComponentsToBePackages() } - private static void DisplaySortedForeachComponents(List unknownPackages, List JfrogNotFoundPackages, List SucessfullPackages, List JfrogFoundPackages, string name) + private static void DisplaySortedForeachComponents(List unknownPackages, List JfrogNotFoundPackages, List SucessfullPackages, List JfrogFoundPackages, string name, string filename) { if (unknownPackages.Any() || JfrogNotFoundPackages.Any() || SucessfullPackages.Any() || JfrogFoundPackages.Any()) { - Logger.Info("\n" + name + "\n"); - DisplayErrorForUnknownPackages(unknownPackages); + Logger.Info("\n" + name + ":\n"); + DisplayErrorForUnknownPackages(unknownPackages, name, filename); DisplayErrorForJfrogFoundPackages(JfrogFoundPackages); DisplayErrorForJfrogPackages(JfrogNotFoundPackages); DisplayErrorForSucessfullPackages(SucessfullPackages); @@ -173,9 +174,7 @@ private static void DisplayErrorForJfrogFoundPackages(List {jfrogFoundPackage.DestRepoName}"); @@ -184,6 +183,11 @@ private static void DisplayErrorForJfrogFoundPackages(List J } } - private static void DisplayErrorForUnknownPackages(List unknownPackages) - { + private static void DisplayErrorForUnknownPackages(List unknownPackages, string name, string filepath) + { + ProjectResponse projectResponse = new ProjectResponse(); + IFileOperations fileOperations = new FileOperations(); + var filename = Path.Combine(filepath, $"Artifactory_{FileConstant.artifactoryReportNotApproved}"); if (unknownPackages.Any()) { + if (name.Equals("Npm")) + { + GetNotApprovedNpmPackages(unknownPackages, projectResponse, fileOperations, filepath, filename); + } + else if (name.Equals("Nuget")) + { + GetNotApprovedNugetPackages(unknownPackages, projectResponse, fileOperations, filepath, filename); + } + else if (name.Equals("Conan")) + { + GetNotApprovedConanPackages(unknownPackages, projectResponse, fileOperations, filepath, filename); + } + else if (name.Equals("Debian")) + { + GetNotApprovedDebianPackages(unknownPackages, projectResponse, fileOperations, filepath, filename); + } + else if (name.Equals("Maven")) + { + GetNotApprovedMavenPackages(unknownPackages, projectResponse, fileOperations, filepath, filename); + } + else if (name.Equals("Python")) + { + GetNotApprovedPythonPackages(unknownPackages, projectResponse, fileOperations, filepath, filename); + } + } + } - foreach (var unknownPackage in unknownPackages) + private static void GetNotApprovedNpmPackages(List unknownPackages, ProjectResponse projectResponse, IFileOperations fileOperations, string filepath, string filename) + { + if (File.Exists(filename)) + { + string json = File.ReadAllText(filename); + ProjectResponse myDeserializedClass = JsonConvert.DeserializeObject(json); + List npmComponents = new List(); + foreach (var npmpackage in unknownPackages) { - Logger.Warn($"Package {unknownPackage.Name}-{unknownPackage.Version} is not in report approved state,hence artifactory upload will not be done!"); + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = npmpackage.Name; + jsonComponents.Version = npmpackage.Version; + npmComponents.Add(jsonComponents); } - Logger.Info("\n"); + myDeserializedClass.Npm = npmComponents; + fileOperations.WriteContentToReportNotApprovedFile(myDeserializedClass, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + + } + else + { + projectResponse.Npm = new List(); + foreach (var npmpackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = npmpackage.Name; + jsonComponents.Version = npmpackage.Version; + projectResponse.Npm.Add(jsonComponents); + } + fileOperations.WriteContentToReportNotApprovedFile(projectResponse, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + Logger.Warn($"Artifactory upload will not be done due to Report not in Approved state and package details can be found at {filename}\n"); + + } + private static void GetNotApprovedNugetPackages(List unknownPackages, ProjectResponse projectResponse, IFileOperations fileOperations, string filepath, string filename) + { + if (File.Exists(filename)) + { + string json = File.ReadAllText(filename); + ProjectResponse myDeserializedClass = JsonConvert.DeserializeObject(json); + List nugetComponents = new List(); + foreach (var nugetpackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = nugetpackage.Name; + jsonComponents.Version = nugetpackage.Version; + nugetComponents.Add(jsonComponents); + } + myDeserializedClass.Nuget = nugetComponents; + fileOperations.WriteContentToReportNotApprovedFile(myDeserializedClass, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + else + { + projectResponse.Nuget = new List(); + foreach (var nugetpackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = nugetpackage.Name; + jsonComponents.Version = nugetpackage.Version; + projectResponse.Nuget.Add(jsonComponents); + } + fileOperations.WriteContentToReportNotApprovedFile(projectResponse, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + Logger.Warn($"Artifactory upload will not be done due to Report not in Approved state and package details can be found at {filename}\n"); + } + private static void GetNotApprovedConanPackages(List unknownPackages, ProjectResponse projectResponse, IFileOperations fileOperations, string filepath, string filename) + { + if (File.Exists(filename)) + { + string json = File.ReadAllText(filename); + + ProjectResponse myDeserializedClass = JsonConvert.DeserializeObject(json); + List conanComponents = new List(); + foreach (var conanpackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = conanpackage.Name; + jsonComponents.Version = conanpackage.Version; + conanComponents.Add(jsonComponents); + } + myDeserializedClass.Conan = conanComponents; + fileOperations.WriteContentToReportNotApprovedFile(myDeserializedClass, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + else + { + projectResponse.Conan = new List(); + foreach (var conanpackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = conanpackage.Name; + jsonComponents.Version = conanpackage.Version; + projectResponse.Conan.Add(jsonComponents); + } + fileOperations.WriteContentToReportNotApprovedFile(projectResponse, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + Logger.Warn($"Artifactory upload will not be done due to Report not in Approved state and package details can be found at {filename}\n"); + + } + private static void GetNotApprovedPythonPackages(List unknownPackages, ProjectResponse projectResponse, IFileOperations fileOperations, string filepath, string filename) + { + if (File.Exists(filename)) + { + string json = File.ReadAllText(filename); + + ProjectResponse myDeserializedClass = JsonConvert.DeserializeObject(json); + List pythonComponents = new List(); + foreach (var pythonPackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = pythonPackage.Name; + jsonComponents.Version = pythonPackage.Version; + pythonComponents.Add(jsonComponents); + } + myDeserializedClass.Python = pythonComponents; + fileOperations.WriteContentToReportNotApprovedFile(myDeserializedClass, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + + + } + else + { + projectResponse.Python = new List(); + foreach (var pythonPackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = pythonPackage.Name; + jsonComponents.Version = pythonPackage.Version; + projectResponse.Python.Add(jsonComponents); + } + fileOperations.WriteContentToReportNotApprovedFile(projectResponse, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + Logger.Warn($"Artifactory upload will not be done due to Report not in Approved state and package details can be found at {filename}\n"); + } + private static void GetNotApprovedDebianPackages(List unknownPackages, ProjectResponse projectResponse, IFileOperations fileOperations, string filepath, string filename) + { + if (File.Exists(filename)) + { + string json = File.ReadAllText(filename); + + ProjectResponse myDeserializedClass = JsonConvert.DeserializeObject(json); + List debianComponents = new List(); + foreach (var debianPackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = debianPackage.Name; + jsonComponents.Version = debianPackage.Version; + debianComponents.Add(jsonComponents); + } + myDeserializedClass.Debian = debianComponents; + fileOperations.WriteContentToReportNotApprovedFile(myDeserializedClass, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + + + } + else + { + projectResponse.Debian = new List(); + foreach (var debianPackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = debianPackage.Name; + jsonComponents.Version = debianPackage.Version; + projectResponse.Debian.Add(jsonComponents); + } + fileOperations.WriteContentToReportNotApprovedFile(projectResponse, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + Logger.Warn($"Artifactory upload will not be done due to Report not in Approved state and package details can be found at {filename}\n"); + } + private static void GetNotApprovedMavenPackages(List unknownPackages, ProjectResponse projectResponse, IFileOperations fileOperations, string filepath, string filename) + { + if (File.Exists(filename)) + { + string json = File.ReadAllText(filename); + + ProjectResponse myDeserializedClass = JsonConvert.DeserializeObject(json); + List mavenComponents = new List(); + foreach (var mavenPackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = mavenPackage.Name; + jsonComponents.Version = mavenPackage.Version; + mavenComponents.Add(jsonComponents); + } + myDeserializedClass.Maven = mavenComponents; + fileOperations.WriteContentToReportNotApprovedFile(myDeserializedClass, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + + + } + else + { + projectResponse.Maven = new List(); + foreach (var mavenPackage in unknownPackages) + { + JsonComponents jsonComponents = new JsonComponents(); + jsonComponents.Name = mavenPackage.Name; + jsonComponents.Version = mavenPackage.Version; + projectResponse.Maven.Add(jsonComponents); + } + fileOperations.WriteContentToReportNotApprovedFile(projectResponse, filepath, FileConstant.artifactoryReportNotApproved, "Artifactory"); + } + Logger.Warn($"Artifactory upload will not be done due to Report not in Approved state and package details can be found at {filename}\n"); + } + public static string GettPathForArtifactoryUpload() + { + string localPathforartifactory = string.Empty; + try + { + String Todaysdate = DateTime.Now.ToString("dd-MM-yyyy_ss"); + localPathforartifactory = $"{Directory.GetParent(Directory.GetCurrentDirectory())}\\ClearingTool\\ArtifactoryFiles\\{Todaysdate}\\"; + if (!Directory.Exists(localPathforartifactory)) + { + localPathforartifactory = Directory.CreateDirectory(localPathforartifactory).ToString(); + } + } + catch (IOException ex) + { + Logger.Error($"GettPathForArtifactoryUpload() ", ex); + } + catch (UnauthorizedAccessException ex) + { + Logger.Error($"GettPathForArtifactoryUpload() ", ex); + } + + return localPathforartifactory; } private static void DisplayErrorForSucessfullPackages(List SucessfullPackages) { @@ -236,12 +485,14 @@ private static void DisplayErrorForSucessfullPackages(List m_ComponentsInBOM, CommonA private static void PackageSettings(Config project) { + string includeList = string.Empty; + string excludeList = string.Empty; + if (project.Include != null) + { + includeList = string.Join(",", project.Include?.ToList()); + } + if (project.Exclude != null) + { + excludeList = string.Join(",", project.Exclude?.ToList()); + } - Logger.Logger.Log(null, Level.Notice, $"\tDEVDEP_REPO_NAME:\t`{project.JfrogDevDestRepoName}`\n\t" + - $"THIRD_PARTY_REPO_NAME:\t`{project.JfrogThirdPartyDestRepoName}`\n\t" + - $"INTERNAL_REPO_NAME:\t`{project.JfrogInternalDestRepoName}`\n\t" + - $"Config:\n\t" + - $"Include: \t", null); - project.Include?.ToList().ForEach(x => Logger.Logger.Log(null, Level.Notice, $"\t\t\t\t`{x}`\t", null)); - Logger.Logger.Log(null, Level.Notice, $"\tExclude:", null); - project.Exclude?.ToList().ForEach(x => Logger.Logger.Log(null, Level.Notice, $"\t\t\t\t`{x}`\n\t", null)); + Logger.Logger.Log(null, Level.Notice, $"\tDEVDEP_REPO_NAME:\t{project.JfrogDevDestRepoName}\n\t" + + $"THIRD_PARTY_REPO_NAME:\t{project.JfrogThirdPartyDestRepoName}\n\t" + + $"INTERNAL_REPO_NAME:\t{project.JfrogInternalDestRepoName}\n\t" + + $"Config:\n\t" + + $"Exclude:\t\t{excludeList}\n\t" + + $"Include: \t\t{includeList}\n", null); } } } diff --git a/src/ArtifactoryUploader/Program.cs b/src/ArtifactoryUploader/Program.cs index b975d48c..2c5750fc 100644 --- a/src/ArtifactoryUploader/Program.cs +++ b/src/ArtifactoryUploader/Program.cs @@ -56,7 +56,6 @@ static async Task Main(string[] args) Logger.Logger.Log(null, Level.Info, $"Input Parameters used in Artifactory Uploader:\n\t", null); Logger.Logger.Log(null, Level.Notice, $"\tBomFilePath:\t\t {appSettings.BomFilePath}\n\t" + $"JFrogUrl:\t\t {appSettings.JFrogApi}\n\t" + - $"Artifactory User:\t {appSettings.ArtifactoryUploadUser}\n\t" + $"Release:\t\t {appSettings.Release}\n\t" + $"LogFolderPath:\t\t {Path.GetFullPath(FolderPath)}\n", null); diff --git a/src/LCT.Common/Constants/FileConstant.cs b/src/LCT.Common/Constants/FileConstant.cs index b89a1e4c..e280983d 100644 --- a/src/LCT.Common/Constants/FileConstant.cs +++ b/src/LCT.Common/Constants/FileConstant.cs @@ -50,5 +50,7 @@ public static class FileConstant public const string CycloneDXFileExtension = ".cdx.json"; public const string SBOMTemplateFileExtension = "CATemplate.cdx.json"; public const string NugetAssetFile = "project.assets.json"; + public const string multipleversionsFileName = "Multipleversions.json"; + public const string artifactoryReportNotApproved = "ReportNotApproved.json"; } } diff --git a/src/LCT.Common/ExceptionHandling.cs b/src/LCT.Common/ExceptionHandling.cs index a32eb7b8..3918532d 100644 --- a/src/LCT.Common/ExceptionHandling.cs +++ b/src/LCT.Common/ExceptionHandling.cs @@ -35,11 +35,11 @@ public static void FossologyException(HttpRequestException ex) { if (500 <= Convert.ToInt32(ex.StatusCode) && Convert.ToInt32(ex.StatusCode) <= 599) { - Logger.Logger.Log(null, Level.Error, $"The exception may arise because fossology is currently unresponsive:{ex.Message} Please try again later", null); + Logger.Logger.Log(null, Level.Error, $"\tThe exception may arise because fossology is currently unresponsive:{ex.Message} Please try again later", null); } else { - Logger.Logger.Log(null, Level.Error, $"The exception may be caused by an incorrect or missing token for fossology :{ex.Message} Please ensure that a valid token is provided and try again", null); + Logger.Logger.Log(null, Level.Error, $"\tThe exception may be caused by an incorrect or missing token for fossology :{ex.Message} Please ensure that a valid token is provided and try again", null); } } diff --git a/src/LCT.Common/FileOperations.cs b/src/LCT.Common/FileOperations.cs index 69fa79f1..bd834838 100644 --- a/src/LCT.Common/FileOperations.cs +++ b/src/LCT.Common/FileOperations.cs @@ -193,5 +193,80 @@ private static void BackupTheGivenFile(string folderPath, string fileName) Environment.ExitCode = -1; } } + /// + /// writes the content to the specified file + /// + /// + /// dataToWrite + /// folderPath + /// fileNameWithExtension + /// projectName + public string WriteContentToReportNotApprovedFile(T dataToWrite, string folderPath, string fileNameWithExtension, string name) + { + try + { + Logger.Debug($"WriteContentToReportNotApprovedFile():folderpath-{folderPath},fileNameWithExtension-{fileNameWithExtension}," + + $"Name-{name}"); + string jsonString = JsonConvert.SerializeObject(dataToWrite, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + string fileName = $"{name}_{fileNameWithExtension}"; + + string filePath = Path.Combine(folderPath, fileName); + Logger.Debug($"filePath-{filePath}"); + File.WriteAllText(filePath, jsonString); + + } + catch (IOException e) + { + Logger.Debug($"WriteContentToReportNotApprovedFile():Error:", e); + return "failure"; + } + catch (UnauthorizedAccessException e) + { + Logger.Debug($"WriteContentToReportNotApprovedFile():Error:", e); + return "failure"; + } + catch (SecurityException e) + { + Logger.Debug($"WriteContentToReportNotApprovedFile():Error:", e); + return "failure"; + } + Logger.Debug($"WriteContentToReportNotApprovedFile():End"); + return "success"; + + } + public string WriteContentToMultipleVersionsFile(T dataToWrite, string folderPath, string fileNameWithExtension, string projectName) + { + try + { + Logger.Debug($"WriteContentToMultipleVersionsFile():folderpath-{folderPath},fileNameWithExtension-{fileNameWithExtension}," + + $"projectName-{projectName}"); + string jsonString = JsonConvert.SerializeObject(dataToWrite, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + string fileName = $"{projectName}_{fileNameWithExtension}"; + + string filePath = Path.Combine(folderPath, fileName); + Logger.Debug($"filePath-{filePath}"); + BackupTheGivenFile(folderPath, fileName); + File.WriteAllText(filePath, jsonString); + + } + catch (IOException e) + { + Logger.Debug($"WriteContentToMultipleVersionsFile():Error:", e); + return "failure"; + } + catch (UnauthorizedAccessException e) + { + Logger.Debug($"WriteContentToMultipleVersionsFile():Error:", e); + return "failure"; + } + catch (SecurityException e) + { + Logger.Debug($"WriteContentToMultipleVersionsFile():Error:", e); + return "failure"; + } + Logger.Debug($"WriteContentToMultipleVersionsFile():End"); + return "success"; + + } } } diff --git a/src/LCT.Common/Interface/IFileOperations.cs b/src/LCT.Common/Interface/IFileOperations.cs index 03ddd803..a4d1c119 100644 --- a/src/LCT.Common/Interface/IFileOperations.cs +++ b/src/LCT.Common/Interface/IFileOperations.cs @@ -41,5 +41,23 @@ public interface IFileOperations /// comparisonBOM data /// filePath public string WriteContentToCycloneDXFile(T dataToWrite, string filePath, string fileNameWithExtension); + + /// + /// Writes the given content to the file + /// + /// Any type + /// Data to write + /// Folder path to save the file + /// File Name with Extension + public string WriteContentToReportNotApprovedFile(T dataToWrite, string folderPath, string fileNameWithExtension, string name); + + /// + /// Writes the given content to the file + /// + /// Any type + /// Data to write + /// Folder path to save the file + /// File Name with Extension + public string WriteContentToMultipleVersionsFile(T dataToWrite, string folderPath, string fileNameWithExtension, string projectName); } } diff --git a/src/LCT.Common/Model/MultipleVersionValues.cs b/src/LCT.Common/Model/MultipleVersionValues.cs new file mode 100644 index 00000000..437e0d1e --- /dev/null +++ b/src/LCT.Common/Model/MultipleVersionValues.cs @@ -0,0 +1,30 @@ +// -------------------------------------------------------------------------------------------------------------------- +// SPDX-FileCopyrightText: 2024 Siemens AG +// +// SPDX-License-Identifier: MIT +// -------------------------------------------------------------------------------------------------------------------- + +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace LCT.Common.Model +{ + /// + /// MultipleVersionValues model + /// + [ExcludeFromCodeCoverage] + public class MultipleVersionValues + { + public string ComponentName { get; set; } + public string ComponentVersion { get; set; } + public string PackageFoundIn { get; set; } + + } + + public class MultipleVersions + { + public List Npm { get; set; } + public List Nuget { get; set; } + public List Conan { get; set; } + } +} diff --git a/src/LCT.PackageIdentifier/ConanProcessor.cs b/src/LCT.PackageIdentifier/ConanProcessor.cs index 1207dd38..e920874e 100644 --- a/src/LCT.PackageIdentifier/ConanProcessor.cs +++ b/src/LCT.PackageIdentifier/ConanProcessor.cs @@ -9,6 +9,8 @@ using LCT.APICommunications.Model.AQL; using LCT.Common; using LCT.Common.Constants; +using LCT.Common.Interface; +using LCT.Common.Model; using LCT.PackageIdentifier.Interface; using LCT.PackageIdentifier.Model; using LCT.Services.Interface; @@ -60,11 +62,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) if (componentsWithMultipleVersions.Count != 0) { - Logger.Warn($"Multiple versions detected :\n"); - foreach (var item in componentsWithMultipleVersions) - { - Logger.Warn($"Component Name : {item.Name}\nComponent Version : {item.Version}\nPackage Found in : {item.Description}\n"); - } + CreateFileForMultipleVersions(componentsWithMultipleVersions, appSettings); } bom.Components = componentsForBOM; @@ -160,6 +158,50 @@ public static bool IsDevDependency(ConanPackage component, List buildNod #endregion #region private methods + + private static void CreateFileForMultipleVersions(List componentsWithMultipleVersions, CommonAppSettings appSettings) + { + MultipleVersions multipleVersions = new MultipleVersions(); + IFileOperations fileOperations = new FileOperations(); + string filename = $"{appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}"; + if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath)) + { + multipleVersions.Conan = new List(); + foreach (var conanPackage in componentsWithMultipleVersions) + { + conanPackage.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : conanPackage.Description; + + MultipleVersionValues jsonComponents = new MultipleVersionValues(); + jsonComponents.ComponentName = conanPackage.Name; + jsonComponents.ComponentVersion = conanPackage.Version; + jsonComponents.PackageFoundIn = conanPackage.Description; + multipleVersions.Conan.Add(jsonComponents); + } + fileOperations.WriteContentToMultipleVersionsFile(multipleVersions, appSettings.BomFolderPath, FileConstant.multipleversionsFileName, appSettings.SW360ProjectName); + Logger.Warn($"\nTotal Multiple versions detected {multipleVersions.Conan.Count} and details can be found at {appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}\n"); + } + else + { + string json = File.ReadAllText(filename); + MultipleVersions myDeserializedClass = JsonConvert.DeserializeObject(json); + List conanComponents = new List(); + foreach (var conanPackage in componentsWithMultipleVersions) + { + conanPackage.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : conanPackage.Description; + + MultipleVersionValues jsonComponents = new MultipleVersionValues(); + jsonComponents.ComponentName = conanPackage.Name; + jsonComponents.ComponentVersion = conanPackage.Version; + jsonComponents.PackageFoundIn = conanPackage.Description; + + conanComponents.Add(jsonComponents); + } + myDeserializedClass.Conan = conanComponents; + + fileOperations.WriteContentToMultipleVersionsFile(myDeserializedClass, appSettings.BomFolderPath, FileConstant.multipleversionsFileName, appSettings.SW360ProjectName); + Logger.Warn($"\nTotal Multiple versions detected {conanComponents.Count} and details can be found at {appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}\n"); + } + } private void ParsingInputFileForBOM(CommonAppSettings appSettings, ref Bom bom) { List configFiles; diff --git a/src/LCT.PackageIdentifier/NpmProcessor.cs b/src/LCT.PackageIdentifier/NpmProcessor.cs index 2479a7aa..b0707658 100644 --- a/src/LCT.PackageIdentifier/NpmProcessor.cs +++ b/src/LCT.PackageIdentifier/NpmProcessor.cs @@ -9,6 +9,8 @@ using LCT.APICommunications.Model.AQL; using LCT.Common; using LCT.Common.Constants; +using LCT.Common.Interface; +using LCT.Common.Model; using LCT.PackageIdentifier.Interface; using LCT.PackageIdentifier.Model; using LCT.Services.Interface; @@ -62,11 +64,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings) if (componentsWithMultipleVersions.Count != 0) { - Logger.Warn($"Multiple versions detected :\n"); - foreach (var item in componentsWithMultipleVersions) - { - Logger.Warn($"Component Name : {item.Name}\nComponent Version : {item.Version}\nPackage Found in : {item.Description}\n"); - } + CreateFileForMultipleVersions(componentsWithMultipleVersions, appSettings); } bom.Components = componentsForBOM; bom.Dependencies = dependencies; @@ -133,6 +131,51 @@ public static List ParsePackageLockJson(string filepath, CommonAppSet return lstComponentForBOM; } + private static void CreateFileForMultipleVersions(List componentsWithMultipleVersions, CommonAppSettings appSettings) + { + MultipleVersions multipleVersions = new MultipleVersions(); + IFileOperations fileOperations = new FileOperations(); + string filename = $"{appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}"; + if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath)) + { + multipleVersions.Npm = new List(); + foreach (var npmpackage in componentsWithMultipleVersions) + { + npmpackage.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : npmpackage.Description; + + MultipleVersionValues jsonComponents = new MultipleVersionValues(); + jsonComponents.ComponentName = npmpackage.Name; + jsonComponents.ComponentVersion = npmpackage.Version; + jsonComponents.PackageFoundIn = npmpackage.Description; + multipleVersions.Npm.Add(jsonComponents); + } + fileOperations.WriteContentToMultipleVersionsFile(multipleVersions, appSettings.BomFolderPath, FileConstant.multipleversionsFileName, appSettings.SW360ProjectName); + Logger.Warn($"\nTotal Multiple versions detected {multipleVersions.Npm.Count} and details can be found at {appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}\n"); + } + else + { + string json = File.ReadAllText(filename); + MultipleVersions myDeserializedClass = JsonConvert.DeserializeObject(json); + List npmComponents = new List(); + foreach (var npmpackage in componentsWithMultipleVersions) + { + npmpackage.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : npmpackage.Description; + + MultipleVersionValues jsonComponents = new MultipleVersionValues(); + jsonComponents.ComponentName = npmpackage.Name; + jsonComponents.ComponentVersion = npmpackage.Version; + jsonComponents.PackageFoundIn = npmpackage.Description; + + npmComponents.Add(jsonComponents); + } + myDeserializedClass.Npm = npmComponents; + + fileOperations.WriteContentToMultipleVersionsFile(myDeserializedClass, appSettings.BomFolderPath, FileConstant.multipleversionsFileName, appSettings.SW360ProjectName); + Logger.Warn($"\nTotal Multiple versions detected {npmComponents.Count} and details can be found at {appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}\n"); + } + } + + private static void GetPackagesForBom(string filepath, ref List bundledComponents, ref List lstComponentForBOM, ref int noOfDevDependent, IEnumerable depencyComponentList) { BomCreator.bomKpiData.ComponentsinPackageLockJsonFile += depencyComponentList.Count(); diff --git a/src/LCT.PackageIdentifier/NugetProcessor.cs b/src/LCT.PackageIdentifier/NugetProcessor.cs index 878697d0..fe4a0749 100644 --- a/src/LCT.PackageIdentifier/NugetProcessor.cs +++ b/src/LCT.PackageIdentifier/NugetProcessor.cs @@ -9,11 +9,14 @@ using LCT.APICommunications.Model.AQL; using LCT.Common; using LCT.Common.Constants; +using LCT.Common.Interface; +using LCT.Common.Model; using LCT.PackageIdentifier.Interface; using LCT.PackageIdentifier.Model; using LCT.PackageIdentifier.Model.NugetModel; using LCT.Services.Interface; using log4net; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; @@ -411,6 +414,50 @@ private void ParsingInputFileForBOM(CommonAppSettings appSettings, ref List componentsWithMultipleVersions, CommonAppSettings appSettings) + { + MultipleVersions multipleVersions = new MultipleVersions(); + IFileOperations fileOperations = new FileOperations(); + string filename = $"{appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}"; + if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath)) + { + multipleVersions.Nuget = new List(); + foreach (var nugetPackage in componentsWithMultipleVersions) + { + nugetPackage.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : nugetPackage.Description; + + MultipleVersionValues jsonComponents = new MultipleVersionValues(); + jsonComponents.ComponentName = nugetPackage.Name; + jsonComponents.ComponentVersion = nugetPackage.Version; + jsonComponents.PackageFoundIn = nugetPackage.Description; + multipleVersions.Nuget.Add(jsonComponents); + } + fileOperations.WriteContentToMultipleVersionsFile(multipleVersions, appSettings.BomFolderPath, FileConstant.multipleversionsFileName, appSettings.SW360ProjectName); + Logger.Warn($"\nTotal Multiple versions detected {multipleVersions.Nuget.Count} and details can be found at {appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}\n"); + } + else + { + string json = File.ReadAllText(filename); + MultipleVersions myDeserializedClass = JsonConvert.DeserializeObject(json); + List nugetComponents = new List(); + foreach (var nugetPackage in componentsWithMultipleVersions) + { + nugetPackage.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : nugetPackage.Description; + + MultipleVersionValues jsonComponents = new MultipleVersionValues(); + jsonComponents.ComponentName = nugetPackage.Name; + jsonComponents.ComponentVersion = nugetPackage.Version; + jsonComponents.PackageFoundIn = nugetPackage.Description; + + nugetComponents.Add(jsonComponents); + } + myDeserializedClass.Nuget = nugetComponents; + + fileOperations.WriteContentToMultipleVersionsFile(myDeserializedClass, appSettings.BomFolderPath, FileConstant.multipleversionsFileName, appSettings.SW360ProjectName); + Logger.Warn($"\nTotal Multiple versions detected {nugetComponents.Count} and details can be found at {appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}\n"); + } + } + private static void ConvertToCycloneDXModel(List listComponentForBOM, List listofComponents, List dependencies) { foreach (var prop in listofComponents) @@ -500,7 +547,7 @@ private static void ParseInputFiles(CommonAppSettings appSettings, string filepa } else { - Logger.Warn("No Proper input files found for Nuget package types."); + Logger.Warn($"Input file NOT_FOUND :{filepath}"); } } @@ -510,12 +557,7 @@ private static void CheckForMultipleVersions(CommonAppSettings appSettings, List if (componentsWithMultipleVersions.Count != 0) { - Logger.Warn($"Multiple versions detected :\n"); - foreach (var item in componentsWithMultipleVersions) - { - item.Description = !string.IsNullOrEmpty(appSettings.CycloneDxSBomTemplatePath) ? appSettings.CycloneDxSBomTemplatePath : item.Description; - Logger.Warn($"Component Name : {item.Name}\nComponent Version : {item.Version}\nPackage Found in : {item.Description}\n"); - } + CreateFileForMultipleVersions(componentsWithMultipleVersions, appSettings); } } diff --git a/src/LCT.PackageIdentifier/Program.cs b/src/LCT.PackageIdentifier/Program.cs index 24acd76d..7775ca79 100644 --- a/src/LCT.PackageIdentifier/Program.cs +++ b/src/LCT.PackageIdentifier/Program.cs @@ -24,6 +24,7 @@ using LCT.APICommunications.Interfaces; using LCT.APICommunications; using LCT.APICommunications.Model; +using System.Linq; namespace LCT.PackageIdentifier { @@ -65,6 +66,14 @@ static async Task Main(string[] args) // Validate application settings await ValidateAppsettingsFile(appSettings,projectReleases); + string listOfInlude = DisplayInclude(appSettings); + string listOfExclude = DisplayExclude(appSettings); + string listOfExcludeComponents = DisplayExcludeComponents(appSettings); + string listOfInternalRepoList = string.Empty; + if (appSettings.InternalRepoList != null) + { + listOfInternalRepoList = string.Join(",", appSettings.InternalRepoList?.ToList()); + } Logger.Logger.Log(null, Level.Notice, $"Input Parameters used in Package Identifier:\n\t" + $"PackageFilePath\t\t --> {appSettings.PackageFilePath}\n\t" + @@ -75,7 +84,12 @@ static async Task Main(string[] args) $"SW360ProjectName\t --> {appSettings.SW360ProjectName}\n\t" + $"SW360ProjectID\t\t --> {appSettings.SW360ProjectID}\n\t" + $"ProjectType\t\t --> {appSettings.ProjectType}\n\t" + - $"LogFolderPath\t\t --> {Path.GetFullPath(FolderPath)}", null); + $"LogFolderPath\t\t --> {Path.GetFullPath(FolderPath)}\n\t" + + $"InternalRepoList\t --> {listOfInternalRepoList}\n\t" + + $"Include\t\t\t --> {listOfInlude}\n\t" + + $"Exclude\t\t\t --> {listOfExclude}\n\t" + + $"ExcludeComponents\t --> {listOfExcludeComponents}\n", null); + if (appSettings.IsTestMode) Logger.Logger.Log(null, Level.Notice, $"\tMode\t\t\t --> {appSettings.Mode}\n", null); @@ -120,6 +134,152 @@ private static async Task ValidateAppsettingsFile(CommonAppSettings appSettings, ISw360ProjectService sw360ProjectService = new Sw360ProjectService(new SW360ApicommunicationFacade(sw360ConnectionSettings)); await BomValidator.ValidateAppSettings(appSettings, sw360ProjectService,projectReleases); } + private static string DisplayInclude(CommonAppSettings appSettings) + { + string totalString = string.Empty; + switch (appSettings.ProjectType.ToUpperInvariant()) + { + case "NPM": + if (appSettings.Npm.Include != null) + { + totalString = string.Join(",", appSettings.Npm.Include?.ToList()); + } + return totalString; + case "NUGET": + if (appSettings.Nuget.Include != null) + { + totalString = string.Join(",", appSettings.Nuget.Include?.ToList()); + } + return totalString; + case "MAVEN": + if (appSettings.Maven.Include != null) + { + totalString = string.Join(",", appSettings.Maven.Include?.ToList()); + } + return totalString; + case "DEBIAN": + if (appSettings.Debian.Include != null) + { + totalString = string.Join(",", appSettings.Debian.Include?.ToList()); + } + + return totalString; + case "PYTHON": + if (appSettings.Python.Include != null) + { + totalString = string.Join(",", appSettings.Python.Include?.ToList()); + } + return totalString; + case "CONAN": + if (appSettings.Conan.Include != null) + { + totalString = string.Join(",", appSettings.Conan.Include?.ToList()); + } + return totalString; + default: + Logger.Error($"Invalid ProjectType - {appSettings.ProjectType}"); + break; + } + return totalString; + } + private static string DisplayExclude(CommonAppSettings appSettings) + { + + string totalString = string.Empty; + switch (appSettings.ProjectType.ToUpperInvariant()) + { + case "NPM": + if (appSettings.Npm.Exclude != null) + { + totalString = string.Join(",", appSettings.Npm.Exclude?.ToList()); + } + return totalString; + case "NUGET": + if (appSettings.Nuget.Exclude != null) + { + totalString = string.Join(",", appSettings.Nuget.Exclude?.ToList()); + } + return totalString; + case "MAVEN": + if (appSettings.Maven.Exclude != null) + { + totalString = string.Join(",", appSettings.Maven.Exclude?.ToList()); + } + return totalString; + case "DEBIAN": + if (appSettings.Debian.Exclude != null) + { + totalString = string.Join(",", appSettings.Debian.Exclude?.ToList()); + } + return totalString; + case "PYTHON": + if (appSettings.Python.Exclude != null) + { + totalString = string.Join(",", appSettings.Python.Exclude?.ToList()); + } + return totalString; + case "CONAN": + if (appSettings.Conan.Exclude != null) + { + totalString = string.Join(",", appSettings.Conan.Exclude?.ToList()); + } + return totalString; + default: + Logger.Error($"Invalid ProjectType - {appSettings.ProjectType}"); + break; + } + return totalString; + } + + private static string DisplayExcludeComponents(CommonAppSettings appSettings) + { + + string totalString = string.Empty; + switch (appSettings.ProjectType.ToUpperInvariant()) + { + case "NPM": + if (appSettings.Npm.ExcludedComponents != null) + { + totalString = string.Join(",", appSettings.Npm.ExcludedComponents?.ToList()); + } + return totalString; + case "NUGET": + if (appSettings.Nuget.ExcludedComponents != null) + { + totalString = string.Join(",", appSettings.Nuget.ExcludedComponents?.ToList()); + } + return totalString; + case "MAVEN": + if (appSettings.Maven.ExcludedComponents != null) + { + totalString = string.Join(",", appSettings.Maven.ExcludedComponents?.ToList()); + } + return totalString; + case "DEBIAN": + if (appSettings.Debian.ExcludedComponents != null) + { + totalString = string.Join(",", appSettings.Debian.ExcludedComponents?.ToList()); + } + + return totalString; + case "PYTHON": + if (appSettings.Python.ExcludedComponents != null) + { + totalString = string.Join(",", appSettings.Python.ExcludedComponents?.ToList()); + } + return totalString; + case "CONAN": + if (appSettings.Conan.ExcludedComponents != null) + { + totalString = string.Join(",", appSettings.Conan.ExcludedComponents?.ToList()); + } + return totalString; + default: + Logger.Error($"Invalid ProjectType - {appSettings.ProjectType}"); + break; + } + return totalString; + } private static string LogFolderInitialisation(CommonAppSettings appSettings) { diff --git a/src/LCT.PackageIdentifier/Scanner.cs b/src/LCT.PackageIdentifier/Scanner.cs index 30a4c5b5..effc2502 100644 --- a/src/LCT.PackageIdentifier/Scanner.cs +++ b/src/LCT.PackageIdentifier/Scanner.cs @@ -49,7 +49,7 @@ public static List FileScanner(string rootPath, Config config) $" - {rootPath}"); } - Logger.Logger.Log(null, Level.Notice, $"\n \n Directory Location: Packages are read from the below locations: \n", null); + Logger.Logger.Log(null, Level.Notice, $"Directory Location: Packages are read from the below locations:", null); foreach (string includePattern in config.Include) { foundConfigFiles = Directory.GetFiles(rootPath, includePattern, SearchOption.AllDirectories); @@ -65,11 +65,11 @@ public static List FileScanner(string rootPath, Config config) if (allFoundConfigFiles.Count == 0) { - Logger.Error("Provided package file path do not contain valid input files."); + Logger.Error(" Provided package file path do not contain valid input files."); Environment.Exit(-1); } - Logger.Logger.Log(null, Level.Notice, $"\n----------------------------------------------------", null); + return allFoundConfigFiles; } @@ -78,8 +78,7 @@ private static void CheckingForExcludedFiles(Config config, IFileOperations file { if (!IsExcluded(configFile, config.Exclude)) { - string currentDirectory = Path.GetDirectoryName(configFile); - Logger.Logger.Log(null, Level.Info, $" {currentDirectory} \n", null); + Logger.Logger.Log(null, Level.Info, $" Input file FOUND :{configFile}", null); allFoundConfigFiles.Add(configFile); fileOperations.ValidateFilePath(configFile); diff --git a/src/LCT.SW360PackageCreator/ComponentCreator.cs b/src/LCT.SW360PackageCreator/ComponentCreator.cs index b24f3332..28b5d791 100644 --- a/src/LCT.SW360PackageCreator/ComponentCreator.cs +++ b/src/LCT.SW360PackageCreator/ComponentCreator.cs @@ -505,7 +505,7 @@ private async Task ComponentAndReleaseAvailable(ComparisonBomData item, { if (item.ComponentStatus == Dataconstant.Available && item.ReleaseStatus == Dataconstant.Available) { - Logger.Logger.Log(null, Level.Notice, $"Release exists : Name - {item.Name} , version - {item.Version}", null); + Logger.Logger.Log(null, Level.Notice, $"Release exists in SW360 : Name - {item.Name} , version - {item.Version}", null); string releaseLink = item.ReleaseLink ?? string.Empty; string releaseId = CommonHelper.GetSubstringOfLastOccurance(releaseLink, "/"); if (!string.IsNullOrWhiteSpace(releaseId)) diff --git a/src/LCT.SW360PackageCreator/Program.cs b/src/LCT.SW360PackageCreator/Program.cs index 3d3f84a4..25419dbb 100644 --- a/src/LCT.SW360PackageCreator/Program.cs +++ b/src/LCT.SW360PackageCreator/Program.cs @@ -64,7 +64,6 @@ static async Task Main(string[] args) Logger.Logger.Log(null, Level.Notice, $"Input parameters used in Package Creator:\n\t" + $"BomFilePath\t\t --> {appSettings.BomFilePath}\n\t" + $"SW360Url\t\t --> {appSettings.SW360URL}\n\t" + - $"FossologyUrl\t\t --> {appSettings.Fossologyurl}\n\t" + $"SW360AuthTokenType\t --> {appSettings.SW360AuthTokenType}\n\t" + $"SW360ProjectName\t --> {appSettings.SW360ProjectName}\n\t" + $"SW360ProjectID\t\t --> {appSettings.SW360ProjectID}\n\t" + From 5ea50eb721298d4449596c0221bb8692114f864e Mon Sep 17 00:00:00 2001 From: Chalapala RaghavendraReddy Date: Mon, 3 Jun 2024 17:22:38 +0530 Subject: [PATCH 23/24] new changes --- src/LCT.PackageIdentifier/ConanProcessor.cs | 2 +- src/LCT.PackageIdentifier/NpmProcessor.cs | 2 +- src/LCT.PackageIdentifier/NugetProcessor.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/LCT.PackageIdentifier/ConanProcessor.cs b/src/LCT.PackageIdentifier/ConanProcessor.cs index e920874e..7fe8b23e 100644 --- a/src/LCT.PackageIdentifier/ConanProcessor.cs +++ b/src/LCT.PackageIdentifier/ConanProcessor.cs @@ -164,7 +164,7 @@ private static void CreateFileForMultipleVersions(List componentsWith MultipleVersions multipleVersions = new MultipleVersions(); IFileOperations fileOperations = new FileOperations(); string filename = $"{appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}"; - if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath)) + if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath) || (!File.Exists(filename))) { multipleVersions.Conan = new List(); foreach (var conanPackage in componentsWithMultipleVersions) diff --git a/src/LCT.PackageIdentifier/NpmProcessor.cs b/src/LCT.PackageIdentifier/NpmProcessor.cs index b0707658..8f4b5bf1 100644 --- a/src/LCT.PackageIdentifier/NpmProcessor.cs +++ b/src/LCT.PackageIdentifier/NpmProcessor.cs @@ -136,7 +136,7 @@ private static void CreateFileForMultipleVersions(List componentsWith MultipleVersions multipleVersions = new MultipleVersions(); IFileOperations fileOperations = new FileOperations(); string filename = $"{appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}"; - if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath)) + if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath) || (!File.Exists(filename))) { multipleVersions.Npm = new List(); foreach (var npmpackage in componentsWithMultipleVersions) diff --git a/src/LCT.PackageIdentifier/NugetProcessor.cs b/src/LCT.PackageIdentifier/NugetProcessor.cs index fe4a0749..a4156ea1 100644 --- a/src/LCT.PackageIdentifier/NugetProcessor.cs +++ b/src/LCT.PackageIdentifier/NugetProcessor.cs @@ -419,7 +419,7 @@ private static void CreateFileForMultipleVersions(List componentsWith MultipleVersions multipleVersions = new MultipleVersions(); IFileOperations fileOperations = new FileOperations(); string filename = $"{appSettings.BomFolderPath}\\{appSettings.SW360ProjectName}_{FileConstant.multipleversionsFileName}"; - if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath)) + if (string.IsNullOrEmpty(appSettings.IdentifierBomFilePath) || (!File.Exists(filename))) { multipleVersions.Nuget = new List(); foreach (var nugetPackage in componentsWithMultipleVersions) From 41bb4157745d9bd14d1dec7b0affe96b415345a3 Mon Sep 17 00:00:00 2001 From: karthika Date: Tue, 11 Jun 2024 13:02:45 +0530 Subject: [PATCH 24/24] Merged with latest development --- src/LCT.Common/CycloneDXBomParser.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/LCT.Common/CycloneDXBomParser.cs b/src/LCT.Common/CycloneDXBomParser.cs index 48d27972..90f57023 100644 --- a/src/LCT.Common/CycloneDXBomParser.cs +++ b/src/LCT.Common/CycloneDXBomParser.cs @@ -15,9 +15,6 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Security.Cryptography; -using System.Text; -using static CycloneDX.Models.Component; namespace LCT.Common { @@ -97,6 +94,6 @@ public static void CheckValidComponentsForProjectType(List bom, strin } } } - + } }