diff --git a/rest/resource-server/src/docs/asciidoc/projects.adoc b/rest/resource-server/src/docs/asciidoc/projects.adoc index e6b7a332c4..b3039c16c3 100644 --- a/rest/resource-server/src/docs/asciidoc/projects.adoc +++ b/rest/resource-server/src/docs/asciidoc/projects.adoc @@ -1251,4 +1251,18 @@ include::{snippets}/should_document_get_projects_by_advance_search/curl-request. include::{snippets}/should_document_get_projects_by_advance_search/http-response.adoc[] ===== Links -include::{snippets}/should_document_get_projects_by_advance_search/links.adoc[] \ No newline at end of file +include::{snippets}/should_document_get_projects_by_advance_search/links.adoc[] + +[[resources-package-get-by-project]] +==== Get Package by ProjectId + +A GET request is used to retrieve a package using a given projectId. + +===== Request parameter +include::{snippets}/should_document_get_package_by_project_id/request-parameters.adoc[] + +===== Example request +include::{snippets}/should_document_get_package_by_project_id-id/curl-request.adoc[] + +===== Example response +include::{snippets}/should_document_get_package_by_project_id-id/http-response.adoc[] 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 5ff76cb89d..28e125581a 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 @@ -78,6 +78,16 @@ import org.eclipse.sw360.datahandler.thrift.licenseinfo.OutputFormatVariant; import org.eclipse.sw360.datahandler.thrift.licenses.License; import org.eclipse.sw360.datahandler.thrift.projects.*; +import org.eclipse.sw360.datahandler.thrift.packages.Package; +import org.eclipse.sw360.datahandler.thrift.projects.ObligationList; +import org.eclipse.sw360.datahandler.thrift.projects.ObligationStatusInfo; +import org.eclipse.sw360.datahandler.thrift.projects.Project; +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.ProjectRelationship; +import org.eclipse.sw360.datahandler.thrift.projects.ProjectDTO; +import org.eclipse.sw360.datahandler.thrift.projects.ClearingRequest; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.datahandler.thrift.users.UserGroup; import org.eclipse.sw360.datahandler.thrift.vendors.Vendor; @@ -98,6 +108,7 @@ import org.eclipse.sw360.rest.resourceserver.release.ReleaseController; import org.eclipse.sw360.rest.resourceserver.release.Sw360ReleaseService; import org.eclipse.sw360.rest.resourceserver.user.Sw360UserService; +import org.eclipse.sw360.rest.resourceserver.vendor.Sw360VendorService; import org.eclipse.sw360.rest.resourceserver.vulnerability.Sw360VulnerabilityService; import org.eclipse.sw360.rest.resourceserver.vulnerability.VulnerabilityController; import org.jetbrains.annotations.NotNull; @@ -226,6 +237,9 @@ public class ProjectController implements RepresentationModelProcessor> getProject( return new ResponseEntity<>(userHalResource, HttpStatus.OK); } + @Operation( + description = "Get a package with project id.", + tags = {"Projects"} + ) + @RequestMapping(value = PROJECTS_URL + "/{id}/packages", method = RequestMethod.GET) + public ResponseEntity>> getPackagesByProjectId( + @Parameter(description = "Project ID", example = "376576") + @PathVariable("id") String id) throws TException { + + User sw360User = restControllerHelper.getSw360UserFromAuthentication(); + Project sw360Project = projectService.getProjectForUserById(id, sw360User); + List> halPackages = new ArrayList<>(); + if (sw360Project.getPackageIdsSize() > 0) { + for (String packageId : sw360Project.getPackageIds()) { + Package sw360Package = packageService.getPackageForUserById(packageId); + HalResource halPackage = createHalPackage(sw360Package, sw360User); + halPackages.add(halPackage); + } + } + return new ResponseEntity(halPackages, HttpStatus.OK); + } + + private HalResource createHalPackage(Package sw360Package, User sw360User) throws TException { + HalResource halPackage = new HalResource<>(sw360Package); + User packageCreator = restControllerHelper.getUserByEmail(sw360Package.getCreatedBy()); + String linkedRelease = sw360Package.getReleaseId(); + + restControllerHelper.addEmbeddedUser(halPackage, packageCreator, "createdBy"); + if (CommonUtils.isNotNullEmptyOrWhitespace(linkedRelease)) { + Release release = releaseService.getReleaseForUserById(linkedRelease, sw360User); + + if (release != null) { + restControllerHelper.addEmbeddedSingleRelease(halPackage, release); + } else { + log.warn("Release not found for ID: {}", linkedRelease); + } + } + if (sw360Package.getModifiedBy() != null) { + restControllerHelper.addEmbeddedModifiedBy(halPackage, sw360User, "modifiedBy"); + } + if (sw360Package.getVendorId() != null) { + Vendor vendor = vendorService.getVendorById(sw360Package.getVendorId()); + if (vendor != null) { + Vendor vendorHalResource = restControllerHelper.convertToEmbeddedVendor(vendor); + halPackage.addEmbeddedResource("sw360:vendors", vendorHalResource); + } else { + log.warn("Vendor not found for ID: {}", sw360Package.getVendorId()); + } + } + return halPackage; + } + @Operation( description = "Get linked projects of a single project.", tags = {"Projects"} 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 00187ea0cb..80ccad138a 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 @@ -276,6 +276,7 @@ public void before() throws TException, IOException { project.setSpecialRisks3rdParty("Lorem Ipsum"); project.setLicenseInfoHeaderText("Lorem Ipsum"); project.setDeliveryChannels("Lorem Ipsum"); + project.setPackageIds(new HashSet<>(Arrays.asList("pkg-001", "pkg-002", "pkg-003"))); project.setVendor(new Vendor()); project.setRemarksAdditionalRequirements("Lorem Ipsum"); ReleaseClearingStateSummary clearingCount = new ReleaseClearingStateSummary(); @@ -3250,4 +3251,35 @@ public void should_document_get_projects_by_advance_search() throws Exception { fieldWithPath("page.number").description("Number of the current page") ))); } + + @Test + public void should_document_get_package_by_project_id() throws Exception { + Set licenseIds = new HashSet<>(); + licenseIds.add("MIT"); + licenseIds.add("GPL"); + + Package packages = new Package("angular-sanitize", "1.8.2", "pkg:npm/angular-sanitize@1.8.2", + CycloneDxComponentType.FRAMEWORK) + .setId("122357345") + .setCreatedBy("admin@sw360.org") + .setCreatedOn("2023-01-02") + .setVcs("git+https://github.com/angular/angular.js.git") + .setHomepageUrl("http://angularjs.org") + .setLicenseIds(licenseIds) + .setReleaseId("12345678") + .setPackageManager(PackageManager.NPM) + .setDescription("Sanitizes an html string by stripping all potentially dangerous tokens."); + + given(this.packageServiceMock.getPackageForUserById(eq(packages.getId()))).willReturn(packages); + + Project sw360Project = new Project(); + sw360Project.setId(project.getId()); + sw360Project.setPackageIds(new HashSet<>(Collections.singleton("122357345"))); + + given(this.projectServiceMock.getProjectForUserById(eq(project.getId()), any())).willReturn(sw360Project); + + mockMvc.perform(get("/api/projects/" + project.getId() + "/packages") + .header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword)) + .accept(MediaTypes.HAL_JSON)).andExpect(status().isOk()); + } }