Skip to content

Commit

Permalink
Adding check for existing institutions (gbif/registry#579)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahakanzn committed Jun 25, 2024
1 parent e87ef79 commit 430c627
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 20 deletions.
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<jacoco-maven-plugin.version>0.8.3</jacoco-maven-plugin.version>

<!-- test -->
<mockito.version>3.12.4</mockito.version>
<junit.version>4.12</junit.version>

<!-- Sonar -->
Expand Down Expand Up @@ -169,6 +170,13 @@
</dependency>

<!-- test -->

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/gbif/collections/sync/SyncResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public static class NoEntityMatch {
private Institution newInstitution;
private Collection newCollection;
private ContactMatch contactMatch;
private int newChangeSuggestion;
}

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.MasterSourceMetadata;
import org.gbif.api.model.collections.suggestions.ChangeSuggestion;
import org.gbif.api.model.common.paging.PagingResponse;
import org.gbif.api.model.registry.Identifier;
import org.gbif.api.model.registry.MachineTag;
Expand Down Expand Up @@ -121,6 +122,26 @@ public List<Institution> getIhInstitutions() {
return result;
}

public List<Institution> getInstitutionsByName(String name) {
List<Institution> result = new ArrayList<>();

boolean endRecords = false;
int offset = 0;
while (!endRecords) {
PagingResponse<Institution> response =
syncCall(api.listInstitutionsByName(name, 1000, offset));
endRecords = response.isEndOfRecords();
offset += response.getLimit();
result.addAll(response.getResults());
}

return result;
}

public int createChangeSuggestion(ChangeSuggestion<Institution> changeSuggestion) {
return syncCall(api.createChangeSuggestion(changeSuggestion));
}

public Institution getInstitution(UUID key) {
return syncCall(api.getInstitution(key));
}
Expand Down Expand Up @@ -259,6 +280,12 @@ Call<PagingResponse<Institution>> listInstitutions(
@Query("limit") int limit,
@Query("offset") int offset);

@GET("institution")
Call<PagingResponse<Institution>> listInstitutionsByName(
@Query("name") String name,
@Query("limit") int limit,
@Query("offset") int offset);

@GET("institution/{key}")
Call<Institution> getInstitution(@Path("key") UUID key);

Expand Down Expand Up @@ -357,6 +384,9 @@ Call<Void> addMasterSourceMetadataToInstitution(
@POST("collection/{collectionKey}/masterSourceMetadata")
Call<Void> addMasterSourceMetadataToCollection(
@Path("collectionKey") UUID collectionKey, @Body MasterSourceMetadata masterSourceMetadata);

@POST("changeSuggestion")
Call<Integer> createChangeSuggestion(@Body ChangeSuggestion<Institution> createSuggestion);
}

/** Adapter necessary for retrofit due to versioning. */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.gbif.collections.sync.clients.proxy;

import java.util.List;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.suggestions.ChangeSuggestion;
import org.gbif.collections.sync.clients.http.GrSciCollHttpClient;
import org.gbif.collections.sync.common.handler.CollectionHandler;
import org.gbif.collections.sync.common.handler.InstitutionHandler;
Expand Down Expand Up @@ -57,6 +59,16 @@ public void removeContactFromInstitution(UUID entityKey, int contactKey) {
institutionHandler.removeContactFromEntityCall(entityKey, contactKey);
}

@Override
public List<Institution> findInstitutionByName(String institutionName) {
return institutionHandler.listInstitutionsByName(institutionName);
}

@Override
public int createChangeSuggestion(ChangeSuggestion<Institution> createSuggestion) {
return institutionHandler.createChangeSuggestion(createSuggestion);
}

public Integer addContactToCollection(UUID entityKey, Contact contact) {
return collectionHandler.addContactToEntityCall(entityKey, contact);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.gbif.collections.sync.clients.proxy;

import java.util.List;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.suggestions.ChangeSuggestion;

public interface GrSciCollProxyClient {

Expand All @@ -12,4 +14,8 @@ public interface GrSciCollProxyClient {
Collection createCollection(Collection newCollection);

boolean updateCollection(Collection oldCollection, Collection newCollection);

List<Institution> findInstitutionByName(String institutionName);

int createChangeSuggestion(ChangeSuggestion<Institution> createSuggestion);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.suggestions.InstitutionChangeSuggestion;
import org.gbif.collections.sync.SyncResult.*;
import org.gbif.collections.sync.clients.proxy.GrSciCollProxyClient;
import org.gbif.collections.sync.common.converter.EntityConverter;
Expand Down Expand Up @@ -126,25 +127,36 @@ public InstitutionAndCollectionMatch handleInstAndCollMatch(MatchResult<S, R> ma

@VisibleForTesting
public NoEntityMatch handleNoMatch(MatchResult<S, R> matchResult) {
// create institution
Institution newInstitution = entityConverter.convertToInstitution(matchResult.getSource());

Institution createdInstitution = proxyClient.createInstitution(newInstitution);

// create collection
Collection createdCollection = createCollection(matchResult.getSource(), createdInstitution);

// same staff for both entities
ContactMatch contactMatchInstitution =
staffResultHandler.handleStaff(matchResult, createdInstitution);
ContactMatch contactMatchCollection =
staffResultHandler.handleStaff(matchResult, createdCollection);

return NoEntityMatch.builder()
.newCollection(createdCollection)
.newInstitution(createdInstitution)
.contactMatch(mergeContactMatches(contactMatchInstitution, contactMatchCollection))
.build();
Institution newInstitution = entityConverter.convertToInstitution(matchResult.getSource());
if (proxyClient.findInstitutionByName(newInstitution.getName()).isEmpty()) {
// create institution
Institution createdInstitution = proxyClient.createInstitution(newInstitution);
// create collection
Collection createdCollection = createCollection(matchResult.getSource(), createdInstitution);

// same staff for both entities
ContactMatch contactMatchInstitution =
staffResultHandler.handleStaff(matchResult, createdInstitution);
ContactMatch contactMatchCollection =
staffResultHandler.handleStaff(matchResult, createdCollection);

return NoEntityMatch.builder()
.newCollection(createdCollection)
.newInstitution(createdInstitution)
.contactMatch(mergeContactMatches(contactMatchInstitution, contactMatchCollection))
.build();
}
else {
// create change suggestion
InstitutionChangeSuggestion institutionChangeSuggestion = new InstitutionChangeSuggestion();
institutionChangeSuggestion.setSuggestedEntity(newInstitution);

int suggestionCreated = proxyClient.createChangeSuggestion(institutionChangeSuggestion);
return NoEntityMatch.builder()
.newChangeSuggestion(suggestionCreated)
.build();
}
}

@VisibleForTesting
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.gbif.collections.sync.common.handler;

import java.util.List;
import org.gbif.api.model.collections.Contact;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.MasterSourceMetadata;
import org.gbif.api.model.collections.suggestions.ChangeSuggestion;
import org.gbif.api.model.registry.Identifier;
import org.gbif.api.model.registry.MachineTag;
import org.gbif.collections.sync.clients.http.GrSciCollHttpClient;
Expand Down Expand Up @@ -75,4 +77,12 @@ public void removeContactFromEntityCall(UUID entityKey, int contactKey) {
() -> grSciCollHttpClient.removeContactFromInstitution(entityKey, contactKey),
exceptionHandler(contactKey, "Failed to remove contact from institution " + entityKey));
}

public List<Institution> listInstitutionsByName(String name) {
return grSciCollHttpClient.getInstitutionsByName(name);
}

public int createChangeSuggestion(ChangeSuggestion<Institution> changeSuggestion) {
return grSciCollHttpClient.createChangeSuggestion(changeSuggestion);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.gbif.collections.sync.ih.match;

import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.CollectionEntity;
import org.gbif.api.model.collections.Institution;
import org.gbif.collections.sync.clients.proxy.IHProxyClient;
import org.gbif.collections.sync.common.parsers.CountryParser;
Expand Down
20 changes: 19 additions & 1 deletion src/test/java/org/gbif/collections/sync/ih/BaseIHTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.gbif.api.vocabulary.Country;
import org.gbif.api.vocabulary.IdentifierType;
import org.gbif.api.vocabulary.collections.IdType;
import org.gbif.api.vocabulary.collections.InstitutionType;
import org.gbif.api.vocabulary.collections.MasterSourceType;
import org.gbif.api.vocabulary.collections.Source;
import org.gbif.collections.sync.SyncResult;
Expand Down Expand Up @@ -382,6 +381,25 @@ protected Map<String, Integer> convertCollectionSummary(IHInstitution.Collection
return map;
}

protected TestEntity<Institution,IHInstitution> createExistingInstitutionWithSameName() {
Institution i = new Institution();
i.setKey(UUID.randomUUID());
i.setCode("bar");
i.setName("bar");
i.setNumberSpecimens(1000);
i.setMasterSource(MasterSourceType.IH);
i.setMasterSourceMetadata(new MasterSourceMetadata(Source.IH_IRN, IRN_TEST));
i.getIdentifiers().add(new Identifier(IdentifierType.IH_IRN, IRN_TEST));
i.getIdentifiers().add(new Identifier(IdentifierType.CITES, CITES_TEST));

IHInstitution ih = new IHInstitution();
ih.setCode("bar");
ih.setOrganization("bar");
ih.setSpecimenTotal(1000);

return TestEntity.<Institution, IHInstitution>builder().entity(i).ih(ih).build();
}

private static IHConfig createConfig() {
IHConfig ihConfig = new IHConfig();
ihConfig.setSyncConfig(createTestSyncConfig());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.gbif.collections.sync.ih;

import java.util.ArrayList;
import java.util.List;
import org.gbif.api.model.collections.Collection;
import org.gbif.api.model.collections.Institution;
import org.gbif.api.model.collections.MasterSourceMetadata;
import org.gbif.api.model.collections.suggestions.InstitutionChangeSuggestion;
import org.gbif.api.model.registry.Identifier;
import org.gbif.api.vocabulary.IdentifierType;
import org.gbif.api.vocabulary.collections.Source;
import org.gbif.collections.sync.SyncResult;
import org.gbif.collections.sync.clients.proxy.GrSciCollProxyClient;
import org.gbif.collections.sync.ih.match.IHMatchResult;
import org.gbif.collections.sync.ih.model.IHInstitution;

Expand All @@ -22,6 +26,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class IHSynchronizerHandlersTest extends BaseIHTest {

Expand Down Expand Up @@ -119,6 +127,53 @@ public void noMatchTest() {
assertEmptyContactMatch(noEntityMatch.getContactMatch());
}

@Test
public void noMatchWithExistingInstitutionNameTest() {

GrSciCollProxyClient proxyClient = mock(GrSciCollProxyClient.class);
// IH institution
IHInstitution ih = new IHInstitution();
ih.setIrn(IRN_TEST);
ih.setCode("foo");
ih.setOrganization("foo");
ih.setSpecimenTotal(1000);

// Expected institution
Institution expectedInstitution = new Institution();
expectedInstitution.setCode(ih.getCode());
expectedInstitution.setName(ih.getOrganization());
expectedInstitution.setMasterSourceMetadata(new MasterSourceMetadata(Source.IH_IRN, IRN_TEST));

// Expected collection
Collection expectedCollection = new Collection();
expectedCollection.setCode(ih.getCode());
expectedCollection.setName(String.format(DEFAULT_COLLECTION_NAME_FORMAT, expectedInstitution.getName()));
expectedCollection.setNumberSpecimens(1000);
expectedCollection.setMasterSourceMetadata(new MasterSourceMetadata(Source.IH_IRN, IRN_TEST));

// add identifier to expected entities
Identifier newIdentifier = new Identifier(IdentifierType.IH_IRN, encodeIRN(IRN_TEST));
newIdentifier.setCreatedBy(TEST_USER);
expectedInstitution.getIdentifiers().add(newIdentifier);
expectedCollection.getIdentifiers().add(newIdentifier);

IHMatchResult match = IHMatchResult.builder().ihInstitution(ih).build();

// Mock behavior for findInstitutionByName
List<Institution> institutionsWithSameName = new ArrayList<>();
institutionsWithSameName.add(expectedInstitution);

when(proxyClient.findInstitutionByName(anyString())).thenReturn(institutionsWithSameName);
when(proxyClient.createChangeSuggestion(any(InstitutionChangeSuggestion.class))).thenReturn(1);
// Call the method under test
SyncResult.NoEntityMatch noEntityMatch = synchronizer.handleNoMatch(match);

// Assertions
assertEquals(1, noEntityMatch.getNewChangeSuggestion());
assertTrue(noEntityMatch.getNewInstitution().lenientEquals(expectedInstitution));
assertEmptyContactMatch(noEntityMatch.getContactMatch());
}

@Test
public void institutionAndCollectionMatchTest() {
TestEntity<Collection, IHInstitution> collectionToUpdate = createCollectionToUpdate();
Expand Down

0 comments on commit 430c627

Please sign in to comment.