Compare commits
7 Commits
b223410940
...
cfdcac44c7
Author | SHA1 | Date |
---|---|---|
Mangala Ekanayake | cfdcac44c7 | |
mangala.ekanayake | a43d12e042 | |
mangala.ekanayake | 0c656f072a | |
mangala.ekanayake | 7d4a243c5e | |
mangala.ekanayake | 883281afee | |
Mangala Ekanayake | 1d0b18d989 | |
Mangala Ekanayake | 674f4637a9 |
|
@ -273,7 +273,13 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
|||
}
|
||||
SearchParameterMap params = new SearchParameterMap();
|
||||
params.setLoadSynchronousUpTo(1);
|
||||
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
|
||||
int versionSeparator = theUri.lastIndexOf('|');
|
||||
if (versionSeparator != -1) {
|
||||
params.add(StructureDefinition.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
|
||||
params.add(StructureDefinition.SP_URL, new UriParam(theUri.substring(0, versionSeparator)));
|
||||
} else {
|
||||
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
|
||||
}
|
||||
search = myDaoRegistry.getResourceDao("StructureDefinition").search(params);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
|
@ -25,15 +24,23 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.param.UriParam;
|
||||
import ca.uhn.fhir.sl.cache.Cache;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.CodeSystem;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
@ -41,13 +48,18 @@ import org.springframework.test.util.ReflectionTestUtils;
|
|||
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.hl7.fhir.common.hapi.validation.support.ValidationConstants.LOINC_LOW;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class JpaPersistedResourceValidationSupportTest {
|
||||
|
@ -115,5 +127,68 @@ class JpaPersistedResourceValidationSupportTest {
|
|||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FetchStructureDefinitionTests {
|
||||
|
||||
@Mock
|
||||
private DaoRegistry myDaoRegistry;
|
||||
|
||||
@InjectMocks
|
||||
private final JpaPersistedResourceValidationSupport testClass = new JpaPersistedResourceValidationSupport(theFhirContext);
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<SearchParameterMap> searchParameterMapCaptor;
|
||||
@Test
|
||||
@DisplayName("fetch StructureDefinition by version less url")
|
||||
void fetchStructureDefinitionForUrl() {
|
||||
final String profileUrl = "http://example.com/fhir/StructureDefinition/exampleProfile";
|
||||
IFhirResourceDao mockDao = mock(IFhirResourceDao.class);
|
||||
when(mockDao.search(any())).thenReturn(mock(IBundleProvider.class));
|
||||
when(myDaoRegistry.getResourceDao(anyString())).thenReturn(mockDao);
|
||||
|
||||
testClass.fetchResource(StructureDefinition.class, profileUrl);
|
||||
|
||||
verify(mockDao).search(searchParameterMapCaptor.capture());
|
||||
SearchParameterMap searchParams = searchParameterMapCaptor.getValue();
|
||||
String uriParam = searchParams.get(StructureDefinition.SP_URL)
|
||||
.get(0)
|
||||
.stream()
|
||||
.map(UriParam.class::cast)
|
||||
.map(UriParam::getValue)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertThat(uriParam).isEqualTo(profileUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("fetch StructureDefinition by versioned url")
|
||||
void fetchStructureDefinitionForVersionedUrl() {
|
||||
final String profileUrl = "http://example.com/fhir/StructureDefinition/exampleProfile|1.1.0";
|
||||
IFhirResourceDao mockDao = mock(IFhirResourceDao.class);
|
||||
when(mockDao.search(any())).thenReturn(mock(IBundleProvider.class));
|
||||
when(myDaoRegistry.getResourceDao(anyString())).thenReturn(mockDao);
|
||||
|
||||
testClass.fetchResource(StructureDefinition.class, profileUrl);
|
||||
|
||||
verify(mockDao).search(searchParameterMapCaptor.capture());
|
||||
SearchParameterMap searchParams = searchParameterMapCaptor.getValue();
|
||||
String uriParam = searchParams.get(StructureDefinition.SP_URL)
|
||||
.get(0)
|
||||
.stream()
|
||||
.map(UriParam.class::cast)
|
||||
.map(UriParam::getValue)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertThat(uriParam).isEqualTo("http://example.com/fhir/StructureDefinition/exampleProfile");
|
||||
|
||||
String versionParam = searchParams.get(StructureDefinition.SP_VERSION)
|
||||
.get(0)
|
||||
.stream()
|
||||
.map(TokenParam.class::cast)
|
||||
.map(TokenParam::getValue)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertThat(versionParam).isEqualTo("1.1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public class ValidateWithRemoteTerminologyTest extends BaseResourceProviderR4Tes
|
|||
final String classSystem = "http://terminology.hl7.org/CodeSystem/v3-ActCode";
|
||||
final String identifierTypeSystem = "http://terminology.hl7.org/CodeSystem/v2-0203";
|
||||
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/encounter-status", "http://hl7.org/fhir/encounter-status", statusCode, "validation/encounter/validateCode-ValueSet-encounter-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/encounter-status", "4.0.1", "http://hl7.org/fhir/encounter-status", statusCode, "validation/encounter/validateCode-ValueSet-encounter-status.json");
|
||||
setupValueSetValidateCode("http://terminology.hl7.org/ValueSet/v3-ActEncounterCode", "http://terminology.hl7.org/CodeSystem/v3-ActCode", classCode, "validation/encounter/validateCode-ValueSet-v3-ActEncounterCode.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/identifier-type", "http://hl7.org/fhir/identifier-type", identifierTypeCode, "validation/encounter/validateCode-ValueSet-identifier-type.json");
|
||||
|
||||
|
@ -138,7 +138,7 @@ public class ValidateWithRemoteTerminologyTest extends BaseResourceProviderR4Tes
|
|||
final String loincSystem = "http://loinc.org";
|
||||
final String system = "http://fhir.infoway-inforoute.ca/io/psca/CodeSystem/ICD9CM";
|
||||
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/observation-status", statusSystem, statusCode, "validation/observation/validateCode-ValueSet-observation-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/observation-status", "4.0.1", statusSystem, statusCode, "validation/observation/validateCode-ValueSet-observation-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/observation-codes", loincSystem, statusCode, "validation/observation/validateCode-ValueSet-codes.json");
|
||||
|
||||
setupCodeSystemValidateCode(statusSystem, statusCode, "validation/observation/validateCode-CodeSystem-observation-status.json");
|
||||
|
@ -171,7 +171,7 @@ public class ValidateWithRemoteTerminologyTest extends BaseResourceProviderR4Tes
|
|||
final String statusSystem = "http://hl7.org/fhir/event-status";
|
||||
final String snomedSystem = "http://snomed.info/sct";
|
||||
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/event-status", statusSystem, statusCode, "validation/procedure/validateCode-ValueSet-event-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/event-status", "4.0.1", statusSystem, statusCode, "validation/procedure/validateCode-ValueSet-event-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/procedure-code", snomedSystem, procedureCode1, "validation/procedure/validateCode-ValueSet-procedure-code-valid.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/procedure-code", snomedSystem, procedureCode2, "validation/procedure/validateCode-ValueSet-procedure-code-invalid.json");
|
||||
|
||||
|
@ -213,7 +213,7 @@ public class ValidateWithRemoteTerminologyTest extends BaseResourceProviderR4Tes
|
|||
final String snomedSystem = "http://snomed.info/sct";
|
||||
final String absentUnknownSystem = "http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips";
|
||||
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/event-status", statusSystem, statusCode, "validation/procedure/validateCode-ValueSet-event-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/event-status", "4.0.1", statusSystem, statusCode, "validation/procedure/validateCode-ValueSet-event-status.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/ValueSet/procedure-code", snomedSystem, procedureCode, "validation/procedure/validateCode-ValueSet-procedure-code-invalid-slice.json");
|
||||
setupValueSetValidateCode("http://hl7.org/fhir/uv/ips/ValueSet/absent-or-unknown-procedures-uv-ips", absentUnknownSystem, procedureCode, "validation/procedure/validateCode-ValueSet-absent-or-unknown-procedure.json");
|
||||
|
||||
|
@ -245,6 +245,15 @@ public class ValidateWithRemoteTerminologyTest extends BaseResourceProviderR4Tes
|
|||
// which also attempts a validateCode against the CodeSystem after the validateCode against the ValueSet
|
||||
}
|
||||
|
||||
private void setupValueSetValidateCode(String theUrl, String theVersion, String theSystem, String theCode, String theTerminologyResponseFile) {
|
||||
ValueSet valueSet = myValueSetProvider.addTerminologyResource(theUrl, theVersion);
|
||||
myValueSetProvider.addTerminologyResource(theSystem, theVersion);
|
||||
myValueSetProvider.addTerminologyResponse(OPERATION_VALIDATE_CODE, valueSet.getUrl(), theCode, ourCtx, theTerminologyResponseFile);
|
||||
|
||||
valueSet.getCompose().addInclude().setSystem(theSystem);
|
||||
}
|
||||
|
||||
|
||||
private void setupCodeSystemValidateCode(String theUrl, String theCode, String theTerminologyResponseFile) {
|
||||
CodeSystem codeSystem = myCodeSystemProvider.addTerminologyResource(theUrl);
|
||||
myCodeSystemProvider.addTerminologyResponse(OPERATION_VALIDATE_CODE, codeSystem.getUrl(), theCode, ourCtx, theTerminologyResponseFile);
|
||||
|
|
|
@ -84,9 +84,14 @@ public interface IValidationProviders {
|
|||
protected void addTerminologyResource(String theUrl, T theResource) {
|
||||
myTerminologyResourceMap.put(theUrl, theResource);
|
||||
}
|
||||
protected void addVersionedTerminologyResource(String theUrl, String theVersion, T theResource) {
|
||||
myTerminologyResourceMap.put(theUrl + "|" + theVersion, theResource);
|
||||
}
|
||||
|
||||
public abstract T addTerminologyResource(String theUrl);
|
||||
|
||||
public abstract T addTerminologyResource(String theUrl, String theVersion);
|
||||
|
||||
protected IBaseParameters getTerminologyResponse(String theOperation, String theUrl, String theCode) throws Exception {
|
||||
String inputKey = getInputKey(theOperation, theUrl, theCode);
|
||||
if (myExceptionMap.containsKey(inputKey)) {
|
||||
|
|
|
@ -95,6 +95,11 @@ public interface IValidationProvidersDstu3 {
|
|||
addTerminologyResource(theUrl, codeSystem);
|
||||
return codeSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeSystem addTerminologyResource(String theUrl, String theVersion) {
|
||||
return addTerminologyResource(theUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -133,5 +138,10 @@ public interface IValidationProvidersDstu3 {
|
|||
addTerminologyResource(theUrl, valueSet);
|
||||
return valueSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet addTerminologyResource(String theUrl, String theVersion) {
|
||||
return addTerminologyResource(theUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,14 @@ public interface IValidationProvidersR4 {
|
|||
addTerminologyResource(theUrl, codeSystem);
|
||||
return codeSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeSystem addTerminologyResource(String theUrl, String theVersion) {
|
||||
CodeSystem codeSystem = addTerminologyResource(theUrl);
|
||||
codeSystem.setVersion(theVersion);
|
||||
addVersionedTerminologyResource(theUrl, theVersion, codeSystem);
|
||||
return codeSystem;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -130,6 +138,7 @@ public interface IValidationProvidersR4 {
|
|||
Class<Parameters> getParameterType() {
|
||||
return Parameters.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet addTerminologyResource(String theUrl) {
|
||||
ValueSet valueSet = new ValueSet();
|
||||
|
@ -138,5 +147,12 @@ public interface IValidationProvidersR4 {
|
|||
addTerminologyResource(theUrl, valueSet);
|
||||
return valueSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet addTerminologyResource(String theUrl, String theVersion) {
|
||||
ValueSet valueSet = addTerminologyResource(theUrl);
|
||||
addVersionedTerminologyResource(theUrl, theVersion, valueSet);
|
||||
return valueSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import ca.uhn.fhir.system.HapiSystemProperties;
|
|||
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import jakarta.annotation.Nullable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
@ -466,18 +467,11 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo
|
|||
return null;
|
||||
}
|
||||
|
||||
String uri = theUri;
|
||||
// handle profile version, if present
|
||||
if (theUri.contains("|")) {
|
||||
String[] parts = theUri.split("\\|");
|
||||
if (parts.length == 2) {
|
||||
uri = parts[0];
|
||||
} else {
|
||||
ourLog.warn("Unrecognized profile uri: {}", theUri);
|
||||
}
|
||||
if (StringUtils.countMatches(theUri, "|") > 1) {
|
||||
ourLog.warn("Unrecognized profile uri: {}", theUri);
|
||||
}
|
||||
|
||||
ResourceKey key = new ResourceKey(class_.getSimpleName(), uri);
|
||||
ResourceKey key = new ResourceKey(class_.getSimpleName(), theUri);
|
||||
@SuppressWarnings("unchecked")
|
||||
T retVal = (T) myFetchResourceCache.get(key);
|
||||
|
||||
|
|
Loading…
Reference in New Issue