From 7a887238861f5affe4fca52076d6fca418314967 Mon Sep 17 00:00:00 2001 From: rudra-superrr Date: Thu, 1 Jun 2023 15:56:38 +0530 Subject: [PATCH] feat(REST): New endpoint split components Signed-off-by: Muhammad Ali --- .../db/ComponentDatabaseHandler.java | 47 +++--- .../src/docs/asciidoc/components.adoc | 34 ++++ .../src/docs/asciidoc/projects.adoc | 14 ++ .../component/ComponentController.java | 32 ++++ .../component/Sw360ComponentService.java | 33 ++++ .../core/JacksonCustomizations.java | 1 - .../core/RestControllerHelper.java | 5 + .../project/ProjectController.java | 18 ++ .../restdocs/ComponentSpecTest.java | 156 +++++++++++++++++- .../restdocs/ProjectSpecTest.java | 15 ++ 10 files changed, 329 insertions(+), 26 deletions(-) diff --git a/backend/src-common/src/main/java/org/eclipse/sw360/datahandler/db/ComponentDatabaseHandler.java b/backend/src-common/src/main/java/org/eclipse/sw360/datahandler/db/ComponentDatabaseHandler.java index 9ae1156c06..a3f7a1ca67 100644 --- a/backend/src-common/src/main/java/org/eclipse/sw360/datahandler/db/ComponentDatabaseHandler.java +++ b/backend/src-common/src/main/java/org/eclipse/sw360/datahandler/db/ComponentDatabaseHandler.java @@ -944,29 +944,30 @@ private void mergeAttachments(Component mergeSelection, Component mergeTarget, C if (mergeTarget.getAttachments() == null) { mergeTarget.setAttachments(new HashSet<>()); } - - Set attachmentIdsSelected = mergeSelection.getAttachments().stream() - .map(Attachment::getAttachmentContentId).collect(Collectors.toSet()); - // add new attachments from source - Set attachmentsToAdd = new HashSet<>(); - mergeSource.getAttachments().forEach(a -> { - if (attachmentIdsSelected.contains(a.getAttachmentContentId())) { - attachmentsToAdd.add(a); - } - }); - // remove moved attachments in source - attachmentsToAdd.forEach(a -> { - mergeTarget.addToAttachments(a); - mergeSource.getAttachments().remove(a); - }); - // delete unchosen attachments from target - Set attachmentsToDelete = new HashSet<>(); - mergeTarget.getAttachments().forEach(a -> { - if (!attachmentIdsSelected.contains(a.getAttachmentContentId())) { - attachmentsToDelete.add(a); - } - }); - mergeTarget.getAttachments().removeAll(attachmentsToDelete); + if (mergeSelection.getAttachments() != null) { + Set attachmentIdsSelected = mergeSelection.getAttachments().stream() + .map(Attachment::getAttachmentContentId).collect(Collectors.toSet()); + // add new attachments from source + Set attachmentsToAdd = new HashSet<>(); + mergeSource.getAttachments().forEach(a -> { + if (attachmentIdsSelected.contains(a.getAttachmentContentId())) { + attachmentsToAdd.add(a); + } + }); + // remove moved attachments in source + attachmentsToAdd.forEach(a -> { + mergeTarget.addToAttachments(a); + mergeSource.getAttachments().remove(a); + }); + // delete unchosen attachments from target + Set attachmentsToDelete = new HashSet<>(); + mergeTarget.getAttachments().forEach(a -> { + if (!attachmentIdsSelected.contains(a.getAttachmentContentId())) { + attachmentsToDelete.add(a); + } + }); + mergeTarget.getAttachments().removeAll(attachmentsToDelete); + } } private void transferReleases(Set releaseIds, Component mergeTarget, Component mergeSource) throws SW360Exception { diff --git a/rest/resource-server/src/docs/asciidoc/components.adoc b/rest/resource-server/src/docs/asciidoc/components.adoc index e8d93fd077..e1ce5964f4 100644 --- a/rest/resource-server/src/docs/asciidoc/components.adoc +++ b/rest/resource-server/src/docs/asciidoc/components.adoc @@ -313,6 +313,40 @@ include::{snippets}/should_document_update_component/http-response.adoc[] include::{snippets}/should_document_update_component/links.adoc[] +[[resources-components-update]] +==== Merge a component + +A `PATCH` request is used to merge two components + +===== Response structure +include::{snippets}/should_document_merge_components/response-fields.adoc[] + +===== Example request +include::{snippets}/should_document_merge_components/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_merge_components/http-response.adoc[] + +===== Links +include::{snippets}/should_document_merge_components/links.adoc[] + +[[resources-components-update]] +==== Split a component + +A `PATCH` request is used to split two components + +===== Response structure +include::{snippets}/should_document_split_components/response-fields.adoc[] + +===== Example request +include::{snippets}/should_document_split_components/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_split_components/http-response.adoc[] + +===== Links +include::{snippets}/should_document_split_components/links.adoc[] + [[resources-components-delete]] ==== Delete a component diff --git a/rest/resource-server/src/docs/asciidoc/projects.adoc b/rest/resource-server/src/docs/asciidoc/projects.adoc index ebe757be91..000ca7f2e2 100644 --- a/rest/resource-server/src/docs/asciidoc/projects.adoc +++ b/rest/resource-server/src/docs/asciidoc/projects.adoc @@ -650,3 +650,17 @@ include::{snippets}/should_document_import_sbom/curl-request.adoc[] ===== Example response include::{snippets}/should_document_import_sbom/http-response.adoc[] + +[[resources-project-getprojectcount]] +==== Get project count of a user + +A `GET` request will get project count of a user. + +===== Example request +include::{snippets}/should_document_get_project_count/curl-request.adoc[] + +===== Response structure +include::{snippets}/should_document_get_project_count/response-fields.adoc[] + +===== Example response +include::{snippets}/should_document_get_project_count/http-response.adoc[] diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/ComponentController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/ComponentController.java index 4eb57d573c..c06a876ed5 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/ComponentController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/ComponentController.java @@ -696,4 +696,36 @@ private ImportBomRequestPreparation handleImportBomRequestPreparation(ImportBomR } return importBomRequestPreparationResponse; } + + @PreAuthorize("hasAuthority('WRITE')") + @RequestMapping(value = COMPONENTS_URL + "/mergecomponents", method = RequestMethod.PATCH) + public ResponseEntity mergeComponents( + @RequestParam(value = "mergeTargetId", required = true) String mergeTargetId, + @RequestParam(value = "mergeSourceId", required = true) String mergeSourceId, + @RequestBody Component mergeSelection ) throws TException { + + + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + + // perform the real merge, update merge target and delete merge sources + RequestStatus requestStatus = componentService.mergeComponents(mergeTargetId, mergeSourceId, mergeSelection, sw360User); + + return new ResponseEntity<>(requestStatus, HttpStatus.OK); + } + + @PreAuthorize("hasAuthority('WRITE')") + @RequestMapping(value = COMPONENTS_URL + "/splitComponents", method = RequestMethod.PATCH) + public ResponseEntity splitComponents( + @RequestBody Map componentMap) throws TException { + + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + + Component srcComponent = componentMap.get("srcComponent"); + Component targetComponent = componentMap.get("targetComponent"); + + // perform the real merge, update merge target and delete merge source + RequestStatus requestStatus = componentService.splitComponents(srcComponent, targetComponent, sw360User); + + return new ResponseEntity<>(requestStatus, HttpStatus.OK); + } } diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/Sw360ComponentService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/Sw360ComponentService.java index b13a841e30..a858678617 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/Sw360ComponentService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/component/Sw360ComponentService.java @@ -275,4 +275,37 @@ public ImportBomRequestPreparation prepareImportSBOM(User user, String attachmen ComponentService.Iface sw360ComponentClient = getThriftComponentClient(); return sw360ComponentClient.prepareImportBom(user, attachmentContentId); } + + public RequestStatus mergeComponents(String componentTargetId, String componentSourceId, Component componentSelection, User user) throws TException { + ComponentService.Iface sw360ComponentClient = getThriftComponentClient(); + RequestStatus requestStatus; + requestStatus = sw360ComponentClient.mergeComponents(componentTargetId, componentSourceId, componentSelection, user); + + if (requestStatus == RequestStatus.IN_USE) { + throw new HttpMessageNotReadableException("Component already in use."); + } else if (requestStatus == RequestStatus.FAILURE) { + throw new HttpMessageNotReadableException("Cannot merge these components"); + } else if (requestStatus == RequestStatus.ACCESS_DENIED) { + throw new RuntimeException("Access denied"); + } + + return requestStatus; + } + + + public RequestStatus splitComponents(Component srcComponent, Component targetComponent, User sw360User) throws TException { + ComponentService.Iface sw360ComponentClient = getThriftComponentClient(); + RequestStatus requestStatus; + requestStatus = sw360ComponentClient.splitComponent(srcComponent, targetComponent, sw360User); + + if (requestStatus == RequestStatus.IN_USE) { + throw new HttpMessageNotReadableException("Component already in use."); + } else if (requestStatus == RequestStatus.FAILURE) { + throw new HttpMessageNotReadableException("Cannot split these components"); + } 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/core/JacksonCustomizations.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/JacksonCustomizations.java index ce766115f9..cc17a44750 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/JacksonCustomizations.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/JacksonCustomizations.java @@ -252,7 +252,6 @@ static abstract class EmbeddedProjectMixin extends ProjectMixin { abstract public boolean isEnableVulnerabilitiesDisplay(); @Override - @JsonIgnore abstract public ProjectState getState(); } diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/RestControllerHelper.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/RestControllerHelper.java index 0c7f7d4f43..01c4f6856c 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/RestControllerHelper.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/core/RestControllerHelper.java @@ -501,7 +501,11 @@ public Project convertToEmbeddedProject(Project project) { Project embeddedProject = new EmbeddedProject(); embeddedProject.setName(project.getName()); embeddedProject.setId(project.getId()); + embeddedProject.setDescription(project.getDescription()); + embeddedProject.setProjectResponsible(project.getProjectResponsible()); embeddedProject.setProjectType(project.getProjectType()); + embeddedProject.setState(project.getState()); + embeddedProject.setClearingState(project.getClearingState()); embeddedProject.setVersion(project.getVersion()); embeddedProject.setVisbility(project.getVisbility()); embeddedProject.setType(null); @@ -521,6 +525,7 @@ public Component convertToEmbeddedComponent(Component component) { Component embeddedComponent = new Component(); embeddedComponent.setId(component.getId()); embeddedComponent.setName(component.getName()); + embeddedComponent.setDescription(component.getDescription()); embeddedComponent.setComponentType(component.getComponentType()); embeddedComponent.setVisbility(component.getVisbility()); embeddedComponent.setMainLicenseIds(component.getMainLicenseIds()); diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java index 4529e50140..f2048fcf94 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java @@ -17,6 +17,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.gson.JsonObject; + import lombok.NonNull; import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; @@ -39,7 +41,9 @@ import org.eclipse.sw360.datahandler.thrift.ReleaseRelationship; 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.Source; +import org.eclipse.sw360.datahandler.thrift.ThriftClients; import org.eclipse.sw360.datahandler.thrift.attachments.Attachment; import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentContent; import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentType; @@ -58,6 +62,7 @@ import org.eclipse.sw360.datahandler.thrift.projects.ProjectClearingState; import org.eclipse.sw360.datahandler.thrift.projects.ProjectLink; import org.eclipse.sw360.datahandler.thrift.projects.ProjectProjectRelationship; +import org.eclipse.sw360.datahandler.thrift.projects.ProjectService; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.datahandler.thrift.vendors.Vendor; import org.eclipse.sw360.datahandler.thrift.vulnerabilities.ProjectVulnerabilityRating; @@ -1209,4 +1214,17 @@ public static TSerializer getJsonSerializer() { } return null; } + + @RequestMapping(value = PROJECTS_URL + "/projectcount", method = RequestMethod.GET) + public void getUserProjectCount(HttpServletResponse response) throws TException { + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + try { + JsonObject resultJson = new JsonObject(); + resultJson.addProperty("status", "success"); + resultJson.addProperty("count", projectService.getMyAccessibleProjectCounts(sw360User)); + response.getWriter().write(resultJson.toString()); + }catch (IOException e) { + throw new SW360Exception(e.getMessage()); + } + } } diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java index b8d24bd41b..59b01f21c9 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ComponentSpecTest.java @@ -100,6 +100,8 @@ public class ComponentSpecTest extends TestRestDocsSpecBase { private Component angularComponent; + private Component angularTargetComponent; + private Attachment attachment; private Project project; @@ -108,6 +110,9 @@ public class ComponentSpecTest extends TestRestDocsSpecBase { private Attachment sBOMAttachment; private RequestSummary requestSummary = new RequestSummary(); + private Release release; + private Release release2; + @Before public void before() throws TException, IOException { Set licenseIds = new HashSet<>(); @@ -157,6 +162,9 @@ public void before() throws TException, IOException { Map angularComponentExternalIds = new HashMap<>(); angularComponentExternalIds.put("component-id-key", "1831A3"); angularComponentExternalIds.put("ws-component-id", "[\"123\",\"598752\"]"); + Map angularTargetComponentExternalIds = new HashMap<>(); + angularComponentExternalIds.put("component-id-key", "1831A4"); + angularComponentExternalIds.put("ws-component-id", "[\"123\",\"598753\"]"); angularComponent = new Component(); angularComponent.setId("17653524"); angularComponent.setName("Angular"); @@ -187,7 +195,41 @@ public void before() throws TException, IOException { angularComponent.setHomepage("https://angular.io"); angularComponent.setMainLicenseIds(licenseIds); angularComponent.setDefaultVendorId("vendorId"); + + + angularTargetComponent = new Component(); + angularTargetComponent.setId("87654321"); + angularTargetComponent.setName("Angular"); + angularTargetComponent.setComponentOwner("John"); + angularTargetComponent.setDescription("Angular is a development platform for building mobile and desktop web applications."); + angularTargetComponent.setCreatedOn("2016-12-15"); + angularTargetComponent.setCreatedBy("admin@sw360.org"); + angularTargetComponent.setModifiedBy("admin1@sw360.org"); + angularTargetComponent.setModifiedOn("2016-12-30"); + angularTargetComponent.setSoftwarePlatforms(new HashSet<>(Arrays.asList("Linux"))); + angularTargetComponent.setMainLicenseIds(new HashSet<>(Arrays.asList("123"))); + angularTargetComponent.setSubscribers(new HashSet<>(Arrays.asList("Mari"))); + angularTargetComponent.setWiki("http://wiki.ubuntu.com/"); + angularTargetComponent.setBlog("http://www.javaworld.com/"); + angularTargetComponent.setComponentType(ComponentType.OSS); + angularTargetComponent.setVendorNames(new HashSet<>(Collections.singletonList("Google"))); + angularTargetComponent.setModerators(new HashSet<>(Arrays.asList("admin@sw360.org", "john@sw360.org"))); + angularTargetComponent.setOwnerAccountingUnit("4822"); + angularTargetComponent.setOwnerCountry("DE"); + angularTargetComponent.setOwnerGroup("AA BB 123 GHV2-DE"); + angularTargetComponent.setCategories(ImmutableSet.of("java", "javascript", "sql")); + angularTargetComponent.setLanguages(ImmutableSet.of("EN", "DE")); + angularTargetComponent.setOperatingSystems(ImmutableSet.of("Windows", "Linux")); + angularTargetComponent.setAttachments(attachmentList); + angularTargetComponent.setExternalIds(angularTargetComponentExternalIds); + angularTargetComponent.setMailinglist("test@liferay.com"); + angularTargetComponent.setAdditionalData(Collections.singletonMap("Key", "Value")); + angularTargetComponent.setHomepage("https://angular.io"); + angularTargetComponent.setMainLicenseIds(licenseIds); + angularTargetComponent.setDefaultVendorId("vendorId"); + componentList.add(angularComponent); + componentList.add(angularTargetComponent); componentListByName.add(angularComponent); Component springComponent = new Component(); @@ -257,6 +299,12 @@ public void before() throws TException, IOException { .setComponentType(ComponentType.OSS) .setExternalIds(Collections.singletonMap("component-id-key", "1831A3")) ); + given(this.componentServiceMock.convertToEmbeddedWithExternalIds(eq(angularTargetComponent))).willReturn( + new Component("Angular") + .setId("87654321") + .setComponentType(ComponentType.OSS) + .setExternalIds(Collections.singletonMap("component-id-key", "1831A4")) + ); given(this.componentServiceMock.convertToEmbeddedWithExternalIds(eq(springComponent))).willReturn( new Component("Spring Framework") .setId("678dstzd8") @@ -274,7 +322,7 @@ public void before() throws TException, IOException { given(this.vendorServiceMock.getVendorById("vendorId")).willReturn(vendor); List releaseList = new ArrayList<>(); - Release release = new Release(); + release = new Release(); release.setId("3765276512"); release.setName("Angular 2.3.0"); release.setCpeid("cpe:/a:Google:Angular:2.3.0:"); @@ -286,7 +334,7 @@ public void before() throws TException, IOException { release.setComponentId(springComponent.getId()); releaseList.add(release); - Release release2 = new Release(); + release2 = new Release(); release2.setId("3765276512"); release2.setName("Angular 2.3.1"); release2.setCpeid("cpe:/a:Google:Angular:2.3.1:"); @@ -840,6 +888,110 @@ public void should_document_update_component() throws Exception { .andDo(documentComponentProperties()); } + @Test + public void should_document_merge_components() throws Exception { + + + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + mockMvc.perform(patch("/api/components/mergecomponents") + .contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(angularTargetComponent)) + .header("Authorization", "Bearer " + accessToken) + .param("mergeTargetId", "87654321") + .param("mergeSourceId", "17653524") + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()) + .andDo(this.documentationHandler.document( + requestParameters( + parameterWithName("mergeSourceId").description("Id of a source component to merge"), + parameterWithName("mergeTargetId").description("Id of a target component to merge") + ), + requestFields( + fieldWithPath("id").description("The Id of the component"), + fieldWithPath("subscribers").description("The subscribers of component"), + fieldWithPath("ownerAccountingUnit").description("The owner accounting unit of the component"), + subsectionWithPath("externalIds").description("When components are imported from other tools, the external ids can be stored here. Store as 'Single String' when single value, or 'Array of String' when multi-values"), + subsectionWithPath("additionalData").description("A place to store additional data used by external tools"), + fieldWithPath("mainLicenseIds").description("The Main License Ids of component"), + fieldWithPath("languages").description("The language of the component"), + fieldWithPath("softwarePlatforms").description("The Software Platforms of component"), + fieldWithPath("operatingSystems").description("The OS on which the component operates"), + fieldWithPath("wiki").description("The wiki of component"), + fieldWithPath("blog").description("The blog of component"), + fieldWithPath("homepage").description("The homepage url of the component"), + fieldWithPath("modifiedOn").description("The date the component was modified"), + + fieldWithPath("name").description("The updated name of the component"), + fieldWithPath("type").description("The updated name of the component"), + fieldWithPath("createdOn").description("The date the component was created"), + fieldWithPath("componentOwner").description("The owner name of the component"), + fieldWithPath("ownerGroup").description("The owner group of the component"), + fieldWithPath("ownerCountry").description("The owner country of the component"), + fieldWithPath("visbility").description("The visibility type of the component"), + fieldWithPath("defaultVendorId").description("Default vendor id of component"), + fieldWithPath("categories").description("The component categories"), + fieldWithPath("mailinglist").description("Component mailing lists"), + fieldWithPath("setVisbility").description("The visibility of the component"), + fieldWithPath("setBusinessUnit").description("Whether or not a business unit is set for the component"), + fieldWithPath("vendors").description("The vendors list"), + fieldWithPath("description").description("The updated component description"), + fieldWithPath("componentType").description("The updated component type, possible values are: " + Arrays.asList(ComponentType.values())) + ))); + } + @Test + public void should_document_split_components() throws Exception { + + + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + Component srcComponent = new Component(); + srcComponent.setId("17653524"); + srcComponent.setName("Angular"); + srcComponent.setComponentOwner("John"); + srcComponent.setDescription("Angular is a development platform for building mobile and desktop web applications."); + List releaseList = new ArrayList<>(); + releaseList.add(release); + Release release2 = new Release(); + releaseList.add(release2); + + srcComponent.setReleases(releaseList); + Component targetComponent = new Component(); + targetComponent.setId("87654321"); + targetComponent.setName("Angular"); + targetComponent.setComponentOwner("John"); + targetComponent.setDescription("Angular is a development platform for building mobile and desktop web applications."); + targetComponent.setReleases(releaseList); + Map componentsMap = new HashMap<>(); + componentsMap.put("srcComponent", srcComponent); + componentsMap.put("targetComponent", targetComponent); + + mockMvc.perform(patch("/api/components/splitComponents") + .contentType(MediaTypes.HAL_JSON) + .content(this.objectMapper.writeValueAsString(componentsMap)) + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()) + .andDo(this.documentationHandler.document( + requestFields( + fieldWithPath("srcComponent.id").description("The ID of the source component"), + fieldWithPath("srcComponent.name").description("The name of the source component"), + fieldWithPath("srcComponent.description").description("The description of the source component"), + fieldWithPath("srcComponent.type").description("The type of the source component"), + fieldWithPath("srcComponent.componentOwner").description("The owner of the source component"), + fieldWithPath("srcComponent.visbility").description("The visibility of the source component"), + fieldWithPath("srcComponent.setVisbility").description("Flag indicating if the visibility is set"), + fieldWithPath("srcComponent.setBusinessUnit").description("Flag indicating if the business unit is set"), + fieldWithPath("targetComponent.id").description("The ID of the target component"), + fieldWithPath("targetComponent.name").description("The name of the target component"), + fieldWithPath("targetComponent.description").description("The description of the target component"), + fieldWithPath("targetComponent.type").description("The type of the target component"), + fieldWithPath("targetComponent.componentOwner").description("The owner of the target component"), + fieldWithPath("targetComponent.visbility").description("The visibility of the target component"), + fieldWithPath("targetComponent.setVisbility").description("Flag indicating if the visibility is set"), + fieldWithPath("targetComponent.setBusinessUnit").description("Flag indicating if the business unit is set") + + ))); + } + @Test public void should_document_delete_components() throws Exception { String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); diff --git a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java index 5f8c6bb200..87aff92c57 100644 --- a/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java +++ b/rest/resource-server/src/test/java/org/eclipse/sw360/rest/resourceserver/restdocs/ProjectSpecTest.java @@ -1666,4 +1666,19 @@ public void should_document_import_sbom() throws Exception { .queryParam("type", "SPDX"); this.mockMvc.perform(builder).andExpect(status().isOk()).andDo(this.documentationHandler.document()); } + + @Test + public void should_document_get_project_count() throws Exception { + String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword); + this.mockMvc.perform(get("/api/projects/projectcount") + .header("Authorization", "Bearer " + accessToken) + .accept(MediaTypes.HAL_JSON) + .contentType(MediaTypes.HAL_JSON)) + .andExpect(status().isOk()) + .andDo(this.documentationHandler.document( + responseFields( + fieldWithPath("status").description("status of the API. Possible values are ``").optional(), + fieldWithPath("count").description("Count of projects for a user.").optional() + ))); + } }