Skip to content

Commit

Permalink
[SELC-5602] fix: catch Duplicate key error and retry to save object w…
Browse files Browse the repository at this point in the history
…ith different UUID (#38)
  • Loading branch information
manuraf authored Sep 19, 2024
1 parent f9a2d80 commit 2091759
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package it.pagopa.selfcare.mscore.connector.dao;

import it.pagopa.selfcare.onboarding.common.InstitutionType;
import it.pagopa.selfcare.mscore.api.InstitutionConnector;
import it.pagopa.selfcare.mscore.connector.dao.model.InstitutionEntity;
import it.pagopa.selfcare.mscore.connector.dao.model.inner.GeoTaxonomyEntity;
import it.pagopa.selfcare.mscore.connector.dao.model.inner.OnboardingEntity;
import it.pagopa.selfcare.mscore.connector.dao.model.mapper.InstitutionEntityMapper;
import it.pagopa.selfcare.mscore.connector.dao.model.mapper.InstitutionMapperHelper;
import it.pagopa.selfcare.mscore.constant.GenericError;
import it.pagopa.selfcare.mscore.constant.RelationshipState;
import it.pagopa.selfcare.mscore.constant.SearchMode;
import it.pagopa.selfcare.mscore.exception.InvalidRequestException;
import it.pagopa.selfcare.mscore.exception.ResourceNotFoundException;
import it.pagopa.selfcare.mscore.model.institution.*;
import it.pagopa.selfcare.mscore.model.onboarding.VerifyOnboardingFilters;
import it.pagopa.selfcare.onboarding.common.InstitutionType;
import it.pagopa.selfcare.product.entity.ProductStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
Expand Down Expand Up @@ -56,7 +56,15 @@ public List<Institution> findAll() {
@Override
public Institution save(Institution institution) {
final InstitutionEntity entity = institutionMapper.convertToInstitutionEntity(institution);
return institutionMapper.convertToInstitution(repository.save(entity));
try {
return institutionMapper.convertToInstitution(repository.save(entity));
} catch (DuplicateKeyException e) {
// the chance of generating two identical UUIDs is astronomically small
// but sometimes happens, we catch this error in order to retry saving object
log.warn(String.format("_id: %s, message: %s", entity.getId(), e.getMessage()));
entity.setId(UUID.randomUUID().toString());
return institutionMapper.convertToInstitution(repository.save(entity));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
Expand Down Expand Up @@ -102,20 +103,13 @@ void findById() {
Assertions.assertTrue(response.isEmpty());
}

@Test
void shouldSaveInstitution() {
private Institution dummyInstitution() {

List<InstitutionGeographicTaxonomies> geographicTaxonomies = new ArrayList<>();
geographicTaxonomies.add(new InstitutionGeographicTaxonomies());

List<Onboarding> onboardings = new ArrayList<>();
Onboarding onboarding = new Onboarding();
onboarding.setBilling(new Billing());
onboarding.setContract("contract");
onboarding.setStatus(RelationshipState.ACTIVE);
onboarding.setCreatedAt(OffsetDateTime.now());
onboarding.setProductId("productId");
onboarding.setUpdatedAt(OffsetDateTime.now());
onboarding.setPricingPlan("pricingPal");
onboardings.add(onboarding);
onboardings.add(dummyOnboarding());

Institution institution = new Institution();
institution.setExternalId("ext");
Expand All @@ -126,6 +120,26 @@ void shouldSaveInstitution() {
institution.setRea("rea");
institution.setGeographicTaxonomies(geographicTaxonomies);

return institution;
}

private Onboarding dummyOnboarding() {
Onboarding onboarding = new Onboarding();
onboarding.setBilling(new Billing());
onboarding.setContract("contract");
onboarding.setStatus(RelationshipState.ACTIVE);
onboarding.setCreatedAt(OffsetDateTime.now());
onboarding.setProductId("productId");
onboarding.setUpdatedAt(OffsetDateTime.now());
onboarding.setPricingPlan("pricingPal");
return onboarding;
}

@Test
void shouldSaveInstitution() {

Onboarding onboarding = dummyOnboarding();
Institution institution = dummyInstitution();
when(institutionRepository.save(any())).thenAnswer(arg -> arg.getArguments()[0]);

Institution response = institutionConnectorImpl.save(institution);
Expand All @@ -139,12 +153,34 @@ void shouldSaveInstitution() {
Onboarding responseOnboarding = institution.getOnboarding().get(0);
Assertions.assertEquals(onboarding.getContract(), responseOnboarding.getContract());
Assertions.assertEquals(onboarding.getStatus(), responseOnboarding.getStatus());
Assertions.assertEquals(onboarding.getCreatedAt(), responseOnboarding.getCreatedAt());
Assertions.assertEquals(onboarding.getProductId(), responseOnboarding.getProductId());
Assertions.assertEquals(onboarding.getUpdatedAt(), responseOnboarding.getUpdatedAt());
Assertions.assertEquals(onboarding.getPricingPlan(), responseOnboarding.getPricingPlan());
}



@Test
void shouldSaveInstitution_whenDuplicateKeyError() {

when(institutionRepository.save(any())).
thenThrow(DuplicateKeyException.class)
.thenAnswer(arg -> arg.getArguments()[0]);

Institution response = institutionConnectorImpl.save(dummyInstitution());

ArgumentCaptor<InstitutionEntity> captor = ArgumentCaptor.forClass(InstitutionEntity.class);
Mockito.verify(institutionRepository, times(2))
.save(captor.capture());

List<InstitutionEntity> entities = captor.getAllValues();
Assertions.assertEquals(entities.get(1).getId(), response.getId());
Assertions.assertEquals(entities.get(1).getExternalId(), response.getExternalId());
Assertions.assertEquals(entities.get(1).getParentDescription(), response.getParentDescription());
Assertions.assertEquals(entities.get(1).getRea(), response.getRea());
Assertions.assertEquals(entities.get(1).getZipCode(), response.getZipCode());
Assertions.assertEquals(entities.get(1).getOnboarding().size(), response.getOnboarding().size());
}

@Test
void findByExternalIdTest() {
InstitutionEntity institutionEntity = new InstitutionEntity();
Expand Down

0 comments on commit 2091759

Please sign in to comment.