Skip to content

Commit

Permalink
feat(REST): Search package by purl and version
Browse files Browse the repository at this point in the history
Signed-off-by: afsahsyeda <afsah.syeda@siemens-healthineers.com>
  • Loading branch information
afsahsyeda committed May 15, 2024
1 parent fe044d0 commit 96863d1
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* Copyright Siemens Healthineers GmBH, 2023. Part of the SW360 Portal Project.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
Expand Down Expand Up @@ -414,14 +414,26 @@ private boolean changeWouldResultInDuplicate(Package before, Package after) {
return duplicates.size() > 0;
}

public List<Package> searchByName(String name) {
return packageRepository.searchByName(name);
}

public List<Package> searchByVersion(String version) {
return packageRepository.searchByVersion(version);
}

public List<Package> searchByPackageManager(String packageManager) {
return packageRepository.searchByPackageManager(packageManager);
}

private List<Package> getPackageByNameAndVersion(String pkgName, String pkgVersion) {
if (isNullEmptyOrWhitespace(pkgName)) {
return Collections.emptyList();
}
return packageRepository.searchByNameAndVersion(pkgName, pkgVersion, true);
}

private List<Package> getPackageByPurl(String purl) {
public List<Package> getPackageByPurl(String purl) {
if (isNullEmptyOrWhitespace(purl)) {
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class PackageRepository extends DatabaseRepositoryCloudantClient<Package>
private static final String BY_LICENSE_IDS = "function(doc) { if (doc.type == 'package') { if (doc.licenseIds) { emit(doc.licenseIds.join(), doc._id); } else { emit('', doc._id); } } }";
private static final String BY_PURL = "function(doc) { if (doc.type == 'package') { emit(doc.purl.trim(), doc._id) } }";
private static final String BY_PURL_LOWERCASE = "function(doc) { if (doc.type == 'package') { emit(doc.purl.toLowerCase().trim(), doc._id) } }";
private static final String BY_VERSION = "function(doc) { if (doc.type == 'package') { emit(doc.version.trim(), doc._id) } }";

public PackageRepository(DatabaseConnectorCloudant db) {
super(db, Package.class);
Expand All @@ -65,6 +66,7 @@ public PackageRepository(DatabaseConnectorCloudant db) {
views.put("byLicenseIds", createMapReduce(BY_LICENSE_IDS, null));
views.put("byPurl", createMapReduce(BY_PURL, null));
views.put("byPurlLowercase", createMapReduce(BY_PURL_LOWERCASE, null));
views.put("byVersion", createMapReduce(BY_VERSION, null));
initStandardDesignDocument(views, db);
}

Expand All @@ -76,26 +78,30 @@ public List<Package> getPackagesByReleaseId(String id) {
return queryView("byReleaseId", id);
}

public List<Package> searchByName(String name, User user) {
public List<Package> searchByName(String name) {
return queryView("byName", name);
}

public List<Package> searchByNameLowerCase(String name, User user) {
public List<Package> searchByNameLowerCase(String name) {
return queryView("byNameLowerCase", name.toLowerCase());
}

public List<Package> searchByPackageManager(String pkgType, User user) {
return queryView("byPackageManager", pkgType.toUpperCase());
public List<Package> searchByPackageManager(String pkgType) {
return queryView("byPackageManager", pkgType.toLowerCase());
}

public List<Package> searchByCreator(String email, User user) {
public List<Package> searchByCreator(String email) {
return queryView("byCreator", email);
}

public List<Package> searchByLicenseeId(String id) {
return queryView("byLicenseIds", id);
}

public List<Package> searchByVersion(String version) {
return queryView("byVersion", version);
}

public List<Package> searchByNameAndVersion(String name, String version, boolean caseInsenstive) {
List<Package> packagesMatchingName;
if (caseInsenstive) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,32 @@ public List<Package> searchPackagesWithFilter(String text, Map<String, Set<Strin
public int getTotalPackagesCount() {
return handler.getTotalPackageCount();
}
}

@Override
public List<Package> searchByName(String name) throws TException {
assertNotEmpty(name);

return handler.searchByName(name);
}

@Override
public List<Package> searchByPackageManager(String pkgManager) throws TException {
assertNotEmpty(pkgManager);

return handler.searchByPackageManager(pkgManager);
}

@Override
public List<Package> searchByVersion(String version) throws TException {
assertNotEmpty(version);

return handler.searchByVersion(version);
}

@Override
public List<Package> searchByPurl(String purl) throws TException {
assertNotEmpty(purl);

return handler.getPackageByPurl(purl);
}
}
20 changes: 20 additions & 0 deletions libraries/datahandler/src/main/thrift/package.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,25 @@ service PackageService {
* total number of packages in the DB
**/
i32 getTotalPackagesCount();

/**
* list of packages which match the `name`
*/
list<Package> searchByName(1: string name);

/**
* list of packages which match the `packageManager`
*/
list<Package> searchByPackageManager(1: string pkgManager);

/**
* list of packages which match the `version`
*/
list<Package> searchByVersion(1: string version);

/**
* list of packages which match the `purl`
*/
list<Package> searchByPurl(1: string purl);

}
44 changes: 14 additions & 30 deletions rest/resource-server/src/docs/asciidoc/packages.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,47 +71,31 @@ include::{snippets}/should_document_get_package/http-response.adoc[]
===== Links
include::{snippets}/should_document_get_package/links.adoc[]

[[resources-packages-list-by-name]]
==== List packages by name
[[resources-search-packages]]
==== Search packages

A `GET` request will list all of the service's packages by name. Use the 'exactMatch' parameter to get packages by name exactly matching the search input.

Note : send query parameter's value in encoded format. (Reference: `https://datatracker.ietf.org/doc/html/rfc3986`)
A `GET` request will filter and list all of the service's packages by name, version, purl and packageManager.

===== Request parameter
include::{snippets}/should_document_get_packages_by_name/request-parameters.adoc[]
include::{snippets}/should_document_search_packages/request-parameters.adoc[]

===== Response structure
include::{snippets}/should_document_get_packages_by_name/response-fields.adoc[]
include::{snippets}/should_document_search_packages/response-fields.adoc[]

===== Example request
include::{snippets}/should_document_get_packages_by_name/curl-request.adoc[]
===== Example request 1
include::{snippets}/should_document_search_packages_by_name/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_get_packages_by_name/http-response.adoc[]
===== Example response 1
include::{snippets}/should_document_search_packages_by_name/http-response.adoc[]

===== Links
include::{snippets}/should_document_get_packages_by_name/links.adoc[]
===== Example request 2
include::{snippets}/should_document_search_packages/curl-request.adoc[]

[[resources-packages-list-by-packageManager]]
==== List packages by packageManager

A `GET` request will list all of the service's packages by packageManager.

===== Request parameter
include::{snippets}/should_document_get_packages_by_package_manager/request-parameters.adoc[]

===== Response structure
include::{snippets}/should_document_get_packages_by_package_manager/response-fields.adoc[]

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

===== Example response
include::{snippets}/should_document_get_packages_by_package_manager/http-response.adoc[]
===== Example response 2
include::{snippets}/should_document_search_packages/http-response.adoc[]

===== Links
include::{snippets}/should_document_get_packages_by_package_manager/links.adoc[]
include::{snippets}/should_document_search_packages/links.adoc[]

[[resources-packages-create]]
==== Creating a package
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,11 @@ public ResponseEntity<?> getPackagesForUser(
Pageable pageable,
@Parameter(description = "The name of the package.")
@RequestParam(value = "name", required = false) String name,
@Parameter(description = "Type of the package manager.")
@Parameter(description = "The version of the package.")
@RequestParam(value = "version", required = false) String version,
@Parameter(description = "The pURL of the package.")
@RequestParam(value = "purl", required = false) String purl,
@Parameter(description = "The package manager of the package.")
@RequestParam(value = "packageManager", required = false) String packageManager,
@Parameter(description = "Get all details of the package.")
@RequestParam(value = "allDetails", required = false) boolean allDetails,
Expand All @@ -227,26 +231,32 @@ public ResponseEntity<?> getPackagesForUser(
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
String queryString = request.getQueryString();
Map<String, String> params = restControllerHelper.parseQueryString(queryString);
boolean isSearchByName = name != null && !name.isEmpty();
boolean isSearchByType = CommonUtils.isNotNullEmptyOrWhitespace(packageManager);
boolean isSearchByName = CommonUtils.isNotNullEmptyOrWhitespace(name);
boolean isSearchByPackageManager = CommonUtils.isNotNullEmptyOrWhitespace(packageManager);
boolean isSearchByVersion = CommonUtils.isNotNullEmptyOrWhitespace(version);
boolean isSearchByPurl = CommonUtils.isNotNullEmptyOrWhitespace(purl);
boolean isNoFilter = false;
List<Package> sw360Packages = new ArrayList<>();

if (isSearchByName) {
sw360Packages.addAll(packageService.searchPackage("name", params.get("name"), isExactMatch));
} else if (isSearchByType) {
sw360Packages.addAll(packageService.searchPackageByName(params.get("name")));
} else if (isSearchByPackageManager) {
packageManager = packageManager.toUpperCase();

if (!EnumUtils.isValidEnum(PackageManager.class, packageManager)) {
return new ResponseEntity<String>("Invalid package manager type. Possible values are "
+Arrays.asList(PackageManager.values()), HttpStatus.BAD_REQUEST);
}
sw360Packages.addAll(packageService.searchPackage("packageManager", packageManager, isExactMatch));
sw360Packages.addAll(packageService.searchByPackageManager(packageManager));
} else if (isSearchByVersion) {
sw360Packages.addAll(packageService.searchPackageByVersion(params.get("version")));
} else if (isSearchByPurl) {
sw360Packages.addAll(packageService.searchPackageByPurl(params.get("purl")));
} else {
sw360Packages.addAll(packageService.getPackagesForUser());
isNoFilter = true;
}
return getPackageResponse(pageable, allDetails, request, sw360User, sw360Packages, isNoFilter);
return getPackageResponse(version, purl, packageManager, pageable, allDetails, request, sw360User, sw360Packages, isNoFilter);
}

private Package convertToPackage(Map<String, Object> requestBody) {
Expand Down Expand Up @@ -278,7 +288,7 @@ private HalResource<Package> createHalPackage(Package sw360Package, User sw360Us
}

@NotNull
private ResponseEntity<CollectionModel<EntityModel<Package>>> getPackageResponse(Pageable pageable,
private ResponseEntity<CollectionModel<EntityModel<Package>>> getPackageResponse(String version, String purl, String packageManager, Pageable pageable,
boolean allDetails, HttpServletRequest request, User sw360User, List<Package> sw360Packages,
boolean isNoFilter)
throws ResourceClassNotFoundException, PaginationParameterException, URISyntaxException, TException {
Expand Down Expand Up @@ -314,7 +324,11 @@ private ResponseEntity<CollectionModel<EntityModel<Package>>> getPackageResponse
packageResources.add(embeddedPackageResource);
};

paginationResult.getResources().stream().forEach(consumer);
paginationResult.getResources().stream()
.filter(pkg -> packageManager == null || packageManager.equals(pkg.getPackageManager().toString()))
.filter(pkg -> version == null || version.isEmpty() || version.equals(pkg.getVersion()))
.filter(pkg -> purl == null || purl.isEmpty() || purl.equals(pkg.getPurl())).forEach(consumer);

CollectionModel<EntityModel<Package>> resources;
if (packageResources.isEmpty()) {
resources = restControllerHelper.emptyPageResource(Package.class, paginationResult);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,26 @@ public List<Package> searchPackage(String field, String searchQuery, boolean isE
return sw360PackageClient.searchPackagesWithFilter(searchQuery, queryMap);
}

public List<Package> searchPackageByName(String name) throws TException {
final PackageService.Iface sw360PackageClient = getThriftPackageClient();
return sw360PackageClient.searchByName(name);
}

public List<Package> searchByPackageManager(String pkgManager) throws TException {
final PackageService.Iface sw360PackageClient = getThriftPackageClient();
return sw360PackageClient.searchByPackageManager(pkgManager);
}

public List<Package> searchPackageByVersion(String version) throws TException {
final PackageService.Iface sw360PackageClient = getThriftPackageClient();
return sw360PackageClient.searchByVersion(version);
}

public List<Package> searchPackageByPurl(String purl) throws TException {
final PackageService.Iface sw360PackageClient = getThriftPackageClient();
return sw360PackageClient.searchByPurl(purl);
}

public int getTotalPackagesCounts() throws TException {
PackageService.Iface sw360PackageClient = getThriftPackageClient();
return sw360PackageClient.getTotalPackagesCount();
Expand Down

0 comments on commit 96863d1

Please sign in to comment.