Skip to content

Commit

Permalink
feat(rest): includeAllAttachments parameter in licenseInfo endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: afsahsyeda <afsah.syeda@siemens-healthineers.com>
  • Loading branch information
afsahsyeda committed Sep 10, 2024
1 parent eec9f15 commit 8b5ec8d
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ private static String findFirstSpdxChildContent(Node parent, String localName) {
* Get license name of spdx:ExtractedLicensingInfo and spdx:ListedLicense.
*/
private static String getExtractedLicenseName(Node extractedLicenseInfo) {
String[] tagNames = { SPDX_NAME, SPDX_LICENSE_NAME_VERSION_1, SPDX_LICENSE_ID };
String[] tagNames = {SPDX_LICENSE_ID, SPDX_NAME, SPDX_LICENSE_NAME_VERSION_1};
for (String tagName : tagNames) {
String name = findFirstSpdxNodeContent(extractedLicenseInfo, tagName);
if (!isNullEmptyOrWhitespace(name)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,17 @@ public static Object[][] dataProviderAdd() {
// @formatter:off
return new Object[][] {
{ spdxExampleFile,
Arrays.asList("Apache-2.0", "LGPL-2.0", "1", "GPL-2.0", "CyberNeko License", "2"),
Arrays.asList("Apache-2.0", "LGPL-2.0", "1", "GPL-2.0", "3", "2"),
4,
"Copyright 2008-2010 John Smith",
Sets.newHashSet("3", "LGPL-2.0") },
{ spdx11ExampleFile,
Arrays.asList("4", "1", "Apache-2.0", "2", "Apache-1.0", "MPL-1.1", "CyberNeko License"),
Arrays.asList("4", "1", "Apache-2.0", "2", "Apache-1.0", "MPL-1.1", "3"),
2,
"Hewlett-Packard Development Company, LP",
Sets.newHashSet("1", "2", "3", "4", "Apache-1.0", "Apache-2.0", "MPL-1.1") },
{ spdx12ExampleFile,
Arrays.asList("4", "1", "Apache-2.0", "2", "Apache-1.0", "MPL-1.1", "CyberNeko License"),
Arrays.asList("4", "1", "Apache-2.0", "2", "Apache-1.0", "MPL-1.1", "3"),
3,
"Hewlett-Packard Development Company, LP",
Sets.newHashSet("1", "2", "3", "4", "Apache-1.0", "Apache-2.0", "MPL-1.1") },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ public class SW360Constants {
.put(TYPE_PACKAGE, "name version")
.build();

public static final Collection<AttachmentType> LICENSE_INFO_ATTACHMENT_TYPES = Arrays.asList(AttachmentType.COMPONENT_LICENSE_INFO_XML, AttachmentType.COMPONENT_LICENSE_INFO_COMBINED);
public static final Collection<AttachmentType> LICENSE_INFO_ATTACHMENT_TYPES = Arrays.asList(AttachmentType.COMPONENT_LICENSE_INFO_XML,
AttachmentType.COMPONENT_LICENSE_INFO_COMBINED);
public static final Collection<AttachmentType> INITIAL_LICENSE_INFO_ATTACHMENT_TYPES = Arrays.asList(AttachmentType.COMPONENT_LICENSE_INFO_XML,
AttachmentType.COMPONENT_LICENSE_INFO_COMBINED, AttachmentType.INITIAL_SCAN_REPORT);
public static final Collection<AttachmentType> SOURCE_CODE_ATTACHMENT_TYPES = Arrays.asList(AttachmentType.SOURCE, AttachmentType.SOURCE_SELF);
public static final String CONTENT_TYPE_OPENXML_SPREADSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ public static List<ReleaseLink> getLinkedReleasesWithAccessibility(Project proje
}
return Collections.emptyList();
}

public static List<ReleaseLink> getLinkedReleaseRelations(Release release, ThriftClients thriftClients, Logger log) {
if (release != null && release.getReleaseIdToRelationship() != null) {
try {
Expand All @@ -536,7 +536,7 @@ public static List<ReleaseLink> getLinkedReleaseRelationsWithAccessibility(Relea
}
return Collections.emptyList();
}

public static Predicate<String> startsWith(final String prefix) {
return new Predicate<String>() {
@Override
Expand Down Expand Up @@ -684,7 +684,7 @@ public static <T> Map<String, T> putAccessibleReleaseNamesInMap(Map<String, T> m
}
return releaseNamesMap;
}

public static <T> Map<String, T> putProjectNamesInMap(Map<String, T> map, List<Project> projects) {
if(map == null || projects == null) {
return Collections.emptyMap();
Expand Down
14 changes: 14 additions & 0 deletions rest/resource-server/src/docs/asciidoc/projects.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,20 @@ include::{snippets}/should_document_get_download_license_info/curl-request.adoc[
===== Example response
include::{snippets}/should_document_get_download_license_info/http-response.adoc[]

[[resources-project-get-download-licenseinfo-with-all-attachments]]
==== Download License Info with all attachments

A `GET` request is used to download the project's license information. The resulting file will include findings from either the CLX or ISR attachment of a linked release.

===== Request parameter
include::{snippets}/should_document_get_download_license_info_with_all_attachemnts/request-parameters.adoc[]

===== Example request
include::{snippets}/should_document_get_download_license_info_with_all_attachemnts/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_get_download_license_info_with_all_attachemnts/http-response.adoc[]

[[resources-project-usedby-list]]
==== Resources using the project

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1368,13 +1368,21 @@ public void downloadLicenseInfo(
@Parameter(description = "The external Ids of the project", example = "376577")
@RequestParam(value = "externalIds", required = false) String externalIds,
@RequestParam(value = "template", required = false) String template,
@Parameter(description = "Generate license info including all attachments of the linked releases")
@RequestParam(value = "includeAllAttachments", required = false ) boolean includeAllAttachments,
HttpServletResponse response
) throws TException, IOException {
final User sw360User = restControllerHelper.getSw360UserFromAuthentication();
final Project sw360Project = projectService.getProjectForUserById(id, sw360User);
List<ProjectLink> mappedProjectLinks = new ArrayList<>();

List<ProjectLink> mappedProjectLinks = projectService.createLinkedProjects(sw360Project,
if (includeAllAttachments) {
mappedProjectLinks = projectService.createLinkedProjects(sw360Project,
projectService.filterAndSortAllAttachments(SW360Constants.INITIAL_LICENSE_INFO_ATTACHMENT_TYPES), true, sw360User);
} else {
mappedProjectLinks = projectService.createLinkedProjects(sw360Project,
projectService.filterAndSortAttachments(SW360Constants.LICENSE_INFO_ATTACHMENT_TYPES), true, sw360User);
}

List<AttachmentUsage> attchmntUsg = attachmentService.getAttachemntUsages(id);

Expand Down Expand Up @@ -1407,14 +1415,17 @@ public void downloadLicenseInfo(
Release release = componentService.getReleaseById(releaseLinkId, sw360User);
for (final Attachment attachment : attachments) {
String attachemntContentId = attachment.getAttachmentContentId();
if (usedAttachmentContentIds.containsKey(attachemntContentId)) {
boolean includeConcludedLicense = usedAttachmentContentIds.get(attachemntContentId);
List<LicenseInfoParsingResult> licenseInfoParsingResult = licenseInfoService
.getLicenseInfoForAttachment(release, sw360User, attachemntContentId, includeConcludedLicense);
excludedLicensesPerAttachments.put(attachemntContentId,
getExcludedLicenses(excludedLicenseIds, licenseInfoParsingResult));
if (includeAllAttachments) {
selectedReleaseAndAttachmentIds.get(releaseLinkId).put(attachemntContentId,
includeConcludedLicense);
false);
} else {
if (usedAttachmentContentIds.containsKey(attachemntContentId)) {
boolean includeConcludedLicense = usedAttachmentContentIds.get(attachemntContentId);
List<LicenseInfoParsingResult> licenseInfoParsingResult = licenseInfoService
.getLicenseInfoForAttachment(release, sw360User, attachemntContentId, includeConcludedLicense);
excludedLicensesPerAttachments.put(attachemntContentId, getExcludedLicenses(excludedLicenseIds, licenseInfoParsingResult));
selectedReleaseAndAttachmentIds.get(releaseLinkId).put(attachemntContentId, includeConcludedLicense);
}
}
}
})));
Expand All @@ -1435,7 +1446,9 @@ public void downloadLicenseInfo(
fileName = orgToTemplate.get(template);
}

final LicenseInfoFile licenseInfoFile = licenseInfoService.getLicenseInfoFile(sw360Project, sw360User, outputGeneratorClassNameWithVariant, selectedReleaseAndAttachmentIds, excludedLicensesPerAttachments, externalIds, fileName);
final LicenseInfoFile licenseInfoFile = licenseInfoService.getLicenseInfoFile(sw360Project, sw360User,
outputGeneratorClassNameWithVariant, selectedReleaseAndAttachmentIds, excludedLicensesPerAttachments,
externalIds, fileName);
byte[] byteContent = licenseInfoFile.bufferForGeneratedOutput().array();
response.setContentType(outputFormatInfo.getMimeType());
response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", filename));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,32 @@ public Function<ProjectLink, ProjectLink> filterAndSortAttachments(Collection<At
.collect(Collectors.toList())));
}

public Function<ProjectLink, ProjectLink> filterAndSortAllAttachments(Collection<AttachmentType> attachmentTypes) {
Predicate<Attachment> filter = att -> attachmentTypes.contains(att.getAttachmentType());
return createProjectLinkMapper(rl -> {
List<Attachment> attachments = nullToEmptyList(rl.getAttachments()).stream()
.filter(filter)
.collect(Collectors.toList());

if (attachments.size() > 1) {
Optional<Attachment> acceptedAttachment = attachments.stream()
.filter(att -> att.getCheckStatus() == CheckStatus.ACCEPTED).findFirst();

if (acceptedAttachment.isPresent()) {
attachments = List.of(acceptedAttachment.get());
} else {
attachments = attachments.stream()
.filter(att -> SW360Constants.LICENSE_INFO_ATTACHMENT_TYPES.contains(att.getAttachmentType()))
.limit(1)
.collect(Collectors.toList());
}
}

rl.setAttachments(attachments);
return rl;
});
}

public Function<ProjectLink, ProjectLink> createProjectLinkMapper(Function<ReleaseLink, ReleaseLink> releaseLinkMapper){
return (projectLink) -> {
List<ReleaseLink> mappedReleaseLinks = nullToEmptyList(projectLink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ public void before() throws TException, IOException {
osi.setStatus(ObligationStatus.OPEN);
osi.setObligationType(obligation.getObligationType());
Map<String, ObligationStatusInfo> obligationStatusMap = Map.of(obligation.getTitle(), osi);

ObligationList obligationLists = new ObligationList();
obligationLists.setProjectId(project8.getId());
obligationLists.setId("009");
Expand Down Expand Up @@ -538,7 +538,7 @@ public void before() throws TException, IOException {

RequestSummary requestSummaryForCycloneDX = new RequestSummary();
requestSummaryForCycloneDX.setMessage("{\"projectId\":\"" + cycloneDXProject.getId() + "\"}");

String projectName="project_name_version_createdOn.xlsx";

AddDocumentRequestSummary requestSummaryForCR = new AddDocumentRequestSummary();
Expand Down Expand Up @@ -2073,6 +2073,25 @@ public void should_document_get_download_license_info() throws Exception {
)));
}

@Test
public void should_document_get_download_license_info_with_all_attachemnts() throws Exception {
String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword);
this.mockMvc.perform(get("/api/projects/" + project.getId()+ "/licenseinfo?generatorClassName=XhtmlGenerator&variant=DISCLOSURE&includeAllAttachments=true")
.header("Authorization", "Bearer " + accessToken)
.accept("application/xhtml+xml"))
.andExpect(status().isOk())
.andDo(this.documentationHandler
.document(requestParameters(
parameterWithName("generatorClassName")
.description("All possible values for output generator class names are "
+ Arrays.asList("DocxGenerator", "XhtmlGenerator", "TextGenerator")),
parameterWithName("variant").description("All the possible values for variants are "
+ Arrays.asList(OutputFormatVariant.values())),
parameterWithName("includeAllAttachments").description("Set this option to `true` to include all attachments from linked releases. "
+ "Note that only one attachment per release will be parsed for "
+ "license information, and if available, a CLX file will be preferred over an ISR file."))));
}

@Test
public void should_document_get_projects_releases() throws Exception {
this.mockMvc.perform(get("/api/projects/releases")
Expand Down

0 comments on commit 8b5ec8d

Please sign in to comment.