diff --git a/rest/resource-server/src/docs/asciidoc/api-guide.adoc b/rest/resource-server/src/docs/asciidoc/api-guide.adoc index 648b4288e4..31feb10efe 100644 --- a/rest/resource-server/src/docs/asciidoc/api-guide.adoc +++ b/rest/resource-server/src/docs/asciidoc/api-guide.adoc @@ -306,4 +306,4 @@ include::clearingRequests.adoc[] include::obligations.adoc[] include::moderationRequests.adoc[] include::fossology.adoc[] - +include::schedule.adoc[] diff --git a/rest/resource-server/src/docs/asciidoc/schedule.adoc b/rest/resource-server/src/docs/asciidoc/schedule.adoc new file mode 100644 index 0000000000..5c260c098c --- /dev/null +++ b/rest/resource-server/src/docs/asciidoc/schedule.adoc @@ -0,0 +1,25 @@ +// +// Copyright Siemens AG, 2023. 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-schedule]] +=== Schedule + +The Schedule resource is used to get and list the Schedule requests. + +[[unschedule-services]] +==== Cancel all schedule services. + +A `DELETE` request will cancel all the services. + +===== Example request +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 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 new file mode 100644 index 0000000000..92fac7b548 --- /dev/null +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/ScheduleAdminController.java @@ -0,0 +1,61 @@ +/* + * Copyright Siemens AG, 2023-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 + */ + +package org.eclipse.sw360.rest.resourceserver.schedule; + +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; + +import org.apache.thrift.TException; +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.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; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +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 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) + public ResponseEntity unscheduleAllServices()throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + RequestStatus requestStatus = scheduleService.cancelAllServices(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 new file mode 100644 index 0000000000..e412684ca7 --- /dev/null +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/schedule/Sw360ScheduleService.java @@ -0,0 +1,45 @@ +/* + * Copyright Siemens AG, 2023-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 + */ + +package org.eclipse.sw360.rest.resourceserver.schedule; + +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.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.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Service +@Slf4j +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class Sw360ScheduleService { + + public RequestStatus cancelAllServices(User sw360User) throws TException { + try { + if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) { + RequestStatus requestStatus = new ThriftClients().makeScheduleClient().unscheduleAllServices(sw360User); + return requestStatus; + } else { + throw new HttpMessageNotReadableException("User is not admin"); + } + } catch (TException e) { + throw new TException(e.getMessage()); + } + } + +} diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ApiSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ApiSpecTest.java index 5a498964ee..ab953728f2 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ApiSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ApiSpecTest.java @@ -183,6 +183,7 @@ public void should_document_index() throws Exception { linkWithRel("sw360:obligations").description("The <>"), linkWithRel("sw360:moderationRequests").description("The <>"), linkWithRel("sw360:fossology").description("The <>"), + linkWithRel("sw360:schedule").description("The <>"), linkWithRel("curies").description("The Curies for documentation"), linkWithRel("profile").description("The profiles of the REST resources") ), 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 new file mode 100644 index 0000000000..7042da0c38 --- /dev/null +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ScheduleSpecTest.java @@ -0,0 +1,70 @@ +/* + * Copyright Siemens AG, 2023-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 + */ + +package org.eclipse.sw360.rest.resourceserver.restdocs; + +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 org.eclipse.sw360.datahandler.thrift.users.User; +import org.eclipse.sw360.rest.resourceserver.TestHelper; +import org.eclipse.sw360.rest.resourceserver.schedule.Sw360ScheduleService; +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.hateoas.MediaTypes; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ScheduleSpecTest extends TestRestDocsSpecBase { + @Value("${sw360.test-user-id}") + private String testUserId; + + @Value("${sw360.test-user-password}") + private String testUserPassword; + + @MockBean + private Sw360UserService userServiceMock; + + @MockBean + private Sw360ScheduleService scheduleServiceMock; + + @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); + + } + + @Test + public void should_document_cancel_all_schedule() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(delete("/api/schedule/unscheduleAllServices") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()); + } +}