Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MODLD-617: special handling when authority is reverted to a previous … #119

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

pkjacob
Copy link
Contributor

@pkjacob pkjacob commented Feb 20, 2025

…state

@@ -176,9 +202,6 @@ private void logMarcAction(Resource resource, String existence, String action) {
private Long saveAndPublishEvent(Resource resource, Function<Resource, ResourceEvent> resourceEventSupplier) {
var newResource = resourceGraphService.saveMergingGraph(resource);
var event = resourceEventSupplier.apply(newResource);
if (event instanceof ResourceReplacedEvent rre) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rre.previous() is already a managed entity (as it was just retrieved from the DB). So, no need to explicitly save

log.error(message);
throw new IllegalArgumentException(message);
}
if (resourceRepo.existsById(modelResource.getId())) {
Copy link
Contributor Author

@pkjacob pkjacob Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scenario:

  1. Via MARC authority, create a authority record with just 100$a - Example: 100 $a Jane Doe
  2. Go back to authority and add a $d to the Person authority - Example: 100 $a Jane Doe $d 1900
  3. Again update the authority and remove $d so that authority is reverted to the original state. - Example: 100 $a Jane Doe

Bug:

After step 2, two resources exists in the DB

  1. ID:1 -- John Doe (isPreferred=false, srsId=null)
  2. ID:2 -- John Doe, 1900 (isPreferred=true, srsId=abcd)

At step 3, saveMarcAuthority method receive John Doe with ID 1 as input.
Here, we first checked for condition if (resourceRepo.existsById(modelResource.getId())). This condition passed & hence we just updated resource 1. Resource 2 was not touched (as replaceAuthority method was not invoked)

So, the states of the resources were as follows after step 3

  1. ID:1 -- John Doe (isPreferred=true, srsId=null) (Folio metadata has a unique constraint. So, two resources cannot have the same srs id)
  2. ID:2 -- John Doe, 1900 (isPreferred=true, srsId=abcd) -> This resource remains untouched as replaceAuthority method is not invoked.

Fix:

In the new logic, we check if the resource pointed by ID and SRS ID are the same. Only then, "update" method is invoked. Else, "replace" method is invoked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if an Authority exists without srsId? I am not sure, is that possible at all?
If yes we will never update it with incoming authority, right?

Copy link
Contributor Author

@pkjacob pkjacob Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SRS ID should be always present for all authorities.
I added code to throw IllegalArgumentException just in case if SRS ID is not present for an incoming record. See line 150.

@pkjacob pkjacob force-pushed the pjacob/MODLD-617 branch 2 times, most recently from dd2007a to 0ff6d93 Compare February 20, 2025 22:02
@pkjacob pkjacob force-pushed the pjacob/MODLD-617 branch 2 times, most recently from 307a16b to e791044 Compare February 20, 2025 23:42
@@ -152,8 +155,8 @@ void fetchAuthorityOrCreateFromSrsRecord_shouldThrowNotFound_ifRecordNotExistsIn
when(exceptionBuilder.notFoundSourceRecordException(any(), any())).thenReturn(emptyRequestProcessingException());

// then
assertThrows(RequestProcessingException.class,
() -> resourceMarcAuthorityService.fetchAuthorityOrCreateFromSrsRecord(agent));
assertThatThrownBy(() -> resourceMarcAuthorityService.fetchAuthorityOrCreateFromSrsRecord(agent))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switching to assertJ to be consistent with other assertions in this file.

@pkjacob pkjacob force-pushed the pjacob/MODLD-617 branch 2 times, most recently from ec122c3 to 17343c7 Compare February 21, 2025 02:16
private boolean existsBySrsIdAndIdUnchanged(Resource resource) {
var id = resource.getId();
var srsId = resource.getFolioMetadata().getSrsId();
return resourceRepo.existsById(id) && getIdBySrsId(srsId).filter(id::equals).isPresent();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused with the method name because here we check resourceRepo.existsById(id)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, Actually, the check resourceRepo.existsById(id) was unnecessary. So, I refactored the method.

private boolean existsBySrsIdAndIdUnchanged(Resource resource) {
var id = resource.getId();
var srsId = resource.getFolioMetadata().getSrsId();
return resourceRepo.existsById(id) && getIdBySrsId(srsId).filter(id::equals).isPresent();
Copy link
Contributor

@PBobylev PBobylev Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if instead of calling resourceRepo.existsById and then getIdBySrsId(srsId) to check equality, we just write a new method FolioMetadataRepository#existsByIdAndSrsId and call it?
It should be enough because:

  1. FolioMetadata doesn't exist without corresponding resource with the same id
  2. One resource could have only one FolioMetadata

Copy link
Contributor Author

@pkjacob pkjacob Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right.
I refactored the method. But with a slightly different way.

  1. Get the Optional<resource ID of the existing resource> from DB using the given SRS ID.
  2. If the Optional is empty, then create new resource in graph.
  3. Else, check if the existing resource ID is same as the ID of the incoming resource. If yes, update the existing resource.
  4. Else, create a new resource and make the old one obsolete.

log.error(message);
throw new IllegalArgumentException(message);
}
if (resourceRepo.existsById(modelResource.getId())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if an Authority exists without srsId? I am not sure, is that possible at all?
If yes we will never update it with incoming authority, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants