From aced20ab99b340a7562d4cc1a1d40f60cfdd00d2 Mon Sep 17 00:00:00 2001 From: Rudra Chopra Date: Thu, 30 Jan 2025 12:53:29 +0530 Subject: [PATCH] feat(rest): Count of attachments used in different projects. Signed-off-by: Rudra Chopra --- .../project/ProjectController.java | 66 ++++++++++++++----- .../project/Sw360ProjectService.java | 48 ++++++++++++++ 2 files changed, 98 insertions(+), 16 deletions(-) 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..3db98093dc 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 @@ -128,6 +128,8 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.eclipse.sw360.datahandler.thrift.users.RequestedAction; +import org.eclipse.sw360.datahandler.thrift.attachments.LicenseInfoUsage; +import org.eclipse.sw360.datahandler.thrift.attachments.SourcePackageUsage; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -136,20 +138,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.InvalidPropertiesFormatException; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -1895,6 +1885,24 @@ public ResponseEntity saveAttachmentUsages( } } + public Map countMap(Collection attachmentTypes, UsageData filter, Project project, User sw360User, String id) throws TException { + boolean projectWithSubProjects = !project.getLinkedProjects().isEmpty(); + List mappedProjectLinks = + (!SW360Constants.ENABLE_FLEXIBLE_PROJECT_RELEASE_RELATIONSHIP) + ? projectService.createLinkedProjects(project, + projectService.filterAndSortAttachments(attachmentTypes), true, sw360User) + : projectService.createLinkedProjectsWithAllReleases(project, + projectService.filterAndSortAttachments(attachmentTypes), true, sw360User); + + if (!projectWithSubProjects) { + mappedProjectLinks = mappedProjectLinks.stream() + .filter(projectLink -> projectLink.getId().equals(id)).collect(Collectors.toList()); + } + + Map countMap = projectService.storeAttachmentUsageCount(mappedProjectLinks, filter); + return countMap; + } + @Operation( description = "Get all attachmentUsages of the projects.", tags = {"Projects"} @@ -1962,12 +1970,27 @@ public ResponseEntity attachmentUsages( } } - List> releaseObjMap = getReleaseObjectMapper(releaseList); + Collection attachmentTypes; + UsageData type; + List> releaseObjMap = new ArrayList<>(); + if ("withCliAttachment".equalsIgnoreCase(filter)) { + attachmentTypes = SW360Constants.LICENSE_INFO_ATTACHMENT_TYPES; + type = UsageData.licenseInfo(new LicenseInfoUsage(Sets.newHashSet())); + Map count = countMap(attachmentTypes, type, sw360Project, sw360User, id); + releaseObjMap = getReleaseObjectMapper(releaseList, count); + } else if ("withSourceAttachment".equalsIgnoreCase(filter)) { + attachmentTypes = SW360Constants.SOURCE_CODE_ATTACHMENT_TYPES; + type = UsageData.sourcePackage(new SourcePackageUsage()); + Map count = countMap(attachmentTypes, type, sw360Project, sw360User, id); + releaseObjMap = getReleaseObjectMapper(releaseList, count); + } else { + releaseObjMap = getReleaseObjectMapper(releaseList, null); + } HalResource userHalResource = attachmentUsageReleases(sw360Project, releaseObjMap, listOfAttachmentUsages); return new ResponseEntity<>(userHalResource, HttpStatus.OK); } - private List> getReleaseObjectMapper(List> releaseList) { + private List> getReleaseObjectMapper(List> releaseList, Map count) { ObjectMapper oMapper = new ObjectMapper(); List> modifiedList = new ArrayList<>(); for (EntityModel rel : releaseList) { @@ -1983,6 +2006,7 @@ private List> getReleaseObjectMapper(List fieldsToKeep = ImmutableSet.of("name", "version", "componentType", "clearingState", ATTACHMENTS); Map valueToKeep = new LinkedHashMap<>(); Link releaseLink = null; + Integer attachmentCount = 0; if (relMap != null) { for (Map.Entry entry : relMap.entrySet()) { if (entry != null && entry.getKey().equals("id")) { @@ -2006,6 +2030,16 @@ private List> getReleaseObjectMapper(List entryMap : count.entrySet()) { + String key = entryMap.getKey(); + if (key.contains((CharSequence) att.get("attachmentContentId"))) { + attachmentCount = entryMap.getValue(); + break; + } + } + map.put("attachmentUsageCount",attachmentCount); + } attList.add(map); } valueToKeep.put(entry.getKey(), attList); @@ -2078,7 +2112,7 @@ public List filterReleases(User sw360User, String filter, Set r final Release sw360Release = releaseService.getReleaseForUserById(relId, sw360User); releaseService.setComponentDependentFieldsInRelease(sw360Release, sw360User); List cliAttachments = sw360Release.getAttachments().stream() - .filter(attachment -> attachment.getAttachmentType() == AttachmentType.COMPONENT_LICENSE_INFO_XML) + .filter(attachment -> attachment.getAttachmentType() == AttachmentType.COMPONENT_LICENSE_INFO_XML || attachment.getAttachmentType() == AttachmentType.COMPONENT_LICENSE_INFO_COMBINED) .collect(Collectors.toList()); Set cliAttachmentsSet = new HashSet<>(cliAttachments); sw360Release.setAttachments(cliAttachmentsSet); diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/Sw360ProjectService.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/Sw360ProjectService.java index d240064e75..1c9ef498f8 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/Sw360ProjectService.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/Sw360ProjectService.java @@ -959,6 +959,48 @@ public Function filterAndSortAttachments(Collection storeAttachmentUsageCount(List mappedProjectLinks, UsageData filter) throws TException { + try { + ThriftClients thriftClients = new ThriftClients(); + AttachmentService.Iface attachmentClient = thriftClients.makeAttachmentClient(); + Map> containedAttachments = extractContainedAttachments(mappedProjectLinks); + Map, Integer> attachmentUsages = attachmentClient.getAttachmentUsageCount(containedAttachments, + filter); + Map countMap = attachmentUsages.entrySet().stream().collect(Collectors.toMap(entry -> { + Entry key = entry.getKey().entrySet().iterator().next(); + return key.getKey().getFieldValue() + "_" + key.getValue(); + }, Entry::getValue)); + return countMap; + } catch (TException e) { + log.error(e.getMessage()); + return Collections.emptyMap(); + } + } + + /** + * Walks through a list of project links and extracts all release attachments + * with their owner. The returned map is a mapping from a release to its + * attachment content ids. + * + * @param projectLinks + * list of project links to walk through + * + * @return map of releases and their attachment content ids + */ + public static Map> extractContainedAttachments(Collection projectLinks) { + Map> attachments = Maps.newHashMap(); + + for (ProjectLink projectLink : projectLinks) { + for (ReleaseLink releaseLink : projectLink.linkedReleases) { + Set attachmentIds = attachments.getOrDefault(Source.releaseId(releaseLink.getId()), Sets.newHashSet()); + attachmentIds.addAll(releaseLink.getAttachments().stream().map(a -> a.getAttachmentContentId()).collect(Collectors.toList())); + attachments.put(Source.releaseId(releaseLink.getId()), attachmentIds); + } + } + + return attachments; + } + public Function filterAndSortAllAttachments(Collection attachmentTypes) { Predicate filter = att -> attachmentTypes.contains(att.getAttachmentType()); return createProjectLinkMapper(rl -> { @@ -1000,6 +1042,12 @@ public List createLinkedProjects(Project project, Function createLinkedProjectsWithAllReleases(Project project, + Function projectLinkMapper, boolean deep, User user) { + final Collection linkedProjects = SW360Utils.getLinkedProjectsWithAllReleasesAsFlatList(project, deep, new ThriftClients(), log, user); + return linkedProjects.stream().map(projectLinkMapper).collect(Collectors.toList()); + } + public Set getReleasesFromProjectIds(List projectIds, boolean transitive, final User sw360User, Sw360ReleaseService releaseService) { final List>> callableTasksToGetReleases = new ArrayList>>();