Skip to content

Commit

Permalink
Allow valueset operations to work against type in JPA
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesagnew committed Oct 6, 2015
1 parent a337528 commit 9fef4f6
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;

import ca.uhn.fhir.context.BaseRuntimeChildDatatypeDefinition;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.IRuntimeDatatypeDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IQueryParameterType;
Expand Down Expand Up @@ -1496,8 +1498,16 @@ private void addParam(String theName, IBase theValue) {
parameterElem.getChildByName("name").getMutator().setValue(parameter, name);

if (theValue instanceof IBaseDatatype) {
String childElementName = "value" + StringUtils.capitalize(myContext.getElementDefinition(theValue.getClass()).getName());
parameterElem.getChildByName(childElementName).getMutator().setValue(parameter, theValue);
BaseRuntimeElementDefinition<?> datatypeDef = myContext.getElementDefinition(theValue.getClass());
if (datatypeDef instanceof IRuntimeDatatypeDefinition) {
Class<? extends IBaseDatatype> profileOf = ((IRuntimeDatatypeDefinition) datatypeDef).getProfileOf();
if (profileOf != null) {
datatypeDef = myContext.getElementDefinition(profileOf);
}
}
String childElementName = "value" + StringUtils.capitalize(datatypeDef.getName());
BaseRuntimeChildDefinition childByName = parameterElem.getChildByName(childElementName);
childByName.getMutator().setValue(parameter, theValue);
} else if (theValue instanceof IBaseResource) {
parameterElem.getChildByName("resource").getMutator().setValue(parameter, theValue);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -312,7 +312,7 @@ public static BaseHttpClientInvocation createOperationInvocation(FhirContext the
FhirTerser t = theContext.newTerser();
List<Object> parameters = t.getValues(theInput, "Parameters.parameter");

Map<String, List<String>> params = new HashMap<String, List<String>>();
Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
for (Object nextParameter : parameters) {
IPrimitiveType<?> nextNameDt = (IPrimitiveType<?>) t.getSingleValueOrNull((IBase) nextParameter, "name");
if (nextNameDt == null || nextNameDt.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDst

//@formatter:off
@Operation(name = "$expand", idempotent = true)
public ValueSet expant(
public ValueSet expand(
HttpServletRequest theServletRequest,
@IdParam(optional=true) IdDt theId,
@OperationParam(name="valueSet", min=0, max=1) ValueSet theValueSet,
Expand Down Expand Up @@ -110,13 +110,13 @@ private String toFilterString(StringDt theFilter) {
})
public Parameters validateCode(
HttpServletRequest theServletRequest,
@IdParam IdDt theId,
@OperationParam(name="identifier") UriDt theValueSetIdentifier,
@OperationParam(name="code") CodeDt theCode,
@OperationParam(name="system") UriDt theSystem,
@OperationParam(name="display") StringDt theDisplay,
@OperationParam(name="coding") CodingDt theCoding,
@OperationParam(name="codeableConcept") CodeableConceptDt theCodeableConcept
@IdParam(optional=true) IdDt theId,
@OperationParam(name="identifier", min=0, max=1) UriDt theValueSetIdentifier,
@OperationParam(name="code", min=0, max=1) CodeDt theCode,
@OperationParam(name="system", min=0, max=1) UriDt theSystem,
@OperationParam(name="display", min=0, max=1) StringDt theDisplay,
@OperationParam(name="coding", min=0, max=1) CodingDt theCoding,
@OperationParam(name="codeableConcept", min=0, max=1) CodeableConceptDt theCodeableConcept
) {
//@formatter:on

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
Expand All @@ -33,6 +35,26 @@ public void before02() throws IOException {
myExtensionalVsId = myValueSetDao.create(upload).getId().toUnqualifiedVersionless();
}

@Test
public void testValidateCodeOperationByCodeAndSystemBad() {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onInstance(myExtensionalVsId)
.named("validate-code")
.withParameter(Parameters.class, "code", new CodeDt("8495-4"))
.andParameter("system", new UriDt("http://loinc.org"))
.execute();
//@formatter:on

String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);

assertEquals(new BooleanDt(true), respParam.getParameter().get(0).getValue());
}



@Test
public void testExpandById() throws IOException {
//@formatter:off
Expand Down Expand Up @@ -115,7 +137,7 @@ public void testExpandByIdentifier() {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onInstance(myExtensionalVsId)
.onType(ValueSet.class)
.named("expand")
.withParameter(Parameters.class, "identifier", new UriDt("http://www.healthintersections.com.au/fhir/ValueSet/extensional-case-2"))
.andParameter("filter", new StringDt("11378"))
Expand All @@ -141,7 +163,7 @@ public void testExpandByValueSet() throws IOException {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onInstance(myExtensionalVsId)
.onType(ValueSet.class)
.named("expand")
.withParameter(Parameters.class, "valueSet", toExpand)
.andParameter("filter", new StringDt("11378"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
Expand Down Expand Up @@ -52,6 +53,7 @@
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
Expand All @@ -70,6 +72,8 @@

public class GenericClientDstu2Test {
private static FhirContext ourCtx;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericClientDstu2Test.class);

private HttpClient myHttpClient;

private HttpResponse myHttpResponse;
Expand Down Expand Up @@ -1089,6 +1093,60 @@ public boolean isEmpty() {
//@formatter:on
}

@Test
public void testOperationWithProfiledDatatypeParam() throws IOException, Exception {
IParser p = ourCtx.newXmlParser();

Parameters outParams = new Parameters();
outParams.addParameter().setValue(new StringDt("STRINGVALOUT1"));
outParams.addParameter().setValue(new StringDt("STRINGVALOUT2"));
final String respString = p.encodeResourceToString(outParams);

ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
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<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});

IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");

int idx = 0;

//@formatter:off
client
.operation()
.onInstance(new IdDt("http://foo/Patient/1"))
.named("validate-code")
.withParameter(Parameters.class, "code", new CodeDt("8495-4"))
.andParameter("system", new UriDt("http://loinc.org"))
.useHttpGet()
.execute();
//@formatter:off

assertEquals("http://example.com/fhir/Patient/1/$validate-code?code=8495-4&system=http%3A%2F%2Floinc.org", capt.getAllValues().get(idx).getURI().toASCIIString());

//@formatter:off
idx++;
client
.operation()
.onInstance(new IdDt("http://foo/Patient/1"))
.named("validate-code")
.withParameter(Parameters.class, "code", new CodeDt("8495-4"))
.andParameter("system", new UriDt("http://loinc.org"))
.execute();
//@formatter:off

assertEquals("http://example.com/fhir/Patient/1/$validate-code", capt.getAllValues().get(idx).getURI().toASCIIString());
ourLog.info(extractBody(capt, idx));
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"code\"/><valueString value=\"8495-4\"/></parameter><parameter><name value=\"system\"/><valueUri value=\"http://loinc.org\"/></parameter></Parameters>",extractBody(capt, idx));

}

@Test
public void testOperationWithListOfParameterResponse() throws Exception {
IParser p = ourCtx.newXmlParser();
Expand Down Expand Up @@ -1556,6 +1614,85 @@ public void testSearchByString() throws Exception {

}

@Test
public void testSearchByUrl() throws Exception {

final String msg = getPatientFeedWithOneResult();

ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
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 {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}
});

IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;

//@formatter:off
ca.uhn.fhir.model.dstu2.resource.Bundle response = client.search()
.byUrl("http://foo?name=http://foo|bar")
.encodedJson()
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://foo?name=http%3A//foo%7Cbar&_format=json", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("Patient?name=http://foo|bar")
.encodedJson()
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=http%3A//foo%7Cbar&_format=json", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("/Patient?name=http://foo|bar")
.encodedJson()
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=http%3A//foo%7Cbar&_format=json", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("Patient")
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("Patient?")
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

try {
client.search().byUrl("foo/bar?test=1");
} catch (IllegalArgumentException e) {
assertEquals("Search URL must be either a complete URL starting with http: or https:, or a relative FHIR URL in the form [ResourceType]?[Params]", e.getMessage());
}
}

/**
* See #191
*/
Expand Down Expand Up @@ -1692,84 +1829,6 @@ public void testSearchWithReverseInclude() throws Exception {

}

@Test
public void testSearchByUrl() throws Exception {

final String msg = getPatientFeedWithOneResult();

ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
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 {
return new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"));
}});

IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
int idx = 0;

//@formatter:off
ca.uhn.fhir.model.dstu2.resource.Bundle response = client.search()
.byUrl("http://foo?name=http://foo|bar")
.encodedJson()
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://foo?name=http%3A//foo%7Cbar&_format=json", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("Patient?name=http://foo|bar")
.encodedJson()
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=http%3A//foo%7Cbar&_format=json", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("/Patient?name=http://foo|bar")
.encodedJson()
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?name=http%3A//foo%7Cbar&_format=json", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("Patient")
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

//@formatter:off
response = client.search()
.byUrl("Patient?")
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
.execute();
//@formatter:on
assertEquals("http://example.com/fhir/Patient?", capt.getAllValues().get(idx).getURI().toString());
assertNotNull(response);
idx++;

try {
client.search().byUrl("foo/bar?test=1");
} catch (IllegalArgumentException e) {
assertEquals("Search URL must be either a complete URL starting with http: or https:, or a relative FHIR URL in the form [ResourceType]?[Params]", e.getMessage());
}
}

@Test
public void testSearchWithSummaryParam() throws Exception {
String msg = "{\"resourceType\":\"Bundle\",\"id\":null,\"base\":\"http://localhost:57931/fhir/contextDev\",\"total\":1,\"link\":[{\"relation\":\"self\",\"url\":\"http://localhost:57931/fhir/contextDev/Patient?identifier=urn%3AMultiFhirVersionTest%7CtestSubmitPatient01&_format=json\"}],\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"1\",\"meta\":{\"versionId\":\"1\",\"lastUpdated\":\"2014-12-20T18:41:29.706-05:00\"},\"identifier\":[{\"system\":\"urn:MultiFhirVersionTest\",\"value\":\"testSubmitPatient01\"}]}}]}";
Expand Down

0 comments on commit 9fef4f6

Please sign in to comment.