-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rest): create new enpoint to upload component csv file.
Signed-off-by: Nikesh kumar <kumar.nikesh@simens.com>
- Loading branch information
Nikesh kumar
committed
May 16, 2024
1 parent
e71c5e5
commit 159a984
Showing
6 changed files
with
450 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright Siemens AG, 2024. 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 | ||
// | ||
|
||
[[resources-importExport]] | ||
=== ImportExport | ||
|
||
The ImportExport resource is used to get and upload request. | ||
|
||
[[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[] |
116 changes: 116 additions & 0 deletions
116
.../main/java/org/eclipse/sw360/rest/resourceserver/importexport/ImportExportController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* 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.importexport; | ||
|
||
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; | ||
|
||
import java.io.IOException; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.apache.thrift.TException; | ||
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.datahandler.thrift.users.User; | ||
import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper; | ||
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; | ||
import org.springframework.hateoas.server.RepresentationModelProcessor; | ||
import org.springframework.http.HttpStatus.Series; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.HttpMediaTypeNotAcceptableException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestMethod; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.Parameter; | ||
import io.swagger.v3.oas.annotations.security.SecurityRequirement; | ||
import lombok.NonNull; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@BasePathAwareController | ||
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) | ||
@RestController | ||
@SecurityRequirement(name = "tokenAuth") | ||
public class ImportExportController implements RepresentationModelProcessor<RepositoryLinksResource> { | ||
public static final String IMPORTEXPORT_URL = "/importExport"; | ||
|
||
private static final MediaType form = null; | ||
|
||
@NonNull | ||
private final RestControllerHelper restControllerHelper; | ||
|
||
@NonNull | ||
private final Sw360ImportExportService importExportService; | ||
|
||
@Override | ||
public RepositoryLinksResource process(RepositoryLinksResource resource) { | ||
resource.add(linkTo(ImportExportController.class).slash("api/importExport").withRel("importExport")); | ||
return resource; | ||
} | ||
|
||
@Operation( | ||
summary = "Upload component csv file.", | ||
description = "Upload component csv file.", | ||
tags = {"Component"} | ||
) | ||
@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<RequestSummary> uploadComponentCsv( | ||
@Parameter(description = "The component csv file to be uploaded.") | ||
@RequestParam("componentFile") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws TException,ServletException,IOException{ | ||
|
||
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 = {"Release"} | ||
) | ||
@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<RequestSummary> uploadReleaseCsv( | ||
@Parameter(description = "The release csv file to be uploaded.") | ||
@RequestParam("releaseFile") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws TException,ServletException,IOException{ | ||
|
||
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 = {"Component"} | ||
) | ||
@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<RequestSummary> uploadComponentAttachment( | ||
@Parameter(description = "The component attachment csv file to be uploaded.") | ||
@RequestParam("attachmentFile") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws TException,ServletException,IOException{ | ||
|
||
User sw360User = restControllerHelper.getSw360UserFromAuthentication(); | ||
RequestSummary requestSummary =importExportService.uploadComponentAttachment(sw360User, file, request); | ||
return ResponseEntity.ok(requestSummary); | ||
} | ||
} |
150 changes: 150 additions & 0 deletions
150
...ain/java/org/eclipse/sw360/rest/resourceserver/importexport/Sw360ImportExportService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/* | ||
* 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.importexport; | ||
|
||
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.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 javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import javax.servlet.http.HttpSession; | ||
import javax.servlet.http.Part; | ||
|
||
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.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; | ||
import org.eclipse.sw360.datahandler.permissions.PermissionUtils; | ||
import org.eclipse.sw360.datahandler.thrift.RequestSummary; | ||
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentService; | ||
import org.eclipse.sw360.datahandler.thrift.components.ComponentService; | ||
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.importer.ComponentAttachmentCSVRecord; | ||
import org.eclipse.sw360.importer.ComponentCSVRecord; | ||
import org.eclipse.sw360.importer.ReleaseLinkCSVRecord; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.converter.HttpMessageNotReadableException; | ||
import org.springframework.stereotype.Service; | ||
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 lombok.RequiredArgsConstructor; | ||
|
||
@SuppressWarnings("serial") | ||
@Service | ||
@RequiredArgsConstructor(onConstructor = @__(@Autowired)) | ||
public class Sw360ImportExportService { | ||
@Value("${sw360.thrift-server-url:http://localhost:8080}") | ||
private String thriftServerUrl; | ||
|
||
@JsonInclude | ||
public RequestSummary uploadComponent(User sw360User, MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException, TException, ServletException { | ||
if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { | ||
throw new RuntimeException("Unable to upload component csv file. User is not admin"); | ||
} | ||
List<CSVRecord> releaseRecords = getCSVFromRequest(request, "file"); | ||
FluentIterable<ComponentCSVRecord> compCSVRecords = convertCSVRecordsToCompCSVRecords(releaseRecords); | ||
ComponentService.Iface sw360ComponentClient = getThriftComponentClient(); | ||
VendorService.Iface sw360VendorClient = getThriftVendorClient(); | ||
AttachmentService.Iface sw360AttachmentClient = getThriftAttachmentClient(); | ||
RequestSummary requestSummary = writeToDatabase(compCSVRecords, sw360ComponentClient, sw360VendorClient, sw360AttachmentClient, sw360User); | ||
return requestSummary; | ||
} | ||
|
||
private List<CSVRecord> 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<Part> 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."); | ||
} | ||
|
||
private ComponentService.Iface getThriftComponentClient() throws TTransportException { | ||
THttpClient thriftClient = new THttpClient(thriftServerUrl + "/components/thrift"); | ||
TProtocol protocol = new TCompactProtocol(thriftClient); | ||
return new ComponentService.Client(protocol); | ||
} | ||
|
||
private VendorService.Iface getThriftVendorClient() throws TTransportException { | ||
THttpClient thriftClient = new THttpClient(thriftServerUrl + "/vendors/thrift"); | ||
TProtocol protocol = new TCompactProtocol(thriftClient); | ||
return new VendorService.Client(protocol); | ||
} | ||
|
||
private AttachmentService.Iface getThriftAttachmentClient() throws TTransportException { | ||
THttpClient thriftClient = new THttpClient(thriftServerUrl + "/attachments/thrift"); | ||
TProtocol protocol = new TCompactProtocol(thriftClient); | ||
return new AttachmentService.Client(protocol); | ||
} | ||
|
||
public RequestSummary uploadReleaseLink(User sw360User, MultipartFile file, HttpServletRequest request) throws IOException, TException, ServletException{ | ||
if (!PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { | ||
throw new RuntimeException("Unable to upload component csv file. User is not admin"); | ||
} | ||
List<CSVRecord> releaseLinkRecords = getCSVFromRequest(request, "file"); | ||
FluentIterable<ReleaseLinkCSVRecord> csvRecords = convertCSVRecordsToReleaseLinkCSVRecords(releaseLinkRecords); | ||
ComponentService.Iface sw360ComponentClient = getThriftComponentClient(); | ||
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 RuntimeException("Unable to upload component attachment csv file. User is not admin"); | ||
} | ||
List<CSVRecord> attachmentRecords = getCSVFromRequest(request, "file"); | ||
FluentIterable<ComponentAttachmentCSVRecord> compCSVRecords = convertCSVRecordsToComponentAttachmentCSVRecords(attachmentRecords); | ||
ComponentService.Iface sw360ComponentClient = getThriftComponentClient(); | ||
AttachmentService.Iface sw360AttachmentClient = getThriftAttachmentClient(); | ||
final RequestSummary requestSummary = writeAttachmentsToDatabase(compCSVRecords, sw360User, sw360ComponentClient, sw360AttachmentClient); | ||
return requestSummary; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.