Skip to content

Commit bc4d72e

Browse files
fix(browse): Fix shared facet count for Classifications/Contributors/Subjects
* fix(browse): Fix shared facet count for Classifications/Contributors/Subjects Closes: MSEARCH-941
1 parent 29a073a commit bc4d72e

File tree

15 files changed

+159
-35
lines changed

15 files changed

+159
-35
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
* Fix "Fix dead link" api-docs workflow step for release builds ([MSEARCH-947](https://folio-org.atlassian.net/browse/MSEARCH-947))
3737
* Fix issue with using member tenant postgres schema on reindexing ([MSEARCH-957](https://folio-org.atlassian.net/browse/MSEARCH-957))
3838
* Fix processing batch of updates to the same instance ([MSEARCH-951](https://folio-org.atlassian.net/browse/MSEARCH-951))
39+
* Fix shared facet count for Classifications/Contributors/Subjects ([MSEARCH-941](https://folio-org.atlassian.net/browse/MSEARCH-941))
3940
* Fix "Effective location (item)" facet hide facets options which should be available for performed search term ([MSEARCH-817](https://folio-org.atlassian.net/browse/MSEARCH-817))
4041

4142
### Tech Dept

src/main/java/org/folio/search/integration/message/interceptor/PopulateInstanceBatchInterceptor.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import static org.folio.search.utils.SearchUtils.SOURCE_CONSORTIUM_PREFIX;
1111

1212
import java.util.ArrayList;
13-
import java.util.Collection;
1413
import java.util.Comparator;
1514
import java.util.List;
1615
import java.util.Map;
@@ -93,22 +92,21 @@ private void populate(List<ResourceEvent> records) {
9392
private void process(String tenant, List<ResourceEvent> batch) {
9493
var recordByResource = batch.stream().collect(Collectors.groupingBy(ResourceEvent::getResourceName));
9594
for (Map.Entry<String, List<ResourceEvent>> recordCollection : recordByResource.entrySet()) {
96-
if (ResourceType.BOUND_WITH.getName().equals(recordCollection.getKey())) {
95+
var resourceType = recordCollection.getKey();
96+
if (ResourceType.BOUND_WITH.getName().equals(resourceType)) {
9797
processBoundWithEvents(tenant, recordCollection);
9898
continue;
9999
}
100100

101-
var repository = repositories.get(ReindexEntityType.fromValue(recordCollection.getKey()));
101+
var repository = repositories.get(ReindexEntityType.fromValue(resourceType));
102102
if (repository != null) {
103103
var recordByOperation = getRecordByOperation(recordCollection);
104-
saveEntities(tenant, recordByOperation, repository);
105-
deleteEntities(tenant, recordCollection.getKey(), recordByOperation, repository);
104+
saveEntities(tenant, recordByOperation.getOrDefault(true, emptyList()), repository);
105+
deleteEntities(tenant, resourceType, recordByOperation.getOrDefault(false, emptyList()), repository);
106106

107-
var noShadowCopiesInstanceEvents = recordByOperation.values().stream().flatMap(Collection::stream).toList();
108-
instanceChildrenResourceService.persistChildren(tenant, ResourceType.byName(recordCollection.getKey()),
109-
noShadowCopiesInstanceEvents);
107+
instanceChildrenResourceService.persistChildren(tenant, ResourceType.byName(resourceType),
108+
recordCollection.getValue());
110109
}
111-
112110
}
113111
}
114112

@@ -135,9 +133,8 @@ private Map<Boolean, List<ResourceEvent>> getRecordByOperation(
135133
.collect(Collectors.groupingBy(resourceEvent -> resourceEvent.getType() != ResourceEventType.DELETE));
136134
}
137135

138-
private void saveEntities(String tenant, Map<Boolean, List<ResourceEvent>> recordByOperation,
139-
MergeRangeRepository repository) {
140-
var resourceToSave = recordByOperation.getOrDefault(true, emptyList()).stream()
136+
private void saveEntities(String tenant, List<ResourceEvent> resourceEvents, MergeRangeRepository repository) {
137+
var resourceToSave = resourceEvents.stream()
141138
.map(SearchConverterUtils::getNewAsMap)
142139
.toList();
143140
if (!resourceToSave.isEmpty()) {
@@ -146,8 +143,8 @@ private void saveEntities(String tenant, Map<Boolean, List<ResourceEvent>> recor
146143
}
147144

148145
private void deleteEntities(String tenant, String resourceType,
149-
Map<Boolean, List<ResourceEvent>> recordByOperation, MergeRangeRepository repository) {
150-
var idsToDrop = recordByOperation.getOrDefault(false, emptyList()).stream()
146+
List<ResourceEvent> resourceEvents, MergeRangeRepository repository) {
147+
var idsToDrop = resourceEvents.stream()
151148
.map(ResourceEvent::getId)
152149
.toList();
153150
if (!idsToDrop.isEmpty()) {

src/main/java/org/folio/search/service/InstanceChildrenResourceService.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package org.folio.search.service;
22

3+
import static org.apache.commons.lang3.StringUtils.startsWith;
4+
import static org.folio.search.utils.SearchConverterUtils.getResourceSource;
5+
import static org.folio.search.utils.SearchUtils.SOURCE_CONSORTIUM_PREFIX;
6+
37
import java.util.List;
48
import java.util.Map;
59
import java.util.stream.Collectors;
@@ -9,6 +13,7 @@
913
import org.folio.search.model.types.ResourceType;
1014
import org.folio.search.service.consortium.ConsortiumTenantProvider;
1115
import org.folio.search.service.converter.preprocessor.extractor.ChildResourceExtractor;
16+
import org.folio.search.utils.SearchConverterUtils;
1217
import org.springframework.stereotype.Component;
1318

1419
/**
@@ -34,8 +39,22 @@ public void persistChildren(String tenantId, ResourceType resourceType, List<Res
3439
if (extractors == null) {
3540
return;
3641
}
42+
3743
var shared = consortiumTenantProvider.isCentralTenant(tenantId);
38-
extractors.forEach(resourceExtractor -> resourceExtractor.persistChildren(shared, events));
44+
var noShadowCopiesInstanceEvents = events.stream()
45+
.filter(resourceEvent -> {
46+
if (ResourceType.INSTANCE.getName().equals(resourceEvent.getResourceName())) {
47+
return !startsWith(getResourceSource(resourceEvent), SOURCE_CONSORTIUM_PREFIX);
48+
}
49+
return true;
50+
})
51+
.toList();
52+
var eventsForResourceSharing = events.stream()
53+
.filter(SearchConverterUtils::isUpdateEventForResourceSharing)
54+
.toList();
55+
extractors.forEach(resourceExtractor -> resourceExtractor.persistChildren(shared, noShadowCopiesInstanceEvents));
56+
extractors.forEach(resourceExtractor ->
57+
resourceExtractor.persistChildrenForResourceSharing(shared, eventsForResourceSharing));
3958
}
4059

4160
public void persistChildrenOnReindex(String tenantId, ResourceType resourceType,
@@ -50,5 +69,4 @@ public void persistChildrenOnReindex(String tenantId, ResourceType resourceType,
5069
.toList();
5170
persistChildren(tenantId, resourceType, events);
5271
}
53-
5472
}

src/main/java/org/folio/search/service/converter/preprocessor/extractor/ChildResourceExtractor.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import static java.util.Collections.emptyList;
44
import static java.util.Collections.emptySet;
5+
import static java.util.stream.Collectors.groupingBy;
6+
import static java.util.stream.Collectors.mapping;
7+
import static java.util.stream.Collectors.toList;
58
import static org.apache.commons.collections4.MapUtils.getObject;
69
import static org.folio.search.utils.SearchConverterUtils.getNewAsMap;
710

@@ -13,13 +16,15 @@
1316
import java.util.Objects;
1417
import java.util.Set;
1518
import lombok.RequiredArgsConstructor;
19+
import lombok.extern.log4j.Log4j2;
1620
import org.folio.search.domain.dto.ResourceEvent;
1721
import org.folio.search.domain.dto.ResourceEventType;
1822
import org.folio.search.model.entity.ChildResourceEntityBatch;
1923
import org.folio.search.model.types.ResourceType;
2024
import org.folio.search.service.reindex.jdbc.InstanceChildResourceRepository;
2125

2226
@RequiredArgsConstructor
27+
@Log4j2
2328
public abstract class ChildResourceExtractor {
2429

2530
private final InstanceChildResourceRepository repository;
@@ -39,7 +44,7 @@ public void persistChildren(boolean shared, List<ResourceEvent> events) {
3944
.map(ResourceEvent::getId)
4045
.toList();
4146
if (!instanceIdsForDeletion.isEmpty()) {
42-
repository.deleteByInstanceIds(instanceIdsForDeletion);
47+
repository.deleteByInstanceIds(instanceIdsForDeletion, null);
4348
}
4449

4550
var eventsForSaving = events.stream()
@@ -59,6 +64,18 @@ public void persistChildren(boolean shared, List<ResourceEvent> events) {
5964
repository.saveAll(new ChildResourceEntityBatch(new ArrayList<>(entities), relations));
6065
}
6166

67+
public void persistChildrenForResourceSharing(boolean shared, List<ResourceEvent> events) {
68+
var eventsForSharingByTenant = events.stream()
69+
.collect(groupingBy(ResourceEvent::getTenant, mapping(ResourceEvent::getId, toList())));
70+
eventsForSharingByTenant.forEach((tenant, instanceIds) -> {
71+
if (Boolean.TRUE.equals(shared)) {
72+
log.warn("Update event for instance sharing is supposed to be for member tenant,"
73+
+ " but received for central tenant: {}, eventId: {}", tenant, String.join(",", instanceIds));
74+
}
75+
repository.deleteByInstanceIds(instanceIds, tenant);
76+
});
77+
}
78+
6279
private List<Map<String, Object>> extractEntities(ResourceEvent event) {
6380
var entities = getChildResources(getNewAsMap(event));
6481
return entities.stream()

src/main/java/org/folio/search/service/reindex/jdbc/CallNumberRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ protected CallNumberRepository(JdbcTemplate jdbcTemplate, JsonConverter jsonConv
164164
}
165165

166166
@Override
167-
public void deleteByInstanceIds(List<String> itemIds) {
167+
public void deleteByInstanceIds(List<String> itemIds, String tenantId) {
168168
var sql = DELETE_QUERY.formatted(JdbcUtils.getSchemaName(context), getParamPlaceholderForUuid(itemIds.size()));
169169
jdbcTemplate.update(sql, itemIds.toArray());
170170
}

src/main/java/org/folio/search/service/reindex/jdbc/ClassificationRepository.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.Map;
1616
import java.util.Objects;
1717
import java.util.Optional;
18+
import java.util.stream.Stream;
1819
import lombok.extern.log4j.Log4j2;
1920
import org.folio.search.configuration.properties.ReindexConfigurationProperties;
2021
import org.folio.search.model.entity.ChildResourceEntityBatch;
@@ -114,7 +115,7 @@ WITH cte AS (SELECT c.id,
114115
WITH deleted_ids as (
115116
DELETE
116117
FROM %1$s.instance_classification
117-
WHERE instance_id IN (%2$s)
118+
WHERE instance_id IN (%2$s) %3$s
118119
RETURNING classification_id
119120
)
120121
UPDATE %1$s.classification
@@ -197,8 +198,18 @@ protected RowMapper<Map<String, Object>> rowToMapMapper() {
197198
}
198199

199200
@Override
200-
public void deleteByInstanceIds(List<String> instanceIds) {
201-
var sql = DELETE_QUERY.formatted(JdbcUtils.getSchemaName(context), getParamPlaceholderForUuid(instanceIds.size()));
201+
public void deleteByInstanceIds(List<String> instanceIds, String tenantId) {
202+
var sql = DELETE_QUERY.formatted(
203+
JdbcUtils.getSchemaName(context),
204+
getParamPlaceholderForUuid(instanceIds.size()),
205+
tenantId == null ? "" : "AND tenant_id = ?");
206+
207+
if (tenantId != null) {
208+
var params = Stream.of(instanceIds, List.of(tenantId)).flatMap(List::stream).toArray();
209+
jdbcTemplate.update(sql, params);
210+
return;
211+
}
212+
202213
jdbcTemplate.update(sql, instanceIds.toArray());
203214
}
204215

src/main/java/org/folio/search/service/reindex/jdbc/ContributorRepository.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.Map;
1515
import java.util.Objects;
1616
import java.util.Optional;
17+
import java.util.stream.Stream;
1718
import lombok.extern.log4j.Log4j2;
1819
import org.folio.search.configuration.properties.ReindexConfigurationProperties;
1920
import org.folio.search.model.entity.ChildResourceEntityBatch;
@@ -122,7 +123,7 @@ ELSE json_build_object(
122123
WITH deleted_ids as (
123124
DELETE
124125
FROM %1$s.instance_contributor
125-
WHERE instance_id IN (%2$s)
126+
WHERE instance_id IN (%2$s) %3$s
126127
RETURNING contributor_id
127128
)
128129
UPDATE %1$s.contributor
@@ -222,8 +223,18 @@ protected RowMapper<Map<String, Object>> rowToMapMapper2() {
222223
}
223224

224225
@Override
225-
public void deleteByInstanceIds(List<String> instanceIds) {
226-
var sql = DELETE_QUERY.formatted(JdbcUtils.getSchemaName(context), getParamPlaceholderForUuid(instanceIds.size()));
226+
public void deleteByInstanceIds(List<String> instanceIds, String tenantId) {
227+
var sql = DELETE_QUERY.formatted(
228+
JdbcUtils.getSchemaName(context),
229+
getParamPlaceholderForUuid(instanceIds.size()),
230+
tenantId == null ? "" : "AND tenant_id = ?");
231+
232+
if (tenantId != null) {
233+
var params = Stream.of(instanceIds, List.of(tenantId)).flatMap(List::stream).toArray();
234+
jdbcTemplate.update(sql, params);
235+
return;
236+
}
237+
227238
jdbcTemplate.update(sql, instanceIds.toArray());
228239
}
229240

src/main/java/org/folio/search/service/reindex/jdbc/InstanceChildResourceRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
public interface InstanceChildResourceRepository {
88

9-
void deleteByInstanceIds(List<String> instanceIds);
9+
void deleteByInstanceIds(List<String> instanceIds, String tenantId);
1010

1111
void saveAll(ChildResourceEntityBatch childResourceEntityBatch);
1212

src/main/java/org/folio/search/service/reindex/jdbc/SubjectRepository.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Map;
1717
import java.util.Objects;
1818
import java.util.Optional;
19+
import java.util.stream.Stream;
1920
import lombok.extern.log4j.Log4j2;
2021
import org.folio.search.configuration.properties.ReindexConfigurationProperties;
2122
import org.folio.search.model.entity.ChildResourceEntityBatch;
@@ -122,7 +123,7 @@ ELSE json_build_object(
122123
WITH deleted_ids as (
123124
DELETE
124125
FROM %1$s.instance_subject
125-
WHERE instance_id IN (%2$s)
126+
WHERE instance_id IN (%2$s) %3$s
126127
RETURNING subject_id
127128
)
128129
UPDATE %1$s.subject
@@ -207,8 +208,18 @@ protected RowMapper<Map<String, Object>> rowToMapMapper() {
207208
}
208209

209210
@Override
210-
public void deleteByInstanceIds(List<String> instanceIds) {
211-
var sql = DELETE_QUERY.formatted(JdbcUtils.getSchemaName(context), getParamPlaceholderForUuid(instanceIds.size()));
211+
public void deleteByInstanceIds(List<String> instanceIds, String tenantId) {
212+
var sql = DELETE_QUERY.formatted(
213+
JdbcUtils.getSchemaName(context),
214+
getParamPlaceholderForUuid(instanceIds.size()),
215+
tenantId == null ? "" : "AND tenant_id = ?");
216+
217+
if (tenantId != null) {
218+
var params = Stream.of(instanceIds, List.of(tenantId)).flatMap(List::stream).toArray();
219+
jdbcTemplate.update(sql, params);
220+
return;
221+
}
222+
212223
jdbcTemplate.update(sql, instanceIds.toArray());
213224
}
214225

src/main/java/org/folio/search/utils/SearchConverterUtils.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import static java.util.Collections.emptyMap;
44
import static org.apache.commons.collections4.MapUtils.getString;
5+
import static org.apache.commons.lang3.StringUtils.removeStart;
6+
import static org.apache.commons.lang3.StringUtils.startsWith;
7+
import static org.folio.search.domain.dto.ResourceEventType.UPDATE;
58
import static org.folio.search.utils.SearchUtils.ID_FIELD;
9+
import static org.folio.search.utils.SearchUtils.SOURCE_CONSORTIUM_PREFIX;
610
import static org.folio.search.utils.SearchUtils.SOURCE_FIELD;
711

812
import java.util.Arrays;
@@ -182,6 +186,13 @@ public static void copyEntityFields(Map<String, Object> source, Map<String, Obje
182186
}
183187
}
184188

189+
public static boolean isUpdateEventForResourceSharing(ResourceEvent event) {
190+
var newSource = getResourceSource(getNewAsMap(event));
191+
return event.getType() == UPDATE
192+
&& startsWith(newSource, SOURCE_CONSORTIUM_PREFIX)
193+
&& Objects.equals(getResourceSource(getOldAsMap(event)), removeStart(newSource, SOURCE_CONSORTIUM_PREFIX));
194+
}
195+
185196
@SuppressWarnings("unchecked")
186197
private static Object getFieldValueByPath(String pathValue, Object value) {
187198
if (value instanceof Map) {

0 commit comments

Comments
 (0)