Add some testing

This commit is contained in:
James Agnew 2019-10-30 09:49:40 -04:00
parent 05d3c35e58
commit d3e66680f0
9 changed files with 326 additions and 236 deletions

View File

@ -45,7 +45,6 @@
<artifactId>hapi-fhir-testpage-overlay</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
<scope>provided</scope>
</dependency>
<!-- HAPI-FHIR uses Logback for logging support. The logback library is included automatically by Maven as a part of the hapi-fhir-base dependency, but you also need to include a logging library. Logback

View File

@ -979,7 +979,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
if (thePerformIndexing) {
newParams = new ResourceIndexedSearchParams();
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, this, theUpdateTime, theEntity, theResource, existingParams, theRequest);
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theUpdateTime, theEntity, theResource, existingParams, theRequest);
changed = populateResourceIntoEntity(theRequest, theResource, theEntity, true);
if (changed.isChanged()) {

View File

@ -88,8 +88,8 @@ public class SearchParamWithInlineReferencesExtractor {
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
protected EntityManager myEntityManager;
public void populateFromResource(ResourceIndexedSearchParams theParams, IDao theCallingDao, Date theUpdateTime, ResourceTable theEntity, IBaseResource theResource, ResourceIndexedSearchParams theExistingParams, RequestDetails theRequest) {
mySearchParamExtractorService.extractFromResource(theParams, theEntity, theResource);
public void populateFromResource(ResourceIndexedSearchParams theParams, Date theUpdateTime, ResourceTable theEntity, IBaseResource theResource, ResourceIndexedSearchParams theExistingParams, RequestDetails theRequest) {
mySearchParamExtractorService.extractFromResource(theRequest, theParams, theEntity, theResource);
Set<Map.Entry<String, RuntimeSearchParam>> activeSearchParams = mySearchParamRegistry.getActiveSearchParams(theEntity.getResourceType()).entrySet();
if (myDaoConfig.getIndexMissingFields() == DaoConfig.IndexEnabledEnum.ENABLED) {

View File

@ -122,6 +122,11 @@
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View File

@ -59,15 +59,43 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
@Autowired
private ModelConfig myModelConfig;
private Set<String> myIgnoredForSearchDatatypes;
private BaseRuntimeChildDefinition quantityValueChild;
private BaseRuntimeChildDefinition quantitySystemChild;
private BaseRuntimeChildDefinition quantityCodeChild;
private BaseRuntimeChildDefinition moneyValueChild;
private BaseRuntimeChildDefinition moneyCurrencyChild;
private BaseRuntimeElementCompositeDefinition<?> locationPositionDefinition;
private BaseRuntimeChildDefinition codeSystemUrlValueChild;
private BaseRuntimeChildDefinition rangeLowValueChild;
private BaseRuntimeChildDefinition rangeHighValueChild;
private BaseRuntimeChildDefinition myQuantityValueValueChild;
private BaseRuntimeChildDefinition myQuantitySystemValueChild;
private BaseRuntimeChildDefinition myQuantityCodeValueChild;
private BaseRuntimeChildDefinition myMoneyValueChild;
private BaseRuntimeChildDefinition myMoneyCurrencyChild;
private BaseRuntimeElementCompositeDefinition<?> myLocationPositionDefinition;
private BaseRuntimeChildDefinition myCodeSystemUrlValueChild;
private BaseRuntimeChildDefinition myRangeLowValueChild;
private BaseRuntimeChildDefinition myRangeHighValueChild;
private BaseRuntimeChildDefinition myAddressLineValueChild;
private BaseRuntimeChildDefinition myAddressCityValueChild;
private BaseRuntimeChildDefinition myAddressStateValueChild;
private BaseRuntimeChildDefinition myAddressCountryValueChild;
private BaseRuntimeChildDefinition myAddressPostalCodeValueChild;
private BaseRuntimeChildDefinition myCapabilityStatementRestSecurityServiceValueChild;
private BaseRuntimeChildDefinition myPeriodStartValueChild;
private BaseRuntimeChildDefinition myPeriodEndValueChild;
private BaseRuntimeChildDefinition myTimingEventValueChild;
private BaseRuntimeChildDefinition myTimingRepeatValueChild;
private BaseRuntimeChildDefinition myTimingRepeatBoundsValueChild;
private BaseRuntimeChildDefinition myDurationSystemValueChild;
private BaseRuntimeChildDefinition myDurationCodeValueChild;
private BaseRuntimeChildDefinition myDurationValueValueChild;
private BaseRuntimeChildDefinition myHumanNameFamilyValueChild;
private BaseRuntimeChildDefinition myHumanNameGivenValueChild;
private BaseRuntimeChildDefinition myContactPointValueValueChild;
private BaseRuntimeChildDefinition myIdentifierSystemValueChild;
private BaseRuntimeChildDefinition myIdentifierValueValueChild;
private BaseRuntimeChildDefinition myIdentifierTypeValueChild;
private BaseRuntimeChildDefinition myIdentifierTypeTextValueChild;
private BaseRuntimeChildDefinition myCodeableConceptCodingValueChild;
private BaseRuntimeChildDefinition myCodeableConceptTextValueChild;
private BaseRuntimeChildDefinition myCodingSystemValueChild;
private BaseRuntimeChildDefinition myCodingCodeValueChild;
private BaseRuntimeChildDefinition myCodingDisplayValueChild;
private BaseRuntimeChildDefinition myContactPointSystemValueChild;
private BaseRuntimeChildDefinition myPatientCommunicationLanguageValueChild;
/**
* Constructor
@ -92,14 +120,14 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
String useSystem;
if (getContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU2)) {
if (resourceTypeName.equals("ValueSet")) {
ca.uhn.fhir.model.dstu2.resource.ValueSet dstu2ValueSet = (ca.uhn.fhir.model.dstu2.resource.ValueSet)theResource;
ca.uhn.fhir.model.dstu2.resource.ValueSet dstu2ValueSet = (ca.uhn.fhir.model.dstu2.resource.ValueSet) theResource;
useSystem = dstu2ValueSet.getCodeSystem().getSystem();
} else {
useSystem = null;
}
} else {
if (resourceTypeName.equals("CodeSystem")) {
useSystem = extractValueAsString(codeSystemUrlValueChild, theResource);
useSystem = extractValueAsString(myCodeSystemUrlValueChild, theResource);
} else {
useSystem = null;
}
@ -186,7 +214,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return extractSearchParams(theResource, extractor, RestSearchParameterTypeEnum.TOKEN);
}
public void addUnexpectedDatatypeWarning(SearchParamSet<? extends BaseResourceIndexedSearchParam> params, RuntimeSearchParam searchParam, IBase value) {
private void addUnexpectedDatatypeWarning(SearchParamSet<? extends BaseResourceIndexedSearchParam> params, RuntimeSearchParam searchParam, IBase value) {
params.addWarning("Search param " + searchParam.getName() + " is of unexpected datatype: " + value.getClass());
}
@ -280,7 +308,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
public SearchParamSet<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(IBaseResource theResource) {
IExtractor<ResourceIndexedSearchParamQuantity> extractor = (params, searchParam, value, path) -> {
if (value.getClass().equals(locationPositionDefinition.getImplementingClass())) {
if (value.getClass().equals(myLocationPositionDefinition.getImplementingClass())) {
ourLog.warn("Position search not currently supported, not indexing location");
return;
}
@ -407,7 +435,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return myModelConfig;
}
public Collection<RuntimeSearchParam> getSearchParams(IBaseResource theResource) {
private Collection<RuntimeSearchParam> getSearchParams(IBaseResource theResource) {
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
Collection<RuntimeSearchParam> retVal = mySearchParamRegistry.getActiveSearchParams(def.getName()).values();
List<RuntimeSearchParam> defaultList = Collections.emptyList();
@ -415,50 +443,14 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return retVal;
}
@PostConstruct
public void start() {
myIgnoredForSearchDatatypes = new HashSet<>();
addIgnoredType(getContext(), "Annotation", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Attachment", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Count", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Distance", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Ratio", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "SampledData", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Signature", myIgnoredForSearchDatatypes);
BaseRuntimeElementCompositeDefinition<?> quantityDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Quantity");
quantityValueChild = quantityDefinition.getChildByName("value");
quantitySystemChild = quantityDefinition.getChildByName("system");
quantityCodeChild = quantityDefinition.getChildByName("code");
BaseRuntimeElementCompositeDefinition<?> moneyDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Money");
moneyValueChild = moneyDefinition.getChildByName("value");
moneyCurrencyChild = moneyDefinition.getChildByName("currency");
BaseRuntimeElementCompositeDefinition<?> locationDefinition = getContext().getResourceDefinition("Location");
BaseRuntimeChildDefinition locationPositionValueChild = locationDefinition.getChildByName("position");
locationPositionDefinition = (BaseRuntimeElementCompositeDefinition<?>) locationPositionValueChild.getChildByName("position");
BaseRuntimeElementCompositeDefinition<?> codeSystemDefinition;
if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
codeSystemDefinition = getContext().getResourceDefinition("CodeSystem");
assert codeSystemDefinition != null;
codeSystemUrlValueChild = codeSystemDefinition.getChildByName("url");
}
BaseRuntimeElementCompositeDefinition<?> rangeDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Range");
rangeLowValueChild = rangeDefinition.getChildByName("low");
rangeHighValueChild = rangeDefinition.getChildByName("high");
}
private void addQuantity_Quantity(String theResourceType, Set<ResourceIndexedSearchParamQuantity> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
Optional<IPrimitiveType<BigDecimal>> valueField = quantityValueChild.getAccessor().getFirstValueOrNull(theValue);
Optional<IPrimitiveType<BigDecimal>> valueField = myQuantityValueValueChild.getAccessor().getFirstValueOrNull(theValue);
if (valueField.isPresent() && valueField.get().getValue() != null) {
BigDecimal nextValueValue = valueField.get().getValue();
String system = extractValueAsString(quantitySystemChild, theValue);
String code = extractValueAsString(quantityCodeChild, theValue);
String system = extractValueAsString(myQuantitySystemValueChild, theValue);
String code = extractValueAsString(myQuantityCodeValueChild, theValue);
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(theResourceType, theSearchParam.getName(), nextValueValue, system, code);
theParams.add(nextEntity);
@ -468,12 +460,12 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
private void addQuantity_Money(String theResourceType, Set<ResourceIndexedSearchParamQuantity> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
Optional<IPrimitiveType<BigDecimal>> valueField = moneyValueChild.getAccessor().getFirstValueOrNull(theValue);
Optional<IPrimitiveType<BigDecimal>> valueField = myMoneyValueChild.getAccessor().getFirstValueOrNull(theValue);
if (valueField.isPresent() && valueField.get().getValue() != null) {
BigDecimal nextValueValue = valueField.get().getValue();
String nextValueString = "urn:iso:std:iso:4217";
String nextValueCode = extractValueAsString(moneyCurrencyChild, theValue);
String nextValueCode = extractValueAsString(myMoneyCurrencyChild, theValue);
String searchParamName = theSearchParam.getName();
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(theResourceType, searchParamName, nextValueValue, nextValueString, nextValueCode);
theParams.add(nextEntity);
@ -483,98 +475,64 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
private void addQuantity_Range(String theResourceType, Set<ResourceIndexedSearchParamQuantity> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
Optional<IBase> low = rangeLowValueChild.getAccessor().getFirstValueOrNull(theValue);
Optional<IBase> low = myRangeLowValueChild.getAccessor().getFirstValueOrNull(theValue);
low.ifPresent(theIBase -> addQuantity_Quantity(theResourceType, theParams, theSearchParam, theIBase));
Optional<IBase> high = rangeHighValueChild.getAccessor().getFirstValueOrNull(theValue);
Optional<IBase> high = myRangeHighValueChild.getAccessor().getFirstValueOrNull(theValue);
high.ifPresent(theIBase -> addQuantity_Quantity(theResourceType, theParams, theSearchParam, theIBase));
}
private void addToken_Identifier(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> identifierDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Identifier");
BaseRuntimeChildDefinition identifierSystemValueChild = identifierDefinition.getChildByName("system");
BaseRuntimeChildDefinition identifierValueValueChild = identifierDefinition.getChildByName("value");
BaseRuntimeChildDefinition identifierTypeValueChild = identifierDefinition.getChildByName("type");
BaseRuntimeElementCompositeDefinition<?> identifierTypeDefinition = (BaseRuntimeElementCompositeDefinition<?>) identifierTypeValueChild.getChildByName("type");
BaseRuntimeChildDefinition identifierTypeTextValueChild = identifierTypeDefinition.getChildByName("text");
String system = extractValueAsString(identifierSystemValueChild, theValue);
String value = extractValueAsString(identifierValueValueChild, theValue);
String system = extractValueAsString(myIdentifierSystemValueChild, theValue);
String value = extractValueAsString(myIdentifierValueValueChild, theValue);
if (isNotBlank(value)) {
createTokenIndexIfNotBlank(theResourceType, theParams, theSearchParam, system, value);
}
Optional<IBase> type = identifierTypeValueChild.getAccessor().getFirstValueOrNull(theValue);
Optional<IBase> type = myIdentifierTypeValueChild.getAccessor().getFirstValueOrNull(theValue);
if (type.isPresent()) {
String text = extractValueAsString(identifierTypeTextValueChild, type.get());
String text = extractValueAsString(myIdentifierTypeTextValueChild, type.get());
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text);
}
}
private void addToken_CodeableConcept(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> codeableConceptDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("CodeableConcept");
BaseRuntimeChildDefinition codeableConceptCodingValueChild = codeableConceptDefinition.getChildByName("coding");
BaseRuntimeChildDefinition codeableConceptTextValueChild = codeableConceptDefinition.getChildByName("text");
List<IBase> codings = codeableConceptCodingValueChild.getAccessor().getValues(theValue);
List<IBase> codings = myCodeableConceptCodingValueChild.getAccessor().getValues(theValue);
for (IBase nextCoding : codings) {
addToken_Coding(theResourceType, theParams, theSearchParam, nextCoding);
}
String text = extractValueAsString(codeableConceptTextValueChild, theValue);
String text = extractValueAsString(myCodeableConceptTextValueChild, theValue);
if (isNotBlank(text)) {
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text);
}
}
private void addToken_Coding(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> codingDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Coding");
BaseRuntimeChildDefinition codingSystemValueChild = codingDefinition.getChildByName("system");
BaseRuntimeChildDefinition codingCodeValueChild = codingDefinition.getChildByName("code");
BaseRuntimeChildDefinition codingDisplayValueChild = codingDefinition.getChildByName("display");
String system = extractValueAsString(codingSystemValueChild, theValue);
String code = extractValueAsString(codingCodeValueChild, theValue);
String system = extractValueAsString(myCodingSystemValueChild, theValue);
String code = extractValueAsString(myCodingCodeValueChild, theValue);
createTokenIndexIfNotBlank(theResourceType, theParams, theSearchParam, system, code);
String text = extractValueAsString(codingDisplayValueChild, theValue);
String text = extractValueAsString(myCodingDisplayValueChild, theValue);
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, text);
}
private void addToken_ContactPoint(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> contactPointDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("ContactPoint");
BaseRuntimeChildDefinition contactPointSystemValueChild = contactPointDefinition.getChildByName("system");
BaseRuntimeChildDefinition contactPointValueValueChild = contactPointDefinition.getChildByName("value");
String system = extractValueAsString(contactPointSystemValueChild, theValue);
String value = extractValueAsString(contactPointValueValueChild, theValue);
String system = extractValueAsString(myContactPointSystemValueChild, theValue);
String value = extractValueAsString(myContactPointValueValueChild, theValue);
createTokenIndexIfNotBlank(theResourceType, theParams, theSearchParam, system, value);
}
private void addToken_PatientCommunication(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> patientDefinition = getContext().getResourceDefinition("Patient");
BaseRuntimeChildDefinition patientCommunicationValueChild = patientDefinition.getChildByName("communication");
BaseRuntimeElementCompositeDefinition<?> patientCommunicationDefinition = (BaseRuntimeElementCompositeDefinition<?>) patientCommunicationValueChild.getChildByName("communication");
BaseRuntimeChildDefinition patientCommunicationLanguageValueChild = patientCommunicationDefinition.getChildByName("language");
List<IBase> values = patientCommunicationLanguageValueChild.getAccessor().getValues(theValue);
List<IBase> values = myPatientCommunicationLanguageValueChild.getAccessor().getValues(theValue);
for (IBase next : values) {
addToken_CodeableConcept(theResourceType, theParams, theSearchParam, next);
}
}
private void addToken_CapabilityStatementRestSecurity(String theResourceType, Set<BaseResourceIndexedSearchParam> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> capabilityStatementDefinition = getContext().getResourceDefinition("CapabilityStatement");
BaseRuntimeChildDefinition capabilityStatementRestChild = capabilityStatementDefinition.getChildByName("rest");
BaseRuntimeElementCompositeDefinition<?> capabilityStatementRestDefinition = (BaseRuntimeElementCompositeDefinition<?>) capabilityStatementRestChild.getChildByName("rest");
BaseRuntimeChildDefinition capabilityStatementRestSecurityValueChild = capabilityStatementRestDefinition.getChildByName("security");
BaseRuntimeElementCompositeDefinition<?> capabilityStatementRestSecurityDefinition = (BaseRuntimeElementCompositeDefinition<?>) capabilityStatementRestSecurityValueChild.getChildByName("security");
BaseRuntimeChildDefinition capabilityStatementRestSecurityServiceValueChild = capabilityStatementRestSecurityDefinition.getChildByName("service");
List<IBase> values = capabilityStatementRestSecurityServiceValueChild.getAccessor().getValues(theValue);
List<IBase> values = myCapabilityStatementRestSecurityServiceValueChild.getAccessor().getValues(theValue);
for (IBase nextValue : values) {
addToken_CodeableConcept(theResourceType, theParams, theSearchParam, nextValue);
}
@ -582,13 +540,9 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addDate_Period(String theResourceType, Set<ResourceIndexedSearchParamDate> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> periodDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Period");
BaseRuntimeChildDefinition periodStartValueChild = periodDefinition.getChildByName("start");
BaseRuntimeChildDefinition periodEndValueChild = periodDefinition.getChildByName("end");
Date start = extractValueAsDate(periodStartValueChild, theValue);
String startAsString = extractValueAsString(periodStartValueChild, theValue);
Date end = extractValueAsDate(periodEndValueChild, theValue);
Date start = extractValueAsDate(myPeriodStartValueChild, theValue);
String startAsString = extractValueAsString(myPeriodStartValueChild, theValue);
Date end = extractValueAsDate(myPeriodEndValueChild, theValue);
if (start != null || end != null) {
ResourceIndexedSearchParamDate nextEntity = new ResourceIndexedSearchParamDate(theResourceType, theSearchParam.getName(), start, end, startAsString);
@ -597,13 +551,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addDate_Timing(String theResourceType, Set<ResourceIndexedSearchParamDate> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> timingDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Timing");
BaseRuntimeChildDefinition timingEventValueChild = timingDefinition.getChildByName("event");
BaseRuntimeChildDefinition timingRepeatValueChild = timingDefinition.getChildByName("repeat");
BaseRuntimeElementCompositeDefinition<?> timingRepeatDefinition = (BaseRuntimeElementCompositeDefinition<?>) timingRepeatValueChild.getChildByName("repeat");
BaseRuntimeChildDefinition timingRepeatBoundsValueChild = timingRepeatDefinition.getChildByName("bounds[x]");
List<IPrimitiveType<Date>> values = extractValuesAsFhirDates(timingEventValueChild, theValue);
List<IPrimitiveType<Date>> values = extractValuesAsFhirDates(myTimingEventValueChild, theValue);
TreeSet<Date> dates = new TreeSet<>();
String firstValue = null;
@ -616,21 +564,16 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
}
Optional<IBase> repeat = timingRepeatValueChild.getAccessor().getFirstValueOrNull(theValue);
Optional<IBase> repeat = myTimingRepeatValueChild.getAccessor().getFirstValueOrNull(theValue);
if (repeat.isPresent()) {
Optional<IBase> bounds = timingRepeatBoundsValueChild.getAccessor().getFirstValueOrNull(repeat.get());
Optional<IBase> bounds = myTimingRepeatBoundsValueChild.getAccessor().getFirstValueOrNull(repeat.get());
if (bounds.isPresent()) {
String boundsType = toRootTypeName(bounds.get());
switch (boundsType) {
case "Period":
BaseRuntimeElementCompositeDefinition<?> periodDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Period");
BaseRuntimeChildDefinition periodStartValueChild = periodDefinition.getChildByName("start");
BaseRuntimeChildDefinition periodEndValueChild = periodDefinition.getChildByName("end");
Date start = extractValueAsDate(periodStartValueChild, bounds.get());
Date end = extractValueAsDate(periodEndValueChild, bounds.get());
if ("Period".equals(boundsType)) {
Date start = extractValueAsDate(myPeriodStartValueChild, bounds.get());
Date end = extractValueAsDate(myPeriodEndValueChild, bounds.get());
dates.add(start);
dates.add(end);
break;
}
}
}
@ -642,14 +585,9 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addNumber_Duration(String theResourceType, Set<ResourceIndexedSearchParamNumber> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> durationDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Duration");
BaseRuntimeChildDefinition durationSystemValueChild = durationDefinition.getChildByName("system");
BaseRuntimeChildDefinition durationCodeValueChild = durationDefinition.getChildByName("code");
BaseRuntimeChildDefinition durationValueValueChild = durationDefinition.getChildByName("value");
String system = extractValueAsString(durationSystemValueChild, theValue);
String code = extractValueAsString(durationCodeValueChild, theValue);
BigDecimal value = extractValueAsBigDecimal(durationValueValueChild, theValue);
String system = extractValueAsString(myDurationSystemValueChild, theValue);
String code = extractValueAsString(myDurationCodeValueChild, theValue);
BigDecimal value = extractValueAsBigDecimal(myDurationValueValueChild, theValue);
if (value != null) {
value = normalizeQuantityContainingTimeUnitsIntoDaysForNumberParam(system, code, value);
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(theResourceType, theSearchParam.getName(), value);
@ -658,15 +596,10 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addNumber_Quantity(String theResourceType, Set<ResourceIndexedSearchParamNumber> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> quantityDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Duration");
BaseRuntimeChildDefinition quantityValueValueChild = quantityDefinition.getChildByName("value");
BaseRuntimeChildDefinition quantitySystemChild = quantityDefinition.getChildByName("system");
BaseRuntimeChildDefinition quantityCodeChild = quantityDefinition.getChildByName("code");
BigDecimal value = extractValueAsBigDecimal(quantityValueValueChild, theValue);
BigDecimal value = extractValueAsBigDecimal(myQuantityValueValueChild, theValue);
if (value != null) {
String system = extractValueAsString(quantitySystemChild, theValue);
String code = extractValueAsString(quantityCodeChild, theValue);
String system = extractValueAsString(myQuantitySystemValueChild, theValue);
String code = extractValueAsString(myQuantityCodeValueChild, theValue);
value = normalizeQuantityContainingTimeUnitsIntoDaysForNumberParam(system, code, value);
ResourceIndexedSearchParamNumber nextEntity = new ResourceIndexedSearchParamNumber(theResourceType, theSearchParam.getName(), value);
theParams.add(nextEntity);
@ -696,16 +629,12 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addString_HumanName(String theResourceType, Set<ResourceIndexedSearchParamString> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> humanNameDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("HumanName");
BaseRuntimeChildDefinition humanNameFamilyValueChild = humanNameDefinition.getChildByName("family");
BaseRuntimeChildDefinition humanNameGivenValueChild = humanNameDefinition.getChildByName("given");
List<String> families = extractValuesAsStrings(humanNameFamilyValueChild, theValue);
List<String> families = extractValuesAsStrings(myHumanNameFamilyValueChild, theValue);
for (String next : families) {
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, next);
}
List<String> givens = extractValuesAsStrings(humanNameGivenValueChild, theValue);
List<String> givens = extractValuesAsStrings(myHumanNameGivenValueChild, theValue);
for (String next : givens) {
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, next);
}
@ -713,61 +642,48 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
}
private void addString_Quantity(String theResourceType, Set<ResourceIndexedSearchParamString> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> quantityDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Quantity");
BaseRuntimeChildDefinition quantityValueChild = quantityDefinition.getChildByName("value");
BigDecimal value = extractValueAsBigDecimal(quantityValueChild, theValue);
BigDecimal value = extractValueAsBigDecimal(myQuantityValueValueChild, theValue);
if (value != null) {
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, value.toPlainString());
}
}
private void addString_Range(String theResourceType, Set<ResourceIndexedSearchParamString> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> rangeDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Range");
BaseRuntimeChildDefinition rangeLowValueChild = rangeDefinition.getChildByName("low");
BigDecimal value = extractValueAsBigDecimal(rangeLowValueChild, theValue);
BigDecimal value = extractValueAsBigDecimal(myRangeLowValueChild, theValue);
if (value != null) {
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, value.toPlainString());
}
}
private void addString_ContactPoint(String theResourceType, Set<ResourceIndexedSearchParamString> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> contactPointDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("ContactPoint");
BaseRuntimeChildDefinition contactPointValueValueChild = contactPointDefinition.getChildByName("value");
String value = extractValueAsString(contactPointValueValueChild, theValue);
String value = extractValueAsString(myContactPointValueValueChild, theValue);
if (isNotBlank(value)) {
createStringIndexIfNotBlank(theResourceType, theParams, theSearchParam, value);
}
}
private void addString_Address(String theResourceType, Set<ResourceIndexedSearchParamString> theParams, RuntimeSearchParam theSearchParam, IBase theValue) {
BaseRuntimeElementCompositeDefinition<?> addressDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Address");
BaseRuntimeChildDefinition addressLineValueChild = addressDefinition.getChildByName("line");
BaseRuntimeChildDefinition addressCityValueChild = addressDefinition.getChildByName("city");
BaseRuntimeChildDefinition addressStateValueChild = addressDefinition.getChildByName("state");
BaseRuntimeChildDefinition addressCountryValueChild = addressDefinition.getChildByName("country");
BaseRuntimeChildDefinition addressPostalCodeValueChild = addressDefinition.getChildByName("postalCode");
List<String> allNames = new ArrayList<>(extractValuesAsStrings(addressLineValueChild, theValue));
List<String> allNames = new ArrayList<>(extractValuesAsStrings(myAddressLineValueChild, theValue));
String city = extractValueAsString(addressCityValueChild, theValue);
String city = extractValueAsString(myAddressCityValueChild, theValue);
if (isNotBlank(city)) {
allNames.add(city);
}
String state = extractValueAsString(addressStateValueChild, theValue);
String state = extractValueAsString(myAddressStateValueChild, theValue);
if (isNotBlank(state)) {
allNames.add(state);
}
String country = extractValueAsString(addressCountryValueChild, theValue);
String country = extractValueAsString(myAddressCountryValueChild, theValue);
if (isNotBlank(country)) {
allNames.add(country);
}
String postalCode = extractValueAsString(addressPostalCodeValueChild, theValue);
String postalCode = extractValueAsString(myAddressPostalCodeValueChild, theValue);
if (isNotBlank(postalCode)) {
allNames.add(postalCode);
}
@ -895,6 +811,107 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return theValue;
}
@PostConstruct
public void start() {
myIgnoredForSearchDatatypes = new HashSet<>();
addIgnoredType(getContext(), "Annotation", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Attachment", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Count", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Distance", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Ratio", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "SampledData", myIgnoredForSearchDatatypes);
addIgnoredType(getContext(), "Signature", myIgnoredForSearchDatatypes);
/*
* This is building up an internal map of all the various field accessors we'll need in order to work
* with the model. This is kind of ugly, but we want to be as efficient as possible since
* search param extraction happens a whole heck of a lot at runtime..
*/
BaseRuntimeElementCompositeDefinition<?> quantityDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Quantity");
myQuantityValueValueChild = quantityDefinition.getChildByName("value");
myQuantitySystemValueChild = quantityDefinition.getChildByName("system");
myQuantityCodeValueChild = quantityDefinition.getChildByName("code");
BaseRuntimeElementCompositeDefinition<?> moneyDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Money");
myMoneyValueChild = moneyDefinition.getChildByName("value");
myMoneyCurrencyChild = moneyDefinition.getChildByName("currency");
BaseRuntimeElementCompositeDefinition<?> locationDefinition = getContext().getResourceDefinition("Location");
BaseRuntimeChildDefinition locationPositionValueChild = locationDefinition.getChildByName("position");
myLocationPositionDefinition = (BaseRuntimeElementCompositeDefinition<?>) locationPositionValueChild.getChildByName("position");
BaseRuntimeElementCompositeDefinition<?> codeSystemDefinition;
if (getContext().getVersion().getVersion().isEqualOrNewerThan(FhirVersionEnum.DSTU3)) {
codeSystemDefinition = getContext().getResourceDefinition("CodeSystem");
assert codeSystemDefinition != null;
myCodeSystemUrlValueChild = codeSystemDefinition.getChildByName("url");
}
BaseRuntimeElementCompositeDefinition<?> rangeDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Range");
myRangeLowValueChild = rangeDefinition.getChildByName("low");
myRangeHighValueChild = rangeDefinition.getChildByName("high");
BaseRuntimeElementCompositeDefinition<?> addressDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Address");
myAddressLineValueChild = addressDefinition.getChildByName("line");
myAddressCityValueChild = addressDefinition.getChildByName("city");
myAddressStateValueChild = addressDefinition.getChildByName("state");
myAddressCountryValueChild = addressDefinition.getChildByName("country");
myAddressPostalCodeValueChild = addressDefinition.getChildByName("postalCode");
BaseRuntimeElementCompositeDefinition<?> capabilityStatementDefinition = getContext().getResourceDefinition("CapabilityStatement");
BaseRuntimeChildDefinition capabilityStatementRestChild = capabilityStatementDefinition.getChildByName("rest");
BaseRuntimeElementCompositeDefinition<?> capabilityStatementRestDefinition = (BaseRuntimeElementCompositeDefinition<?>) capabilityStatementRestChild.getChildByName("rest");
BaseRuntimeChildDefinition capabilityStatementRestSecurityValueChild = capabilityStatementRestDefinition.getChildByName("security");
BaseRuntimeElementCompositeDefinition<?> capabilityStatementRestSecurityDefinition = (BaseRuntimeElementCompositeDefinition<?>) capabilityStatementRestSecurityValueChild.getChildByName("security");
myCapabilityStatementRestSecurityServiceValueChild = capabilityStatementRestSecurityDefinition.getChildByName("service");
BaseRuntimeElementCompositeDefinition<?> periodDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Period");
myPeriodStartValueChild = periodDefinition.getChildByName("start");
myPeriodEndValueChild = periodDefinition.getChildByName("end");
BaseRuntimeElementCompositeDefinition<?> timingDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Timing");
myTimingEventValueChild = timingDefinition.getChildByName("event");
myTimingRepeatValueChild = timingDefinition.getChildByName("repeat");
BaseRuntimeElementCompositeDefinition<?> timingRepeatDefinition = (BaseRuntimeElementCompositeDefinition<?>) myTimingRepeatValueChild.getChildByName("repeat");
myTimingRepeatBoundsValueChild = timingRepeatDefinition.getChildByName("bounds[x]");
BaseRuntimeElementCompositeDefinition<?> durationDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Duration");
myDurationSystemValueChild = durationDefinition.getChildByName("system");
myDurationCodeValueChild = durationDefinition.getChildByName("code");
myDurationValueValueChild = durationDefinition.getChildByName("value");
BaseRuntimeElementCompositeDefinition<?> humanNameDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("HumanName");
myHumanNameFamilyValueChild = humanNameDefinition.getChildByName("family");
myHumanNameGivenValueChild = humanNameDefinition.getChildByName("given");
BaseRuntimeElementCompositeDefinition<?> contactPointDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("ContactPoint");
myContactPointValueValueChild = contactPointDefinition.getChildByName("value");
myContactPointSystemValueChild = contactPointDefinition.getChildByName("system");
BaseRuntimeElementCompositeDefinition<?> identifierDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Identifier");
myIdentifierSystemValueChild = identifierDefinition.getChildByName("system");
myIdentifierValueValueChild = identifierDefinition.getChildByName("value");
myIdentifierTypeValueChild = identifierDefinition.getChildByName("type");
BaseRuntimeElementCompositeDefinition<?> identifierTypeDefinition = (BaseRuntimeElementCompositeDefinition<?>) myIdentifierTypeValueChild.getChildByName("type");
myIdentifierTypeTextValueChild = identifierTypeDefinition.getChildByName("text");
BaseRuntimeElementCompositeDefinition<?> codeableConceptDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("CodeableConcept");
myCodeableConceptCodingValueChild = codeableConceptDefinition.getChildByName("coding");
myCodeableConceptTextValueChild = codeableConceptDefinition.getChildByName("text");
BaseRuntimeElementCompositeDefinition<?> codingDefinition = (BaseRuntimeElementCompositeDefinition<?>) getContext().getElementDefinition("Coding");
myCodingSystemValueChild = codingDefinition.getChildByName("system");
myCodingCodeValueChild = codingDefinition.getChildByName("code");
myCodingDisplayValueChild = codingDefinition.getChildByName("display");
BaseRuntimeElementCompositeDefinition<?> patientDefinition = getContext().getResourceDefinition("Patient");
BaseRuntimeChildDefinition patientCommunicationValueChild = patientDefinition.getChildByName("communication");
BaseRuntimeElementCompositeDefinition<?> patientCommunicationDefinition = (BaseRuntimeElementCompositeDefinition<?>) patientCommunicationValueChild.getChildByName("communication");
myPatientCommunicationLanguageValueChild = patientCommunicationDefinition.getChildByName("language");
}
@FunctionalInterface
public interface IValueExtractor {
@ -966,5 +983,4 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return null;
}
}

View File

@ -20,14 +20,21 @@ package ca.uhn.fhir.jpa.searchparam.extractor;
* #L%
*/
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import com.google.common.annotations.VisibleForTesting;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.Set;
@Service
@Lazy
@ -36,14 +43,33 @@ public class SearchParamExtractorService {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
@Autowired
private IInterceptorBroadcaster myInterceptorBroadcaster;
public void extractFromResource(ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource) {
theParams.myStringParams.addAll(extractSearchParamStrings(theResource));
theParams.myNumberParams.addAll(extractSearchParamNumber(theResource));
theParams.myQuantityParams.addAll(extractSearchParamQuantity(theResource));
theParams.myDateParams.addAll(extractSearchParamDates(theResource));
theParams.myUriParams.addAll(extractSearchParamUri(theResource));
theParams.myCoordsParams.addAll(extractSearchParamCoords(theResource));
public void extractFromResource(RequestDetails theRequestDetails, ResourceIndexedSearchParams theParams, ResourceTable theEntity, IBaseResource theResource) {
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamString> strings = extractSearchParamStrings(theResource);
handleWarnings(theRequestDetails, strings);
theParams.myStringParams.addAll(strings);
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamNumber> numbers = extractSearchParamNumber(theResource);
handleWarnings(theRequestDetails, numbers);
theParams.myNumberParams.addAll(numbers);
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamQuantity> quantities = extractSearchParamQuantity(theResource);
handleWarnings(theRequestDetails, quantities);
theParams.myQuantityParams.addAll(quantities);
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamDate> dates = extractSearchParamDates(theResource);
handleWarnings(theRequestDetails, dates);
theParams.myDateParams.addAll(dates);
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamUri> uris = extractSearchParamUri(theResource);
handleWarnings(theRequestDetails, uris);
theParams.myUriParams.addAll(uris);
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamCoords> coords = extractSearchParamCoords(theResource);
handleWarnings(theRequestDetails, coords);
theParams.myCoordsParams.addAll(coords);
ourLog.trace("Storing date indexes: {}", theParams.myDateParams);
@ -64,40 +90,60 @@ public class SearchParamExtractorService {
populateResourceTable(theParams.myTokenParams, theEntity);
}
void handleWarnings(RequestDetails theRequestDetails, ISearchParamExtractor.SearchParamSet<?> theSearchParamSet) {
if (theSearchParamSet.getWarnings().isEmpty()) {
return;
}
// If extraction generated any warnings, broadcast an error
for (String next : theSearchParamSet.getWarnings()) {
StorageProcessingMessage messageHolder = new StorageProcessingMessage();
messageHolder.setMessage(next);
HookParams params = new HookParams()
.add(RequestDetails.class, theRequestDetails)
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
.add(StorageProcessingMessage.class, messageHolder);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequestDetails, Pointcut.JPA_PERFTRACE_WARNING, params);
}
}
private void populateResourceTable(Collection<? extends BaseResourceIndexedSearchParam> theParams, ResourceTable theResourceTable) {
for (BaseResourceIndexedSearchParam next : theParams) {
next.setResource(theResourceTable);
}
}
private Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamCoords> extractSearchParamCoords(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamCoords(theResource);
}
private Set<ResourceIndexedSearchParamDate> extractSearchParamDates(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamDate> extractSearchParamDates(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamDates(theResource);
}
private Set<ResourceIndexedSearchParamNumber> extractSearchParamNumber(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamNumber(theResource);
}
private Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamQuantity(theResource);
}
private Set<ResourceIndexedSearchParamString> extractSearchParamStrings(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamString> extractSearchParamStrings(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamStrings(theResource);
}
private Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<BaseResourceIndexedSearchParam> extractSearchParamTokens(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamTokens(theResource);
}
private Set<ResourceIndexedSearchParamUri> extractSearchParamUri(IBaseResource theResource) {
private ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamUri> extractSearchParamUri(IBaseResource theResource) {
return mySearchParamExtractor.extractSearchParamUri(theResource);
}
@VisibleForTesting
void setInterceptorBroadcasterForUnitTest(IInterceptorBroadcaster theJpaInterceptorBroadcaster) {
myInterceptorBroadcaster = theJpaInterceptorBroadcaster;
}
}

View File

@ -46,7 +46,7 @@ public class IndexedSearchParamExtractor {
String resourceType = myContext.getResourceDefinition(theResource).getName();
entity.setResourceType(resourceType);
ResourceIndexedSearchParams resourceIndexedSearchParams = new ResourceIndexedSearchParams();
mySearchParamExtractorService.extractFromResource(resourceIndexedSearchParams, entity, theResource);
mySearchParamExtractorService.extractFromResource(theRequest, resourceIndexedSearchParams, entity, theResource);
myResourceLinkExtractor.extractResourceLinks(resourceIndexedSearchParams, entity, theResource, theResource.getMeta().getLastUpdated(), myInlineResourceLinkResolver, false, theRequest);
return resourceIndexedSearchParams;
}

View File

@ -12,10 +12,10 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
import ca.uhn.fhir.util.TestUtil;
import com.google.common.collect.Sets;
import org.hamcrest.Matchers;
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -25,7 +25,8 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.contains;
public class SearchParamExtractorDstu3Test {
@ -114,63 +115,42 @@ public class SearchParamExtractorDstu3Test {
SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), ourCtx, ourValidationSupport, searchParamRegistry);
extractor.start();
try {
{
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.STRING, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
Patient resource = new Patient();
extractor.extractSearchParamStrings(resource);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamString> outcome = extractor.extractSearchParamStrings(resource);
assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient"));
}
try {
{
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.TOKEN, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
Patient resource = new Patient();
extractor.extractSearchParamTokens(resource);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
ISearchParamExtractor.SearchParamSet<BaseResourceIndexedSearchParam> outcome = extractor.extractSearchParamTokens(resource);
assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient"));
}
try {
{
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.QUANTITY, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
Patient resource = new Patient();
extractor.extractSearchParamQuantity(resource);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamQuantity> outcome = extractor.extractSearchParamQuantity(resource);
assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient"));
}
try {
{
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.DATE, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
Patient resource = new Patient();
extractor.extractSearchParamDates(resource);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamDate> outcome = extractor.extractSearchParamDates(resource);
assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient"));
}
try {
{
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.NUMBER, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
Patient resource = new Patient();
extractor.extractSearchParamNumber(resource);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamNumber> outcome = extractor.extractSearchParamNumber(resource);
assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient"));
}
try {
{
searchParamRegistry.addSearchParam(new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.URI, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE));
Patient resource = new Patient();
extractor.extractSearchParamUri(resource);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
ISearchParamExtractor.SearchParamSet<ResourceIndexedSearchParamUri> outcome = extractor.extractSearchParamUri(resource);
assertThat(outcome.getWarnings(), Matchers.contains("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient"));
}
try {
RuntimeSearchParam sp = new RuntimeSearchParam("foo", "foo", "Patient", RestSearchParameterTypeEnum.REFERENCE, Sets.newHashSet(), Sets.newHashSet(), RuntimeSearchParam.RuntimeSearchParamStatusEnum.ACTIVE);
searchParamRegistry.addSearchParam(sp);
Patient resource = new Patient();
extractor.extractResourceLinks(resource, sp);
} catch (ConfigurationException e) {
assertEquals("Search param foo is of unexpected datatype: class org.hl7.fhir.dstu3.model.Patient", e.getMessage());
}
}

View File

@ -0,0 +1,44 @@
package ca.uhn.fhir.jpa.searchparam.extractor;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Autowired;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class SearchParamExtractorServiceTest {
private SearchParamExtractorService mySvc;
@Autowired
private IInterceptorBroadcaster myRequestInterceptorBroadcaster;
@Autowired
private IInterceptorBroadcaster myJpaInterceptorBroadcaster;
@Before
public void before() {
mySvc = new SearchParamExtractorService();
mySvc.setInterceptorBroadcasterForUnitTest(myJpaInterceptorBroadcaster);
}
@Test
public void testHandleWarnings() {
ISearchParamExtractor.SearchParamSet<Object> searchParamSet = new ISearchParamExtractor.SearchParamSet<>();
searchParamSet.addWarning("help i'm a bug");
searchParamSet.addWarning("Spiff");
mySvc.handleWarnings(new ServletRequestDetails(myRequestInterceptorBroadcaster), searchParamSet);
verify(myJpaInterceptorBroadcaster, times(2)).callHooks(eq(Pointcut.JPA_PERFTRACE_WARNING), any());
verify(myRequestInterceptorBroadcaster, times(2)).callHooks(eq(Pointcut.JPA_PERFTRACE_WARNING), any());
}
}