Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ public void persistChildrenOnReindex(String tenantId, ResourceType resourceType,
.tenant(tenantId)
._new(instance))
.toList();
persistChildren(tenantId, resourceType, events);

var extractors = resourceExtractors.get(resourceType);
if (extractors == null) {
return;
}

var shared = consortiumTenantProvider.isCentralTenant(tenantId);

// Process child resources normally
extractors.forEach(resourceExtractor ->
resourceExtractor.persistChildren(tenantId, shared, events));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,29 @@ public Map<String, List<SearchDocumentBody>> convert(Collection<ResourceEvent> r
.collect(groupingBy(SearchDocumentBody::getResource));
}

/**
* Converts {@link ResourceEvent} objects to a flat list of {@link SearchDocumentBody} objects.
* All events are expected to carry the same tenant ID that matches the current execution context —
* per-tenant grouping and context switching are therefore skipped entirely.
*
* @param resourceEvents list with {@link ResourceEvent} objects, all belonging to the current tenant
* @return flat {@link List} of {@link SearchDocumentBody} objects
*/
public List<SearchDocumentBody> convertForReindex(Collection<ResourceEvent> resourceEvents) {
log.debug("convertForReindex:: by [resourceEvents.size: {}]", collectionToLogMsg(resourceEvents, true));

if (CollectionUtils.isEmpty(resourceEvents)) {
return List.of();
}

return resourceEvents.stream()
.flatMap(this::populateResourceEvents)
.map(event -> event.getId() != null ? event : event.id(getResourceEventId(event)))
.map(searchDocumentConverter::convert)
.flatMap(Optional::stream)
.toList();
}

private List<SearchDocumentBody> convertForTenant(Entry<String, List<ResourceEvent>> entry) {
var convert = (Supplier<List<SearchDocumentBody>>) () ->
entry.getValue().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,11 @@ private SearchDocumentBody convert(ConversionContext context) {
var baseFields = convertMapUsingResourceFields(getNewAsMap(resourceEvent), resourceDescriptionFields, context);
var searchFields = searchFieldsProcessor.getSearchFields(context);
var resultDocument = mergeSafely(baseFields, searchFields);
return SearchDocumentBody.of(searchDocumentBodyConverter.apply(resultDocument),
indexingDataFormat, resourceEvent, INDEX);
// Release the large _new Map before serialization — resultDocument is already a fully independent copy.
// ResourceEvent is still referenced by SearchDocumentBody for id/tenant/resource metadata only.
resourceEvent.setNew(null);
var documentBody = searchDocumentBodyConverter.apply(resultDocument);
return SearchDocumentBody.of(documentBody, indexingDataFormat, resourceEvent, INDEX);
}

private List<String> getResourceLanguages(List<String> languageSource, Map<String, Object> resourceData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,24 @@

import static org.apache.commons.collections4.MapUtils.getMap;
import static org.apache.commons.collections4.MapUtils.getString;
import static org.folio.search.model.entity.CallNumberEntity.CALL_NUMBER_MAX_LENGTH;
import static org.apache.commons.lang3.StringUtils.truncate;
import static org.folio.search.utils.SearchConverterUtils.getNewAsMap;
import static org.folio.search.utils.SearchUtils.prepareForExpectedFormat;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.folio.search.domain.dto.ResourceEvent;
import org.folio.search.domain.dto.TenantConfiguredFeature;
import org.folio.search.model.entity.CallNumberEntity;
import org.folio.search.model.entity.InstanceCallNumberEntity;
import org.folio.search.model.types.ResourceType;
import org.folio.search.service.FeatureConfigService;
import org.folio.search.service.converter.preprocessor.extractor.ChildResourceExtractor;
import org.folio.search.service.reindex.jdbc.CallNumberRepository;
import org.folio.search.utils.JsonConverter;
import org.folio.search.utils.ShaUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

Expand All @@ -36,14 +34,16 @@ public class CallNumberResourceExtractor extends ChildResourceExtractor {
public static final String SUFFIX_FIELD = "suffix";
public static final String TYPE_ID_FIELD = "typeId";

private final JsonConverter jsonConverter;
private static final int CALL_NUMBER_MAX_LENGTH = 50;
private static final int CALL_NUMBER_PREFIX_MAX_LENGTH = 20;
private static final int CALL_NUMBER_SUFFIX_MAX_LENGTH = 25;
private static final int CALL_NUMBER_TYPE_MAX_LENGTH = 40;

private final FeatureConfigService featureConfigService;

public CallNumberResourceExtractor(CallNumberRepository repository,
JsonConverter jsonConverter,
FeatureConfigService featureConfigService) {
super(repository);
this.jsonConverter = jsonConverter;
this.featureConfigService = featureConfigService;
}

Expand All @@ -57,14 +57,12 @@ protected List<Map<String, Object>> constructRelations(boolean shared, ResourceE
List<Map<String, Object>> entities) {
var resourceMap = getNewAsMap(event);
return entities.stream()
.map(entity -> InstanceCallNumberEntity.builder()
.callNumberId(getString(entity, "id"))
.itemId(getString(resourceMap, "id"))
.instanceId(getString(resourceMap, "instanceId"))
.locationId(getString(resourceMap, "effectiveLocationId"))
.tenantId(event.getTenant())
.build())
.map(jsonConverter::convertToMap)
.map(entity -> Map.<String, Object>of(
"callNumberId", getString(entity, "id"),
"itemId", getString(resourceMap, "id"),
"instanceId", getString(resourceMap, "instanceId"),
"locationId", getString(resourceMap, "effectiveLocationId"),
"tenantId", event.getTenant()))
.toList();
}

Expand All @@ -73,9 +71,24 @@ protected Map<String, Object> constructEntity(Map<String, Object> entityProperti
if (entityProperties == null || !featureConfigService.isEnabled(TenantConfiguredFeature.BROWSE_CALL_NUMBERS)) {
return Collections.emptyMap();
}
return toCallNumberEntity(entityProperties)
.map(jsonConverter::convertToMap)
.orElse(Collections.emptyMap());
var callNumberComponents = getCallNumberComponents(entityProperties);
var callNumber = prepareForExpectedFormat(
getString(callNumberComponents, CALL_NUMBER_FIELD), CALL_NUMBER_MAX_LENGTH);
if (StringUtils.isBlank(callNumber)) {
return Collections.emptyMap();
}
var callNumberPrefix = truncate(getString(callNumberComponents, PREFIX_FIELD), CALL_NUMBER_PREFIX_MAX_LENGTH);
var callNumberSuffix = truncate(getString(callNumberComponents, SUFFIX_FIELD), CALL_NUMBER_SUFFIX_MAX_LENGTH);
var callNumberTypeId = truncate(getString(callNumberComponents, TYPE_ID_FIELD), CALL_NUMBER_TYPE_MAX_LENGTH);
var id = ShaUtils.sha(callNumber, callNumberPrefix, callNumberSuffix, callNumberTypeId);

var entity = new HashMap<String, Object>();
entity.put("id", id);
entity.put("callNumber", callNumber);
entity.put("callNumberPrefix", callNumberPrefix);
entity.put("callNumberSuffix", callNumberSuffix);
entity.put("callNumberTypeId", callNumberTypeId);
return entity;
}

@Override
Expand All @@ -88,22 +101,6 @@ protected Set<Map<String, Object>> getChildResources(Map<String, Object> event)
return Set.of(event);
}

private Optional<CallNumberEntity> toCallNumberEntity(Map<String, Object> entityProperties) {
var callNumberComponents = getCallNumberComponents(entityProperties);
var callNumber = prepareForExpectedFormat(getString(callNumberComponents, CALL_NUMBER_FIELD),
CALL_NUMBER_MAX_LENGTH);
if (StringUtils.isNotBlank(callNumber)) {
var callNumberEntity = CallNumberEntity.builder()
.callNumber(callNumber)
.callNumberPrefix(getString(callNumberComponents, PREFIX_FIELD))
.callNumberSuffix(getString(callNumberComponents, SUFFIX_FIELD))
.callNumberTypeId(getString(callNumberComponents, TYPE_ID_FIELD))
.build();
return Optional.of(callNumberEntity);
}
return Optional.empty();
}

@SuppressWarnings("unchecked")
private Map<String, Object> getCallNumberComponents(Map<String, Object> entityProperties) {
return (Map<String, Object>) getMap(entityProperties, EFFECTIVE_CALL_NUMBER_COMPONENTS_FIELD,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.folio.search.service.reindex;

import java.util.Collection;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.message.FormattedMessage;
Expand Down Expand Up @@ -75,7 +74,7 @@ public boolean process(ReindexRecordsEvent event) {
private FolioIndexOperationResponse fetchRecordsAndIndexForUploadRange(ReindexRangeIndexEvent event) {
try {
var resourceEvents = uploadRangeService.fetchRecordRange(event);
var documents = documentConverter.convert(resourceEvents).values().stream().flatMap(Collection::stream).toList();
var documents = documentConverter.convertForReindex(resourceEvents);
return elasticRepository.indexResources(documents);
} catch (Exception ex) {
throw handleReindexUploadFailure(event, ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,6 @@ protected RowMapper<Map<String, Object>> rowToMapMapper() {
protected RowMapper<Map<String, Object>> rowToMapMapper2() {
return (rs, rowNum) -> {
var callNumberMap = getCallNumberMap(rs);
var maps = jsonConverter.fromJsonToListOfMaps(getInstances(rs)).stream().filter(Objects::nonNull).toList();
if (!maps.isEmpty()) {
callNumberMap.put(SUB_RESOURCE_INSTANCES_FIELD, maps);
}
callNumberMap.put(LAST_UPDATED_DATE_FIELD, rs.getTimestamp("last_updated_date"));
return callNumberMap;
};
Expand All @@ -278,8 +274,7 @@ private Map<String, Object> getCallNumberMap(ResultSet rs) throws SQLException {
callNumberMap.put(CALL_NUMBER_PREFIX_FIELD, getCallNumberPrefix(rs));
callNumberMap.put(CALL_NUMBER_SUFFIX_FIELD, callNumberSuffix);
callNumberMap.put(CALL_NUMBER_TYPE_ID_FIELD, getCallNumberTypeId(rs));
var subResources = jsonConverter.toJson(parseInstanceSubResources(getInstances(rs)));
var maps = jsonConverter.fromJsonToListOfMaps(subResources).stream().filter(Objects::nonNull).toList();
var maps = jsonConverter.fromJsonToListOfMaps(getInstances(rs)).stream().filter(Objects::nonNull).toList();
if (!maps.isEmpty()) {
callNumberMap.put(SUB_RESOURCE_INSTANCES_FIELD, maps);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,7 @@ protected String getFetchBySql() {

@Override
protected RowMapper<Map<String, Object>> rowToMapMapper() {
return (rs, rowNum) -> {
Map<String, Object> classification = new HashMap<>();
classification.put("id", getId(rs));
classification.put(CLASSIFICATION_NUMBER_ENTITY_FIELD, getNumber(rs));
classification.put("typeId", getTypeId(rs));

var maps = jsonConverter.fromJsonToListOfMaps(getInstances(rs)).stream().filter(Objects::nonNull).toList();
if (!maps.isEmpty()) {
classification.put(SUB_RESOURCE_INSTANCES_FIELD, maps);
}

return classification;
};
return (rs, rowNum) -> buildClassificationMap(rs);
}

@Override
Expand Down Expand Up @@ -238,21 +226,26 @@ public void saveAll(ChildResourceEntityBatch entityBatch) {

protected RowMapper<Map<String, Object>> rowToMapMapper2() {
return (rs, rowNum) -> {
Map<String, Object> classification = new HashMap<>();
classification.put("id", getId(rs));
classification.put(CLASSIFICATION_NUMBER_ENTITY_FIELD, getNumber(rs));
classification.put("typeId", getTypeId(rs));
var classification = buildClassificationMap(rs);
classification.put(LAST_UPDATED_DATE_FIELD, rs.getTimestamp("last_updated_date"));

var maps = jsonConverter.fromJsonToListOfMaps(getInstances(rs)).stream().filter(Objects::nonNull).toList();
if (!maps.isEmpty()) {
classification.put(SUB_RESOURCE_INSTANCES_FIELD, maps);
}

return classification;
};
}

private Map<String, Object> buildClassificationMap(ResultSet rs) throws SQLException {
Map<String, Object> classification = new HashMap<>();
classification.put("id", getId(rs));
classification.put(CLASSIFICATION_NUMBER_ENTITY_FIELD, getNumber(rs));
classification.put("typeId", getTypeId(rs));

var maps = jsonConverter.fromJsonToListOfMaps(getInstances(rs)).stream().filter(Objects::nonNull).toList();
if (!maps.isEmpty()) {
classification.put(SUB_RESOURCE_INSTANCES_FIELD, maps);
}

return classification;
}

private String getId(ResultSet rs) throws SQLException {
return rs.getString("id");
}
Expand Down
Loading
Loading