Skip to content

Commit

Permalink
MSEARCH-829: code fixes and test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
PBobylev committed Sep 4, 2024
1 parent d07890d commit 5bc676f
Show file tree
Hide file tree
Showing 39 changed files with 1,264 additions and 363 deletions.
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* Provides `consortium-search v1.2`

### Features
* Implement indices recreation of linked-data-work and linked-data-authority ([MSEARCH-820](https://issues.folio.org/browse/MSEARCH-820))
* Implement indices recreation of the Linked Data resources ([MSEARCH-820](https://issues.folio.org/browse/MSEARCH-820))
* Extension of mod-search consortium items/holdings API ([MSEARCH-788](https://issues.folio.org/browse/MSEARCH-788))
* Create location index and process location events ([MSEARCH-703](https://issues.folio.org/browse/MSEARCH-703))
* Implement reindexing of locations ([MSEARCH-702](https://issues.folio.org/browse/MSEARCH-702))
Expand All @@ -22,6 +22,7 @@
* Search consolidated items/holdings data in consortium ([MSEARCH-759](https://folio-org.atlassian.net/browse/MSEARCH-759))
* Create linked data work index and process linked data work events ([MSEARCH-781](https://folio-org.atlassian.net/browse/MSEARCH-781))
* Create linked data authority index and process linked data authority events ([MSEARCH-784](https://folio-org.atlassian.net/browse/MSEARCH-784))
* Create linked data instance index and process linked data instance events ([MSEARCH-829](https://folio-org.atlassian.net/browse/MSEARCH-829))
* Allow Unified List of Inventory Locations in a Consortium to be fetched by member tenants ([MSEARCH-660](https://folio-org.atlassian.net/browse/MSEARCH-660))
* Implement Indexing of Campuses from Kafka ([MSEARCH-770](https://issues.folio.org/browse/MSEARCH-770))
* Extend response with additional Location fields for Inventory Locations in a Consortium endpoint ([MSEARCH-775](https://folio-org.atlassian.net/browse/MSEARCH-775))
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,11 @@ x-okapi-token: [JWT_TOKEN]
```

* `resourceName` parameter is optional and equal to `instance` by default. Possible values: `instance`, `authority`, `locations`,
`linked-data-work`, `linked-data-authority`. Please note that `locations` reindex is synchronous.
`linked-data-instance`, `linked-data-work`, `linked-data-authority`. Please note that `locations` reindex is synchronous.
* `recreateIndex` parameter is optional and equal to `false` by default. If it is equal to `true` then mod-search
will drop existing indices for tenant and resource, creating them again. Executing request with this parameter
equal to `true` in query will erase all the tenant data in mod-search.
* Please note that for `linked-data-work` and `linked-data-authority` resources the endpoint is used only for index recreation
* Please note that for `linked-data-instance`, `linked-data-work` and `linked-data-authority` resources the endpoint is used only for index recreation
purpose and actual reindex operation is triggered through mod-linked-data.

### Monitoring reindex process
Expand Down Expand Up @@ -421,6 +421,7 @@ Consortium feature on module enable is defined by 'centralTenantId' tenant param
|:-------|:----------------------------------|:-------------------------------------------------------------------------------------|
| GET | `/search/instances` | Search by instances and to this instance items and holding-records |
| GET | `/search/authorities` | Search by authority records |
| GET | `/search/linked-data/instances` | Search linked data graph instance resource descriptions |
| GET | `/search/linked-data/works` | Search linked data graph work resource descriptions |
| GET | `/search/linked-data/authorities` | Search linked data graph authority resource descriptions |
| GET | `/search/{recordType}/facets` | Get facets where recordType could be: instances, authorities, contributors, subjects |
Expand Down
17 changes: 17 additions & 0 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@
"user-tenants.collection.get"
]
},
{
"methods": [
"GET"
],
"pathPattern": "/search/linked-data/instances",
"permissionsRequired": [
"search.linked-data.instance.collection.get"
],
"modulePermissions": [
"user-tenants.collection.get"
]
},
{
"methods": [
"GET"
Expand Down Expand Up @@ -639,6 +651,11 @@
"displayName": "Search - searches authorities by given query",
"description": "Searches authorities by given query"
},
{
"permissionName": "search.linked-data.instance.collection.get",
"displayName": "Search - searches linked data instances by given query",
"description": "Searches linked data instances by given query"
},
{
"permissionName": "search.linked-data.work.collection.get",
"displayName": "Search - searches linked data works by given query",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class ResourceEventBatchInterceptor implements BatchInterceptor<String, R
Map.entry("inventory.campus", SearchUtils.CAMPUS_RESOURCE),
Map.entry("inventory.institution", SearchUtils.INSTITUTION_RESOURCE),
Map.entry("inventory.library", SearchUtils.LIBRARY_RESOURCE),
Map.entry("linked-data.instance", SearchUtils.LINKED_DATA_INSTANCE_RESOURCE),
Map.entry("linked-data.work", SearchUtils.LINKED_DATA_WORK_RESOURCE),
Map.entry("linked-data.authority", SearchUtils.LINKED_DATA_AUTHORITY_RESOURCE)
);
Expand Down
13 changes: 8 additions & 5 deletions src/main/java/org/folio/search/service/IndexService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static java.lang.Boolean.TRUE;
import static org.folio.search.utils.SearchUtils.INSTANCE_RESOURCE;
import static org.folio.search.utils.SearchUtils.LINKED_DATA_AUTHORITY_RESOURCE;
import static org.folio.search.utils.SearchUtils.LINKED_DATA_INSTANCE_RESOURCE;
import static org.folio.search.utils.SearchUtils.LINKED_DATA_WORK_RESOURCE;
import static org.folio.search.utils.SearchUtils.LOCATION_RESOURCE;
import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
Expand Down Expand Up @@ -131,7 +132,7 @@ public FolioIndexOperationResponse updateMappings(String resourceName, String te
*/
public void createIndexIfNotExist(String resourceName, String tenantId) {
var index = indexNameProvider.getIndexName(resourceName, tenantId);
if (!indexRepository.indexExists(index)) {
if (! indexRepository.indexExists(index)) {
createIndex(resourceName, tenantId);
}
}
Expand Down Expand Up @@ -168,7 +169,7 @@ && notConsortiumMemberTenant(tenantId)) {
/**
* Runs reindex request for mod-inventory-storage.
*
* @param resource - resource name as {@link String} object
* @param resource - resource name as {@link String} object
*/
public ReindexJob reindexInventoryAsync(String resource) {
var reindexUri = fromUriString(RESOURCE_STORAGE_REINDEX_URI).buildAndExpand(resource).toUri();
Expand Down Expand Up @@ -224,7 +225,7 @@ private List<String> getResourceNamesToReindex(ReindexRequest reindexRequest) {
var resourceDescription = resourceDescriptionService.find(resourceName);
if (resourceDescription.isEmpty()
|| resourceDescription.get().getParent() != null
|| !resourceDescription.get().isReindexSupported()) {
|| ! resourceDescription.get().isReindexSupported()) {
throw new RequestValidationException(
"Reindex request contains invalid resource name", RESOURCE_NAME_PARAMETER, resourceName);
}
Expand Down Expand Up @@ -271,7 +272,7 @@ private void updateNumberOfReplicas(ObjectNode settings, Integer numberOfReplica

private void updateRefreshInterval(ObjectNode settings, Integer refreshInt) {
if (refreshInt != null && refreshInt != 0) {
settings.put("refresh_interval", refreshInt == -1 ? "-1" : refreshInt + "s");
settings.put("refresh_interval", refreshInt == - 1 ? "-1" : refreshInt + "s");
}
}

Expand All @@ -294,6 +295,8 @@ private static String normalizeResourceName(String url) {
}

private boolean isLinkedDataResource(String resource) {
return LINKED_DATA_WORK_RESOURCE.equals(resource) || LINKED_DATA_AUTHORITY_RESOURCE.equals(resource);
return LINKED_DATA_INSTANCE_RESOURCE.equals(resource)
|| LINKED_DATA_WORK_RESOURCE.equals(resource)
|| LINKED_DATA_AUTHORITY_RESOURCE.equals(resource);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package org.folio.search.service.setter.linkeddata.authority;

import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.LinkedDataAuthority;
import org.folio.search.service.lccn.LccnNormalizer;
import org.folio.search.service.setter.FieldProcessor;
import org.folio.search.service.setter.linkeddata.common.LinkedDataLccnProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class LinkedDataAuthorityLccnProcessor implements FieldProcessor<LinkedDataAuthority, Set<String>> {

private final LinkedDataLccnProcessor linkedDataLccnProcessor;

public LinkedDataAuthorityLccnProcessor(@Autowired LccnNormalizer lccnNormalizer) {
this.linkedDataLccnProcessor = new LinkedDataLccnProcessor(lccnNormalizer);
}

@Override
public Set<String> getFieldValue(LinkedDataAuthority linkedDataAuthority) {
return linkedDataLccnProcessor.getFieldValue(linkedDataAuthority.getIdentifiers());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package org.folio.search.service.setter.linkeddata.instance;

import static java.util.Optional.ofNullable;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.LinkedDataInstance;
import org.folio.search.domain.dto.LinkedDataWorkOnly;
import org.folio.search.service.setter.FieldProcessor;
import org.folio.search.service.setter.linkeddata.common.LinkedDataContributorProcessor;
import org.springframework.stereotype.Component;
Expand All @@ -15,7 +21,16 @@ public class LinkedDataInstanceContributorProcessor implements FieldProcessor<Li

@Override
public Set<String> getFieldValue(LinkedDataInstance linkedDataInstance) {
return linkedDataContributorProcessor.getFieldValue(linkedDataInstance.getContributors());
var instanceContributors = ofNullable(linkedDataInstance.getContributors())
.stream()
.flatMap(Collection::stream)
.filter(Objects::nonNull);
var workContributors = ofNullable(linkedDataInstance.getParentWork())
.map(LinkedDataWorkOnly::getContributors)
.stream()
.flatMap(Collection::stream);
var contributors = Stream.concat(instanceContributors, workContributors).toList();
return linkedDataContributorProcessor.getFieldValue(contributors);
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package org.folio.search.service.setter.linkeddata.instance;

import static java.util.Optional.ofNullable;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.LinkedDataInstance;
import org.folio.search.domain.dto.LinkedDataWorkOnly;
import org.folio.search.service.setter.FieldProcessor;
import org.folio.search.service.setter.linkeddata.common.LinkedDataNoteProcessor;
import org.springframework.stereotype.Component;
Expand All @@ -15,7 +21,16 @@ public class LinkedDataInstanceNoteProcessor implements FieldProcessor<LinkedDat

@Override
public Set<String> getFieldValue(LinkedDataInstance linkedDataInstance) {
return linkedDataNoteProcessor.getFieldValue(linkedDataInstance.getNotes());
var instanceNotes = ofNullable(linkedDataInstance.getNotes())
.stream()
.flatMap(Collection::stream)
.filter(Objects::nonNull);
var workNotes = ofNullable(linkedDataInstance.getParentWork())
.map(LinkedDataWorkOnly::getNotes)
.stream()
.flatMap(Collection::stream);
var contributors = Stream.concat(instanceNotes, workNotes).toList();
return linkedDataNoteProcessor.getFieldValue(contributors);
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package org.folio.search.service.setter.linkeddata.instance;

import static java.util.Optional.ofNullable;

import java.util.Collection;
import java.util.Objects;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.LinkedDataInstance;
import org.folio.search.domain.dto.LinkedDataWorkOnly;
import org.folio.search.service.setter.FieldProcessor;
import org.folio.search.service.setter.linkeddata.common.LinkedDataSortTitleProcessor;
import org.springframework.stereotype.Component;
Expand All @@ -14,7 +20,16 @@ public class LinkedDataInstanceSortTitleProcessor implements FieldProcessor<Link

@Override
public String getFieldValue(LinkedDataInstance linkedDataInstance) {
return linkedDataSortTitleProcessor.getFieldValue(linkedDataInstance.getTitles());
var instanceTitles = ofNullable(linkedDataInstance.getTitles())
.stream()
.flatMap(Collection::stream)
.filter(Objects::nonNull);
var workTitles = ofNullable(linkedDataInstance.getParentWork())
.map(LinkedDataWorkOnly::getTitles)
.stream()
.flatMap(Collection::stream);
var titles = Stream.concat(instanceTitles, workTitles).toList();
return linkedDataSortTitleProcessor.getFieldValue(titles);
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package org.folio.search.service.setter.linkeddata.instance;

import static java.util.Optional.ofNullable;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.LinkedDataInstance;
import org.folio.search.domain.dto.LinkedDataWorkOnly;
import org.folio.search.service.setter.FieldProcessor;
import org.folio.search.service.setter.linkeddata.common.LinkedDataTitleProcessor;
import org.springframework.stereotype.Component;
Expand All @@ -15,7 +21,16 @@ public class LinkedDataInstanceTitleProcessor implements FieldProcessor<LinkedDa

@Override
public Set<String> getFieldValue(LinkedDataInstance linkedDataInstance) {
return linkedDataTitleProcessor.getFieldValue(linkedDataInstance.getTitles());
var instanceTitles = ofNullable(linkedDataInstance.getTitles())
.stream()
.flatMap(Collection::stream)
.filter(Objects::nonNull);
var workTitles = ofNullable(linkedDataInstance.getParentWork())
.map(LinkedDataWorkOnly::getTitles)
.stream()
.flatMap(Collection::stream);
var titles = Stream.concat(instanceTitles, workTitles).toList();
return linkedDataTitleProcessor.getFieldValue(titles);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ public class LinkedDataWorkContributorProcessor implements FieldProcessor<Linked

@Override
public Set<String> getFieldValue(LinkedDataWork linkedDataWork) {
var workContributors = ofNullable(linkedDataWork.getContributors()).stream().flatMap(Collection::stream);
var instanceContributors = ofNullable(linkedDataWork.getInstances()).stream().flatMap(Collection::stream)
.map(LinkedDataInstanceOnly::getContributors).filter(Objects::nonNull).flatMap(Collection::stream);
var workContributors = ofNullable(linkedDataWork.getContributors())
.stream()
.flatMap(Collection::stream);
var instanceContributors = ofNullable(linkedDataWork.getInstances())
.stream()
.flatMap(Collection::stream)
.map(LinkedDataInstanceOnly::getContributors)
.filter(Objects::nonNull)
.flatMap(Collection::stream);
var contributors = Stream.concat(workContributors, instanceContributors).toList();
return linkedDataContributorProcessor.getFieldValue(contributors);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ public class LinkedDataWorkNoteProcessor implements FieldProcessor<LinkedDataWor

@Override
public Set<String> getFieldValue(LinkedDataWork linkedDataWork) {
var workNotes = ofNullable(linkedDataWork.getNotes()).stream().flatMap(Collection::stream);
var instNotes = ofNullable(linkedDataWork.getInstances()).stream().flatMap(Collection::stream)
var workNotes = ofNullable(linkedDataWork.getNotes())
.stream()
.flatMap(Collection::stream);
var instanceNotes = ofNullable(linkedDataWork.getInstances()).stream().flatMap(Collection::stream)
.filter(Objects::nonNull)
.map(LinkedDataInstanceOnly::getNotes)
.flatMap(Collection::stream);
var notes = Stream.concat(workNotes, instNotes).toList();
var notes = Stream.concat(workNotes, instanceNotes).toList();
return linkedDataNoteProcessor.getFieldValue(notes);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
package org.folio.search.service.setter.linkeddata.work;

import static java.util.Optional.ofNullable;

import java.util.Collection;
import java.util.Objects;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.LinkedDataInstanceOnly;
import org.folio.search.domain.dto.LinkedDataWork;
import org.folio.search.service.setter.FieldProcessor;
import org.folio.search.service.setter.linkeddata.common.LinkedDataSortTitleProcessor;
Expand All @@ -20,11 +14,7 @@ public class LinkedDataWorkSortTitleProcessor implements FieldProcessor<LinkedDa

@Override
public String getFieldValue(LinkedDataWork linkedDataWork) {
var workTitles = ofNullable(linkedDataWork.getTitles()).stream().flatMap(Collection::stream);
var instanceTitles = ofNullable(linkedDataWork.getInstances()).stream().flatMap(Collection::stream)
.map(LinkedDataInstanceOnly::getTitles).filter(Objects::nonNull).flatMap(Collection::stream);
var titles = Stream.concat(workTitles, instanceTitles).toList();
return linkedDataSortTitleProcessor.getFieldValue(titles);
return linkedDataSortTitleProcessor.getFieldValue(linkedDataWork.getTitles());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ public class LinkedDataWorkTitleProcessor implements FieldProcessor<LinkedDataWo

@Override
public Set<String> getFieldValue(LinkedDataWork linkedDataWork) {
var workTitles = ofNullable(linkedDataWork.getTitles()).stream().flatMap(Collection::stream);
var instTitles = ofNullable(linkedDataWork.getInstances()).stream().flatMap(Collection::stream)
var workTitles = ofNullable(linkedDataWork.getTitles())
.stream()
.flatMap(Collection::stream);
var instTitles = ofNullable(linkedDataWork.getInstances())
.stream()
.flatMap(Collection::stream)
.filter(Objects::nonNull)
.map(LinkedDataInstanceOnly::getTitles)
.flatMap(Collection::stream);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/folio/search/utils/SearchUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class SearchUtils {
public static final String CONTRIBUTOR_RESOURCE = getResourceName(Contributor.class);
public static final String LOCATION_RESOURCE = "location";
public static final String CLASSIFICATION_TYPE_RESOURCE = "classification-type";
public static final String LINKED_DATA_INSTANCE_RESOURCE = "linked-data-instance";
public static final String LINKED_DATA_WORK_RESOURCE = "linked-data-work";
public static final String LINKED_DATA_AUTHORITY_RESOURCE = "linked-data-authority";
public static final String CAMPUS_RESOURCE = "campus";
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ folio:
group-id: ${folio.environment}-mod-search-location-type-group
linked-data:
concurrency: ${KAFKA_LINKED_DATA_CONCURRENCY:1}
topic-pattern: (${folio.environment}\.)(.*\.)linked-data\.(work|authority)
topic-pattern: (${folio.environment}\.)(.*\.)linked-data\.(instance|work|authority)
group-id: ${folio.environment}-mod-search-linked-data-group
okapiUrl: ${okapi.url}
logging:
Expand Down
Loading

0 comments on commit 5bc676f

Please sign in to comment.