Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rest): create new endpoint for bulk delete function #2416

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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 @@ -173,8 +173,11 @@ public BulkOperationNode deleteBulkRelease(String releaseId, User user, boolean
Release referencingRelease = workReleaseMap.get(referencingReleaseId);
Map<String, ReleaseRelationship> relationMap = referencingRelease.getReleaseIdToRelationship();
relationMap.remove(leafReleaseId);
if (!isPreview) {
releaseRepository.update(referencingRelease);
//Do not update the repository link if both the referencing Release and the referenced Release are externally referenced.
if (!externalLinkMap.get(referencingReleaseId)) {
if (!isPreview) {
releaseRepository.update(referencingRelease);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import org.eclipse.sw360.datahandler.thrift.*;
import org.eclipse.sw360.datahandler.thrift.components.*;
import org.eclipse.sw360.datahandler.thrift.projects.Project;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectProjectRelationship;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectRelationship;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectType;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.datahandler.thrift.users.UserGroup;
import org.eclipse.sw360.datahandler.thrift.vendors.Vendor;
Expand All @@ -34,6 +37,10 @@
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.google.common.collect.ImmutableMap;

import java.io.BufferedWriter;
import java.io.FileWriter;
Expand All @@ -48,6 +55,8 @@
@RunWith(MockitoJUnitRunner.class)
public class BulkDeleteUtilTest {

private static final Logger log = LogManager.getLogger(BulkDeleteUtilTest.class);

private static final String dbName = DatabaseSettingsTest.COUCH_DB_DATABASE;
private static final String attachmentsDbName = DatabaseSettingsTest.COUCH_DB_ATTACHMENTS;
private static final String changeLogsDbName = DatabaseSettingsTest.COUCH_DB_CHANGELOGS;
Expand Down Expand Up @@ -154,7 +163,7 @@ public void tearDown() throws Exception {
@Test
public void testGetAllLinkedReleaseMap() throws Exception {
if (!isFeatureEnable()) {
System.out.println("BulkReleaseDeletion is disabled. these test is Skipped.");
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

Expand Down Expand Up @@ -230,7 +239,7 @@ public void testGetExternalLinkMap() throws Exception {
@Test
public void testDeleteBulkRelease001() throws Exception {
if (!isFeatureEnable()) {
System.out.println("BulkReleaseDeletion is disabled. these test is Skipped.");
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

Expand Down Expand Up @@ -461,7 +470,7 @@ private void checkBulkOperationNode(BulkOperationNode node, Map<String, Object[]
//@Test
public void testDeleteBulkRelease002() throws Exception {
if (!isFeatureEnable()) {
System.out.println("BulkReleaseDeletion is disabled. these test is Skipped.");
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

Expand Down Expand Up @@ -517,10 +526,64 @@ public void testDeleteBulkRelease002() throws Exception {
}
}

@Test
public void testDeleteBulkRelease_ExternalLink001() throws Exception {
if (!isFeatureEnable()) {
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

List<String> releaseIdList = new ArrayList<String>();
List<String> componentIdList = new ArrayList<String>();

createTestRecords002(1, 2, releaseIdList, componentIdList);
String rootReleaseId = releaseIdList.get(0);
assertEquals(3, releaseIdList.size());
assertEquals(3, componentIdList.size());

Project project = new Project().setId("P1").setName("project1").setVisbility(Visibility.EVERYONE).setProjectType(ProjectType.CUSTOMER);
project.putToReleaseIdToUsage(rootReleaseId, new ProjectReleaseRelationship(ReleaseRelationship.CONTAINED, MainlineState.OPEN));
databaseConnector.add(project);

BulkOperationNode level1Component = bulkDeleteUtil.deleteBulkRelease(rootReleaseId, user1, false);
assertNotNull(level1Component);

//Check the BulkOperationNode status
//Object[0] : NodeType, Object[1] : ResultState
Map<String, Object[]> expectedResults = new HashMap<String, Object[]>();
expectedResults.put(releaseIdList.get(0), new Object[]{BulkOperationNodeType.RELEASE, BulkOperationResultState.EXCLUDED});
expectedResults.put(releaseIdList.get(1), new Object[]{BulkOperationNodeType.RELEASE, BulkOperationResultState.EXCLUDED});
expectedResults.put(releaseIdList.get(2), new Object[]{BulkOperationNodeType.RELEASE, BulkOperationResultState.EXCLUDED});
expectedResults.put(componentIdList.get(0), new Object[]{BulkOperationNodeType.COMPONENT, BulkOperationResultState.EXCLUDED});
expectedResults.put(componentIdList.get(1), new Object[]{BulkOperationNodeType.COMPONENT, BulkOperationResultState.EXCLUDED});
expectedResults.put(componentIdList.get(2), new Object[]{BulkOperationNodeType.COMPONENT, BulkOperationResultState.EXCLUDED});
checkBulkOperationNode(level1Component, expectedResults);

//Releases to be undeleted
for (String releaseId : releaseIdList) {
assertTrue(this.releaseExists(releaseId));
}

//Release links to be undeleted
Release release0 = databaseConnector.get(Release.class, releaseIdList.get(0));
assertEquals(1, release0.getReleaseIdToRelationshipSize());
Release release1 = databaseConnector.get(Release.class, releaseIdList.get(1));
assertEquals(1, release1.getReleaseIdToRelationshipSize());
Release release2 = databaseConnector.get(Release.class, releaseIdList.get(2));
assertEquals(0, release2.getReleaseIdToRelationshipSize());

//Components and links to be undeleted
for (String componentId : componentIdList) {
assertTrue(this.componentExists(componentId));
Component component = databaseConnector.get(Component.class, componentId);
assertEquals(1, component.getReleaseIdsSize());
}
}

@Test
public void testDeleteBulkRelease_ConflictError001() throws Exception {
if (!isFeatureEnable()) {
System.out.println("BulkReleaseDeletion is disabled. these test is Skipped.");
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

Expand Down Expand Up @@ -743,7 +806,7 @@ public void checkDeletedReleaseListInLoop(int loopCount, List<Release> deletedRe
@Test
public void testDeleteBulkRelease_ConflictError002() throws Exception {
if (!isFeatureEnable()) {
System.out.println("BulkReleaseDeletion is disabled. these test is Skipped.");
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

Expand Down Expand Up @@ -931,7 +994,7 @@ public void checkDeletedReleaseListInLoop(int loopCount, List<Release> deletedRe
@Test
public void testDeleteBulkRelease_ConflictError003() throws Exception {
if (!isFeatureEnable()) {
System.out.println("BulkReleaseDeletion is disabled. these test is Skipped.");
log.warn("BulkReleaseDeletion is disabled. these test is Skipped.");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public Sw360Module() {
setMixInAnnotation(RestrictedResource.class, Sw360Module.RestrictedResourceMixin.class);
setMixInAnnotation(RestApiToken.class, Sw360Module.RestApiTokenMixin.class);
setMixInAnnotation(ProjectLink.class, Sw360Module.ProjectLinkMixin.class);
setMixInAnnotation(BulkOperationNode.class, Sw360Module.BulkOperationNodeMixin.class);

// Make spring doc aware of the mixin(s)
SpringDocUtils.getConfig()
Expand Down Expand Up @@ -207,6 +208,7 @@ public Sw360Module() {
.replaceWithClass(RestrictedResource.class, RestrictedResourceMixin.class)
.replaceWithClass(RestApiToken.class, Sw360Module.RestApiTokenMixin.class)
.replaceWithClass(ProjectLink.class, ProjectLinkMixin.class)
.replaceWithClass(BulkOperationNode.class, BulkOperationNodeMixin.class)
.replaceWithClass(SPDXDocument.class, Sw360Module.SPDXDocumentMixin.class)
.replaceWithClass(DocumentCreationInformation.class, Sw360Module.DocumentCreationInformationMixin.class)
.replaceWithClass(PackageInformation.class, Sw360Module.PackageInformationMixin.class)
Expand Down Expand Up @@ -2637,5 +2639,22 @@ public abstract static class RestApiTokenMixin extends RestApiToken {
"setTreeLevel",
})
abstract static class ProjectLinkMixin extends ProjectLink {}

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(value = {
"setId",
"setName",
"setVersion",
"setType",
"setParentId",
"setChildList",
"childListSize",
"childListIterator",
"setState",
"setAdditionalData",
"additionalDataSize"
})
static abstract class BulkOperationNodeMixin extends BulkOperationNode {
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import org.eclipse.sw360.datahandler.thrift.spdx.documentcreationinformation.DocumentCreationInformation;
import org.eclipse.sw360.datahandler.thrift.spdx.spdxdocument.SPDXDocument;
import org.eclipse.sw360.datahandler.thrift.spdx.spdxpackageinfo.PackageInformation;
import org.eclipse.sw360.datahandler.thrift.components.BulkOperationNode;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.datahandler.thrift.vendors.Vendor;
import org.eclipse.sw360.datahandler.thrift.vulnerabilities.ReleaseVulnerabilityRelation;
Expand Down Expand Up @@ -1768,4 +1769,24 @@ private Set<Attachment> getAttachmentsFromRequest(Object attachmentData, ObjectM
})
.collect(Collectors.toSet());
}

@PreAuthorize("hasAuthority('WRITE')")
@Operation(
summary = "Bulk delete releases.",
description = "Bulk delete existing releases.",
tags = {"Releases"}
)
@DeleteMapping(value = RELEASES_URL + "/{id}/bulkDelete")
public ResponseEntity<BulkOperationNode> bulkDeleteReleases(
@Parameter(description = "The release id to be bulk-deleted.")
@PathVariable("id") String id,
@Parameter(description = "isPreview flag for bulk deletion.")
@RequestParam(value = "isPreview", defaultValue="false", required = false) boolean isPreview
) throws TException {
User user = restControllerHelper.getSw360UserFromAuthentication();
BulkOperationNode result = releaseService.deleteBulkRelease(id, user, isPreview);

return new ResponseEntity<BulkOperationNode>(result, HttpStatus.OK);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,11 @@ public RequestStatus deleteRelease(String releaseId, User sw360User) throws TExc
}
return deleteStatus;
}

public BulkOperationNode deleteBulkRelease(String releaseId, User sw360User, boolean isPreview) throws TException {
ComponentService.Iface sw360ComponentClient = getThriftComponentClient();
return sw360ComponentClient.deleteBulkRelease(releaseId, sw360User, isPreview);
}

public Set<Project> getProjectsByRelease(String releaseId, User sw360User) throws TException {
return projectService.getProjectsByRelease(releaseId, sw360User);
Expand Down
Loading