From cf1872a5898fdced56fd95bca0b1df11d0e6171c Mon Sep 17 00:00:00 2001 From: Nikesh kumar Date: Thu, 14 Dec 2023 14:59:19 +0530 Subject: [PATCH] feat(rest): Create new endpoint for schedule CVE and schedule attachment deletion. Signed-off-by: Nikesh kumar --- .../src/docs/asciidoc/schedule.adoc | 69 +++++++++++++++++- .../schedule/ScheduleAdminController.java | 59 +++++++++++++-- .../schedule/Sw360ScheduleService.java | 70 ++++++++++++++++-- .../restdocs/ScheduleSpecTest.java | 71 +++++++++++++++++-- 4 files changed, 252 insertions(+), 17 deletions(-) diff --git a/rest/resource-server/src/docs/asciidoc/schedule.adoc b/rest/resource-server/src/docs/asciidoc/schedule.adoc index 5c260c098c..2f541f2e70 100644 --- a/rest/resource-server/src/docs/asciidoc/schedule.adoc +++ b/rest/resource-server/src/docs/asciidoc/schedule.adoc @@ -8,6 +8,7 @@ // SPDX-License-Identifier: EPL-2.0 // + [[resources-schedule]] === Schedule @@ -22,4 +23,70 @@ A `DELETE` request will cancel all the services. include::{snippets}/should_document_cancel_all_schedule/curl-request.adoc[] ===== Example response -include::{snippets}/should_document_cancel_all_schedule/http-response.adoc[] \ No newline at end of file +include::{snippets}/should_document_cancel_all_schedule/http-response.adoc[] + +[[schedule-cve]] +==== Schedule cve service + +A `POST` request will schedule the cve service. + +===== Example request +include::{snippets}/should_document_schedule_cve_service/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_schedule_cve_service/http-response.adoc[] + +[[unschedule-cve]] +==== Unschedule cve search + +A `DELETE` request will unschedule the cve search. + +===== Example request +include::{snippets}/should_document_unschedule_cve_search/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_unschedule_cve_search/http-response.adoc[] + +[[schedule-service]] +==== Schedule service for attachment deletion from local FS. + +A `POST` request will schedule attachment deletion. + +===== Example request +include::{snippets}/should_document_schedule_service_from_local/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_schedule_service_from_local/http-response.adoc[] + +[[cancel-schedule]] +==== Cancel schedule attachment from local fs. + +A `DELETE` request will schedule attachment deletion. + +===== Example request +include::{snippets}/should_document_cancel_schedule_attachment/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_cancel_schedule_attachment/http-response.adoc[] + +[[delete-attachment]] +==== Delete attachment from local fs. + +A `DELETE` request will schedule attachment deletion. + +===== Example request +include::{snippets}/should_document_delete_old_attachment_from_local/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_delete_old_attachment_from_local/http-response.adoc[] + +[[cve-search]] +==== Schedule cve search. + +A `POST` request will schedule the cve search. + +===== Example request +include::{snippets}/should_document_schedule_cve_search/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_schedule_cve_search/http-response.adoc[] diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/ScheduleAdminController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/ScheduleAdminController.java index 92fac7b548..b27316835c 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/ScheduleAdminController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/ScheduleAdminController.java @@ -17,6 +17,7 @@ import org.eclipse.sw360.datahandler.thrift.RequestStatus; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper; +import org.eclipse.sw360.datahandler.thrift.RequestSummary; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.rest.webmvc.BasePathAwareController; import org.springframework.data.rest.webmvc.RepositoryLinksResource; @@ -30,20 +31,20 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import lombok.NonNull; import lombok.RequiredArgsConstructor; - + @BasePathAwareController @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RestController @SecurityRequirement(name = "tokenAuth") -public class ScheduleAdminController implements RepresentationModelProcessor { +public class ScheduleAdminController implements RepresentationModelProcessor { public static final String SCHEDULE_URL = "/schedule"; - + @NonNull private final RestControllerHelper restControllerHelper; - + @NonNull private Sw360ScheduleService scheduleService; - + @Override public RepositoryLinksResource process(RepositoryLinksResource resource) { @@ -58,4 +59,52 @@ public ResponseEntity unscheduleAllServices()throws TException { HttpStatus status = HttpStatus.OK; return new ResponseEntity<>(requestStatus, status); } + + @RequestMapping(value = SCHEDULE_URL + "/cveService", method = RequestMethod.POST) + public ResponseEntity scheduleCve()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestSummary requestSummary = scheduleService.scheduleCveSearch(sw360User); + HttpStatus status = HttpStatus.OK; + return new ResponseEntity<>(requestSummary, status); + } + + @RequestMapping(value = SCHEDULE_URL + "/unscheduleCve", method = RequestMethod.DELETE) + public ResponseEntity unscheduleCveSearch()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestStatus requestStatus = scheduleService.cancelCveSearch(sw360User); + HttpStatus status = HttpStatus.OK; + return new ResponseEntity<>(requestStatus, status); + } + + @RequestMapping(value = SCHEDULE_URL + "/deleteAttachment", method = RequestMethod.POST) + public ResponseEntity scheduleDeleteAttachment()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestSummary requestSummary = scheduleService.deleteAttachmentService(sw360User); + HttpStatus status = HttpStatus.OK; + return new ResponseEntity<>(requestSummary, status); + } + + @RequestMapping(value = SCHEDULE_URL + "/unScheduleDeleteAttachment", method = RequestMethod.DELETE) + public ResponseEntity unscheduleDeleteAttachment()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestStatus requestStatus = scheduleService.cancelDeleteAttachment(sw360User); + HttpStatus status = HttpStatus.OK; + return new ResponseEntity<>(requestStatus, status); + } + + @RequestMapping(value = SCHEDULE_URL + "/DeleteOldAttachment", method = RequestMethod.DELETE) + public ResponseEntity attachmentDeleteLocalFS()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestStatus requestStatus = scheduleService.cancelAttachmentDeletionLocalFS(sw360User); + HttpStatus status = HttpStatus.OK; + return new ResponseEntity<>(requestStatus, status); + } + + @RequestMapping(value = SCHEDULE_URL + "/cveSearch", method = RequestMethod.POST) + public ResponseEntity cveSearch()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestStatus requestStatus = scheduleService.triggerCveSearch(sw360User); + HttpStatus status = HttpStatus.OK; + return new ResponseEntity<>(requestStatus, status); + } } diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/Sw360ScheduleService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/Sw360ScheduleService.java index e412684ca7..356c3cb864 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/Sw360ScheduleService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/Sw360ScheduleService.java @@ -11,35 +11,91 @@ package org.eclipse.sw360.rest.resourceserver.schedule; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.thrift.TException; import org.eclipse.sw360.datahandler.permissions.PermissionUtils; import org.eclipse.sw360.datahandler.thrift.RequestStatus; +import org.eclipse.sw360.datahandler.thrift.RequestSummary; +import org.eclipse.sw360.datahandler.thrift.SW360Exception; import org.eclipse.sw360.datahandler.thrift.ThriftClients; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.datahandler.thrift.users.UserGroup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; @Service -@Slf4j @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class Sw360ScheduleService { + private static final Logger log = LogManager.getLogger(Sw360ScheduleService.class); + + private RequestSummary scheduleService(User sw360User, String serviceName) throws TException { + try { + if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { + return new ThriftClients().makeScheduleClient().scheduleService(serviceName); + } else { + throw new SW360Exception("Access Denied").setErrorCode(403); + } + } catch (SW360Exception sw360Exp) { + if (sw360Exp.getErrorCode() == 403) { + throw new AccessDeniedException("User has not admin access"); + } + } + } + + private RequestStatus unscheduleService(User sw360User, String serviceName) throws TException { + try { + if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { + return new ThriftClients().makeScheduleClient().unscheduleService(serviceName, sw360User); + } else { + throw new SW360Exception("Access Denied").setErrorCode(403); + } + } catch (SW360Exception sw360Exp) { + if (sw360Exp.getErrorCode() == 403) { + throw new AccessDeniedException("User has not admin access"); + } + } + } public RequestStatus cancelAllServices(User sw360User) throws TException { try { if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { - RequestStatus requestStatus = new ThriftClients().makeScheduleClient().unscheduleAllServices(sw360User); - return requestStatus; + return new ThriftClients().makeScheduleClient().unscheduleAllServices(sw360User); } else { - throw new HttpMessageNotReadableException("User is not admin"); + throw new SW360Exception("Access Denied").setErrorCode(403); + } + } catch (SW360Exception sw360Exp) { + if (sw360Exp.getErrorCode() == 403) { + throw new AccessDeniedException("User has not admin access"); } - } catch (TException e) { - throw new TException(e.getMessage()); } } + public RequestSummary scheduleCveSearch(User sw360User) throws TException { + return scheduleService(sw360User, ThriftClients.CVESEARCH_SERVICE); + } + + public RequestStatus cancelCveSearch(User sw360User) throws TException { + return unscheduleService(sw360User, ThriftClients.CVESEARCH_SERVICE); + } + + public RequestSummary deleteAttachmentService(User sw360User) throws TException { + return scheduleService(sw360User, ThriftClients.DELETE_ATTACHMENT_SERVICE); + } + + public RequestStatus cancelDeleteAttachment(User sw360User) throws TException { + return unscheduleService(sw360User, ThriftClients.DELETE_ATTACHMENT_SERVICE); + } + + public RequestStatus cancelAttachmentDeletionLocalFS(User sw360User) throws TException { + return new ThriftClients().makeAttachmentClient().deleteOldAttachmentFromFileSystem(); + } + + public RequestStatus triggerCveSearch(User sw360User) throws TException { + return new ThriftClients().makeCvesearchClient().update(); + } } diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ScheduleSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ScheduleSpecTest.java index 7042da0c38..2afc36e8b4 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ScheduleSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ScheduleSpecTest.java @@ -13,14 +13,14 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; 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 static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; + +import org.eclipse.sw360.datahandler.thrift.RequestSummary; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.rest.resourceserver.TestHelper; import org.eclipse.sw360.rest.resourceserver.schedule.Sw360ScheduleService; @@ -47,15 +47,23 @@ public class ScheduleSpecTest extends TestRestDocsSpecBase { @MockBean private Sw360ScheduleService scheduleServiceMock; + private RequestSummary requestSummary = new RequestSummary(); + @Before public void before() throws TException { - + User sw360User = new User(); sw360User.setId("123456789"); sw360User.setEmail("admin@sw360.org"); sw360User.setFullname("John Doe"); given(this.userServiceMock.getUserByEmailOrExternalId("admin@sw360.org")).willReturn(sw360User); given(this.scheduleServiceMock.cancelAllServices(any())).willReturn(RequestStatus.SUCCESS); + given(this.scheduleServiceMock.scheduleCveSearch(any())).willReturn(requestSummary); + given(this.scheduleServiceMock.cancelCveSearch(any())).willReturn(RequestStatus.SUCCESS); + given(this.scheduleServiceMock.deleteAttachmentService(any())).willReturn(requestSummary); + given(this.scheduleServiceMock.cancelDeleteAttachment(any())).willReturn(RequestStatus.SUCCESS); + given(this.scheduleServiceMock.cancelAttachmentDeletionLocalFS(any())).willReturn(RequestStatus.SUCCESS); + given(this.scheduleServiceMock.triggerCveSearch(any())).willReturn(RequestStatus.SUCCESS); } @@ -67,4 +75,59 @@ public void should_document_cancel_all_schedule() throws Exception { .accept(MediaTypes.HAL_JSON)) .andExpect(status().isOk()); } + + @Test + public void should_document_schedule_cve_service() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(post("/api/schedule/cveService") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void should_document_unschedule_cve_search() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(delete("/api/schedule/unscheduleCve") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void should_document_schedule_service_from_local() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(post("/api/schedule/deleteAttachment") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void should_document_schedule_cve_search() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(post("/api/schedule/cveSearch") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void should_document_cancel_schedule_attachment() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(delete("/api/schedule/unScheduleDeleteAttachment") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } + + @Test + public void should_document_delete_old_attachment_from_local() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(delete("/api/schedule/DeleteOldAttachment") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } + }