diff --git a/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java b/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java index a7afdd61c6..c389abe7ce 100644 --- a/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java +++ b/libraries/datahandler/src/main/java/org/eclipse/sw360/datahandler/common/SW360Constants.java @@ -138,6 +138,8 @@ public class SW360Constants { public static final String ADD_LIST_EMAIL = "listEmail"; public static final String DEPARTMENT_KEY = "departmentKey"; public static final String DELETE_LIST_EMAIL = "deleteEmail"; + public static final String SBOM = "sbom"; + /** * Hashmap containing the name field for each type. @@ -162,6 +164,8 @@ public class SW360Constants { AttachmentType.COMPONENT_LICENSE_INFO_COMBINED, AttachmentType.INITIAL_SCAN_REPORT); public static final Collection 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"; + public static final String CONTENT_TYPE_XML = "application/xml"; + public static final String CONTENT_TYPE_JSON = "application/json"; public static final String NOTIFICATION_CLASS_RELEASE = "release"; public static final String NOTIFICATION_CLASS_MODERATION_REQUEST = "moderation"; diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java index 0fd25f7324..f59f220d4c 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportController.java @@ -7,6 +7,7 @@ import static com.google.common.base.Strings.isNullOrEmpty; import static org.eclipse.sw360.datahandler.common.SW360Constants.CONTENT_TYPE_OPENXML_SPREADSHEET; +import static org.eclipse.sw360.datahandler.common.SW360Constants.XML_FILE_EXTENSION; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import java.io.IOException; @@ -84,7 +85,7 @@ public void getProjectReport( @Parameter(description = "Module name.", schema = @Schema(allowableValues = { SW360Constants.PROJECTS, SW360Constants.COMPONENTS, SW360Constants.LICENSES, LICENSE_INFO, LICENSES_RESOURCE_BUNDLE, SW360Constants.PROJECT_RELEASE_SPREADSHEET_WITH_ECCINFO, - EXPORT_CREATE_PROJ_CLEARING_REPORT + EXPORT_CREATE_PROJ_CLEARING_REPORT,SW360Constants.SBOM })) @RequestParam(value = "module", required = true) String module, @Parameter(description = "Exclude release version from the license info file") @@ -101,6 +102,8 @@ public void getProjectReport( @RequestParam(value = "externalIds", required = false, defaultValue = "") String externalIds, @Parameter(description = "Generate report for only current project or with Sub projects. Can be supplied with modules [" + LICENSE_INFO + ", " + EXPORT_CREATE_PROJ_CLEARING_REPORT + "]") @RequestParam(value = "withSubProject", required = false, defaultValue = "false") boolean withSubProject, + @Parameter(description = "Type of SBOM file extention") + @RequestParam(value = "bomType", required = false) String bomType, HttpServletRequest request, HttpServletResponse response ) throws TException { @@ -139,6 +142,10 @@ public void getProjectReport( exportProjectCreateClearingRequest(response, sw360User, module, projectId, excludeReleaseVersion, generatorClassName, variant, template, externalIds); break; + case SW360Constants.SBOM: + exportSBOM(response, sw360User, module, projectId,generatorClassName, + bomType,withSubProject); + break; default: break; } @@ -371,4 +378,28 @@ private String getBaseUrl(HttpServletRequest request) { String ctx = request.getContextPath(); return url.substring(0, url.length() - uri.length() + ctx.length()) + "/"; } + + + private void exportSBOM( + HttpServletResponse response, User sw360User, String module, String projectId, + String generatorClassName, String bomType, boolean withSubProject + ) throws TException { + try { + String buff = sw360ReportService.getProjectSBOMBuffer(sw360User, projectId,bomType,withSubProject); + response.setContentType(SW360Constants.CONTENT_TYPE_JSON); + String fileName = sw360ReportService.getSBOMFileName(sw360User, projectId, module, bomType); + + if (null == buff) { + throw new TException("No data available for the user " + sw360User.getEmail()); + } + if(SW360Constants.XML_FILE_EXTENSION.equalsIgnoreCase(bomType)){ + response.setContentType(SW360Constants.CONTENT_TYPE_XML); + } + response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName)); + copyDataStreamToResponse(response, ByteBuffer.wrap(buff.getBytes())); + } catch (Exception e) { + log.error(e); + throw new TException(e.getMessage()); + } + } } diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java index e0526c8090..b81b61049a 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/report/SW360ReportService.java @@ -35,6 +35,8 @@ import org.eclipse.sw360.exporter.ReleaseExporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.eclipse.sw360.datahandler.thrift.RequestSummary; +import org.eclipse.sw360.datahandler.thrift.RequestStatus; import lombok.RequiredArgsConstructor; @@ -437,4 +439,41 @@ public ByteBuffer getProjectReleaseSpreadSheetWithEcc(User user, String projectI } return ByteBuffer.wrap(IOUtils.toByteArray(exporter.makeExcelExport(releases))); } + + public String getProjectSBOMBuffer(User user, String projectId, String bomType, boolean withSubProject) throws TException { + String bomString = ""; + try { + if (CommonUtils.isNotNullEmptyOrWhitespace(projectId)) { + + RequestSummary summary = projectclient.exportCycloneDxSbom(projectId, bomType, withSubProject, user); + RequestStatus status = summary.getRequestStatus(); + if (RequestStatus.FAILED_SANITY_CHECK.equals(status)) { + bomString = "{\"status\": \"" + status.name() + "\"}"; + } else if (RequestStatus.ACCESS_DENIED.equals(status)) { + bomString = "{\"status\": \"" + status.name() + "\", \"message\": \"" + SW360Constants.SBOM_IMPORT_EXPORT_ACCESS_USER_ROLE + "\"}"; + } else if (RequestStatus.FAILURE.equals(status)) { + bomString = "{\"status\": \"" + status.name() + "\", \"message\": \"" + summary.getMessage() + "\"}"; + } else { + bomString = summary.getMessage(); + } + } + } catch (TException e) { + log.error("An error occured while generating SBOM file for export.", e); + } + return bomString; + } + + public String getSBOMFileName(User user, String projectId, String module, String bomType) throws TException { + String documentName = ""; + if(projectId != null && !projectId.equalsIgnoreCase("null")) { + Project project = projectclient.getProjectById(projectId, user); + documentName = String.format("project_%s(%s)_%s.xml", project.getName(), project.getVersion(), + SW360Utils.getCreatedOnTime(), "_SBOM"); + if(SW360Constants.JSON_FILE_EXTENSION.equalsIgnoreCase(bomType)){ + documentName = String.format("project_%s(%s)_%s.json", project.getName(), project.getVersion(), + SW360Utils.getCreatedOnTime(), "_SBOM"); + } + } + return documentName; + } }