Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public class ProjectRepository extends SummaryAwareRepository<Project> {
"function(doc) {" +
" if (doc.type == 'project' && doc.packageIds) {" +
" for(var i in doc.packageIds) {" +
" emit(doc.packageIds[i], doc._id);" +
" emit(i, doc._id);" +
" }" +
" }" +
"}";
Expand Down
41 changes: 41 additions & 0 deletions rest/resource-server/src/docs/asciidoc/packages.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,44 @@ include::{snippets}/should_document_delete_package/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_delete_package/http-response.adoc[]


[[resources-package-usage]]
==== Get Package Usage Information

A `GET` request to `/api/packages/{id}/usage` will get the usage information for a specific package, including whether the package is being used and the count of projects using it.

===== Path parameters
[cols="2,1,2"]
|===
|Name |Type |Description

|id
|String
|The ID of the package to check usage for
|===

===== Response structure
[cols="2,1,2"]
|===
|Path |Type |Description

|count
|Number
|Number of projects using this package

|isUsed
|Boolean
|Flag indicating if the package is used in any project
|===

===== Example request
include::{snippets}/should_document_get_package_usage/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_get_package_usage/http-response.adoc[]

===== Error response
When the package is not found:

include::{snippets}/should_document_get_package_usage_not_found/http-response.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.eclipse.sw360.rest.resourceserver.core.HalResource;
import org.eclipse.sw360.rest.resourceserver.core.OpenAPIPaginationHelper;
import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper;
import org.eclipse.sw360.rest.resourceserver.project.Sw360ProjectService;
import org.eclipse.sw360.rest.resourceserver.release.Sw360ReleaseService;
import org.eclipse.sw360.rest.resourceserver.user.Sw360UserService;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -87,6 +88,9 @@ public class PackageController implements RepresentationModelProcessor<Repositor
@NonNull
private final SW360PackageService packageService;

@NonNull
private final Sw360ProjectService projectService;

@NonNull
private Sw360ReleaseService releaseService;

Expand Down Expand Up @@ -421,4 +425,41 @@ private ResponseEntity<CollectionModel<EntityModel<Package>>> getPackageResponse
}
return filterMap;
}

@Operation(
summary = "Check if a package is being used and get the count.",
description = "Returns whether the package is being used and the total count of usages.",
tags = {"Packages"},
responses = {
@ApiResponse(
responseCode = "200", description = "Package usage information",
content = {
@Content(mediaType = "application/json",
schema = @Schema(
example = """
{
isUsed: true,
count: 5
}
"""
)
)
}
)
}
)

@RequestMapping(value = PACKAGES_URL + "/{id}/usage", method = RequestMethod.GET)
public ResponseEntity<Map<String, Object>> getPackageUsageInfo(
@Parameter(description = "The id of the package to check usage for")
@PathVariable("id") String id
) throws TException {

Map<String, Object> response = new HashMap<>();
int usageCount = projectService.getProjectCountByPackageId(id);
response.put("isUsed", usageCount > 0);
response.put("count", usageCount);

return new ResponseEntity<>(response, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1888,4 +1888,21 @@ private static PaginationData pageableToPaginationData(
return new PaginationData().setDisplayStart((int) pageable.getOffset())
.setRowsPerPage(pageable.getPageSize()).setSortColumnNumber(column.getValue()).setAscending(ascending);
}

public int getProjectCountByPackageId(String packageId) throws TException {
ThriftClients thriftClients = new ThriftClients();
ProjectService.Iface projectClient = thriftClients.makeProjectClient();
int count;
try {
count = projectClient.getProjectCountByPackageId(packageId);
} catch (SW360Exception sw360Exp) {
if (sw360Exp.getErrorCode() == 404) {
throw new ResourceNotFoundException("Requested Package Id Not Found");
}
else {
throw sw360Exp;
}
}
return count;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.eclipse.sw360.datahandler.thrift.users.UserGroup;
import org.eclipse.sw360.rest.resourceserver.TestHelper;
import org.eclipse.sw360.rest.resourceserver.packages.SW360PackageService;
import org.eclipse.sw360.rest.resourceserver.project.Sw360ProjectService;
import org.eclipse.sw360.rest.resourceserver.release.Sw360ReleaseService;
import org.hamcrest.Matchers;
import org.junit.Before;
Expand All @@ -60,6 +61,7 @@
import org.springframework.hateoas.MediaTypes;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;

@RunWith(SpringJUnit4ClassRunner.class)
public class PackageSpecTest extends TestRestDocsSpecBase {
Expand All @@ -76,6 +78,9 @@ public class PackageSpecTest extends TestRestDocsSpecBase {
@MockitoBean
private Sw360ReleaseService releaseServiceMock;

@MockitoBean
private Sw360ProjectService projectServiceMock;

private Package package1;
private Package package2;
private Package package3;
Expand Down Expand Up @@ -465,4 +470,36 @@ public void should_document_delete_package() throws Exception {
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk());
}

@Test
public void should_document_get_package_usage() throws Exception {
String packageId = package1.getId();
int projectCount = 5;

given(projectServiceMock.getProjectCountByPackageId(packageId)).willReturn(projectCount);

mockMvc.perform(get("/api/packages/" + packageId + "/usage")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk())
.andDo(this.documentationHandler.document(
responseFields(
fieldWithPath("count").description("Number of projects using this package"),
fieldWithPath("isUsed").description("Flag indicating if the package is used in any project")
)));
}

@Test
public void should_document_get_package_usage_not_found() throws Exception {
String packageId = "non-existent-id";

given(projectServiceMock.getProjectCountByPackageId(packageId))
.willThrow(new ResourceNotFoundException("Could not find package with id: " + packageId));

mockMvc.perform(get("/api/packages/" + packageId + "/usage")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isNotFound());
}

}