Work on GraphQL updates

This commit is contained in:
James Agnew 2019-09-06 14:56:17 -04:00
parent 785d40a777
commit 722c7a8211
18 changed files with 102 additions and 23 deletions

View File

@ -182,4 +182,13 @@ public class TestUtil {
return defaultString(theString).replace("\r", ""); return defaultString(theString).replace("\r", "");
} }
/**
* <b>THIS IS FOR UNIT TESTS ONLY - DO NOT CALL THIS METHOD FROM USER CODE</b>
* <p>
* Strip \r chars from a string to account for line ending platform differences
*/
public static String stripWhitespace(String theString) {
return stripReturns(theString).replace(" ", "");
}
} }

View File

@ -52,7 +52,7 @@ public class TermValueSetConceptDesignation implements Serializable {
@JoinColumn(name = "VALUESET_CONCEPT_PID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TRM_VALUESET_CONCEPT_PID")) @JoinColumn(name = "VALUESET_CONCEPT_PID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TRM_VALUESET_CONCEPT_PID"))
private TermValueSetConcept myConcept; private TermValueSetConcept myConcept;
@ManyToOne() @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "VALUESET_PID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TRM_VSCD_VS_PID")) @JoinColumn(name = "VALUESET_PID", referencedColumnName = "PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TRM_VSCD_VS_PID"))
private TermValueSet myValueSet; private TermValueSet myValueSet;

View File

@ -44,9 +44,11 @@ import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
public class GraphQLR4ProviderTest { public class JpaGraphQLR4ProviderTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GraphQLR4ProviderTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaGraphQLR4ProviderTest.class);
public static final String DATA_PREFIX = "{\"data\": ";
public static final String DATA_SUFFIX = "}";
private static CloseableHttpClient ourClient; private static CloseableHttpClient ourClient;
private static FhirContext ourCtx = FhirContext.forR4(); private static FhirContext ourCtx = FhirContext.forR4();
private static int ourPort; private static int ourPort;
@ -67,14 +69,14 @@ public class GraphQLR4ProviderTest {
ourLog.info(responseContent); ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + "{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"family\":\"FAMILY\",\n" + " \"family\":\"FAMILY\",\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" + " \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" +
" },{\n" + " },{\n" +
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" + " \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(responseContent)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(responseContent));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json")); assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
} finally { } finally {
@ -93,12 +95,12 @@ public class GraphQLR4ProviderTest {
ourLog.info(responseContent); ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + "{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"],\n" + " \"given\":[\"GIVEN1\",\"GIVEN2\"],\n" +
" \"family\":\"FAMILY\"\n" + " \"family\":\"FAMILY\"\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(responseContent)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(responseContent));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json")); assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
} finally { } finally {
@ -117,7 +119,7 @@ public class GraphQLR4ProviderTest {
ourLog.info(responseContent); ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + "{\n" +
" \"Patient\":{\n" + " \"Patient\":{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"],\n" + " \"given\":[\"GIVEN1\",\"GIVEN2\"],\n" +
@ -126,7 +128,7 @@ public class GraphQLR4ProviderTest {
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" + " \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
" }]\n" + " }]\n" +
" }\n" + " }\n" +
"}"), TestUtil.stripReturns(responseContent)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(responseContent));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json")); assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
} finally { } finally {
@ -145,7 +147,7 @@ public class GraphQLR4ProviderTest {
ourLog.info(responseContent); ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + "{\n" +
" \"PatientList\":[{\n" + " \"PatientList\":[{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"family\":\"pet\",\n" + " \"family\":\"pet\",\n" +
@ -158,7 +160,7 @@ public class GraphQLR4ProviderTest {
" \"given\":[\"GivenOnlyB1\",\"GivenOnlyB2\"]\n" + " \"given\":[\"GivenOnlyB1\",\"GivenOnlyB2\"]\n" +
" }]\n" + " }]\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(responseContent)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(responseContent));
assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json")); assertThat(status.getFirstHeader(Constants.HEADER_CONTENT_TYPE).getValue(), startsWith("application/json"));
} finally { } finally {

View File

@ -5,8 +5,8 @@ import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.dstu3.model.Patient; import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.Test; import org.junit.Test;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -14,6 +14,8 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static ca.uhn.fhir.jpa.provider.JpaGraphQLR4ProviderTest.DATA_PREFIX;
import static ca.uhn.fhir.jpa.provider.JpaGraphQLR4ProviderTest.DATA_SUFFIX;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public class GraphQLProviderDstu3Test extends BaseResourceProviderDstu3Test { public class GraphQLProviderDstu3Test extends BaseResourceProviderDstu3Test {
@ -30,14 +32,14 @@ public class GraphQLProviderDstu3Test extends BaseResourceProviderDstu3Test {
try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) { try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp); ourLog.info(resp);
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX +"{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"family\":\"FAM\",\n" + " \"family\":\"FAM\",\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" + " \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" +
" },{\n" + " },{\n" +
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" + " \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(resp)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(resp));
} }
} }
@ -52,7 +54,7 @@ public class GraphQLProviderDstu3Test extends BaseResourceProviderDstu3Test {
try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) { try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp); ourLog.info(resp);
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX +"{\n" +
" \"PatientList\":[{\n" + " \"PatientList\":[{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"family\":\"FAM\",\n" + " \"family\":\"FAM\",\n" +
@ -65,7 +67,7 @@ public class GraphQLProviderDstu3Test extends BaseResourceProviderDstu3Test {
" \"given\":[\"GivenOnlyB1\",\"GivenOnlyB2\"]\n" + " \"given\":[\"GivenOnlyB1\",\"GivenOnlyB2\"]\n" +
" }]\n" + " }]\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(resp)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(resp));
} }
} }

View File

@ -14,6 +14,8 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static ca.uhn.fhir.jpa.provider.JpaGraphQLR4ProviderTest.DATA_PREFIX;
import static ca.uhn.fhir.jpa.provider.JpaGraphQLR4ProviderTest.DATA_SUFFIX;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public class GraphQLProviderR4Test extends BaseResourceProviderR4Test { public class GraphQLProviderR4Test extends BaseResourceProviderR4Test {
@ -30,14 +32,14 @@ public class GraphQLProviderR4Test extends BaseResourceProviderR4Test {
try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) { try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp); ourLog.info(resp);
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + "{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"family\":\"FAM\",\n" + " \"family\":\"FAM\",\n" +
" \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" + " \"given\":[\"GIVEN1\",\"GIVEN2\"]\n" +
" },{\n" + " },{\n" +
" \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" + " \"given\":[\"GivenOnly1\",\"GivenOnly2\"]\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(resp)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(resp));
} }
} }
@ -52,7 +54,7 @@ public class GraphQLProviderR4Test extends BaseResourceProviderR4Test {
try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) { try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) {
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
ourLog.info(resp); ourLog.info(resp);
assertEquals(TestUtil.stripReturns("{\n" + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + "{\n" +
" \"PatientList\":[{\n" + " \"PatientList\":[{\n" +
" \"name\":[{\n" + " \"name\":[{\n" +
" \"family\":\"FAM\",\n" + " \"family\":\"FAM\",\n" +
@ -65,7 +67,7 @@ public class GraphQLProviderR4Test extends BaseResourceProviderR4Test {
" \"given\":[\"GivenOnlyB1\",\"GivenOnlyB2\"]\n" + " \"given\":[\"GivenOnlyB1\",\"GivenOnlyB2\"]\n" +
" }]\n" + " }]\n" +
" }]\n" + " }]\n" +
"}"), TestUtil.stripReturns(resp)); "}" + DATA_SUFFIX), TestUtil.stripWhitespace(resp));
} }
} }

View File

@ -877,6 +877,11 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException { public boolean conformsToProfile(Object appContext, Base item, String url) throws FHIRException {
return false; return false;
} }
@Override
public ValueSet resolveValueSet(Object appContext, String url) {
return null;
}
} }
private static <T extends Enum<?>> String extractSystem(Enumeration<T> theBoundCode) { private static <T extends Enum<?>> String extractSystem(Enumeration<T> theBoundCode) {

View File

@ -336,6 +336,18 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
expandedValueSet = new ValueSetExpansionOutcome(expansion); expandedValueSet = new ValueSetExpansionOutcome(expansion);
} }
/*
* We'll just accept all mimetypes, since this is pretty much impossible to exhaustively
* validate.
*/
if (theVs != null && "http://hl7.org/fhir/ValueSet/mimetypes".equals(theVs.getUrl())) {
ConceptDefinitionComponent definition = new ConceptDefinitionComponent();
definition.setCode(wantCode);
definition.setDisplay(wantCode);
ValidationResult retVal = new ValidationResult(definition);
return retVal;
}
if (expandedValueSet == null) { if (expandedValueSet == null) {
expandedValueSet = expand(theVs, null); expandedValueSet = expand(theVs, null);
} }

View File

@ -389,6 +389,11 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
@Override @Override
public List<String> getTypeNames() { public List<String> getTypeNames() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -66,7 +66,8 @@ public class GraphQLEngineTest {
engine.setGraphQL(Parser.parse("{valueQuantity{value,unit}}")); engine.setGraphQL(Parser.parse("{valueQuantity{value,unit}}"));
engine.execute(); engine.execute();
ObjectValue output = engine.getOutput(); GraphQLResponse output = engine.getOutput();
output.setWriteWrapper(false);
StringBuilder outputBuilder = new StringBuilder(); StringBuilder outputBuilder = new StringBuilder();
output.write(outputBuilder, 0, "\n"); output.write(outputBuilder, 0, "\n");
@ -100,7 +101,8 @@ public class GraphQLEngineTest {
engine.setServices(createStorageServices()); engine.setServices(createStorageServices());
engine.execute(); engine.execute();
ObjectValue output = engine.getOutput(); GraphQLResponse output = engine.getOutput();
output.setWriteWrapper(false);
StringBuilder outputBuilder = new StringBuilder(); StringBuilder outputBuilder = new StringBuilder();
output.write(outputBuilder, 0, "\n"); output.write(outputBuilder, 0, "\n");

View File

@ -438,4 +438,9 @@ public final class HapiWorkerContext implements IWorkerContext, ValueSetExpander
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
} }

View File

@ -339,6 +339,11 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
@Override @Override
public void generateSnapshot(org.hl7.fhir.r5.model.StructureDefinition p) throws FHIRException { public void generateSnapshot(org.hl7.fhir.r5.model.StructureDefinition p) throws FHIRException {
// nothing yet // nothing yet

View File

@ -522,6 +522,11 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
@Override @Override
public Parameters getExpansionParameters() { public Parameters getExpansionParameters() {
return myExpansionProfile; return myExpansionProfile;

View File

@ -669,6 +669,11 @@ public class FhirInstanceValidator extends org.hl7.fhir.r4.hapi.validation.BaseV
return convertValidationResult(result); return convertValidationResult(result);
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
} }
private static class ResourceKey { private static class ResourceKey {

View File

@ -145,6 +145,12 @@ public class SnapshotGeneratingValidationSupport implements IValidationSupport {
public boolean prependLinks() { public boolean prependLinks() {
return false; return false;
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
} }
} }

View File

@ -282,6 +282,11 @@ public class FhirInstanceValidator extends org.hl7.fhir.r5.hapi.validation.BaseV
// nothing yet // nothing yet
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
@Override @Override
public org.hl7.fhir.r5.model.Parameters getExpansionParameters() { public org.hl7.fhir.r5.model.Parameters getExpansionParameters() {
return myExpansionProfile; return myExpansionProfile;

View File

@ -131,6 +131,11 @@ public class SnapshotGeneratingValidationSupport implements IValidationSupport {
return null; return null;
} }
@Override
public String getLinkForUrl(String corePath, String url) {
throw new UnsupportedOperationException();
}
@Override @Override
public BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException { public BindingResolution resolveBinding(StructureDefinition def, String url, String path) throws FHIRException {
return null; return null;

View File

@ -562,7 +562,7 @@
<properties> <properties>
<fhir_core_version>4.0.2-SNAPSHOT</fhir_core_version> <fhir_core_version>4.0.8-SNAPSHOT</fhir_core_version>
<ucum_version>1.0.2</ucum_version> <ucum_version>1.0.2</ucum_version>
<!-- configure timestamp in MANIFEST.MF for maven-war-provider --> <!-- configure timestamp in MANIFEST.MF for maven-war-provider -->

View File

@ -113,6 +113,10 @@
the RequestValidatingInterceptor, but not including any HAPI FHIR security interceptors) the RequestValidatingInterceptor, but not including any HAPI FHIR security interceptors)
could be bypassed if a Content Type was not included. could be bypassed if a Content Type was not included.
</action> </action>
<action type="fix">
The GraphQL provider did not wrap the respone in a "data" element as described in the FHIR
specification. This has been corrected.
</action>
</release> </release>
<release version="4.0.1" date="2019-09-03" description="Igloo (Point Release)"> <release version="4.0.1" date="2019-09-03" description="Igloo (Point Release)">
<action type="fix"> <action type="fix">