Skip to content

Commit

Permalink
[MSEARCH-772]. Return Unified List of Inventory Libraries in a Consor…
Browse files Browse the repository at this point in the history
…tium
  • Loading branch information
BKadirkhodjaev committed Jun 27, 2024
1 parent 7c1baac commit b298099
Show file tree
Hide file tree
Showing 19 changed files with 726 additions and 9 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* Implement Indexing of Institutions from Kafka ([MSEARCH-771](https://issues.folio.org/browse/MSEARCH-771))
* Implement Indexing of Libraries from Kafka ([MSEARCH-769](https://issues.folio.org/browse/MSEARCH-769))
* Return Unified List of Inventory Campuses in a Consortium ([MSEARCH-773](https://issues.folio.org/browse/MSEARCH-773))
* Return Unified List of Inventory Libraries in a Consortium ([MSEARCH-772](https://issues.folio.org/browse/MSEARCH-772))

### Bug fixes
* Do not delete kafka topics if collection topic is enabled ([MSEARCH-725](https://folio-org.atlassian.net/browse/MSEARCH-725))
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,7 @@ Special API that provide consolidated access to records in consortium environmen
| GET | `/search/consortium/items` | Returns consolidated items |
| GET | `/search/consortium/locations` | Returns consolidated locations |
| GET | `/search/consortium/campuses` | Returns consolidated campuses |
| GET | `/search/consortium/libraries` | Returns consolidated libraries |

## Additional Information

Expand Down
17 changes: 17 additions & 0 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,18 @@
"user-tenants.collection.get"
]
},
{
"methods": [
"GET"
],
"pathPattern": "/search/consortium/libraries",
"permissionsRequired": [
"consortium-search.libraries.collection.get"
],
"modulePermissions": [
"user-tenants.collection.get"
]
},
{
"methods": [
"GET"
Expand Down Expand Up @@ -750,6 +762,11 @@
"permissionName": "consortium-search.campuses.collection.get",
"displayName": "Consortium Search - fetch campuses records",
"description": "Returns campus records in consortium"
},
{
"permissionName": "consortium-search.libraries.collection.get",
"displayName": "Consortium Search - fetch libraries records",
"description": "Returns library records in consortium"
}
],
"launchDescriptor": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.folio.search.domain.dto.ConsortiumHoldingCollection;
import org.folio.search.domain.dto.ConsortiumItem;
import org.folio.search.domain.dto.ConsortiumItemCollection;
import org.folio.search.domain.dto.ConsortiumLibraryCollection;
import org.folio.search.domain.dto.ConsortiumLocationCollection;
import org.folio.search.domain.dto.Instance;
import org.folio.search.domain.dto.SortOrder;
Expand All @@ -25,6 +26,7 @@
import org.folio.search.service.consortium.ConsortiumCampusService;
import org.folio.search.service.consortium.ConsortiumInstanceSearchService;
import org.folio.search.service.consortium.ConsortiumInstanceService;
import org.folio.search.service.consortium.ConsortiumLibraryService;
import org.folio.search.service.consortium.ConsortiumLocationService;
import org.folio.search.service.consortium.ConsortiumTenantService;
import org.folio.spring.integration.XOkapiHeaders;
Expand All @@ -48,6 +50,7 @@ public class SearchConsortiumController implements SearchConsortiumApi {
private final ConsortiumLocationService locationService;
private final ConsortiumInstanceSearchService searchService;
private final ConsortiumCampusService campusService;
private final ConsortiumLibraryService libraryService;

@Override
public ResponseEntity<ConsortiumHoldingCollection> getConsortiumHoldings(String tenantHeader, String instanceId,
Expand Down Expand Up @@ -114,6 +117,21 @@ public ResponseEntity<ConsortiumCampusCollection> getConsortiumCampuses(String t
.totalRecords(result.getTotalRecords()));
}

@Override
public ResponseEntity<ConsortiumLibraryCollection> getConsortiumLibraries(String tenantHeader,
String tenantId,
Integer limit,
Integer offset,
String sortBy,
SortOrder sortOrder) {
var result = libraryService.fetchLibraries(tenantHeader, tenantId, limit, offset, sortBy, sortOrder);

return ResponseEntity.ok(new
ConsortiumLibraryCollection()
.libraries(result.getRecords())
.totalRecords(result.getTotalRecords()));
}

@Override
public ResponseEntity<ConsortiumHolding> getConsortiumHolding(UUID id, String tenantHeader) {
var tenant = verifyAndGetTenant(tenantHeader);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.folio.search.repository;

import static org.folio.search.utils.SearchUtils.TENANT_ID_FIELD_NAME;
import static org.folio.search.utils.SearchUtils.performExceptionalOperation;
import static org.opensearch.search.sort.SortOrder.ASC;
import static org.opensearch.search.sort.SortOrder.DESC;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.search.domain.dto.ConsortiumLibrary;
import org.folio.search.domain.dto.SortOrder;
import org.folio.search.model.SearchResult;
import org.folio.search.service.converter.ElasticsearchDocumentConverter;
import org.jetbrains.annotations.NotNull;
import org.opensearch.action.search.SearchRequest;
import org.opensearch.action.search.SearchResponse;
import org.opensearch.client.RequestOptions;
import org.opensearch.client.RestHighLevelClient;
import org.opensearch.index.query.QueryBuilders;
import org.opensearch.search.builder.SearchSourceBuilder;
import org.opensearch.search.sort.SortBuilders;
import org.springframework.stereotype.Repository;

@Log4j2
@Repository
@RequiredArgsConstructor
public class ConsortiumLibraryRepository {

public static final String LIBRARY_INDEX = "library";
private static final String OPERATION_TYPE = "searchApi";
private final IndexNameProvider indexNameProvider;
private final ElasticsearchDocumentConverter documentConverter;

private final RestHighLevelClient client;

public SearchResult<ConsortiumLibrary> fetchLibraries(String tenantHeader,
String tenantId,
Integer limit,
Integer offset,
String sortBy,
SortOrder sortOrder) {

var sourceBuilder = getSearchSourceBuilder(tenantId, limit, offset, sortBy, sortOrder);
var response = search(sourceBuilder, tenantHeader);
return documentConverter.convertToSearchResult(response, ConsortiumLibrary.class);
}

@NotNull
private static SearchSourceBuilder getSearchSourceBuilder(String tenantId,
Integer limit,
Integer offset,
String sortBy,
SortOrder sortOrder) {
var sourceBuilder = new SearchSourceBuilder();
Optional.ofNullable(tenantId)
.ifPresent(id -> sourceBuilder
.query(QueryBuilders
.termQuery(TENANT_ID_FIELD_NAME, id)));

return sourceBuilder
.from(offset)
.sort(SortBuilders
.fieldSort(sortBy)
.order(sortOrder == SortOrder.DESC ? DESC : ASC))
.size(limit);
}

private SearchResponse search(SearchSourceBuilder sourceBuilder, String tenantHeader) {
var index = indexNameProvider.getIndexName(LIBRARY_INDEX, tenantHeader);
var searchRequest = new SearchRequest(index);

searchRequest.source(sourceBuilder);

return performExceptionalOperation(() -> client.search(searchRequest,
RequestOptions.DEFAULT), index, OPERATION_TYPE);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.folio.search.service.consortium;

import java.util.Set;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.search.domain.dto.ConsortiumLibrary;
import org.folio.search.domain.dto.SortOrder;
import org.folio.search.model.SearchResult;
import org.folio.search.repository.ConsortiumLibraryRepository;
import org.springframework.stereotype.Service;

@Log4j2
@Service
@RequiredArgsConstructor
public class ConsortiumLibraryService {

private static final Set<String> VALID_SORT_BY = Set.of("id", "name", "tenantId");
private final ConsortiumLibraryRepository repository;
private final ConsortiumTenantExecutor executor;

public SearchResult<ConsortiumLibrary> fetchLibraries(String tenantHeader,
String tenantId,
Integer limit,
Integer offset,
String sortBy,
SortOrder sortOrder) {
log.info("fetching consortium libraries for tenant: {}, tenantId: {}, sortBy: {}",
tenantHeader,
tenantId,
sortBy);

validateSortByValue(sortBy);

return executor.execute(
tenantHeader,
() -> repository.fetchLibraries(tenantHeader, tenantId, limit, offset, sortBy, sortOrder));
}

private void validateSortByValue(String sortBy) {
if (!VALID_SORT_BY.contains(sortBy)) {
throw new IllegalArgumentException("Invalid sortBy value: " + sortBy);
}
}

}
3 changes: 3 additions & 0 deletions src/main/resources/swagger.api/mod-search.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ paths:
/search/consortium/campuses:
$ref: 'paths/search-consortium/search-consortium-campuses.yaml'

/search/consortium/libraries:
$ref: 'paths/search-consortium/search-consortium-libraries.yaml'

/search/consortium/batch/items:
$ref: 'paths/search-consortium/search-consortium-batch-items.yaml'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
in: query
name: limit
description: Limit the number of elements returned in the response.
schema:
type: integer
minimum: 0
maximum: 1000
default: 1000
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
in: query
name: sortBy
description: |
Defines a field to sort by.
Possible values:
- id
- tenantId
- campusId
- name
required: false
schema:
type: string
default: name
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
get:
operationId: getConsortiumLibraries
summary: Get Consortium Libraries
description: Get a list of libraries (only for consortium environment)
tags:
- search-consortium
parameters:
- $ref: '../../parameters/tenant-id-query-param.yaml'
- $ref: '../../parameters/consortium-libraries-limit-param.yaml'
- $ref: '../../parameters/offset-param.yaml'
- $ref: '../../parameters/sort-by-library-name-param.yaml'
- $ref: '../../parameters/sort-order-param.yaml'
- $ref: '../../parameters/x-okapi-tenant-header.yaml'
responses:
'200':
description: List of libraries
content:
application/json:
schema:
$ref: '../../schemas/entity/consortiumLibraryCollection.yaml'
'400':
$ref: '../../responses/badRequestResponse.yaml'
'500':
$ref: '../../responses/internalServerErrorResponse.yaml'
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
type: object
properties:
id:
description: Library ID
type: string
tenantId:
description: Tenant ID of the Library
type: string
name:
description: Library name
type: string
campusId:
description: The UUID of the campus, the second-level location unit, this (shelf) library belongs to.
type: string
metadata:
$ref: "../dto/common/metadata.yaml"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type: object
properties:
libraries:
type: array
items:
$ref: './consortiumLibrary.yaml'
totalRecords:
type: integer
Loading

0 comments on commit b298099

Please sign in to comment.