diff --git a/rest/resource-server/src/docs/asciidoc/vendors.adoc b/rest/resource-server/src/docs/asciidoc/vendors.adoc index 65c3ea3086..431d1de9c2 100644 --- a/rest/resource-server/src/docs/asciidoc/vendors.adoc +++ b/rest/resource-server/src/docs/asciidoc/vendors.adoc @@ -118,3 +118,17 @@ include::{snippets}/should_document_get_export_vendor/curl-request.adoc[] ===== Example response include::{snippets}/should_document_get_export_vendor/http-response.adoc[] + +[[resources-vendor-merge]] +==== Merge vendors + +A `PATCH` request will merge the source vendor with the target vendor. + +===== Request structure +include::{snippets}/should_document_merge_vendor/request-fields.adoc[] + +===== Example request +include::{snippets}/should_document_merge_vendor/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_merge_vendor/http-response.adoc[] \ No newline at end of file diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/Sw360VendorService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/Sw360VendorService.java index f4bade9696..42ddd01395 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/Sw360VendorService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/Sw360VendorService.java @@ -186,4 +186,20 @@ public Set getAllReleaseList(String vendorId) throws TException { Set releases = componentsClient.getReleasesByVendorId(vendorId); return releases; } + + public RequestStatus mergeVendors(String vendorTargetId, String vendorSourceId, Vendor vendorSelection, User user) throws TException { + VendorService.Iface sw360VendorClient = getThriftVendorClient(); + RequestStatus requestStatus; + requestStatus = sw360VendorClient.mergeVendors(vendorTargetId, vendorSourceId, vendorSelection, user); + + if (requestStatus == RequestStatus.IN_USE) { + throw new HttpMessageNotReadableException("Vendor already in use."); + } else if (requestStatus == RequestStatus.FAILURE) { + throw new HttpMessageNotReadableException("Cannot merge these vendors"); + } else if (requestStatus == RequestStatus.ACCESS_DENIED) { + throw new RuntimeException("Access denied"); + } + + return requestStatus; + } } diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/VendorController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/VendorController.java index eae860e1a9..572ed6c60f 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/VendorController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/vendor/VendorController.java @@ -274,6 +274,29 @@ public ResponseEntity exportVendor(HttpServletResponse response) throws TExce return ResponseEntity.ok(HttpStatus.OK); } + @PreAuthorize("hasAuthority('WRITE')") + @Operation( + summary = "Merge two vendors.", + description = "Merge source vendor into target vendor.", + tags = {"Vendor"} + ) + @RequestMapping(value = VENDORS_URL + "/mergeVendors", method = RequestMethod.PATCH) + public ResponseEntity mergeVendors( + @Parameter(description = "The id of the merge target vendor.") + @RequestParam(value = "mergeTargetId", required = true) String mergeTargetId, + @Parameter(description = "The id of the merge source vendor.") + @RequestParam(value = "mergeSourceId", required = true) String mergeSourceId, + @Parameter(description = "The merge selection.") + @RequestBody Vendor mergeSelection + ) throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + + // perform the real merge, update merge target and delete merge sources + RequestStatus requestStatus = vendorService.mergeVendors(mergeTargetId, mergeSourceId, mergeSelection, sw360User); + + return new ResponseEntity<>(requestStatus, HttpStatus.OK); + } + private void copyDataStreamToResponse(HttpServletResponse response, ByteBuffer buffer) throws IOException { FileCopyUtils.copy(buffer.array(), response.getOutputStream()); } diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/VendorSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/VendorSpecTest.java index ce51eed399..6c33e3fbe1 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/VendorSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/VendorSpecTest.java @@ -36,11 +36,10 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; -import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; -import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; @RunWith(SpringJUnit4ClassRunner.class) public class VendorSpecTest extends TestRestDocsSpecBase { @@ -99,6 +98,7 @@ public void before() throws TException{ given(this.vendorServiceMock.getAllReleaseList(eq(vendor.getId()))).willReturn(releases); given(this.vendorServiceMock.getVendors()).willReturn(vendorList); + given(this.vendorServiceMock.mergeVendors(eq(vendor.getId()),eq(vendor2.getId()), any(), any())).willReturn(RequestStatus.SUCCESS); given(this.vendorServiceMock.vendorUpdate(any(), any(), any())).willReturn(RequestStatus.SUCCESS); given(this.vendorServiceMock.getVendorById(eq(vendor.getId()))).willReturn(vendor); given(this.vendorServiceMock.deleteVendorByid(any(), any())).willReturn(RequestStatus.SUCCESS); @@ -235,4 +235,27 @@ public void should_document_get_export_vendor() throws Exception{ .andExpect(status().isOk()) .andDo(this.documentationHandler.document()); } + + @Test + public void should_document_merge_vendor() throws Exception{ + mockMvc.perform(patch("/api/vendors/mergeVendors") + .contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(vendor)) + .header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword)) + .param("mergeTargetId", "87654321") + .param("mergeSourceId", "17653524") + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()) + .andDo(this.documentationHandler.document( + queryParameters( + parameterWithName("mergeSourceId").description("Id of a source vendor to merge"), + parameterWithName("mergeTargetId").description("Id of a target vendor to merge") + ), + requestFields( + fieldWithPath("fullName").description("The full name of the vendor"), + fieldWithPath("shortName").description("The short name of the vendor"), + fieldWithPath("url").description("The vendor's home page URL"), + fieldWithPath("type").description("The type of document") + ))); + } }