Get coded valuesets working once again for DSTU2 resoruces

This commit is contained in:
James Agnew 2015-08-13 17:58:31 -04:00
parent 2766af2693
commit 77f151901a
8 changed files with 5140 additions and 109 deletions

View File

@ -23,6 +23,8 @@ package ca.uhn.fhir.jpa.dao;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
@ -40,7 +42,7 @@ import ca.uhn.fhir.validation.ValidationResult;
public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDstu2<QuestionnaireResponse> {
private FhirContext myRefImplCtx = FhirContext.forDstu2Hl7Org();
@Override
protected void validateResourceForStorage(IResource theResource) {
super.validateResourceForStorage(theResource);
@ -69,19 +71,18 @@ public class FhirResourceDaoQuestionnaireResponseDstu2 extends FhirResourceDaoDs
@Override
public <T extends IBaseResource> T load(Class<T> theType, IIdType theId) throws ResourceNotFoundException {
/*
* The QuestionnaireResponse validator uses RI structures, so for now we need
* to convert between that and HAPI structures. This is a bit hackish, but
* hopefully it will go away at some point.
* The QuestionnaireResponse validator uses RI structures, so for now we need to convert between that and HAPI structures. This is a bit hackish, but hopefully it will go away at some point.
*/
if ("ValueSet".equals(theType.getSimpleName())) {
IFhirResourceDao<ValueSet> dao = getDao(ValueSet.class);
ValueSet in = dao.read(theId);
String encoded = getContext().newJsonParser().encodeResourceToString(in);
// TODO: this is temporary until structures-dstu2 catches up to structures-hl7org.dstu2
encoded = encoded.replace("\"define\"", "\"codeSystem\"");
return myRefImplCtx.newJsonParser().parseResource(theType, encoded);
} else if ("Questionnaire".equals(theType.getSimpleName())) {
IFhirResourceDao<Questionnaire> dao = getDao(Questionnaire.class);

View File

@ -51,11 +51,13 @@ import ca.uhn.fhir.model.dstu2.resource.OperationDefinition;
import ca.uhn.fhir.model.dstu2.resource.OperationDefinition.Parameter;
import ca.uhn.fhir.model.dstu2.valueset.ConditionalDeleteStatusEnum;
import ca.uhn.fhir.model.dstu2.valueset.ConformanceResourceStatusEnum;
import ca.uhn.fhir.model.dstu2.valueset.ConformanceStatementKindEnum;
import ca.uhn.fhir.model.dstu2.valueset.OperationParameterUseEnum;
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum;
import ca.uhn.fhir.model.dstu2.valueset.RestfulConformanceModeEnum;
import ca.uhn.fhir.model.dstu2.valueset.SystemRestfulInteractionEnum;
import ca.uhn.fhir.model.dstu2.valueset.TypeRestfulInteractionEnum;
import ca.uhn.fhir.model.dstu2.valueset.UnknownContentCodeEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.IdParam;
@ -162,11 +164,11 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
retVal.setPublisher(myPublisher);
retVal.setDate(DateTimeDt.withCurrentTime());
retVal.setFhirVersion("0.5.0"); // TODO: pull from model
retVal.setAcceptUnknown("extensions"); // TODO: make this configurable - this is a fairly big effort since the parser
retVal.setAcceptUnknown(UnknownContentCodeEnum.UNKNOWN_EXTENSIONS); // TODO: make this configurable - this is a fairly big effort since the parser
// needs to be modified to actually allow it
retVal.getImplementation().setDescription(myRestfulServer.getImplementationDescription());
retVal.setKind("instance");
retVal.setKind(ConformanceStatementKindEnum.INSTANCE);
retVal.getSoftware().setName(myRestfulServer.getServerName());
retVal.getSoftware().setVersion(myRestfulServer.getServerVersion());
retVal.addFormat(Constants.CT_FHIR_XML);

View File

@ -27,6 +27,8 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.client.interceptor.BearerTokenAuthInterceptor;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.Constants;
public class BundleTypeDstu2Test {
@ -74,4 +76,18 @@ public class BundleTypeDstu2Test {
assertThat(body, Matchers.containsString("<type value=\"" + BundleTypeEnum.TRANSACTION.getCode()));
}
public static void main(String[] args) {
FhirContext ctx = FhirContext.forDstu2();
IGenericClient client = ctx.newRestfulGenericClient("http://54.165.58.158:8081/FHIRServer/fhir");
client.registerInterceptor(new BearerTokenAuthInterceptor("AN3uCTC5B"));
client.registerInterceptor(new LoggingInterceptor(true));
Bundle result = client.search().forResource(Patient.class).where(Patient.NAME.matches().value("Alice")).execute();
System.out.println(result.getEntries().size());
}
}

View File

@ -35,14 +35,15 @@ import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
import ca.uhn.fhir.rest.client.exceptions.FhirClientInappropriateForServerException;
import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
public class ClientServerValidationTestDstu2 {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ClientServerValidationTestDstu2.class);
private FhirContext myCtx;
private boolean myFirstResponse;
private HttpClient myHttpClient;
private HttpResponse myHttpResponse;
private boolean myFirstResponse;
@Before
public void before() {
@ -54,6 +55,119 @@ public class ClientServerValidationTestDstu2 {
myFirstResponse = true;
}
@Test
public void testClientUsesInterceptors() throws Exception {
Conformance conf = new Conformance();
conf.setFhirVersion("0.5.0");
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
if (myFirstResponse) {
myFirstResponse = false;
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
} else {
Patient resource = new Patient();
resource.addName().addFamily().setValue("FAM");
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
}
}
});
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
assertEquals(2, capt.getAllValues().size());
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
}
@Test
public void testForceConformanceCheck() throws Exception {
Conformance conf = new Conformance();
conf.setFhirVersion("0.5.0");
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
if (myFirstResponse) {
myFirstResponse = false;
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
} else {
Patient resource = new Patient();
resource.addName().addFamily().setValue("FAM");
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
}
}
});
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
client.forceConformanceCheck();
assertEquals(1, capt.getAllValues().size());
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
assertEquals(2, capt.getAllValues().size());
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
}
@Test
public void testServerReturnsAnHttp401() throws Exception {
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 401, "Unauthorized"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_TEXT));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader("Unauthorized"), Charset.forName("UTF-8"));
}
});
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
try {
client.read().resource(Patient.class).withId("123").execute();
fail();
} catch (AuthenticationException e) {
// good
}
}
@Test
public void testServerReturnsAppropriateVersionForDstu2_040() throws Exception {
Conformance conf = new Conformance();
@ -157,94 +271,4 @@ public class ClientServerValidationTestDstu2 {
}
}
@Test
public void testClientUsesInterceptors() throws Exception {
Conformance conf = new Conformance();
conf.setFhirVersion("0.5.0");
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
if (myFirstResponse) {
myFirstResponse = false;
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
} else {
Patient resource = new Patient();
resource.addName().addFamily().setValue("FAM");
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
}
}
});
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
assertEquals(2, capt.getAllValues().size());
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
}
@Test
public void testForceConformanceCheck() throws Exception {
Conformance conf = new Conformance();
conf.setFhirVersion("0.5.0");
final String confResource = myCtx.newXmlParser().encodeResourceToString(conf);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<InputStream>() {
@Override
public InputStream answer(InvocationOnMock theInvocation) throws Throwable {
if (myFirstResponse) {
myFirstResponse = false;
return new ReaderInputStream(new StringReader(confResource), Charset.forName("UTF-8"));
} else {
Patient resource = new Patient();
resource.addName().addFamily().setValue("FAM");
return new ReaderInputStream(new StringReader(myCtx.newXmlParser().encodeResourceToString(resource)), Charset.forName("UTF-8"));
}
}
});
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
client.registerInterceptor(new BasicAuthInterceptor("USER", "PASS"));
client.forceConformanceCheck();
assertEquals(1, capt.getAllValues().size());
Patient pt = (Patient) client.read(new UriDt("http://foo/Patient/123"));
assertEquals("FAM", pt.getNameFirstRep().getFamilyAsSingleString());
assertEquals(2, capt.getAllValues().size());
Header auth = capt.getAllValues().get(0).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
auth = capt.getAllValues().get(1).getFirstHeader("Authorization");
assertNotNull(auth);
assertEquals("Basic VVNFUjpQQVNT", auth.getValue());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -228,7 +228,7 @@ public class TinderStructuresMojo extends AbstractMojo {
String dtOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/composite";
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet("dstu2", ".");
rp.setBaseResourceNames(Arrays.asList( "observation"
rp.setBaseResourceNames(Arrays.asList( "bundle"
// //, "contract"
// "valueset", "organization", "location"
// , "observation", "conformance"

View File

@ -31,6 +31,8 @@ import ca.uhn.fhir.model.dstu.resource.ValueSet.ComposeInclude;
import ca.uhn.fhir.model.dstu.resource.ValueSet.Define;
import ca.uhn.fhir.model.dstu.resource.ValueSet.DefineConcept;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.model.dstu2.resource.ValueSet.CodeSystem;
import ca.uhn.fhir.model.dstu2.resource.ValueSet.CodeSystemConcept;
import ca.uhn.fhir.model.dstu2.resource.ValueSet.ComposeIncludeConcept;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.parser.IParser;
@ -187,7 +189,7 @@ public class ValueSetGenerator {
}
private ValueSetTm parseValueSet(ca.uhn.fhir.model.dstu2.resource.ValueSet nextVs) {
myConceptCount += nextVs.getDefine().getConcept().size();
myConceptCount += nextVs.getCodeSystem().getConcept().size();
ourLog.info("Parsing ValueSetTm #{} - {} - {} concepts total", myValueSetCount++, nextVs.getName(), myConceptCount);
// output.addConcept(next.getCode().getValue(),
// next.getDisplay().getValue(), next.getDefinition());
@ -200,9 +202,9 @@ public class ValueSetGenerator {
vs.setClassName(toClassName(nextVs.getName()));
{
ca.uhn.fhir.model.dstu2.resource.ValueSet.Define define = nextVs.getDefine();
CodeSystem define = nextVs.getCodeSystem();
String system = define.getSystemElement().getValueAsString();
for (ca.uhn.fhir.model.dstu2.resource.ValueSet.DefineConcept nextConcept : define.getConcept()) {
for (CodeSystemConcept nextConcept : define.getConcept()) {
String nextCodeValue = nextConcept.getCode();
String nextCodeDisplay = StringUtils.defaultString(nextConcept.getDisplay());
String nextCodeDefinition = StringUtils.defaultString(nextConcept.getDefinition());

View File

@ -81,20 +81,20 @@ public abstract class BaseStructureParser {
myResources.add(theResource);
}
private void bindValueSets(BaseElement theResource, ValueSetGenerator theVsp) {
if (isNotBlank(theResource.getBinding())) {
String bindingClass = theVsp.getClassForValueSetIdAndMarkAsNeeded(theResource.getBinding());
private void bindValueSets(BaseElement theElement, ValueSetGenerator theVsp) {
if (isNotBlank(theElement.getBinding())) {
String bindingClass = theVsp.getClassForValueSetIdAndMarkAsNeeded(theElement.getBinding());
if (bindingClass != null) {
ourLog.debug("Adding binding ValueSet class: {}", bindingClass);
theResource.setBindingClass(bindingClass);
theElement.setBindingClass(bindingClass);
addImport(bindingClass);
myLocallyDefinedClassNames.put(bindingClass, "valueset");
} else {
ourLog.debug("No binding found for: {}", theResource.getBinding());
ourLog.debug("No binding found for: {}", theElement.getBinding());
ourLog.debug(" * Valid: {}", new TreeSet<String>(theVsp.getValueSets().keySet()));
}
}
for (BaseElement next : theResource.getChildren()) {
for (BaseElement next : theElement.getChildren()) {
bindValueSets(next, theVsp);
}
}