Skip to content

Commit

Permalink
MODLD-527: Inspect SRS MARC record to support Inventory workflow (#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
askhat-abishev authored Oct 8, 2024
1 parent d2c1311 commit 7e52873
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 0 deletions.
11 changes: 11 additions & 0 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
"pathPattern": "/resource/metadata/{inventoryId}/id",
"permissionsRequired": [ "linked-data.resources.bib.id.get" ],
"modulePermissions": []
},
{
"methods": [ "GET" ],
"pathPattern": "/resource/check/{inventoryId}/supported",
"permissionsRequired": [ "linked-data.resources.support-check.get" ],
"modulePermissions": ["source-storage.records.get"]
}
]
},
Expand Down Expand Up @@ -166,6 +172,11 @@
"displayName": "Linked Data: Get the ID of an instance resource using the inventory instance ID",
"description": "Get the ID of a linked-data instance resource using the inventory instance ID"
},
{
"permissionName": "linked-data.resources.support-check.get",
"displayName": "Linked Data: Check if marc to bib conversion is supported",
"description": "Check if marc to bib conversion is supported by mod-linked-data"
},
{
"permissionName": "linked-data.profiles.get",
"displayName": "Linked Data: Get the profiles for performing CRUD operations on resources",
Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<lib-linked-data-dictionary.version>1.0.1-SNAPSHOT</lib-linked-data-dictionary.version>
<lib-linked-data-marc4ld.version>1.0.2-SNAPSHOT</lib-linked-data-marc4ld.version>
<lib-linked-data-fingerprint.version>1.0.1-SNAPSHOT</lib-linked-data-fingerprint.version>
<mod-source-record-storage-client.version>5.9.0-SNAPSHOT</mod-source-record-storage-client.version>
<maven-checkstyle-plugin.checkstyle.version>10.18.2</maven-checkstyle-plugin.checkstyle.version>

<!-- Test dependencies versions -->
Expand Down Expand Up @@ -94,6 +95,11 @@
<artifactId>lib-linked-data-fingerprint</artifactId>
<version>${lib-linked-data-fingerprint.version}</version>
</dependency>
<dependency>
<groupId>org.folio</groupId>
<artifactId>mod-source-record-storage-client</artifactId>
<version>${mod-source-record-storage-client.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/org/folio/linked/data/client/SrsClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.folio.linked.data.client;

import org.folio.rest.jaxrs.model.Record;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "source-storage")
public interface SrsClient {

@GetMapping(value = "/records/{inventoryId}/formatted?idType=INSTANCE")
ResponseEntity<Record> getFormattedSourceStorageInstanceRecordById(@PathVariable("inventoryId") String inventoryId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public ResponseEntity<ResourceIdDto> getResourceIdByResourceInventoryId(String i
return ResponseEntity.ok(resourceService.getResourceIdByInventoryId(inventoryId));
}

@Override
public ResponseEntity<String> isSupportedByInventoryId(String inventoryId) {
return ResponseEntity.ok(resourceMarcService.isSupportedByInventoryId(inventoryId).toString());
}

@Override
public ResponseEntity<ResourceResponseDto> updateResource(Long id, String okapiTenant,
@Valid ResourceRequestDto resourceDto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface ResourceMarcService {

ResourceMarcViewDto getResourceMarcView(Long id);

Boolean isSupportedByInventoryId(String inventoryId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@
import static org.folio.linked.data.util.BibframeUtils.extractWorkFromInstance;
import static org.folio.linked.data.util.Constants.IS_NOT_FOUND;
import static org.folio.linked.data.util.Constants.RESOURCE_WITH_GIVEN_ID;
import static org.folio.marc4ld.util.MarcUtil.isLanguageMaterial;
import static org.folio.marc4ld.util.MarcUtil.isMonographicComponentPartOrItem;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.folio.linked.data.client.SrsClient;
import org.folio.linked.data.domain.dto.ResourceMarcViewDto;
import org.folio.linked.data.exception.NotFoundException;
import org.folio.linked.data.exception.ValidationException;
Expand All @@ -30,6 +35,7 @@
import org.folio.linked.data.repo.ResourceEdgeRepository;
import org.folio.linked.data.repo.ResourceRepository;
import org.folio.marc4ld.service.ld2marc.Bibframe2MarcMapper;
import org.folio.rest.jaxrs.model.Record;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -49,6 +55,7 @@ public class ResourceMarcServiceImpl implements ResourceMarcService {
private final ResourceGraphService resourceGraphService;
private final FolioMetadataRepository folioMetadataRepository;
private final ApplicationEventPublisher applicationEventPublisher;
private final SrsClient srsClient;


public Long saveMarcResource(org.folio.ld.dictionary.model.Resource modelResource) {
Expand All @@ -73,6 +80,17 @@ public ResourceMarcViewDto getResourceMarcView(Long id) {
return resourceDtoMapper.toMarcViewDto(resource, marc);
}

@Override
public Boolean isSupportedByInventoryId(String inventoryId) {
var response = srsClient.getFormattedSourceStorageInstanceRecordById(inventoryId);
return Optional.ofNullable(response.getBody())
.map(Record::getParsedRecord)
.map(parsedRecord -> (Map<?, ?>) parsedRecord.getContent())
.map(content -> (String) content.get("leader"))
.map(this::isMonograph)
.orElse(false);
}

private void validateMarkViewSupportedType(Resource resource) {
if (resource.isOfType(INSTANCE)) {
return;
Expand Down Expand Up @@ -183,4 +201,8 @@ private void addOutgoingEdges(Resource resource) {
edgeRepo.findByIdSourceHash(resource.getId())
.forEach(resource::addOutgoingEdge);
}

private boolean isMonograph(String leader) {
return isLanguageMaterial(leader.charAt(6)) && isMonographicComponentPartOrItem(leader.charAt(7));
}
}
17 changes: 17 additions & 0 deletions src/main/resources/swagger.api/mod-linked-data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,23 @@ paths:
'404':
description: No resource id is found by its inventory id

/resource/check/{inventoryId}/supported:
get:
operationId: isSupportedByInventoryId
description: Check if marc to bib conversion is supported
parameters:
- $ref: '#/components/parameters/inventoryId'
responses:
'200':
description: true if marc to bib conversion is supported and false if not supported
content:
text/plain:
schema:
type: string
example: true|false
'500':
$ref: '#/components/responses/internalServerErrorResponse'

/profile:
get:
operationId: getProfile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
import static org.folio.linked.data.test.TestUtil.OBJECT_MAPPER;
import static org.folio.linked.data.test.TestUtil.random;
import static org.folio.linked.data.test.TestUtil.randomLong;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import org.folio.ld.dictionary.model.FolioMetadata;
import org.folio.linked.data.client.SrsClient;
import org.folio.linked.data.domain.dto.ResourceMarcViewDto;
import org.folio.linked.data.exception.NotFoundException;
import org.folio.linked.data.exception.ValidationException;
Expand All @@ -32,14 +36,20 @@
import org.folio.linked.data.repo.ResourceEdgeRepository;
import org.folio.linked.data.repo.ResourceRepository;
import org.folio.marc4ld.service.ld2marc.Bibframe2MarcMapper;
import org.folio.rest.jaxrs.model.ParsedRecord;
import org.folio.rest.jaxrs.model.Record;
import org.folio.spring.testing.type.UnitTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;

@UnitTest
@ExtendWith(MockitoExtension.class)
Expand All @@ -66,6 +76,8 @@ class ResourceMarcServiceTest {
private ResourceGraphService resourceGraphService;
@Spy
private ObjectMapper objectMapper = OBJECT_MAPPER;
@Mock
private SrsClient srsClient;

@Test
void getResourceMarcView_shouldReturnExistedEntity() {
Expand Down Expand Up @@ -269,4 +281,49 @@ void saveMarcAuthority_shouldCreateNewAuthorityVersionAndMarkOldAsObsolete_ifGiv
assertThat(mapped.getIncomingEdges()).contains(new ResourceEdge(existed, mapped, REPLACED_BY));
}

@ParameterizedTest
@CsvSource({
"a, a",
"a, m"
})
void isSupportedByInventoryId_shouldReturnTrue(char type, char level) {
//given
var inventoryId = UUID.randomUUID().toString();
var marcRecord = createRecord(type, level);
when(srsClient.getFormattedSourceStorageInstanceRecordById(inventoryId))
.thenReturn(new ResponseEntity<>(marcRecord, HttpStatusCode.valueOf(200)));

//expect
assertTrue(resourceMarcService.isSupportedByInventoryId(inventoryId));
}

@ParameterizedTest
@CsvSource({
"' ', ' '",
"' ', a",
"' ', m",
"a, ' '",
"a, s",
"o, a",
"o, m",
})
void isSupportedByInventoryId_shouldReturnFalse(char type, char level) {
//given
var inventoryId = UUID.randomUUID().toString();
var marcRecord = createRecord(type, level);
when(srsClient.getFormattedSourceStorageInstanceRecordById(inventoryId))
.thenReturn(new ResponseEntity<>(marcRecord, HttpStatusCode.valueOf(200)));

//expect
assertFalse(resourceMarcService.isSupportedByInventoryId(inventoryId));
}

private org.folio.rest.jaxrs.model.Record createRecord(char type, char level) {
var leader = "04809n a2200865 i 4500";
leader = leader.substring(0, 6) + type + level + leader.substring(8);
var content = Map.of("leader", leader);
var parsedRecord = new ParsedRecord().withContent(content);
return new Record().withParsedRecord(parsedRecord);
}

}

0 comments on commit 7e52873

Please sign in to comment.