From be7606f32eb14ccc3ce30de01f619deccb4a28d7 Mon Sep 17 00:00:00 2001 From: nikesh kumar Date: Mon, 12 Feb 2024 12:36:12 +0530 Subject: [PATCH] feat(rest): create new enpoint to upload component csv file. Signed-off-by: Nikesh kumar --- .../src/docs/asciidoc/api-guide.adoc | 1 + .../src/docs/asciidoc/importExport.adoc | 58 ++++++++- .../importexport/ImportExportController.java | 78 +++++++++++- .../Sw360ImportExportService.java | 116 ++++++++++++++++-- .../restdocs/ImportExportSpec.java | 109 ++++++++++++++++ 5 files changed, 349 insertions(+), 13 deletions(-) create mode 100644 rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ImportExportSpec.java diff --git a/rest/resource-server/src/docs/asciidoc/api-guide.adoc b/rest/resource-server/src/docs/asciidoc/api-guide.adoc index 17fafca60d..cee04dd6e9 100644 --- a/rest/resource-server/src/docs/asciidoc/api-guide.adoc +++ b/rest/resource-server/src/docs/asciidoc/api-guide.adoc @@ -311,3 +311,4 @@ include::ecc.adoc[] include::importExport.adoc[] include::attachmentCleanUp.adoc[] include::databaseSanitation.adoc[] +include::importExport.adoc[] diff --git a/rest/resource-server/src/docs/asciidoc/importExport.adoc b/rest/resource-server/src/docs/asciidoc/importExport.adoc index db22a1689b..00dafa1a37 100644 --- a/rest/resource-server/src/docs/asciidoc/importExport.adoc +++ b/rest/resource-server/src/docs/asciidoc/importExport.adoc @@ -1,4 +1,3 @@ -// // Copyright Siemens AG, 2024. Part of the SW360 Portal Project. // // This program and the accompanying materials are made @@ -77,4 +76,59 @@ A `GET` request to download the component information in csv format. include::{snippets}/should_document_get_download_component_details/curl-request.adoc[] ===== Example response -include::{snippets}/should_document_get_download_component_details/http-response.adoc[] \ No newline at end of file +include::{snippets}/should_document_get_download_component_details/http-response.adoc[] + +[[upload-component]] +==== Upload component csv file. + +A `POST` request help to upload the component csv file. + +[red]#Request parameter# +|=== +|Parameter |Description +|componentFile |Upload the component CSV file. +|=== + +===== Example request +include::{snippets}/should_document_upload_component_file/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_upload_component_file/http-response.adoc[] + +[[upload-release]] +==== Upload release link csv file. + +A `POST` request help to upload the release csv file. + +[red]#Request parameter# +|=== +|Parameter |Description + +|releaseFile +|Upload the release link csv file. +|=== + +===== Example request +include::{snippets}/should_document_upload_release_link_file/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_upload_release_link_file/http-response.adoc[] + +[[upload-component-attachment]] +==== Upload component attachment file. + +A `POST` request help to upload the component attachment file. + +[red]#Request parameter# +|=== +|Parameter |Description + +|component +|Upload the component attachment file. +|=== + +===== Example request +include::{snippets}/should_document_upload_component_attachment_file/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_upload_component_attachment_file/http-response.adoc[] diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/ImportExportController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/ImportExportController.java index ac06747003..6764aa0b87 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/ImportExportController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/ImportExportController.java @@ -16,10 +16,15 @@ import java.io.IOException; import org.apache.thrift.TException; +import org.apache.thrift.transport.TTransportException; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.eclipse.sw360.datahandler.common.CommonUtils; +import org.eclipse.sw360.datahandler.thrift.RequestStatus; +import org.eclipse.sw360.datahandler.thrift.RequestSummary; +import org.eclipse.sw360.rest.resourceserver.project.ProjectController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.rest.webmvc.BasePathAwareController; import org.springframework.data.rest.webmvc.RepositoryLinksResource; @@ -38,6 +43,13 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import org.springframework.http.HttpStatus.Series; +import org.springframework.http.MediaType; +import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.NonNull; @@ -47,11 +59,13 @@ @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RestController @SecurityRequirement(name = "tokenAuth") -public class ImportExportController implements RepresentationModelProcessor { +public class ImportExportController implements RepresentationModelProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(ImportExportController.class); public static final String IMPORTEXPORT_URL = "/importExport"; + private static final MediaType form = null; + @NonNull private final RestControllerHelper restControllerHelper; @@ -114,7 +128,7 @@ public void downloadAttachmentSample(HttpServletResponse response) { ) @PreAuthorize("hasAuthority('WRITE')") @GetMapping(value = IMPORTEXPORT_URL + "/downloadAttachmentInfo") - public void downloadAttachmentInfo(HttpServletResponse response) { + public void downloadAttachmentInfo(HttpServletResponse response) throws TTransportException{ try { User sw360User = restControllerHelper.getSw360UserFromAuthentication(); importExportService.getDownloadAttachmentInfo(sw360User, response); @@ -198,4 +212,64 @@ public ResponseEntity handleGlobalException(Exception e) { LOGGER.error("Unhandled exception: {}", e.getMessage(), e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } + + @Operation( + summary = "Upload component CSV file.", + description = "Upload a component CSV file to the system.", + tags = {"ImportExport"}, + parameters = { + @Parameter(name = "Content-Type", in = ParameterIn.HEADER, required = true, description = "The content type of the request. Supported values: multipart/mixed or multipart/form-data.") + } + ) + @RequestMapping(value = IMPORTEXPORT_URL + "/uploadComponent", method = RequestMethod.POST, consumes = { + MediaType.MULTIPART_MIXED_VALUE, + MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity uploadComponentCsv( + @Parameter(description = "The component csv file to be uploaded.") @RequestParam("componentFile") MultipartFile file, + HttpServletRequest request, HttpServletResponse response) throws TException, IOException, ServletException { + + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestSummary requestSummary = importExportService.uploadComponent(sw360User, file, request, response); + return ResponseEntity.ok(requestSummary); + } + + @Operation( + summary = "Release link file.", + description = "Release link file.", + tags = {"ImportExport"}, + parameters = { + @Parameter(name = "Content-Type", in = ParameterIn.HEADER, required = true, description = "The content type of the request. Supported values: multipart/mixed or multipart/form-data."), + } + ) + @RequestMapping(value = IMPORTEXPORT_URL + "/uploadRelease", method = RequestMethod.POST, consumes = { + MediaType.MULTIPART_MIXED_VALUE, + MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity uploadReleaseCsv( + @Parameter(description = "The release csv file to be uploaded.") @RequestParam("releaseFile") MultipartFile file, + HttpServletRequest request, HttpServletResponse response) throws TException, IOException, ServletException { + + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestSummary requestSummary = importExportService.uploadReleaseLink(sw360User, file, request); + return ResponseEntity.ok(requestSummary); + } + + @Operation( + summary = "Component attachment file.", + description = "Component attachment file.", + tags = {"ImportExport"}, + parameters = { + @Parameter(name = "Content-Type", in = ParameterIn.HEADER, required = true, description = "The content type of the request. Supported values: multipart/mixed or multipart/form-data."), + } + ) + @RequestMapping(value = IMPORTEXPORT_URL + "/componentAttachment", method = RequestMethod.POST, consumes = { + MediaType.MULTIPART_MIXED_VALUE, + MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity uploadComponentAttachment( + @Parameter(description = "The component attachment csv file to be uploaded.") @RequestParam("attachmentFile") MultipartFile file, + HttpServletRequest request, HttpServletResponse response) throws TException, IOException, ServletException { + + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestSummary requestSummary = importExportService.uploadComponentAttachment(sw360User, file, request); + return ResponseEntity.ok(requestSummary); + } } diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/Sw360ImportExportService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/Sw360ImportExportService.java index 3ce26ca151..eefd4f5b4b 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/Sw360ImportExportService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/importexport/Sw360ImportExportService.java @@ -13,28 +13,53 @@ import static org.eclipse.sw360.importer.ComponentImportUtils.getFlattenedView; import static org.eclipse.sw360.importer.ComponentImportUtils.getReleasesById; +import static org.eclipse.sw360.datahandler.common.ImportCSV.readAsCSVRecords; +import static org.eclipse.sw360.importer.ComponentImportUtils.convertCSVRecordsToCompCSVRecords; +import static org.eclipse.sw360.importer.ComponentImportUtils.convertCSVRecordsToComponentAttachmentCSVRecords; +import static org.eclipse.sw360.importer.ComponentImportUtils.convertCSVRecordsToReleaseLinkCSVRecords; +import static org.eclipse.sw360.importer.ComponentImportUtils.writeAttachmentsToDatabase; +import static org.eclipse.sw360.importer.ComponentImportUtils.writeReleaseLinksToDatabase; +import static org.eclipse.sw360.importer.ComponentImportUtils.writeToDatabase; import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Consumer; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; import org.apache.thrift.TException; +import org.apache.thrift.protocol.TCompactProtocol; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.transport.THttpClient; +import org.apache.thrift.transport.TTransportException; +import org.apache.tomcat.util.http.fileupload.FileItem; +import org.apache.tomcat.util.http.fileupload.RequestContext; +import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; import org.eclipse.sw360.datahandler.common.SW360Utils; import org.eclipse.sw360.datahandler.permissions.PermissionUtils; import org.eclipse.sw360.datahandler.thrift.ReleaseRelationship; +import org.eclipse.sw360.datahandler.thrift.RequestSummary; import org.eclipse.sw360.datahandler.thrift.ThriftClients; import org.eclipse.sw360.datahandler.thrift.ThriftUtils; import org.eclipse.sw360.datahandler.thrift.attachments.Attachment; +import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentService; import org.eclipse.sw360.datahandler.thrift.components.Component; import org.eclipse.sw360.datahandler.thrift.components.ComponentService; import org.eclipse.sw360.datahandler.thrift.components.ComponentService.Iface; import org.eclipse.sw360.datahandler.thrift.components.Release; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.datahandler.thrift.users.UserGroup; +import org.eclipse.sw360.datahandler.thrift.vendors.VendorService; import org.eclipse.sw360.exporter.CSVExport; import org.eclipse.sw360.importer.ComponentAttachmentCSVRecord; import org.eclipse.sw360.importer.ComponentAttachmentCSVRecordBuilder; @@ -44,20 +69,33 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.google.common.base.Joiner; +import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Part; + import lombok.RequiredArgsConstructor; + @Service @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class Sw360ImportExportService { + @Value("${sw360.thrift-server-url:http://localhost:8080}") + private String thriftServerUrl; private final Logger log = LoggerFactory.getLogger(this.getClass()); private static final String CONTENT_DISPOSITION = "Content-Disposition"; + ThriftClients thriftClients = new ThriftClients(); public void getDownloadCsvComponentTemplate(User sw360User, HttpServletResponse response) throws IOException { if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { @@ -86,7 +124,7 @@ public void getDownloadAttachmentTemplate(User sw360User, HttpServletResponse re FileCopyUtils.copy(byteArrayInputStream, response.getOutputStream()); } - public void getDownloadAttachmentInfo(User sw360User, HttpServletResponse response) throws IOException { + public void getDownloadAttachmentInfo(User sw360User, HttpServletResponse response) throws IOException, TTransportException { List> csvRows = new ArrayList<>(); if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { throw new AccessDeniedException("User is not admin"); @@ -139,8 +177,8 @@ private void printAttachments(Set attachments, List } } - private List getComponentDetailedSummaryForExport() { - final ComponentService.Iface componentClient = getThriftComponentClient(); + private List getComponentDetailedSummaryForExport() throws TTransportException{ + final ComponentService.Iface componentClient = thriftClients.makeComponentClient(); final List componentDetailedSummaryForExport; try { @@ -153,10 +191,6 @@ private List getComponentDetailedSummaryForExport() { return componentDetailedSummaryForExport; } - private Iface getThriftComponentClient() { - return new ThriftClients().makeComponentClient(); - } - public void getDownloadReleaseSample(User sw360User, HttpServletResponse response) throws TException, IOException { if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { throw new AccessDeniedException("User is not admin"); @@ -185,7 +219,8 @@ public void getDownloadReleaseLink(User sw360User, HttpServletResponse response) } } - ByteArrayInputStream byteArrayInputStream = CSVExport.createCSV(ReleaseLinkCSVRecord.getCSVHeaderIterable(), csvRows); + ByteArrayInputStream byteArrayInputStream = CSVExport.createCSV(ReleaseLinkCSVRecord.getCSVHeaderIterable(), + csvRows); String filename = String.format("ReleaseLinkInfo_%s.csv", SW360Utils.getCreatedOn()); response.setHeader(CONTENT_DISPOSITION, String.format("Release; filename=\"%s\"", filename)); FileCopyUtils.copy(byteArrayInputStream, response.getOutputStream()); @@ -231,7 +266,8 @@ private void printReleaseLinkEntry(Component component, Release release, Release csvRows.add(releaseLinkCSVRecordBuilder.build().getCSVIterable()); } - public void getComponentDetailedExport(User sw360User, HttpServletResponse response) throws TException, IOException { + public void getComponentDetailedExport(User sw360User, HttpServletResponse response) + throws TException, IOException { if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { throw new AccessDeniedException("User is not admin"); } @@ -244,5 +280,67 @@ public void getComponentDetailedExport(User sw360User, HttpServletResponse respo String filename = String.format("ComponentsReleasesVendors_%s.csv", SW360Utils.getCreatedOn()); response.setHeader(CONTENT_DISPOSITION, String.format("Components; filename=\"%s\"", filename)); FileCopyUtils.copy(byteArrayInputStream, response.getOutputStream()); + + } + + @JsonInclude + public RequestSummary uploadComponent(User sw360User, MultipartFile file, HttpServletRequest request, + HttpServletResponse response) throws IOException, TException, ServletException { + if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { + throw new AccessDeniedException("Unable to upload component csv file. User is not admin"); + } + List releaseRecords = getCSVFromRequest(request, "file"); + FluentIterable compCSVRecords = convertCSVRecordsToCompCSVRecords(releaseRecords); + ComponentService.Iface sw360ComponentClient = thriftClients.makeComponentClient(); + VendorService.Iface sw360VendorClient = thriftClients.makeVendorClient(); + AttachmentService.Iface sw360AttachmentClient = thriftClients.makeAttachmentClient(); + RequestSummary requestSummary = writeToDatabase(compCSVRecords, sw360ComponentClient, sw360VendorClient, + sw360AttachmentClient, sw360User); + return requestSummary; + } + + private List getCSVFromRequest(HttpServletRequest request, String fileUploadFormId) + throws IOException, TException, ServletException { + final InputStream stream = getInputStreamFromRequest(request, fileUploadFormId); + return readAsCSVRecords(stream); + } + + private InputStream getInputStreamFromRequest(HttpServletRequest request, String fileUploadFormId) + throws IOException, ServletException { + Collection parts = request.getParts(); + + for (Part part : parts) { + if (!part.getName().equals(fileUploadFormId)) { + return part.getInputStream(); + } + } + throw new IOException("File not found in the request with the specified field name."); + } + + public RequestSummary uploadReleaseLink(User sw360User, MultipartFile file, HttpServletRequest request) + throws IOException, TException, ServletException { + if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { + throw new AccessDeniedException("Unable to upload component csv file. User is not admin"); + } + List releaseLinkRecords = getCSVFromRequest(request, "file"); + FluentIterable csvRecords = convertCSVRecordsToReleaseLinkCSVRecords(releaseLinkRecords); + ComponentService.Iface sw360ComponentClient = thriftClients.makeComponentClient(); + final RequestSummary requestSummary = writeReleaseLinksToDatabase(csvRecords, sw360ComponentClient, sw360User); + return requestSummary; + } + + public RequestSummary uploadComponentAttachment(User sw360User, MultipartFile file, HttpServletRequest request) + throws IOException, TException, ServletException { + if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { + throw new AccessDeniedException("Unable to upload component attachment csv file. User is not admin"); + } + List attachmentRecords = getCSVFromRequest(request, "file"); + FluentIterable compCSVRecords = convertCSVRecordsToComponentAttachmentCSVRecords( + attachmentRecords); + ComponentService.Iface sw360ComponentClient = thriftClients.makeComponentClient(); + AttachmentService.Iface sw360AttachmentClient = thriftClients.makeAttachmentClient(); + final RequestSummary requestSummary = writeAttachmentsToDatabase(compCSVRecords, sw360User, + sw360ComponentClient, sw360AttachmentClient); + return requestSummary; } } diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ImportExportSpec.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ImportExportSpec.java new file mode 100644 index 0000000000..258170ddb3 --- /dev/null +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ImportExportSpec.java @@ -0,0 +1,109 @@ +/* + * Copyright Siemens AG, 2024-2025. + * Part of the SW360 Portal Project. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ + + +package org.eclipse.sw360.rest.resourceserver.restdocs; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.IOException; + +import org.apache.thrift.TException; +import org.eclipse.sw360.datahandler.thrift.RequestStatus; +import org.eclipse.sw360.datahandler.thrift.RequestSummary; +import org.eclipse.sw360.datahandler.thrift.licenses.LicenseType; +import org.eclipse.sw360.datahandler.thrift.users.User; +import org.eclipse.sw360.rest.resourceserver.TestHelper; +import org.eclipse.sw360.rest.resourceserver.importexport.Sw360ImportExportService; +import org.eclipse.sw360.rest.resourceserver.user.Sw360UserService; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import jakarta.servlet.ServletException; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ImportExportSpec extends TestRestDocsSpecBase { + + @Value("${sw360.test-user-id}") + private String testUserId; + + @Value("${sw360.test-user-password}") + private String testUserPassword; + + @MockBean + private Sw360ImportExportService importExportService; + + private RequestSummary requestSummary = new RequestSummary(); + + @Before + @SuppressWarnings("unchecked") + public void before() throws TException, IOException, ServletException { + User sw360User = new User(); + sw360User.setId("123456789"); + sw360User.setEmail("admin@sw360.org"); + sw360User.setFullname("John Doe"); + + requestSummary.setRequestStatus(RequestStatus.SUCCESS); + LicenseType licensetype = new LicenseType(); + licensetype.setId("1234"); + licensetype.setLicenseType("wer"); + licensetype.setLicenseTypeId(123); + licensetype.setType("xyz"); + + given(this.importExportService.uploadComponent(any(), any(), any(),any())).willReturn(requestSummary); + given(this.userServiceMock.getUserByEmailOrExternalId("admin@sw360.org")).willReturn(sw360User); + given(this.importExportService.uploadReleaseLink(any(), any(), any())).willReturn(requestSummary); + given(this.importExportService.uploadComponentAttachment(any(), any(), any())).willReturn(requestSummary); + + } + + @Test + public void should_document_upload_component_file() throws Exception { + MockMultipartFile file = new MockMultipartFile("componentFile","file=@/bom.spdx.rdf".getBytes()); + String accessToken = TestHelper.generateAuthHeader(testUserId, testUserPassword); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/api/importExport/uploadComponent") + .file(file) + .header("Authorization", accessToken) + .queryParam("componentFile", "Must need to attach file."); + this.mockMvc.perform(builder).andExpect(status().isOk()).andDo(this.documentationHandler.document()); + } + + @Test + public void should_document_upload_release_link_file() throws Exception { + MockMultipartFile file = new MockMultipartFile("releaseFile","file=@/bom.spdx.rdf".getBytes()); + String accessToken = TestHelper.generateAuthHeader(testUserId, testUserPassword); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/api/importExport/uploadRelease") + .file(file) + .header("Authorization", accessToken) + .queryParam("releaseFile", "Must need to attach file."); + this.mockMvc.perform(builder).andExpect(status().isOk()).andDo(this.documentationHandler.document()); + } + + @Test + public void should_document_upload_component_attachment_file() throws Exception { + MockMultipartFile file = new MockMultipartFile("attachmentFile","file=@/bom.spdx.rdf".getBytes()); + String accessToken = TestHelper.generateAuthHeader(testUserId, testUserPassword); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/api/importExport/componentAttachment") + .file(file) + .header("Authorization", accessToken) + .queryParam("attachmentFile", "Must need to attach file."); + this.mockMvc.perform(builder).andExpect(status().isOk()).andDo(this.documentationHandler.document()); + } +}