Skip to content

Commit

Permalink
feat(rest): endpoint to remove orphaned obligations from project.
Browse files Browse the repository at this point in the history
Signed-off-by: Rudra Chopra <prabhuchopra@gmail.com>
  • Loading branch information
rudra-superrr committed Nov 13, 2024
1 parent 9452b2b commit ff75496
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
14 changes: 14 additions & 0 deletions rest/resource-server/src/docs/asciidoc/projects.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,20 @@ include::{snippets}/should_document_delete_project/curl-request.adoc[]
===== Example response
include::{snippets}/should_document_delete_project/http-response.adoc[]

[[resources-projects-remove-orphaned-obligations]]
==== Remove orphaned obligations

A `PATCH` request will update the project's obligations.

===== Request structure 1
Pass an array of orphaned obligations title in request body.

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

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

[[resources-project-link-projects]]
==== Link project to the projects

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2527,6 +2527,44 @@ private Map<String, Object> createPaginationMetadata(Pageable pageable, Map<Stri
return responseBody;
}

@PreAuthorize("hasAuthority('WRITE')")
@Operation(
summary = "delete orphan obligations",
description = "Pass an array of orphan obligation titles in request body.",
tags = {"Projects"}
)
@RequestMapping(value = PROJECTS_URL + "/{id}/orphanObligation", method = RequestMethod.PATCH)
public ResponseEntity<?> removeOrphanObligation(
@Parameter(description = "Project ID.")
@PathVariable("id") String id,
@Parameter(description = "Array of orphaned obligations title",
examples = {
@ExampleObject(value = "[\"title1\",\"title2\",\"title3\"]")
// TODO: Add example for MAP value
}
)
@RequestBody List<String> obligationTitlesInRequestBody
) throws URISyntaxException, TException {
final User sw360User = restControllerHelper.getSw360UserFromAuthentication();
final Project sw360Project = projectService.getProjectForUserById(id, sw360User);

ObligationList obligation = new ObligationList();
RequestStatus status = null;
Map<String, ObligationStatusInfo> obligationStatusMap = Maps.newHashMap();

if (CommonUtils.isNotNullEmptyOrWhitespace(sw360Project.getLinkedObligationId())) {
obligation = projectService.getObligationData(sw360Project.getLinkedObligationId(), sw360User);
obligationStatusMap = CommonUtils.nullToEmptyMap(obligation.getLinkedObligationStatus());
status = projectService.removeOrphanObligations(obligationStatusMap, obligationTitlesInRequestBody, sw360Project, sw360User, obligation);
} else {
return new ResponseEntity<>("No linked obligation found for the project", HttpStatus.NOT_FOUND);
}
if (status == RequestStatus.SUCCESS) {
return new ResponseEntity<>("Orphaned Obligation Removed Successfully", HttpStatus.OK);
}
return new ResponseEntity<>("Failed to Remove Orphaned Obligation", HttpStatus.NOT_FOUND);
}

@Operation(
description = "Get license obligation data of project tab.",
tags = {"Project"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,28 @@ static AttachmentUsage mergeAttachmentUsages(AttachmentUsage u1, AttachmentUsage
return mergedUsage;
}

public RequestStatus removeOrphanObligations(Map<String, ObligationStatusInfo> obligationStatusMap, List<String> obligationTitlesInRequestBody, Project project, User user, ObligationList obligation) {
try {
ThriftClients thriftClients = new ThriftClients();
ProjectService.Iface client = thriftClients.makeProjectClient();
RequestStatus status = null;

for (String topic : obligationTitlesInRequestBody) {
if (obligationStatusMap.containsKey(topic)) {
obligationStatusMap.remove(topic);
} else {
status = RequestStatus.FAILURE;
return status;
}
}
status = client.updateLinkedObligations(obligation, user);
return status;
} catch (TException exception) {
log.error("Failed to remove orphan obligation for project: " + project.getId(), exception);
}
return RequestStatus.FAILURE;
}

public Map<String, ObligationStatusInfo> getLicenseObligationData(Map<String, Set<Release>> licensesFromAttachmentUsage, User user) {
ThriftClients thriftClients = new ThriftClients();
LicenseService.Iface licenseClient = thriftClients.makeLicenseClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,10 @@ public void before() throws TException, IOException {
project8.setId("123456733");
project8.setName("oblProject");
project8.setVersion("3");
project8.setLinkedObligationId("0001");
project8.setLinkedObligationId("009");
linkedReleases3.put("376527651233", projectReleaseRelationship);
project8.setReleaseIdToUsage(linkedReleases3);
List<String> title = Arrays.asList("obligation_title");

Source ownerSrc3 = Source.releaseId("376527651233");
Source usedBySrc3 = Source.projectId("123456733");
Expand Down Expand Up @@ -599,6 +600,7 @@ public void before() throws TException, IOException {
given(this.projectServiceMock.validate(any(), any(), any(), any())).willReturn(true);
given(this.projectServiceMock.deselectedAttachmentUsagesFromRequest(any(), eq(selectedUsages), any(), any(), any())).willReturn(deselectedUsagesFromRequest);
given(this.projectServiceMock.selectedAttachmentUsagesFromRequest(any(), eq(selectedUsages), any(), any(), any())).willReturn(selectedUsagesFromRequest);
given(this.projectServiceMock.removeOrphanObligations(eq(obligationStatusMap), any(), eq(project8), any(), eq(obligationLists))).willReturn(RequestStatus.SUCCESS);
given(this.projectServiceMock.getProjectForUserById(eq(projectForAtt.getId()), any())).willReturn(projectForAtt);
given(this.projectServiceMock.getProjectForUserById(eq(SPDXProject.getId()), any())).willReturn(SPDXProject);
given(this.projectServiceMock.getProjectForUserById(eq(cycloneDXProject.getId()), any())).willReturn(cycloneDXProject);
Expand Down Expand Up @@ -2226,6 +2228,17 @@ public void should_document_delete_project() throws Exception {
.andExpect(status().isOk());
}

@Test
public void should_document_remove_orphaned_obligations() throws Exception {
List<String> orphanedObligationTitles = Arrays.asList("obligation_title");
mockMvc.perform(patch("/api/projects/" + project8.getId() + "/orphanObligation")
.content(this.objectMapper.writeValueAsString(orphanedObligationTitles))
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk());
}

private void add_patch_releases(MockHttpServletRequestBuilder requestBuilder) throws Exception {
List<String> releaseIds = Arrays.asList("3765276512", "5578999", "3765276513");

Expand Down

0 comments on commit ff75496

Please sign in to comment.