Skip to content
Merged
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
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
- Use system user context for processing kafka messages [MODLD-1026](https://folio-org.atlassian.net/browse/MODLD-1026)
- Update dimensions property URI [MODLD-1024](https://folio-org.atlassian.net/browse/MODLD-1024)
- Use GitHub Workflows for Maven [MODLD-971](https://folio-org.atlassian.net/browse/MODLD-971)
- Get rid of RESOURCE_PREFERRED property [MODLD-1028](https://folio-org.atlassian.net/browse/MODLD-1028)

## 1.0.4 (04-24-2025)
- Work Edit form - Instance read-only section: "Notes about the instance" data is not shown [MODLD-716](https://folio-org.atlassian.net/browse/MODLD-716)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.folio.linked.data.mapper.dto.resource.common;

import static java.util.Objects.nonNull;
import static org.folio.linked.data.util.ResourceUtils.ensureLatestReplaced;

import lombok.RequiredArgsConstructor;
Expand All @@ -9,7 +10,6 @@
import org.folio.linked.data.model.entity.Resource;
import org.folio.linked.data.model.entity.ResourceTypeEntity;
import org.folio.linked.data.service.reference.ReferenceService;
import org.folio.linked.data.util.ResourceUtils;

@RequiredArgsConstructor
public abstract class ReferenceMapperUnit implements SingleResourceMapperUnit {
Expand All @@ -21,7 +21,7 @@ protected ReferenceResponse toReference(Resource resource) {
return new ReferenceResponse()
.id(String.valueOf(latestResource.getId()))
.label(latestResource.getLabel())
.isPreferred(isPreferred(latestResource))
.isPreferred(isFolioResource(latestResource))
.types(latestResource.getTypes().stream().map(ResourceTypeEntity::getUri).toList());
}

Expand All @@ -31,7 +31,7 @@ public Resource toEntity(Object dto, Resource parentEntity) {
return referenceService.resolveReference(reference);
}

protected boolean isPreferred(Resource resource) {
return ResourceUtils.isPreferred(resource);
protected boolean isFolioResource(Resource resource) {
return nonNull(resource.getFolioMetadata());
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.folio.linked.data.mapper.dto.resource.common.agent;

import static java.util.Objects.nonNull;
import static java.util.Optional.ofNullable;
import static org.folio.ld.dictionary.PredicateDictionary.CONTRIBUTOR;
import static org.folio.ld.dictionary.PredicateDictionary.CREATOR;
import static org.folio.linked.data.util.ResourceUtils.ensureLatestReplaced;
import static org.folio.linked.data.util.ResourceUtils.isPreferred;

import java.util.Set;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -35,7 +35,7 @@ public <P> P toDto(Resource resourceToConvert, P parentDto, ResourceMappingConte
.id(String.valueOf(resourceToConvert.getId()))
.label(resourceToConvert.getLabel())
.type(resourceToConvert.getTypes().iterator().next().getUri())
.isPreferred(isPreferred(resourceToConvert));
.isPreferred(nonNull(resourceToConvert.getFolioMetadata()));
agentRoleAssigner.assignRoles(agent, context.parentResource());

if (context.predicate().getUri().equals(CREATOR.getUri())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package org.folio.linked.data.mapper.dto.resource.common.work.sub.reference;

import static java.util.Optional.ofNullable;
import static org.folio.ld.dictionary.PredicateDictionary.FOCUS;
import static org.folio.ld.dictionary.PredicateDictionary.SUBJECT;
import static org.folio.ld.dictionary.PredicateDictionary.SUB_FOCUS;
import static org.folio.ld.dictionary.PropertyDictionary.RESOURCE_PREFERRED;
import static org.folio.ld.dictionary.ResourceTypeDictionary.CONCEPT;
import static org.folio.linked.data.util.ResourceUtils.copyWithoutPreferred;

import java.util.Optional;
import java.util.Set;
import org.folio.linked.data.domain.dto.Reference;
import org.folio.linked.data.domain.dto.WorkRequest;
Expand All @@ -20,7 +16,6 @@
import org.folio.linked.data.service.reference.ReferenceService;
import org.folio.linked.data.service.resource.hash.HashService;
import org.springframework.stereotype.Component;
import tools.jackson.databind.JsonNode;

@Component
@MapperUnit(type = CONCEPT, predicate = SUBJECT, requestDto = Reference.class)
Expand Down Expand Up @@ -55,17 +50,9 @@ public <P> P toDto(Resource resourceToConvert, P parentDto, ResourceMappingConte
}

@Override
public boolean isPreferred(Resource resource) {
return getPreferredFromDoc(resource)
.orElseGet(() -> hasNoSubFocusEdges(resource) && isFocusEdgePreferred(resource));
}

private Optional<Boolean> getPreferredFromDoc(Resource resource) {
return ofNullable(resource.getDoc())
.map(doc -> doc.get(RESOURCE_PREFERRED.getValue()))
.filter(jsonNode -> !jsonNode.isEmpty())
.map(jsonNode -> jsonNode.get(0))
.map(JsonNode::asBoolean);
public boolean isFolioResource(Resource resource) {
return super.isFolioResource(resource)
|| hasNoSubFocusEdges(resource) && isFocusEdgeFolioResource(resource);
}

private boolean hasNoSubFocusEdges(Resource resource) {
Expand All @@ -74,19 +61,19 @@ private boolean hasNoSubFocusEdges(Resource resource) {
.noneMatch(predicate -> predicate.equals(SUB_FOCUS.getUri()));
}

private boolean isFocusEdgePreferred(Resource resource) {
private boolean isFocusEdgeFolioResource(Resource resource) {
return resource.getOutgoingEdges().stream()
.filter(edge -> edge.getPredicate().getUri().equals(FOCUS.getUri()))
.findFirst()
.map(ResourceEdge::getTarget)
.flatMap(this::getPreferredFromDoc)
.map(super::isFolioResource)
.orElse(false);
}

private Resource wrapWithConcept(Resource subject) {
var concept = new Resource()
.setLabel(subject.getLabel())
.setDoc(copyWithoutPreferred(subject))
.setDoc(subject.getDoc().deepCopy())
.addTypes(CONCEPT);
subject.getTypes().forEach(concept::addType);
concept.addOutgoingEdge(new ResourceEdge(concept, subject, FOCUS));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import static java.util.stream.Collectors.toCollection;
import static org.apache.commons.lang3.ObjectUtils.notEqual;
import static org.folio.ld.dictionary.PredicateDictionary.REPLACED_BY;
import static org.folio.ld.dictionary.PropertyDictionary.RESOURCE_PREFERRED;
import static org.folio.linked.data.util.ResourceUtils.isPreferred;
import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;

import java.util.LinkedHashSet;
Expand Down Expand Up @@ -110,7 +108,7 @@ private ResourceSaveResult updateResource(Resource existingResource, Resource in
existingResource.setDoc(mergeDocs(existingResource, incomingResource));
existingResource.setActive(incomingResource.isActive());
addFolioMetadataIfAbsent(existingResource, incomingResource.getFolioMetadata());
removeReplacedByEdgeIfPreferred(existingResource);
removeReplacedByEdgeIfFolioResource(existingResource);
return ResourceSaveResult.updated(existingResource);
}

Expand All @@ -127,20 +125,11 @@ private void addFolioMetadataIfAbsent(Resource existingResource, FolioMetadata i
}

private JsonNode mergeDocs(Resource existingResource, Resource incomingResource) {
var mergedDoc = JsonUtils.merge(existingResource.getDoc(), incomingResource.getDoc());
resetPreferredFlagWithIncomingValue(incomingResource, mergedDoc);
return mergedDoc;
return JsonUtils.merge(existingResource.getDoc(), incomingResource.getDoc());
}

private void resetPreferredFlagWithIncomingValue(Resource incomingResource, JsonNode mergedDoc) {
var resourcePreferred = RESOURCE_PREFERRED.getValue();
ofNullable(incomingResource.getDoc())
.flatMap(incomingDoc -> JsonUtils.getProperty(incomingDoc, resourcePreferred))
.ifPresent(incomingPreferredFlag -> JsonUtils.setProperty(mergedDoc, resourcePreferred, incomingPreferredFlag));
}

private void removeReplacedByEdgeIfPreferred(Resource resource) {
if (isPreferred(resource)) {
private void removeReplacedByEdgeIfFolioResource(Resource resource) {
if (nonNull(resource.getFolioMetadata())) {
resource.getOutgoingEdges().removeIf(edge -> edge.getPredicate().getUri().equals(REPLACED_BY.getUri()));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import static org.folio.linked.data.domain.dto.AssignmentCheckResponseDto.InvalidAssignmentReasonEnum.NOT_VALID_FOR_TARGET;
import static org.folio.linked.data.domain.dto.AssignmentCheckResponseDto.InvalidAssignmentReasonEnum.UNSUPPORTED_MARC;
import static org.folio.linked.data.util.Constants.MSG_NOT_FOUND_IN;
import static org.folio.linked.data.util.ResourceUtils.setPreferred;

import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -171,7 +170,6 @@ private Long replaceAuthority(Resource resource) {
private Long markObsoleteAndReplace(Resource previous, Resource incoming) {
if (Objects.equals(previous.getTypes(), incoming.getTypes())) {
var previousObsolete = markObsolete(previous);
setPreferred(incoming, true);
addReplacedByRelation(previousObsolete, incoming);
logMarcAction(incoming,
"not found by id, but found by srsId [" + incoming.getFolioMetadata().getSrsId() + "]",
Expand All @@ -180,7 +178,6 @@ private Long markObsoleteAndReplace(Resource previous, Resource incoming) {
}
markObsolete(previous);
logMarcAction(previous, "set as obsolete", "be saved");
setPreferred(incoming, true);
var saveGraphResult = resourceGraphService.saveMergingGraph(incoming);
logMarcAction(incoming, "set as preferred", "be saved");
return saveGraphResult.rootResource().getId();
Expand Down Expand Up @@ -212,7 +209,6 @@ private Long saveAndPublishEvent(Resource resource, Function<Resource, ResourceE

private Resource markObsolete(Resource resource) {
resource.setActive(false);
setPreferred(resource, false);
resource.setFolioMetadata(null);
return resource;
}
Expand Down
23 changes: 0 additions & 23 deletions src/main/java/org/folio/linked/data/util/ResourceUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;
import static org.folio.ld.dictionary.PredicateDictionary.INSTANTIATES;
import static org.folio.ld.dictionary.PredicateDictionary.REPLACED_BY;
import static org.folio.ld.dictionary.PropertyDictionary.RESOURCE_PREFERRED;
import static org.folio.ld.dictionary.ResourceTypeDictionary.INSTANCE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.LIGHT_RESOURCE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.WORK;
Expand Down Expand Up @@ -125,10 +124,6 @@ public static Resource ensureLatestReplaced(Resource resource) {
.orElse(resource);
}

public static void setPreferred(Resource resource, boolean preferred) {
addProperty(resource, RESOURCE_PREFERRED, String.valueOf(preferred));
}

public static void addProperty(Resource resource, PropertyDictionary property, String value) {
if (StringUtils.isBlank(value)) {
return;
Expand All @@ -140,31 +135,13 @@ public static void addProperty(Resource resource, PropertyDictionary property, S
((ObjectNode) resource.getDoc()).set(property.getValue(), arrayNode);
}

public static boolean isPreferred(Resource resource) {
return getPropertyValues(resource, RESOURCE_PREFERRED)
.stream()
.anyMatch(Boolean::parseBoolean);
}

public static List<String> getTypeUris(Resource resource) {
return resource.getTypes()
.stream()
.map(ResourceTypeEntity::getUri)
.toList();
}

public static JsonNode copyWithoutPreferred(Resource subject) {
return ofNullable(subject.getDoc())
.map(node -> {
var copiedDoc = node.deepCopy();
if (copiedDoc.isObject()) {
((ObjectNode) copiedDoc).remove(RESOURCE_PREFERRED.getValue());
}
return copiedDoc;
})
.orElse(null);
}

public static List<String> getPropertyValues(Resource resource, PropertyDictionary property) {
return ofNullable(resource.getDoc())
.map(doc -> doc.get(property.getValue()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import lombok.SneakyThrows;
import org.folio.linked.data.e2e.mappings.PostResourceIT;
import org.folio.linked.data.model.entity.Resource;
import org.folio.linked.data.util.ResourceUtils;
import org.springframework.test.web.servlet.ResultActions;

public class HubAsSubjectIT extends PostResourceIT {
Expand Down Expand Up @@ -57,7 +56,6 @@ protected void validateGraph(Resource resource) {

assertThat(concept.getLabel()).isEqualTo("Hub AAP 😊");
validateResourceType(concept, "http://bibfra.me/vocab/lite/Concept", "http://bibfra.me/vocab/lite/Hub");
assertThat(ResourceUtils.isPreferred(concept)).isFalse();

var hub = getFirstOutgoingResource(concept, "http://bibfra.me/vocab/lite/focus");
validateResourceType(hub, "http://bibfra.me/vocab/lite/Hub");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ private List<Resource> readAndAssertAuthoritiesInTheDb() {
assertThat(authoritiesFromDb).hasSize(2);
var expectedLabelCreated = "bValue, aValue, cValue, qValue, dValue -- xValue -- zValue -- yValue -- vValue";
var expectedLabelUpdated = expectedLabelCreated.replace("aValue", "newAValue");
assertAuthority(authoritiesFromDb.getFirst(), expectedLabelCreated, false, false, authoritiesFromDb.get(1));
assertAuthority(authoritiesFromDb.get(1), expectedLabelUpdated, true, true, null);
assertAuthority(authoritiesFromDb.getFirst(), expectedLabelCreated, false, authoritiesFromDb.get(1));
assertAuthority(authoritiesFromDb.get(1), expectedLabelUpdated, true, null);
return authoritiesFromDb;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
import org.folio.ld.dictionary.PropertyDictionary;
import org.folio.ld.dictionary.ResourceTypeDictionary;
import org.folio.linked.data.e2e.base.IntegrationTest;
import org.folio.linked.data.model.entity.FolioMetadata;
import org.folio.linked.data.model.entity.Resource;
import org.folio.linked.data.model.entity.ResourceEdge;
import org.folio.linked.data.service.resource.graph.ResourceGraphService;
import org.folio.linked.data.service.tenant.TenantScopedExecutionService;
import org.folio.linked.data.test.MonographTestUtil;
import org.folio.linked.data.test.resource.ResourceTestService;
import org.folio.linked.data.util.JsonUtils;
import org.folio.spring.tools.kafka.KafkaAdminService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -136,7 +136,7 @@ void testResourcesMerging1_and_2() {
}

@Test
void should_remove_replacedBy_edge_when_resource_becomes_preferred() {
void shouldRemoveReplacedByEdge_whenResourceGetsFolioMetadata() {
// given
var replacedByTargetResource = createResource(2L, Map.of()).setDoc(getInitialDoc());
var lccnResource = new Resource().setIdAndRefreshEdges(3L).addTypes(ID_LCCN);
Expand All @@ -153,6 +153,7 @@ void should_remove_replacedBy_edge_when_resource_becomes_preferred() {
var newSourceResource = createResource(1L,
Map.of(PredicateDictionary.STATUS, List.of(statusResource))
).setDoc(getNewDoc());
newSourceResource.setFolioMetadata(new FolioMetadata(newSourceResource));
resourceGraphService.saveMergingGraph(newSourceResource);

// then
Expand Down Expand Up @@ -190,26 +191,15 @@ private void assertResourceDoc(String id, JsonNode expected) {
}

private JsonNode getInitialDoc() {
return getDocWithPreferredFlag("samples/json_merge/existing.jsonl", false);
return TEST_JSON_MAPPER.readTree(loadResourceAsString("samples/json_merge/existing.jsonl"));
}

private JsonNode getNewDoc() {
return getDocWithPreferredFlag("samples/json_merge/incoming.jsonl", true);
return TEST_JSON_MAPPER.readTree(loadResourceAsString("samples/json_merge/incoming.jsonl"));
}

private JsonNode getMergedDoc() {
return getDocWithPreferredFlag("samples/json_merge/merged.jsonl", true);
}

private JsonNode getDocWithPreferredFlag(String docFile, boolean isPreferred) {
var preferredJson = """
{
"http://library.link/vocab/resourcePreferred": [
"$PREFERRED_FLAG"
]
}
""".replace("$PREFERRED_FLAG", String.valueOf(isPreferred));
return JsonUtils.merge(TEST_JSON_MAPPER.readTree(loadResourceAsString(docFile)), TEST_JSON_MAPPER.readTree(preferredJson));
return TEST_JSON_MAPPER.readTree(loadResourceAsString("samples/json_merge/merged.jsonl"));
}

private Resource createGraph1toto2() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ void shouldProcessAuthoritySourceRecordDomainCreateEvent() {

assertThat(found).isPresent();
var expectedLabel = "bValue, aaValue, cValue, qValue, dValue -- xValue -- zValue -- yValue -- vValue";
assertAuthority(found.get(), expectedLabel, true, true, null);
assertAuthority(found.get(), expectedLabel, true, null);
}

@Test
Expand Down Expand Up @@ -229,8 +229,8 @@ void shouldProcessAuthoritySourceRecordDomainUpdateEvent() {
var updatedResource = found.getFirst();
var expectedLabelCreated = "bValue, aValue, cValue, qValue, dValue -- xValue -- zValue -- yValue -- vValue";
var expectedLabelUpdated = expectedLabelCreated.replace("aValue", "newAValue");
assertAuthority(createdResource, expectedLabelCreated, false, false, updatedResource);
assertAuthority(updatedResource, expectedLabelUpdated, true, true, null);
assertAuthority(createdResource, expectedLabelCreated, false, updatedResource);
assertAuthority(updatedResource, expectedLabelUpdated, true, null);
}

}
Loading
Loading