Skip to content

Commit

Permalink
CND-94 pt 2 - Feature flag modernized deduplication (#259)
Browse files Browse the repository at this point in the history
* Add api call for matching

* Fix code smell / bug

* Update PatientMatchingService with feature flag to use new deduplication check. Default: false

* Remove possible null

* Fix bug

* Split deduplication call into service to ease testing. Add additional unit tests for modernized matching

* More testing

* Response test

* Clean up some awkward logic

* Improved test coverage

* Fix jurisdiction code lookup

---------

Co-authored-by: Michael Peels <[email protected]>
  • Loading branch information
mpeels and Michael Peels authored Dec 19, 2024
1 parent ca200a7 commit ffce196
Show file tree
Hide file tree
Showing 17 changed files with 1,348 additions and 264 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ srte-data-service/.gradle/*
### env ###
*.env

.vscode/*
.vscode/
application-local.yaml

containers/builder/NEDSSDev/

build
build
bin/

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,11 @@ public PersonContainer processingPatient(LabResultProxyContainer labResultProxyC
//NOTE: This matching also persist patient accordingly
//NOTE: Either new or existing patient, it will be processed within this method
edxPatientMatchFoundDT = patientMatchingService.getMatchingPatient(personContainer);
edxLabInformationDto.setMultipleSubjectMatch(patientMatchingService.getMultipleMatchFound());
if (edxPatientMatchFoundDT != null) {
edxLabInformationDto.setMultipleSubjectMatch(edxPatientMatchFoundDT.isMultipleMatch());
} else {
edxLabInformationDto.setMultipleSubjectMatch(false);
}
personUid = personContainer.getThePersonDto().getPersonUid();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package gov.cdc.dataprocessing.service.implementation.person.matching;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;

@Configuration
public class DeduplicationClient {

@Bean("deduplicationRestClient")
public RestClient restClient(@Value("${features.modernizedMatching.url}") String modernizedMatchingUrl) {
return RestClient.builder().baseUrl(modernizedMatchingUrl).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package gov.cdc.dataprocessing.service.implementation.person.matching;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClient;

@Component
public class DeduplicationService {

private RestClient restClient;

public DeduplicationService(
@Qualifier("deduplicationRestClient") RestClient restClient) {
this.restClient = restClient;
}

public MatchResponse match(PersonMatchRequest request) {
return restClient.post()
.uri("/match")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(request)
.retrieve()
.body(MatchResponse.class);
}

public void relate(RelateRequest relateRequest) {
restClient.post()
.uri("/relate")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(relateRequest)
.retrieve()
.body(Void.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package gov.cdc.dataprocessing.service.implementation.person.matching;

import java.util.List;

public record LinkResponse(
String patient_reference_id,
String person_reference_id,
String prediction, // match, possible_match, no_match
List<Results> results) {
public record Results(
String person_reference_id,
Double belongingness_ratio) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package gov.cdc.dataprocessing.service.implementation.person.matching;

public record MatchResponse(
Long match,
MatchType matchType,
LinkResponse linkResponse) {

public enum MatchType {
EXACT,
POSSIBLE,
NONE
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package gov.cdc.dataprocessing.service.implementation.person.matching;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;

import gov.cdc.dataprocessing.model.container.model.PersonContainer;
import gov.cdc.dataprocessing.model.dto.entity.EntityIdDto;
import gov.cdc.dataprocessing.model.dto.entity.EntityLocatorParticipationDto;
import gov.cdc.dataprocessing.model.dto.locator.PostalLocatorDto;
import gov.cdc.dataprocessing.model.dto.locator.TeleLocatorDto;
import gov.cdc.dataprocessing.model.dto.person.PersonDto;
import gov.cdc.dataprocessing.model.dto.person.PersonNameDto;
import gov.cdc.dataprocessing.model.dto.person.PersonRaceDto;

public record PersonMatchRequest(
PersonDto personDto,
Collection<PersonNameDto> names,
Collection<PersonRaceDto> races,
Collection<PostalLocatorDto> postalLocators,
Collection<TeleLocatorDto> teleLocators,
Collection<EntityIdDto> identifications) {
public PersonMatchRequest(PersonContainer personContainer) {
this(
personContainer.getThePersonDto(),
personContainer.getThePersonNameDtoCollection(),
personContainer.getThePersonRaceDtoCollection(),
Optional.of(personContainer.getTheEntityLocatorParticipationDtoCollection())
.orElseGet(ArrayList::new)
.stream()
.map(EntityLocatorParticipationDto::getThePostalLocatorDto)
.filter(Objects::nonNull)
.toList(),
Optional.of(personContainer.getTheEntityLocatorParticipationDtoCollection())
.orElseGet(ArrayList::new)
.stream()
.map(EntityLocatorParticipationDto::getTheTeleLocatorDto)
.filter(Objects::nonNull)
.toList(),
personContainer.getTheEntityIdDtoCollection());

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package gov.cdc.dataprocessing.service.implementation.person.matching;

import gov.cdc.dataprocessing.service.implementation.person.matching.MatchResponse.MatchType;

public record RelateRequest(
Long nbsPerson,
Long nbsPersonParent,
MatchType matchType,
LinkResponse linkResponse) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@
"java:S1149", "java:S112", "java:S107", "java:S1195", "java:S1135", "java:S6201", "java:S1192", "java:S135", "java:S117"})
public interface IPatientMatchingService {
EdxPatientMatchDto getMatchingPatient(PersonContainer personContainer) throws DataProcessingException;
boolean getMultipleMatchFound();
Long updateExistingPerson(PersonContainer personContainer, String businessTriggerCd) throws DataProcessingException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public long getPAJHash(String programAreaCode, String jurisdictionCode)
try
{
Integer programAreaNumericID = Integer.valueOf(cacheApiService.getSrteCacheString(ObjectName.PROGRAM_AREA_CODES_WITH_NBS_UID.name(), programAreaCode));
Integer jurisdictionNumericID = Integer.valueOf(cacheApiService.getSrteCacheString(ObjectName.PROGRAM_AREA_CODES_WITH_NBS_UID.name(), jurisdictionCode));
Integer jurisdictionNumericID = Integer.valueOf(cacheApiService.getSrteCacheString(ObjectName.JURISDICTION_CODE_WITH_NBS_UID.name(), jurisdictionCode));
hashCode = (jurisdictionNumericID.longValue() * 100000L) + programAreaNumericID.longValue();
}
catch(Exception e)
Expand Down
Loading

0 comments on commit ffce196

Please sign in to comment.