Skip to content

Commit

Permalink
fix: #17 Retrieve Beacon Facets when logged-in
Browse files Browse the repository at this point in the history
Beacon facets must be retrieved if the user is logged in, no matter if the user is using or not beacon facets to filter the results.

The class `BeaconDatasetsSearchService` was altered to comply to this requirement:
- if the user is not logged-in automatically CKAN query is triggered without enhancement. Check line 75.
- If there are beacon queries we trigger a search on Beacon Network. Check lines 79 and 109.
- if there are no beacon filters or beacon's resultsets is not empty, we query on CKAN. Check lines 81 and 134.
- Beacon facets/filters are always inserted into CKAN output. Check lines 87 and 175.

With those rules, we are able to properly enrich CKAN output with beacon response, including facets and resultsets, if there is any.

Several different test cases were introduced to cover most of the scenarios.
  • Loading branch information
brunopacheco1 committed Apr 16, 2024
1 parent e5aeba3 commit 088d6f5
Show file tree
Hide file tree
Showing 4 changed files with 470 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import io.github.genomicdatainfrastructure.discovery.model.FacetGroup;
import io.github.genomicdatainfrastructure.discovery.model.SearchedDataset;
import io.github.genomicdatainfrastructure.discovery.remote.beacon.api.BeaconQueryApi;
import io.github.genomicdatainfrastructure.discovery.remote.beacon.model.BeaconIndividualsRequest;
import io.github.genomicdatainfrastructure.discovery.remote.beacon.model.BeaconIndividualsResponse;
import io.github.genomicdatainfrastructure.discovery.remote.beacon.model.BeaconIndividualsResponseContent;
import io.github.genomicdatainfrastructure.discovery.remote.beacon.model.BeaconResultSet;
Expand Down Expand Up @@ -71,25 +70,21 @@ public BeaconDatasetsSearchService(

@Override
public DatasetsSearchResponse search(DatasetSearchQuery query, String accessToken) {
var beaconQuery = BeaconIndividualsRequestMapper.from(query);

var beaconAuthorization = retrieveBeaconAuthorization(accessToken);

if (beaconAuthorization == null || beaconQuery.getQuery().getFilters().isEmpty()) {
if (beaconAuthorization == null) {
return datasetsSearchService.search(query, accessToken);
}

var beaconResponse = queryOnBeacon(beaconAuthorization, beaconQuery);
var resultsets = queryOnBeaconIfThereAreBeaconFilters(beaconAuthorization, query);

var datasetsReponse = DatasetsSearchResponse.builder()
.count(0)
.build();
if (!beaconResponse.isEmpty()) {
var enhancedQuery = enhanceQueryFacets(query, beaconResponse);
datasetsReponse = datasetsSearchService.search(enhancedQuery, accessToken);
}
var datasetsSearchResponse = queryOnCkanIfThereIsNoBeaconFilterOrResultsetsIsNotEmpty(
accessToken,
query,
resultsets
);

return enhanceDatasetsResponse(beaconAuthorization, datasetsReponse, beaconResponse);
return enhanceDatasetsResponse(beaconAuthorization, datasetsSearchResponse, resultsets);
}

private String retrieveBeaconAuthorization(String accessToken) {
Expand All @@ -111,10 +106,14 @@ private String retrieveBeaconAuthorization(String accessToken) {
}
}

private List<BeaconResultSet> queryOnBeacon(
private List<BeaconResultSet> queryOnBeaconIfThereAreBeaconFilters(
String beaconAuthorization,
BeaconIndividualsRequest beaconQuery
DatasetSearchQuery query
) {
var beaconQuery = BeaconIndividualsRequestMapper.from(query);
if (beaconQuery.getQuery().getFilters().isEmpty()) {
return List.of();
}

var response = beaconQueryApi.listIndividuals(beaconAuthorization, beaconQuery);

Expand All @@ -128,10 +127,29 @@ private List<BeaconResultSet> queryOnBeacon(
.filter(Objects::nonNull)
.filter(it -> BEACON_DATASET_TYPE.equals(it.getSetType()))
.filter(it -> isNotBlank(it.getId()))
.filter(it -> it.getResultsCount() > 0)
.filter(it -> it.getResultsCount() != null && it.getResultsCount() > 0)
.toList();
}

private DatasetsSearchResponse queryOnCkanIfThereIsNoBeaconFilterOrResultsetsIsNotEmpty(
String beaconAuthorization,
DatasetSearchQuery query,
List<BeaconResultSet> resultSets
) {
var nonNullFacets = ofNullable(query.getFacets()).orElseGet(List::of);
var thereIsAtLeastOneBeaconFilter = nonNullFacets.stream()
.anyMatch(it -> BEACON_FACET_GROUP.equals(it.getFacetGroup()));

if (thereIsAtLeastOneBeaconFilter && resultSets.isEmpty()) {
return DatasetsSearchResponse.builder()
.count(0)
.build();
}

var enhancedQuery = enhanceQueryFacets(query, resultSets);
return datasetsSearchService.search(enhancedQuery, beaconAuthorization);
}

private DatasetSearchQuery enhanceQueryFacets(
DatasetSearchQuery query,
List<BeaconResultSet> resultSets
Expand All @@ -156,38 +174,38 @@ private DatasetSearchQuery enhanceQueryFacets(

private DatasetsSearchResponse enhanceDatasetsResponse(
String beaconAuthorization,
DatasetsSearchResponse datasetsReponse,
DatasetsSearchResponse datasetsSearchReponse,
List<BeaconResultSet> resultSets
) {
var facetGroupCount = new HashMap<String, Integer>();
facetGroupCount.put(BEACON_FACET_GROUP, resultSets.size());
if (isNotEmpty(datasetsReponse.getFacetGroupCount())) {
facetGroupCount.putAll(datasetsReponse.getFacetGroupCount());
if (isNotEmpty(datasetsSearchReponse.getFacetGroupCount())) {
facetGroupCount.putAll(datasetsSearchReponse.getFacetGroupCount());
}

var facetGroups = new ArrayList<FacetGroup>();
facetGroups.add(beaconFilteringTermsService.listFilteringTerms(beaconAuthorization));
if (isNotEmpty(datasetsReponse.getFacetGroups())) {
facetGroups.addAll(datasetsReponse.getFacetGroups());
if (isNotEmpty(datasetsSearchReponse.getFacetGroups())) {
facetGroups.addAll(datasetsSearchReponse.getFacetGroups());
}

var results = List.<SearchedDataset>of();
if (isNotEmpty(datasetsReponse.getResults())) {
if (isNotEmpty(datasetsSearchReponse.getResults())) {
var recordCounts = resultSets.stream()
.collect(toMap(
BeaconResultSet::getId,
BeaconResultSet::getResultsCount
));

results = datasetsReponse.getResults()
results = datasetsSearchReponse.getResults()
.stream()
.map(it -> it.toBuilder()
.recordsCount(recordCounts.get(it.getIdentifier()))
.build())
.toList();
}

return datasetsReponse.toBuilder()
return datasetsSearchReponse.toBuilder()
.facetGroupCount(facetGroupCount)
.facetGroups(facetGroups)
.results(results)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ private List<Facet> buildFacets(
return termsGroupedByType.entrySet().stream()
.filter(entry -> facetIdsMappedByName.containsKey(entry.getKey()))
.map(entry -> Facet.builder()
.key(entry.getKey())
.label(facetIdsMappedByName.get(entry.getKey()))
.key(facetIdsMappedByName.get(entry.getKey()))
.label(entry.getKey())
.values(entry.getValue())
.build())
.toList();
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ quarkus.rest-client.ckan_yaml.url=http://localhost:4000
quarkus.rest-client.keycloak_yaml.url=http://localhost:4000
quarkus.rest-client.keycloak_yaml.beacon_idp_alias=LSAAI
quarkus.rest-client.beacon_yaml.url=http://localhost:4000
quarkus.rest-client.beacon_yaml.read-timeout=60000
%dev.quarkus.oidc.auth-server-url=https://keycloak-test.healthdata.nl/realms/ckan
%dev.quarkus.oidc.client-id=ckan
%dev.quarkus.rest-client.ckan_yaml.url=https://ckan-test.healthdata.nl/
Expand Down
Loading

0 comments on commit 088d6f5

Please sign in to comment.