Skip to content

Commit

Permalink
fix (rest) : rest api created for component search by lucene search
Browse files Browse the repository at this point in the history
Signed-off-by: Keerthi B L <[email protected]>
  • Loading branch information
keerthi-bl committed Nov 22, 2023
1 parent ad69c47 commit 02d84be
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 25 deletions.
17 changes: 17 additions & 0 deletions rest/resource-server/src/docs/asciidoc/components.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ include::{snippets}/should_document_get_components_with_all_details/curl-request
===== Example response
include::{snippets}/should_document_get_components_with_all_details/http-response.adoc[]

[[resources-components-list-with-lucenesearch]]
==== Listing by lucene search

A `GET` request will list all of the service's components by lucenesearch.

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

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

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

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

[[resources-recent-components-list]]
==== Listing recent components

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.sw360.datahandler.common.CommonUtils;
import org.eclipse.sw360.datahandler.common.SW360Constants;
import org.eclipse.sw360.datahandler.common.SW360Utils;
import org.eclipse.sw360.datahandler.couchdb.lucene.LuceneAwareDatabaseConnector;
import org.eclipse.sw360.datahandler.resourcelists.PaginationParameterException;
import org.eclipse.sw360.datahandler.resourcelists.PaginationResult;
import org.eclipse.sw360.datahandler.resourcelists.ResourceClassNotFoundException;
Expand Down Expand Up @@ -90,6 +91,8 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;

Expand Down Expand Up @@ -141,6 +144,8 @@ public ResponseEntity<CollectionModel<EntityModel<Component>>> getComponents(
@RequestParam(value = "fields", required = false) List<String> fields,
@Parameter(description = "Flag to get components with all details.")
@RequestParam(value = "allDetails", required = false) boolean allDetails,
@Parameter(description = "lucenesearch parameter to filter the components.")
@RequestParam(value = "luceneSearch", required = false) boolean luceneSearch,
HttpServletRequest request
) throws TException, URISyntaxException, PaginationParameterException, ResourceClassNotFoundException {

Expand All @@ -150,42 +155,73 @@ public ResponseEntity<CollectionModel<EntityModel<Component>>> getComponents(
String queryString = request.getQueryString();
Map<String, String> params = parseQueryString(queryString);

if (name != null && !name.isEmpty()) {
allComponents.addAll(componentService.searchComponentByName(params.get("name").replace("%20"," ")));
Map<String, Set<String>> filterMap = new HashMap<>();
if (luceneSearch) {
if (CommonUtils.isNotNullEmptyOrWhitespace(componentType)) {
Set<String> values = CommonUtils.splitToSet(componentType);
filterMap.put(Component._Fields.COMPONENT_TYPE.getFieldName(), values);
}
if (CommonUtils.isNotNullEmptyOrWhitespace(name)) {
Set<String> values = CommonUtils.splitToSet(name);
values = values.stream().map(LuceneAwareDatabaseConnector::prepareWildcardQuery)
.collect(Collectors.toSet());
filterMap.put(Component._Fields.NAME.getFieldName(), values);
}
allComponents.addAll(componentService.refineSearch(filterMap, sw360User));
} else {
allComponents.addAll(componentService.getComponentsForUser(sw360User));
if (name != null && !name.isEmpty()) {
allComponents.addAll(componentService.searchComponentByName(params.get("name").replace("%20", " ")));
} else {
allComponents.addAll(componentService.getComponentsForUser(sw360User));
}
}

PaginationResult<Component> paginationResult = restControllerHelper.createPaginationResult(request, pageable, allComponents, SW360Constants.TYPE_COMPONENT);
PaginationResult<Component> paginationResult = restControllerHelper.createPaginationResult(request, pageable,
allComponents, SW360Constants.TYPE_COMPONENT);

CollectionModel resources = getFilteredComponentResources(componentType, fields, allDetails, luceneSearch,
sw360User, paginationResult);
return new ResponseEntity<>(resources, HttpStatus.OK);
}

private CollectionModel getFilteredComponentResources(String componentType, List<String> fields, boolean allDetails,
boolean luceneSearch, User sw360User, PaginationResult<Component> paginationResult)
throws URISyntaxException {
List<EntityModel<Component>> componentResources = new ArrayList<>();
paginationResult.getResources().stream()
.filter(component -> componentType == null || (component.isSetComponentType() && componentType.equals(component.componentType.name())))
.forEach(c -> {
EntityModel<Component> embeddedComponentResource = null;
if (!allDetails) {
Component embeddedComponent = restControllerHelper.convertToEmbeddedComponent(c, fields);
embeddedComponentResource = EntityModel.of(embeddedComponent);
} else {
try {
embeddedComponentResource = createHalComponent(c, sw360User);
} catch (TException e) {
throw new RuntimeException(e);
}
if (embeddedComponentResource == null) {
return;
}
}
componentResources.add(embeddedComponentResource);
});
Consumer<Component> consumer = c -> {
EntityModel<Component> embeddedComponentResource = null;
if (!allDetails) {
Component embeddedComponent = restControllerHelper.convertToEmbeddedComponent(c, fields);
embeddedComponentResource = EntityModel.of(embeddedComponent);
} else {
try {
embeddedComponentResource = createHalComponent(c, sw360User);
} catch (TException e) {
throw new RuntimeException(e);
}
if (embeddedComponentResource == null) {
return;
}
}
componentResources.add(embeddedComponentResource);
};

if (luceneSearch) {
paginationResult.getResources().stream().forEach(consumer);
} else {
paginationResult.getResources().stream()
.filter(component -> componentType == null
|| (component.isSetComponentType() && componentType.equals(component.componentType.name())))
.forEach(consumer);
}

CollectionModel resources;
if (componentResources.size() == 0) {
if (componentResources.isEmpty()) {
resources = restControllerHelper.emptyPageResource(Component.class, paginationResult);
} else {
resources = restControllerHelper.generatePagesResource(paginationResult, componentResources);
}
return new ResponseEntity<>(resources, HttpStatus.OK);
return resources;
}

private Map<String, String> parseQueryString(String queryString) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,4 +323,9 @@ public int countProjectsByComponentId(String componentId, User sw360user) throws
Set<String> releaseIds = SW360Utils.getReleaseIds(component.getReleases());
return projectService.countProjectsByReleaseIds(releaseIds);
}

public List<Component> refineSearch(Map<String, Set<String>> filterMap, User sw360User) throws TException {
ComponentService.Iface sw360ComponentClient = getThriftComponentClient();
return sw360ComponentClient.refineSearchAccessibleComponents(null, filterMap, sw360User);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ public void before() throws TException, IOException {
given(this.componentServiceMock.getComponentsForUser(any())).willReturn(componentList);
given(this.sw360ReportServiceMock.getComponentBuffer(any(),anyBoolean())).willReturn(ByteBuffer.allocate(10000));
given(this.componentServiceMock.getRecentComponents(any())).willReturn(componentList);
given(this.componentServiceMock.refineSearch(any(), any())).willReturn(componentList);
given(this.componentServiceMock.getComponentSubscriptions(any())).willReturn(componentList);
given(this.componentServiceMock.getMyComponentsForUser(any())).willReturn(componentList);
given(this.componentServiceMock.getComponentForUserById(eq("17653524"), any())).willReturn(angularComponent);
Expand Down Expand Up @@ -549,6 +550,36 @@ public void should_document_get_components() throws Exception {
)));
}

@Test
public void should_document_get_components_by_lucene_search() throws Exception {
String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword);
mockMvc.perform(get("/api/components").header("Authorization", "Bearer " + accessToken)
.param("name", angularComponent.getName()).param("luceneSearch", "true").param("sort", "name,desc")
.param("page", "0").param("page_entries", "5").accept(MediaTypes.HAL_JSON)).andExpect(status().isOk())
.andDo(this.documentationHandler.document(
requestParameters(parameterWithName("name").description("name of components"),
parameterWithName("luceneSearch").description("Defines whether luceneSearch is required while searching the component"),
parameterWithName("page").description("Page of components"),
parameterWithName("page_entries").description("Amount of components per page"),
parameterWithName("sort").description("Defines order of the components")),
links(linkWithRel("curies").description("Curies are used for online documentation"),
linkWithRel("first").description("Link to first page"),
linkWithRel("last").description("Link to last page")),
responseFields(
subsectionWithPath("_embedded.sw360:components.[]id").description("The id of the component"),
subsectionWithPath("_embedded.sw360:components.[]name").description("The name of the component"),
subsectionWithPath("_embedded.sw360:components.[]componentType").description("The component type, possible values are: "+ Arrays.asList(ComponentType.values())),
subsectionWithPath("_embedded.sw360:components.[]visbility").description("The visbility of the component"),
subsectionWithPath("_embedded.sw360:components.[]description").description("The description of the component"),
subsectionWithPath("_embedded.sw360:components").description("An array of <<resources-components, Components resources>>"),
subsectionWithPath("_links").description("<<resources-index-links,Links>> to other resources"),
fieldWithPath("page").description("Additional paging information"),
fieldWithPath("page.size").description("Number of components per page"),
fieldWithPath("page.totalElements").description("Total number of all existing components"),
fieldWithPath("page.totalPages").description("Total number of pages"),
fieldWithPath("page.number").description("Number of the current page"))));
}

@Test
public void should_document_get_components_with_all_details() throws Exception {
String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword);
Expand Down

0 comments on commit 02d84be

Please sign in to comment.