Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rest): Create new endpoint for schedule CVE and schedule attachment deletion in admin tab. #2243

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 68 additions & 1 deletion rest/resource-server/src/docs/asciidoc/schedule.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// SPDX-License-Identifier: EPL-2.0
//


[[resources-schedule]]
=== Schedule

Expand All @@ -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[]
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[]
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -30,33 +31,81 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@BasePathAwareController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RestController
@SecurityRequirement(name = "tokenAuth")
@SecurityRequirement(name = "basic")
public class ScheduleAdminController implements RepresentationModelProcessor<RepositoryLinksResource> {
public static final String SCHEDULE_URL = "/schedule";

@NonNull
private final RestControllerHelper restControllerHelper;

@NonNull
private Sw360ScheduleService scheduleService;


@Override
public RepositoryLinksResource process(RepositoryLinksResource resource) {
resource.add(linkTo(ScheduleAdminController.class).slash("api/schedule").withRel("schedule"));
return resource;
}

@RequestMapping(value = SCHEDULE_URL + "/unscheduleAllServices", method = RequestMethod.DELETE)
@RequestMapping(value = SCHEDULE_URL + "/unscheduleAllServices", method = RequestMethod.POST)
public ResponseEntity<?> unscheduleAllServices()throws TException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
RequestStatus requestStatus = scheduleService.cancelAllServices(sw360User);
HttpStatus status = HttpStatus.OK;
HttpStatus status = HttpStatus.ACCEPTED;
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.ACCEPTED;
return new ResponseEntity<>(requestSummary, status);
}

@RequestMapping(value = SCHEDULE_URL + "/unscheduleCve", method = RequestMethod.POST)
public ResponseEntity<?> unscheduleCveSearch()throws TException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
RequestStatus requestStatus = scheduleService.cancelCveSearch(sw360User);
HttpStatus status = HttpStatus.ACCEPTED;
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.ACCEPTED;
return new ResponseEntity<>(requestSummary, status);
}

@RequestMapping(value = SCHEDULE_URL + "/unScheduleDeleteAttachment", method = RequestMethod.POST)
public ResponseEntity<?> unscheduleDeleteAttachment()throws TException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
RequestStatus requestStatus = scheduleService.cancelDeleteAttachment(sw360User);
HttpStatus status = HttpStatus.ACCEPTED;
return new ResponseEntity<>(requestStatus, status);
}

@RequestMapping(value = SCHEDULE_URL + "/cancelAttachmentDeletion", method = RequestMethod.POST)
public ResponseEntity<?> attachmentDeleteLocalFS()throws TException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
RequestStatus requestStatus = scheduleService.cancelAttachmentDeletionLocalFS(sw360User);
HttpStatus status = HttpStatus.ACCEPTED;
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.ACCEPTED;
return new ResponseEntity<>(requestStatus, status);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,101 @@

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)) {
ThriftClients thriftClients = new ThriftClients();
return thriftClients.makeScheduleClient().scheduleService(serviceName);
} else {
throw new AccessDeniedException("User does not have admin access");
}
} catch (SW360Exception sw360Exp) {
if (sw360Exp.getErrorCode() == 403) {
throw new AccessDeniedException("User does not have admin access", sw360Exp);
} else {
throw sw360Exp;
}
}
}

private RequestStatus unscheduleService(User sw360User, String serviceName) throws TException {
try {
if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) {
ThriftClients thriftClients = new ThriftClients();
return thriftClients.makeScheduleClient().unscheduleService(serviceName, sw360User);
} else {
throw new AccessDeniedException("User does not have admin access");
}
} catch (SW360Exception sw360Exp) {
if (sw360Exp.getErrorCode() == 403) {
throw new AccessDeniedException("User does not have admin access", sw360Exp);
} else {
throw sw360Exp;
}
}
}

public RequestStatus cancelAllServices(User sw360User) throws TException {
try {
if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) {
RequestStatus requestStatus = new ThriftClients().makeScheduleClient().unscheduleAllServices(sw360User);
return requestStatus;
ThriftClients thriftClients = new ThriftClients();
return thriftClients.makeScheduleClient().unscheduleAllServices(sw360User);
} else {
throw new AccessDeniedException("User does not have admin access");
}
} catch (SW360Exception sw360Exp) {
if (sw360Exp.getErrorCode() == 403) {
throw new AccessDeniedException("User does not have admin access", sw360Exp);
} else {
throw new HttpMessageNotReadableException("User is not admin");
throw sw360Exp;
}
} 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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

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;
Expand All @@ -40,23 +43,80 @@ 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("[email protected]");
sw360User.setFullname("John Doe");
given(this.userServiceMock.getUserByEmailOrExternalId("[email protected]")).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);

}

@Test
public void should_document_cancel_all_schedule() throws Exception {
mockMvc.perform(delete("/api/schedule/unscheduleAllServices")
mockMvc.perform(post("/api/schedule/unscheduleAllServices")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isAccepted());
}

@Test
public void should_document_schedule_cve_service() throws Exception {
mockMvc.perform(post("/api/schedule/cveService")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk());
.andExpect(status().isAccepted());
}

@Test
public void should_document_unschedule_cve_search() throws Exception {
mockMvc.perform(post("/api/schedule/unscheduleCve")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isAccepted());
}

@Test
public void should_document_schedule_service_from_local() throws Exception {
mockMvc.perform(post("/api/schedule/deleteAttachment")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isAccepted());
}

@Test
public void should_document_schedule_cve_search() throws Exception {
mockMvc.perform(post("/api/schedule/cveSearch")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isAccepted());
}

@Test
public void should_document_cancel_schedule_attachment() throws Exception {
mockMvc.perform(post("/api/schedule/unScheduleDeleteAttachment")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isAccepted());
}

@Test
public void should_document_delete_old_attachment_from_local() throws Exception {
mockMvc.perform(post("/api/schedule/cancelAttachmentDeletion")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isAccepted());
}

}