Skip to content

Commit

Permalink
feat(browse-classifications): implement endpoint to browse by classif…
Browse files Browse the repository at this point in the history
…ications (#522)

Define API
Implement new endpoint logic
-- Change logic of indexing to create shelving order for each algorithm
-- Use browse config to find right field for browse
-- Moved instance pre-processor earlier in a flow due to consortium complication logic

Closes: MSEARCH-665
Signed-off-by: psmagin <[email protected]>
  • Loading branch information
psmagin authored Feb 27, 2024
1 parent 19dbd93 commit 631fb52
Show file tree
Hide file tree
Showing 46 changed files with 1,103 additions and 309 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* Prepare and populate index for classification browse ([MSEARCH-668](https://issues.folio.org/browse/MSEARCH-668))
* Instance search: Add query search option that search instances by normalized LCCN ([MSEARCH-661](https://issues.folio.org/browse/MSEARCH-661))
* Implement browse config management endpoints ([MSEARCH-674](https://issues.folio.org/browse/MSEARCH-674))
* Implement endpoint to browse by classifications ([MSEARCH-665](https://issues.folio.org/browse/MSEARCH-665))
* Authority search: Modify query search option to search authorities by normalized LCCN ([MSEARCH-663](https://issues.folio.org/browse/MSEARCH-663))

### Bug fixes
Expand Down
19 changes: 18 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
},
{
"id": "browse",
"version": "1.2",
"version": "1.3",
"handlers": [
{
"methods": [
Expand All @@ -197,6 +197,18 @@
"user-tenants.collection.get"
]
},
{
"methods": [
"GET"
],
"pathPattern": "/browse/classification-numbers/{browseOptionId}/instances",
"permissionsRequired": [
"browse.classification-numbers.instances.collection.get"
],
"modulePermissions": [
"user-tenants.collection.get"
]
},
{
"methods": [
"GET"
Expand Down Expand Up @@ -469,6 +481,11 @@
"displayName": "Browse - provides collections of browse items for instance by call number",
"description": "Browse instances by given query"
},
{
"permissionName": "browse.classification-numbers.instances.collection.get",
"displayName": "Browse - provides collections of browse by classification number",
"description": "Browse by classification number"
},
{
"permissionName": "browse.subjects.instances.collection.get",
"displayName": "Browse - provides collections of browse items for instance by subjects",
Expand Down
3 changes: 3 additions & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ COMPOSE_PROJECT_NAME=folio-mod-search
DEBUG_PORT=5010
OKAPI_URL=http://api-mock:8080
APP_PORT=8081
PGADMIN_DEFAULT_EMAIL=[email protected]
PGADMIN_DEFAULT_PASSWORD=admin
PGADMIN_PORT=5050
33 changes: 26 additions & 7 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ services:
JAVA_OPTIONS: -Xmx120m -Xms120m
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:${DEBUG_PORT}
okapi.url: ${OKAPI_URL}
KAFKA_CONTRIBUTORS_TOPIC_PARTITIONS: 1
KAFKA_SUBJECTS_TOPIC_PARTITIONS: 1
KAFKA_CONSORTIUM_INSTANCE_TOPIC_PARTITIONS: 1
BROWSE_CLASSIFICATIONS_ENABLED: true

api-mock:
container_name: api-mock-mod-search
image: wiremock/wiremock:2.32.0
container_name: api-mock
networks:
- mod-search-local
command:
Expand All @@ -37,7 +41,7 @@ services:
- ../src/test/resources/mappings:/home/wiremock/mappings

opensearch:
container_name: opensearch
container_name: opensearch-mod-search
image: dev.folio/opensearch:1.3.2
build:
context: opensearch
Expand All @@ -56,7 +60,7 @@ services:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"

opensearch-dashboards:
container_name: opensearch-dashboards
container_name: opensearch-dashboards-mod-search
image: dev.folio/opensearch-dashboards:1.3.2
build:
context: dashboards
Expand All @@ -71,15 +75,15 @@ services:
- opensearch

zookeeper:
container_name: zookeeper
container_name: zookeeper-mod-search
image: wurstmeister/zookeeper:3.4.6
networks:
- mod-search-local
ports:
- "2181:2181"

kafka:
container_name: kafka
container_name: kafka-mod-search
image: wurstmeister/kafka:2.13-2.8.1
networks:
- mod-search-local
Expand All @@ -99,7 +103,7 @@ services:
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "false"

kafka-ui:
container_name: kafka-ui-quick-marc
container_name: kafka-ui-mod-search
image: provectuslabs/kafka-ui:latest
ports:
- "8080:8080"
Expand All @@ -115,7 +119,7 @@ services:
- mod-search-local

postgres:
container_name: postgres
container_name: postgres-mod-search
image: postgres:12-alpine
networks:
- mod-search-local
Expand All @@ -126,10 +130,25 @@ services:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: okapi_modules

pgadmin:
container_name: pgadmin-mod-search
image: dpage/pgadmin4:6.7
networks:
- mod-search-local
ports:
- ${PGADMIN_PORT}:80
volumes:
- "pgadmin-data:/var/lib/pgadmin"
environment:
PGADMIN_CONFIG_SERVER_MODE: "False"
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}

networks:
mod-search-local:
driver: bridge

volumes:
es-data: { }
db-data: { }
pgadmin-data: { }
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.util.Set;
import lombok.Data;
import org.folio.search.domain.dto.TenantConfiguredFeature;
import org.folio.search.model.types.ClassificationType;
import org.folio.search.model.types.IndexingDataFormat;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -47,8 +46,6 @@ public class SearchConfigurationProperties {
*/
private Map<TenantConfiguredFeature, Boolean> searchFeatures = emptyMap();

private Map<ClassificationType, String[]> browseClassificationTypes = emptyMap();

/**
* Indexing settings for different resources.
*/
Expand Down
35 changes: 33 additions & 2 deletions src/main/java/org/folio/search/controller/BrowseController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import static org.folio.search.utils.SearchUtils.AUTHORITY_BROWSING_FIELD;
import static org.folio.search.utils.SearchUtils.AUTHORITY_RESOURCE;
import static org.folio.search.utils.SearchUtils.CALL_NUMBER_BROWSING_FIELD;
import static org.folio.search.utils.SearchUtils.CLASSIFICATION_NUMBER_BROWSING_FIELD;
import static org.folio.search.utils.SearchUtils.CONTRIBUTOR_BROWSING_FIELD;
import static org.folio.search.utils.SearchUtils.CONTRIBUTOR_RESOURCE;
import static org.folio.search.utils.SearchUtils.INSTANCE_CLASSIFICATION_RESOURCE;
import static org.folio.search.utils.SearchUtils.INSTANCE_RESOURCE;
import static org.folio.search.utils.SearchUtils.INSTANCE_SUBJECT_RESOURCE;
import static org.folio.search.utils.SearchUtils.SHELVING_ORDER_BROWSING_FIELD;
Expand All @@ -14,16 +16,21 @@

import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.AuthorityBrowseResult;
import org.folio.search.domain.dto.BrowseOptionType;
import org.folio.search.domain.dto.CallNumberBrowseResult;
import org.folio.search.domain.dto.CallNumberType;
import org.folio.search.domain.dto.ClassificationNumberBrowseItem;
import org.folio.search.domain.dto.ClassificationNumberBrowseResult;
import org.folio.search.domain.dto.ContributorBrowseResult;
import org.folio.search.domain.dto.SubjectBrowseResult;
import org.folio.search.exception.RequestValidationException;
import org.folio.search.model.BrowseResult;
import org.folio.search.model.service.BrowseRequest;
import org.folio.search.model.service.BrowseRequest.BrowseRequestBuilder;
import org.folio.search.rest.resource.BrowseApi;
import org.folio.search.service.browse.AuthorityBrowseService;
import org.folio.search.service.browse.CallNumberBrowseService;
import org.folio.search.service.browse.ClassificationBrowseService;
import org.folio.search.service.browse.ContributorBrowseService;
import org.folio.search.service.browse.SubjectBrowseService;
import org.folio.search.service.consortium.TenantProvider;
Expand All @@ -42,6 +49,7 @@ public class BrowseController implements BrowseApi {
private final AuthorityBrowseService authorityBrowseService;
private final CallNumberBrowseService callNumberBrowseService;
private final ContributorBrowseService contributorBrowseService;
private final ClassificationBrowseService classificationBrowseService;
private final TenantProvider tenantProvider;

@Override
Expand Down Expand Up @@ -80,6 +88,21 @@ public ResponseEntity<CallNumberBrowseResult> browseInstancesByCallNumber(String
.next(instanceByCallNumber.getNext()));
}

@Override
public ResponseEntity<ClassificationNumberBrowseResult> browseInstancesByClassificationNumber(
BrowseOptionType browseOptionId, String query, String tenant, Integer limit, Boolean expandAll,
Boolean highlightMatch, Integer precedingRecordsCount) {

var browseRequest = getBrowseRequestBuilder(query, tenant, limit, expandAll, highlightMatch, precedingRecordsCount)
.resource(INSTANCE_CLASSIFICATION_RESOURCE)
.browseOptionType(browseOptionId)
.targetField(CLASSIFICATION_NUMBER_BROWSING_FIELD)
.build();

var browseResult = classificationBrowseService.browse(browseRequest);
return ResponseEntity.ok(toBrowseResultDto(browseResult));
}

@Override
public ResponseEntity<ContributorBrowseResult> browseInstancesByContributor(String query, String tenant,
Integer limit, Boolean highlightMatch,
Expand Down Expand Up @@ -110,9 +133,17 @@ public ResponseEntity<SubjectBrowseResult> browseInstancesBySubject(String query
.next(browseResult.getNext()));
}

private ClassificationNumberBrowseResult toBrowseResultDto(BrowseResult<ClassificationNumberBrowseItem> result) {
return new ClassificationNumberBrowseResult()
.totalRecords(result.getTotalRecords())
.items(result.getRecords())
.prev(result.getPrev())
.next(result.getNext());
}

private BrowseRequestBuilder getBrowseRequestBuilder(String query, String tenant, Integer limit,
Boolean expandAll, Boolean highlightMatch,
Integer precedingRecordsCount) {
Boolean expandAll, Boolean highlightMatch,
Integer precedingRecordsCount) {
if (precedingRecordsCount != null && precedingRecordsCount >= limit) {
throw new RequestValidationException("Preceding records count must be less than request limit",
"precedingRecordsCount", String.valueOf(precedingRecordsCount));
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import lombok.Setter;
import lombok.ToString;
import org.folio.search.configuration.jpa.StringListConverter;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.Hibernate;

@Getter
@Setter
Expand Down Expand Up @@ -46,12 +46,8 @@ public final boolean equals(Object o) {
if (o == null) {
return false;
}
Class<?> effectiveClass = o instanceof HibernateProxy
? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass()
: o.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass()
: this.getClass();
Class<?> effectiveClass = Hibernate.getClass(o);
Class<?> thisEffectiveClass = Hibernate.getClass(this);
if (thisEffectiveClass != effectiveClass) {
return false;
}
Expand Down
10 changes: 3 additions & 7 deletions src/main/java/org/folio/search/model/config/BrowseConfigId.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.Hibernate;

@Getter
@Embeddable
Expand All @@ -32,12 +32,8 @@ public final boolean equals(Object o) {
if (o == null) {
return false;
}
Class<?> effectiveClass = o instanceof HibernateProxy
? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass()
: o.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy
? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass()
: this.getClass();
Class<?> effectiveClass = Hibernate.getClass(o);
Class<?> thisEffectiveClass = Hibernate.getClass(this);
if (thisEffectiveClass != effectiveClass) {
return false;
}
Expand Down
17 changes: 15 additions & 2 deletions src/main/java/org/folio/search/model/service/BrowseRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.folio.search.domain.dto.BrowseOptionType;
import org.folio.search.model.ResourceRequest;

@Data
@Builder()
@Builder
@RequiredArgsConstructor(staticName = "of")
public class BrowseRequest implements ResourceRequest {

Expand All @@ -20,6 +21,11 @@ public class BrowseRequest implements ResourceRequest {
*/
private final String tenantId;

/**
* Browse option type.
*/
private final BrowseOptionType browseOptionType;

/**
* A CQL query string with search conditions.
*/
Expand Down Expand Up @@ -63,7 +69,14 @@ public class BrowseRequest implements ResourceRequest {
public static BrowseRequest of(String resource, String tenantId, String query, Integer limit, String targetField,
String subField, Boolean expandAll, Boolean highlightMatch,
Integer precedingRecordsCount) {
return new BrowseRequest(resource, tenantId, query, limit, targetField, subField, null, expandAll,
return new BrowseRequest(resource, tenantId, null, query, limit, targetField, subField, null, expandAll,
highlightMatch, precedingRecordsCount);
}

public static BrowseRequest of(String resource, String tenantId, BrowseOptionType optionType, String query,
Integer limit, String targetField, String subField, Boolean expandAll,
Boolean highlightMatch, Integer precedingRecordsCount) {
return new BrowseRequest(resource, tenantId, optionType, query, limit, targetField, subField, null, expandAll,
highlightMatch, precedingRecordsCount);
}
}
Loading

0 comments on commit 631fb52

Please sign in to comment.