R5 appointment not storing. (#3621)

* Failing test, works on #3459

* Test, changelog

* Remove dead test
This commit is contained in:
Tadgh 2022-05-17 16:31:17 -07:00 committed by GitHub
parent 27024067b0
commit 3a286c306f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 11 deletions

View File

@ -0,0 +1,4 @@
---
type: fix
issue: 3459
title: "Previously, R5 Appointment resources would fail to save in JPA servers due to a path splitting problem during Search Parameter extraction. This has been corrected."

View File

@ -1108,19 +1108,27 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
@Override
public String[] split(String thePaths) {
if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) {
if (!thePaths.contains("|")) {
return new String[]{thePaths};
}
return splitPathsR4(thePaths);
} else {
if (!thePaths.contains("|") && !thePaths.contains(" or ")) {
return new String[]{thePaths};
}
if (shouldAttemptToSplitPath(thePaths)) {
return splitOutOfParensOrs(thePaths);
} else {
return new String[]{thePaths};
}
}
public boolean shouldAttemptToSplitPath(String thePath) {
if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.R4)) {
if (thePath.contains("|")) {
return true;
}
} else {
//DSTU 3 and below used "or" as well as "|"
if (thePath.contains("|") || thePath.contains(" or ")) {
return true;
}
}
return false;
}
/**
* Iteratively splits a string on any ` or ` or | that is ** not** contained inside a set of parentheses. e.g.
*
@ -1136,7 +1144,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
private String[] splitOutOfParensOrs(String thePaths) {
List<String> topLevelOrExpressions = splitOutOfParensToken(thePaths, " or ");
List<String> retVal = topLevelOrExpressions.stream()
.flatMap(s -> splitOutOfParensToken(s, "|").stream())
.flatMap(s -> splitOutOfParensToken(s, " |").stream())
.collect(Collectors.toList());
return retVal.toArray(new String[retVal.size()]);
}

View File

@ -7,6 +7,8 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.HasAndListParam;
import ca.uhn.fhir.rest.param.HasOrListParam;
import ca.uhn.fhir.rest.param.HasParam;
import org.hl7.fhir.r5.model.Appointment;
import org.hl7.fhir.r5.model.Enumerations;
import org.hl7.fhir.r5.model.Organization;
import org.hl7.fhir.r5.model.Patient;
import org.hl7.fhir.r5.model.Practitioner;
@ -14,6 +16,7 @@ import org.hl7.fhir.r5.model.PractitionerRole;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.ContextConfiguration;
import java.util.Collections;
import java.util.Date;
import java.util.stream.Collectors;
@ -49,7 +52,6 @@ public class FhirResourceDaoR5SearchNoFtTest extends BaseJpaR5Test {
IBundleProvider outcome = myPractitionerDao.search(params);
assertEquals(1, outcome.getResources(0, 1).size());
}
@Test
public void testHasWithTargetReferenceQualified() {
Organization org = new Organization();

View File

@ -0,0 +1,74 @@
package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam;
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
import ca.uhn.fhir.jpa.model.util.UcumServiceUtil;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.jpa.searchparam.extractor.PathAndRef;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR5;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.server.util.FhirContextSearchParamRegistry;
import ca.uhn.fhir.util.HapiExtensions;
import com.google.common.collect.Sets;
import org.hl7.fhir.r5.model.Appointment;
import org.hl7.fhir.r5.model.Enumerations;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static java.util.Comparator.comparing;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
public class SearchParamExtractorR5Test {
private static final Logger ourLog = LoggerFactory.getLogger(SearchParamExtractorR5Test.class);
private static final FhirContext ourCtx = FhirContext.forR5Cached();
private FhirContextSearchParamRegistry mySearchParamRegistry;
@BeforeEach
public void before() {
mySearchParamRegistry = new FhirContextSearchParamRegistry(ourCtx);
}
@Test
public void testParamWithOrInPath() {
//Given a basic appointment
Appointment appointment = new Appointment();
appointment.setStatus(Appointment.AppointmentStatus.ARRIVED);
appointment.setStart(new Date());
appointment.setEnd(new Date());
Appointment.AppointmentParticipantComponent participant = new Appointment.AppointmentParticipantComponent();
participant.setStatus(Enumerations.ParticipationStatus.ACCEPTED);
appointment.setParticipant(Collections.singletonList(participant));
//When we extract the Date SPs
SearchParamExtractorR5 extractor = new SearchParamExtractorR5(new ModelConfig(), new PartitionSettings(), ourCtx, mySearchParamRegistry);
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamDate> dates = extractor.extractSearchParamDates(appointment);
//We find one, and the lexer doesn't explode.
assertEquals(1, dates.size());
}
}