Cleanup tests for java config in JPA

This commit is contained in:
jamesagnew 2015-10-19 20:19:40 -04:00
parent 9c0f6f993d
commit 938a251ae9
22 changed files with 2881 additions and 341 deletions

View File

@ -81,14 +81,24 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
@Override @Override
public ValueSet expand(IIdType theId, String theFilter) { public ValueSet expand(IIdType theId, String theFilter) {
ValueSet source = loadValueSetForExpansion(theId);
return expand(source, theFilter);
}
private ValueSet loadValueSetForExpansion(IIdType theId) {
if (theId.getValue().startsWith("http://hl7.org/fhir/")) {
org.hl7.fhir.instance.model.ValueSet valueSet = myValidationSupport.fetchResource(myRiCtx, org.hl7.fhir.instance.model.ValueSet.class, theId.getValue());
if (valueSet != null) {
return getContext().newJsonParser().parseResource(ValueSet.class, myRiCtx.newJsonParser().encodeResourceToString(valueSet));
}
}
BaseHasResource sourceEntity = readEntity(theId); BaseHasResource sourceEntity = readEntity(theId);
if (sourceEntity == null) { if (sourceEntity == null) {
throw new ResourceNotFoundException(theId); throw new ResourceNotFoundException(theId);
} }
ValueSet source = (ValueSet) toResource(sourceEntity, false); ValueSet source = (ValueSet) toResource(sourceEntity, false);
return source;
return expand(source, theFilter);
} }
@Override @Override
@ -182,7 +192,7 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
if (!haveCodeableConcept && !haveCoding && !haveCode) { if (!haveCodeableConcept && !haveCoding && !haveCode) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate"); throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
} }
if (!(haveCodeableConcept ^ haveCoding ^ haveCode)) { if (!multiXor(haveCodeableConcept, haveCoding, haveCode)) {
throw new InvalidRequestException("$validate-code can only validate (system AND code) OR (coding) OR (codeableConcept)"); throw new InvalidRequestException("$validate-code can only validate (system AND code) OR (coding) OR (codeableConcept)");
} }
@ -199,11 +209,9 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
if (theCode == null || theCode.isEmpty()) { if (theCode == null || theCode.isEmpty()) {
throw new InvalidRequestException("Either ValueSet ID or ValueSet identifier or system and code must be provided. Unable to validate."); throw new InvalidRequestException("Either ValueSet ID or ValueSet identifier or system and code must be provided. Unable to validate.");
} }
Set<Long> ids = searchForIds(ValueSet.SP_CODE, new TokenParam(toStringOrNull(theSystem), theCode.getValue())); String code = theCode.getValue();
valueSetIds = new ArrayList<IIdType>(); String system = toStringOrNull(theSystem);
for (Long next : ids) { valueSetIds = findValueSetIdsContainingSystemAndCode(code, system);
valueSetIds.add(new IdDt("ValueSet", next));
}
} }
for (IIdType nextId : valueSetIds) { for (IIdType nextId : valueSetIds) {
@ -223,6 +231,30 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
return new ValidateCodeResult(false, "Code not found", null); return new ValidateCodeResult(false, "Code not found", null);
} }
private List<IIdType> findValueSetIdsContainingSystemAndCode(String theCode, String theSystem) {
if (theSystem != null && theSystem.startsWith("http://hl7.org/fhir/")) {
return Collections.singletonList((IIdType)new IdDt(theSystem));
}
List<IIdType> valueSetIds;
Set<Long> ids = searchForIds(ValueSet.SP_CODE, new TokenParam(theSystem, theCode));
valueSetIds = new ArrayList<IIdType>();
for (Long next : ids) {
valueSetIds.add(new IdDt("ValueSet", next));
}
return valueSetIds;
}
private static boolean multiXor(boolean... theValues) {
int count = 0;
for (int i = 0; i < theValues.length; i++) {
if (theValues[i]) {
count++;
}
}
return count == 1;
}
private String toStringOrNull(IPrimitiveType<String> thePrimitive) { private String toStringOrNull(IPrimitiveType<String> thePrimitive) {
return thePrimitive != null ? thePrimitive.getValue() : null; return thePrimitive != null ? thePrimitive.getValue() : null;
} }
@ -259,4 +291,68 @@ public class FhirResourceDaoValueSetDstu2 extends FhirResourceDaoDstu2<ValueSet>
return null; return null;
} }
@Override
public ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.LookupCodeResult lookupCode(CodeDt theCode, UriDt theSystem, CodingDt theCoding) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false;
boolean haveSystem = theSystem != null && theSystem.isEmpty() == false;
if (!haveCoding && !(haveSystem && haveCode)) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
}
if (!multiXor(haveCoding, (haveSystem && haveCode)) || (haveSystem != haveCode)) {
throw new InvalidRequestException("$lookup can only validate (system AND code) OR (coding.system AND coding.code)");
}
String code;
String system;
if (haveCoding) {
code = theCoding.getCode();
system = theCoding.getSystem();
} else {
code = theCode.getValue();
system = theSystem.getValue();
}
List<IIdType> valueSetIds = findValueSetIdsContainingSystemAndCode(code, system);
for (IIdType nextId : valueSetIds) {
ValueSet expansion = expand(nextId, null);
List<ExpansionContains> contains = expansion.getExpansion().getContains();
ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.LookupCodeResult result = lookup(contains, system, code);
if (result != null) {
return result;
}
}
LookupCodeResult retVal = new LookupCodeResult();
retVal.setFound(false);
retVal.setSearchedForCode(code);
retVal.setSearchedForSystem(system);
return retVal;
}
private ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.LookupCodeResult lookup(List<ExpansionContains> theContains, String theSystem, String theCode) {
for (ExpansionContains nextCode : theContains) {
String system = nextCode.getSystem();
String code = nextCode.getCode();
if (theSystem.equals(system) && theCode.equals(code)) {
ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.LookupCodeResult retVal = new LookupCodeResult();
retVal.setSearchedForCode(code);
retVal.setSearchedForSystem(system);
retVal.setFound(true);
if (nextCode.getAbstract() != null) {
retVal.setCodeIsAbstract(nextCode.getAbstract().booleanValue());
}
retVal.setCodeDisplay(nextCode.getDisplay());
retVal.setCodeSystemVersion(nextCode.getVersion());
retVal.setCodeSystemDisplayName("Unknown"); // TODO: implement
return retVal;
}
}
return null;
}
} }

View File

@ -33,13 +33,81 @@ import ca.uhn.fhir.model.primitive.UriDt;
public interface IFhirResourceDaoValueSet<T extends IBaseResource> extends IFhirResourceDao<T> { public interface IFhirResourceDaoValueSet<T extends IBaseResource> extends IFhirResourceDao<T> {
ValueSet expand(IIdType theId, String theFilter); ValueSet expand(IIdType theId, String theFilter);
ValueSet expand(ValueSet theSource, String theFilter); ValueSet expand(ValueSet theSource, String theFilter);
ValueSet expandByIdentifier(String theUri, String theFilter); ValueSet expandByIdentifier(String theUri, String theFilter);
LookupCodeResult lookupCode(CodeDt theCode, UriDt theSystem, CodingDt theCoding);
ValidateCodeResult validateCode(UriDt theValueSetIdentifier, IIdType theId, CodeDt theCode, UriDt theSystem, StringDt theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept); ValidateCodeResult validateCode(UriDt theValueSetIdentifier, IIdType theId, CodeDt theCode, UriDt theSystem, StringDt theDisplay, CodingDt theCoding, CodeableConceptDt theCodeableConcept);
public class LookupCodeResult {
private String myCodeDisplay;
private boolean myCodeIsAbstract;
private String myCodeSystemDisplayName;
private String myCodeSystemVersion;
private boolean myFound;
private String mySearchedForCode;
private String mySearchedForSystem;
public String getCodeDisplay() {
return myCodeDisplay;
}
public String getCodeSystemDisplayName() {
return myCodeSystemDisplayName;
}
public String getCodeSystemVersion() {
return myCodeSystemVersion;
}
public String getSearchedForCode() {
return mySearchedForCode;
}
public String getSearchedForSystem() {
return mySearchedForSystem;
}
public boolean isCodeIsAbstract() {
return myCodeIsAbstract;
}
public boolean isFound() {
return myFound;
}
public void setCodeDisplay(String theCodeDisplay) {
myCodeDisplay = theCodeDisplay;
}
public void setCodeIsAbstract(boolean theCodeIsAbstract) {
myCodeIsAbstract = theCodeIsAbstract;
}
public void setCodeSystemDisplayName(String theCodeSystemDisplayName) {
myCodeSystemDisplayName = theCodeSystemDisplayName;
}
public void setCodeSystemVersion(String theCodeSystemVersion) {
myCodeSystemVersion = theCodeSystemVersion;
}
public void setFound(boolean theFound) {
myFound = theFound;
}
public void setSearchedForCode(String theSearchedForCode) {
mySearchedForCode = theSearchedForCode;
}
public void setSearchedForSystem(String theSearchedForSystem) {
mySearchedForSystem = theSearchedForSystem;
}
}
public class ValidateCodeResult { public class ValidateCodeResult {
private String myDisplay; private String myDisplay;
private String myMessage; private String myMessage;

View File

@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet; import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.LookupCodeResult;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult; import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult;
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt; import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt; import ca.uhn.fhir.model.dstu2.composite.CodingDt;
@ -41,6 +42,7 @@ import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDstu2<ValueSet> { public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDstu2<ValueSet> {
@ -102,6 +104,42 @@ public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDst
return theFilter != null ? theFilter.getValue() : null; return theFilter != null ? theFilter.getValue() : null;
} }
//@formatter:off
@Operation(name = "$lookup", idempotent = true, returnParameters= {
@OperationParam(name="name", type=StringDt.class, min=1),
@OperationParam(name="version", type=StringDt.class, min=0),
@OperationParam(name="display", type=StringDt.class, min=1),
@OperationParam(name="abstract", type=BooleanDt.class, min=1),
})
public Parameters lookup(
HttpServletRequest theServletRequest,
@OperationParam(name="code", min=0, max=1) CodeDt theCode,
@OperationParam(name="system", min=0, max=1) UriDt theSystem,
@OperationParam(name="coding", min=0, max=1) CodingDt theCoding
) {
//@formatter:on
startRequest(theServletRequest);
try {
IFhirResourceDaoValueSet<ValueSet> dao = (IFhirResourceDaoValueSet<ValueSet>) getDao();
LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding);
if (result.isFound()==false) {
throw new ResourceNotFoundException("Unable to find code[" + result.getSearchedForCode() + "] in system[" + result.getSearchedForSystem() + "]");
}
Parameters retVal = new Parameters();
retVal.addParameter().setName("name").setValue(new StringDt(result.getCodeSystemDisplayName()));
if (isNotBlank(result.getCodeSystemVersion())) {
retVal.addParameter().setName("version").setValue(new StringDt(result.getCodeSystemVersion()));
}
retVal.addParameter().setName("display").setValue(new StringDt(result.getCodeDisplay()));
retVal.addParameter().setName("abstract").setValue(new BooleanDt(result.isCodeIsAbstract()));
return retVal;
} finally {
endRequest(theServletRequest);
}
}
//@formatter:off //@formatter:off
@Operation(name = "$validate-code", idempotent = true, returnParameters= { @Operation(name = "$validate-code", idempotent = true, returnParameters= {
@OperationParam(name="result", type=BooleanDt.class, min=1), @OperationParam(name="result", type=BooleanDt.class, min=1),
@ -137,4 +175,6 @@ public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDst
endRequest(theServletRequest); endRequest(theServletRequest);
} }
} }
} }

View File

@ -0,0 +1,8 @@
package ca.uhn.fhir.jpa.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DispatcherServletConfig {
//nothing
}

View File

@ -20,10 +20,13 @@ import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.DispatcherServlet;
import ca.uhn.fhir.jpa.config.DispatcherServletConfig;
import ca.uhn.fhir.jpa.config.TestDstu2Config;
import ca.uhn.fhir.jpa.dao.BaseJpaDstu2Test; import ca.uhn.fhir.jpa.dao.BaseJpaDstu2Test;
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider; import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
@ -126,7 +129,7 @@ public abstract class BaseResourceProviderDstu2Test extends BaseJpaDstu2Test {
DispatcherServlet dispatcherServlet = new DispatcherServlet(); DispatcherServlet dispatcherServlet = new DispatcherServlet();
// dispatcherServlet.setApplicationContext(webApplicationContext); // dispatcherServlet.setApplicationContext(webApplicationContext);
dispatcherServlet.setContextConfigLocation("classpath:/fhir-spring-subscription-config-dstu2.xml"); dispatcherServlet.setContextClass(AnnotationConfigWebApplicationContext.class);
ServletHolder subsServletHolder = new ServletHolder(); ServletHolder subsServletHolder = new ServletHolder();
subsServletHolder.setServlet(dispatcherServlet); subsServletHolder.setServlet(dispatcherServlet);
proxyHandler.addServlet(subsServletHolder, "/*"); proxyHandler.addServlet(subsServletHolder, "/*");

View File

@ -1,7 +1,11 @@
package ca.uhn.fhir.jpa.provider; package ca.uhn.fhir.jpa.provider;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -21,9 +25,10 @@ import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestDstu1Config;
import ca.uhn.fhir.jpa.dao.BaseJpaTest; import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
@ -60,7 +65,7 @@ import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
public class ResourceProviderDstu1Test extends BaseJpaTest { public class ResourceProviderDstu1Test extends BaseJpaTest {
private static ClassPathXmlApplicationContext ourAppCtx; private static AnnotationConfigApplicationContext ourAppCtx;
private static IGenericClient ourClient; private static IGenericClient ourClient;
private static DaoConfig ourDaoConfig; private static DaoConfig ourDaoConfig;
private static FhirContext ourCtx = FhirContext.forDstu1(); private static FhirContext ourCtx = FhirContext.forDstu1();
@ -523,7 +528,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
ourServerBase = "http://localhost:" + port + "/fhir/context"; ourServerBase = "http://localhost:" + port + "/fhir/context";
ourAppCtx = new ClassPathXmlApplicationContext("hapi-fhir-server-resourceproviders-dstu1.xml", "fhir-jpabase-spring-test-config.xml"); ourAppCtx = new AnnotationConfigApplicationContext(TestDstu1Config.class);
ourDaoConfig = (DaoConfig) ourAppCtx.getBean(DaoConfig.class); ourDaoConfig = (DaoConfig) ourAppCtx.getBean(DaoConfig.class);

View File

@ -11,9 +11,11 @@ import java.io.IOException;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import ca.uhn.fhir.model.dstu2.resource.Parameters; import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.ValueSet; import ca.uhn.fhir.model.dstu2.resource.ValueSet;
import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.BooleanDt;
@ -36,7 +38,7 @@ public class ResourceProviderDstu2ValueSetTest extends BaseResourceProviderDstu2
} }
@Test @Test
public void testValidateCodeOperationByCodeAndSystemBad() { public void testValidateCodeOperationByCodeAndSystemInstance() {
//@formatter:off //@formatter:off
Parameters respParam = ourClient Parameters respParam = ourClient
.operation() .operation()
@ -53,8 +55,147 @@ public class ResourceProviderDstu2ValueSetTest extends BaseResourceProviderDstu2
assertEquals(new BooleanDt(true), respParam.getParameter().get(0).getValue()); assertEquals(new BooleanDt(true), respParam.getParameter().get(0).getValue());
} }
@Test
public void testValidateCodeOperationByCodeAndSystemType() {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onType(ValueSet.class)
.named("validate-code")
.withParameter(Parameters.class, "code", new CodeDt("8450-9"))
.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 testLookupOperationByCodeAndSystem() {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onType(ValueSet.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeDt("8450-9"))
.andParameter("system", new UriDt("http://loinc.org"))
.execute();
//@formatter:on
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals("name", respParam.getParameter().get(0).getName());
assertEquals(new StringDt("Unknown"), respParam.getParameter().get(0).getValue());
assertEquals("display", respParam.getParameter().get(1).getName());
assertEquals(new StringDt("Systolic blood pressure--expiration"), respParam.getParameter().get(1).getValue());
assertEquals("abstract", respParam.getParameter().get(2).getName());
assertEquals(new BooleanDt(false), respParam.getParameter().get(2).getValue());
}
@Test
@Ignore
public void testLookupOperationForBuiltInCode() {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onType(ValueSet.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeDt("M"))
.andParameter("system", new UriDt("http://hl7.org/fhir/v3/MaritalStatus"))
.execute();
//@formatter:on
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals("name", respParam.getParameter().get(0).getName());
assertEquals(new StringDt("Unknown"), respParam.getParameter().get(0).getValue());
assertEquals("display", respParam.getParameter().get(1).getName());
assertEquals(new StringDt("Married"), respParam.getParameter().get(1).getValue());
assertEquals("abstract", respParam.getParameter().get(2).getName());
assertEquals(new BooleanDt(false), respParam.getParameter().get(2).getValue());
}
@Test
public void testLookupOperationByCoding() {
//@formatter:off
Parameters respParam = ourClient
.operation()
.onType(ValueSet.class)
.named("lookup")
.withParameter(Parameters.class, "coding", new CodingDt("http://loinc.org", "8450-9"))
.execute();
//@formatter:on
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals("name", respParam.getParameter().get(0).getName());
assertEquals(new StringDt("Unknown"), respParam.getParameter().get(0).getValue());
assertEquals("display", respParam.getParameter().get(1).getName());
assertEquals(new StringDt("Systolic blood pressure--expiration"), respParam.getParameter().get(1).getValue());
assertEquals("abstract", respParam.getParameter().get(2).getName());
assertEquals(new BooleanDt(false), respParam.getParameter().get(2).getValue());
}
@Test
public void testLookupOperationByInvalidCombination() {
//@formatter:off
try {
ourClient
.operation()
.onType(ValueSet.class)
.named("lookup")
.withParameter(Parameters.class, "coding", new CodingDt("http://loinc.org", "8450-9"))
.andParameter("code", new CodeDt("8450-9"))
.andParameter("system", new UriDt("http://loinc.org"))
.execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: $lookup can only validate (system AND code) OR (coding.system AND coding.code)", e.getMessage());
}
//@formatter:on
}
@Test
public void testLookupOperationByInvalidCombination2() {
//@formatter:off
try {
ourClient
.operation()
.onType(ValueSet.class)
.named("lookup")
.withParameter(Parameters.class, "coding", new CodingDt("http://loinc.org", "8450-9"))
.andParameter("system", new UriDt("http://loinc.org"))
.execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: $lookup can only validate (system AND code) OR (coding.system AND coding.code)", e.getMessage());
}
//@formatter:on
}
@Test
public void testLookupOperationByInvalidCombination3() {
//@formatter:off
try {
ourClient
.operation()
.onType(ValueSet.class)
.named("lookup")
.withParameter(Parameters.class, "coding", new CodingDt("http://loinc.org", null))
.execute();
fail();
} catch (InvalidRequestException e) {
assertEquals("HTTP 400 Bad Request: No code, coding, or codeableConcept provided to validate", e.getMessage());
}
//@formatter:on
}
@Test @Test
public void testExpandById() throws IOException { public void testExpandById() throws IOException {
//@formatter:off //@formatter:off

View File

@ -1,205 +0,0 @@
package ca.uhn.fhir.jpa.provider;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.testutil.RandomServerPortProvider;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
import ca.uhn.fhir.model.dstu2.resource.PaymentNotice;
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
public class ResourceProviderMultiVersionTest extends BaseJpaTest {
private static ClassPathXmlApplicationContext ourAppCtx;
private static IGenericClient ourClientDstu2;
private static Server ourServer;
private static IGenericClient ourClientDstu1;
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
ourAppCtx.stop();
}
@Test
public void testSubmitPatient() {
Patient p = new Patient();
p.addIdentifier("urn:MultiFhirVersionTest", "testSubmitPatient01");
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
p.getGender().setValueAsEnum(AdministrativeGenderCodesEnum.M);
IdDt id = (IdDt) ourClientDstu1.create().resource(p).execute().getId();
// Read back as DSTU1
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
assertEquals("testSubmitPatient01", p.getIdentifierFirstRep().getValue().getValue());
assertEquals(1, patDstu1.getUndeclaredExtensionsByUrl("http://foo#ext1").size());
assertEquals("M", patDstu1.getGender().getCodingFirstRep().getCode().getValue());
// Read back as DEV
ca.uhn.fhir.model.dstu2.resource.Patient patDstu2;
patDstu2 = ourClientDstu2.read(ca.uhn.fhir.model.dstu2.resource.Patient.class, id);
assertEquals("testSubmitPatient01", p.getIdentifierFirstRep().getValue().getValue());
assertEquals(1, patDstu2.getUndeclaredExtensionsByUrl("http://foo#ext1").size());
assertEquals(null, patDstu2.getGender());
// Search using new bundle format
Bundle bundle = ourClientDstu2.search().forResource(ca.uhn.fhir.model.dstu2.resource.Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:MultiFhirVersionTest", "testSubmitPatient01")).encodedJson().execute();
patDstu2 = (ca.uhn.fhir.model.dstu2.resource.Patient) bundle.getEntries().get(0).getResource();
assertEquals("testSubmitPatient01", p.getIdentifierFirstRep().getValue().getValue());
assertEquals(1, patDstu2.getUndeclaredExtensionsByUrl("http://foo#ext1").size());
assertEquals(null, patDstu2.getGender());
}
@Test
public void testSubmitPatientDstu2() {
ca.uhn.fhir.model.dstu2.resource.Patient p = new ca.uhn.fhir.model.dstu2.resource.Patient();
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testSubmitPatientDstu201");
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
p.setGender(AdministrativeGenderEnum.MALE);
IdDt id = (IdDt) ourClientDstu2.create().resource(p).execute().getId();
// Read back as DSTU1
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
assertEquals("testSubmitPatientDstu201", p.getIdentifierFirstRep().getValue());
assertEquals(1, patDstu1.getUndeclaredExtensionsByUrl("http://foo#ext1").size());
assertEquals(null, patDstu1.getGender().getCodingFirstRep().getCode().getValue());
// Read back as DEV
ca.uhn.fhir.model.dstu2.resource.Patient patDstu2;
patDstu2 = ourClientDstu2.read(ca.uhn.fhir.model.dstu2.resource.Patient.class, id);
assertEquals("testSubmitPatientDstu201", p.getIdentifierFirstRep().getValue());
assertEquals(1, patDstu2.getUndeclaredExtensionsByUrl("http://foo#ext1").size());
assertEquals("male", patDstu2.getGender());
// Search using new bundle format
Bundle bundle = ourClientDstu2.search().forResource(ca.uhn.fhir.model.dstu2.resource.Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode("urn:MultiFhirVersionTest", "testSubmitPatientDstu201")).encodedJson().execute();
patDstu2 = (ca.uhn.fhir.model.dstu2.resource.Patient) bundle.getEntries().get(0).getResource();
assertEquals("testSubmitPatientDstu201", p.getIdentifierFirstRep().getValue());
assertEquals(1, patDstu2.getUndeclaredExtensionsByUrl("http://foo#ext1").size());
assertEquals("male", patDstu2.getGender());
}
@SuppressWarnings("deprecation")
@Test
public void testUnknownResourceType() {
ca.uhn.fhir.model.dstu2.resource.Patient p = new ca.uhn.fhir.model.dstu2.resource.Patient();
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType01");
IdDt id = (IdDt) ourClientDstu2.create().resource(p).execute().getId();
PaymentNotice s = new PaymentNotice();
s.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType02");
ourClientDstu2.create().resource(s).execute().getId();
Bundle history = ourClientDstu2.history(null, id, null, null);
assertEquals(PaymentNotice.class, history.getEntries().get(0).getResource().getClass());
assertEquals(ca.uhn.fhir.model.dstu2.resource.Patient.class, history.getEntries().get(1).getResource().getClass());
history = ourClientDstu1.history(null, id, null, null);
assertEquals(ca.uhn.fhir.model.dstu.resource.Patient.class, history.getEntries().get(0).getResource().getClass());
history = ourClientDstu2.history().onServer().andReturnDstu1Bundle().execute();
assertEquals(PaymentNotice.class, history.getEntries().get(0).getResource().getClass());
assertEquals(ca.uhn.fhir.model.dstu2.resource.Patient.class, history.getEntries().get(1).getResource().getClass());
history = ourClientDstu1.history().onServer().andReturnDstu1Bundle().execute();
assertEquals(ca.uhn.fhir.model.dstu.resource.Patient.class, history.getEntries().get(0).getResource().getClass());
history = ourClientDstu1.history().onInstance(id).andReturnDstu1Bundle().execute();
assertEquals(ca.uhn.fhir.model.dstu.resource.Patient.class, history.getEntries().get(0).getResource().getClass());
}
@SuppressWarnings("unchecked")
@BeforeClass
public static void beforeClass() throws Exception {
//@formatter:off
ourAppCtx = new ClassPathXmlApplicationContext(
"hapi-fhir-server-resourceproviders-dstu1.xml",
"hapi-fhir-server-resourceproviders-dstu2.xml",
"fhir-jpabase-spring-test-config.xml"
);
//@formatter:on
int port = RandomServerPortProvider.findFreePort();
ServletContextHandler proxyHandler = new ServletContextHandler();
proxyHandler.setContextPath("/");
ourServer = new Server(port);
/*
* DEV resources
*/
RestfulServer restServerDstu2 = new RestfulServer(ourAppCtx.getBean("myFhirContextDstu2", FhirContext.class));
List<IResourceProvider> rpsDstu2 = (List<IResourceProvider>) ourAppCtx.getBean("myResourceProvidersDstu2", List.class);
restServerDstu2.setResourceProviders(rpsDstu2);
JpaSystemProviderDstu2 systemProvDstu2 = (JpaSystemProviderDstu2) ourAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class);
restServerDstu2.setPlainProviders(systemProvDstu2);
ServletHolder servletHolder = new ServletHolder();
servletHolder.setServlet(restServerDstu2);
proxyHandler.addServlet(servletHolder, "/fhir/contextDstu2/*");
/*
* DSTU resources
*/
RestfulServer restServerDstu1 = new RestfulServer(ourAppCtx.getBean("myFhirContextDstu1", FhirContext.class));
List<IResourceProvider> rpsDstu1 = (List<IResourceProvider>) ourAppCtx.getBean("myResourceProvidersDstu1", List.class);
restServerDstu1.setResourceProviders(rpsDstu1);
JpaSystemProviderDstu1 systemProvDstu1 = (JpaSystemProviderDstu1) ourAppCtx.getBean("mySystemProviderDstu1", JpaSystemProviderDstu1.class);
restServerDstu1.setPlainProviders(systemProvDstu1);
servletHolder = new ServletHolder();
servletHolder.setServlet(restServerDstu1);
proxyHandler.addServlet(servletHolder, "/fhir/contextDstu1/*");
/*
* Start server
*/
ourServer.setHandler(proxyHandler);
ourServer.start();
/*
* DEV Client
*/
String serverBaseDstu2 = "http://localhost:" + port + "/fhir/contextDstu2";
FhirContext ctxDstu2 = ourAppCtx.getBean("myFhirContextDstu2", FhirContext.class);
ctxDstu2.getRestfulClientFactory().setSocketTimeout(600 * 1000);
ourClientDstu2 = ctxDstu2.newRestfulGenericClient(serverBaseDstu2);
ourClientDstu2.registerInterceptor(new LoggingInterceptor(true));
/*
* DSTU1 Client
*/
String serverBaseDstu1 = "http://localhost:" + port + "/fhir/contextDstu1";
FhirContext ctxDstu1 = ourAppCtx.getBean("myFhirContextDstu1", FhirContext.class);
ctxDstu1.getRestfulClientFactory().setSocketTimeout(600 * 1000);
ourClientDstu1 = ctxDstu1.newRestfulGenericClient(serverBaseDstu1);
ourClientDstu1.registerInterceptor(new LoggingInterceptor(true));
}
}

View File

@ -16,9 +16,11 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestDstu1Config;
import ca.uhn.fhir.jpa.dao.BaseJpaTest; import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.rp.dstu.ObservationResourceProvider; import ca.uhn.fhir.jpa.rp.dstu.ObservationResourceProvider;
@ -39,7 +41,7 @@ public class SystemProviderDstu1Test extends BaseJpaTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderDstu1Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderDstu1Test.class);
private static Server ourServer; private static Server ourServer;
private static ClassPathXmlApplicationContext ourAppCtx; private static AnnotationConfigApplicationContext ourAppCtx;
private static FhirContext ourCtx; private static FhirContext ourCtx;
private static IGenericClient ourClient; private static IGenericClient ourClient;
@ -72,7 +74,7 @@ public class SystemProviderDstu1Test extends BaseJpaTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
ourAppCtx = new ClassPathXmlApplicationContext("fhir-jpabase-spring-test-config.xml", "hapi-fhir-server-resourceproviders-dstu1.xml"); ourAppCtx = new AnnotationConfigApplicationContext(TestDstu1Config.class);
IFhirResourceDao<Patient> patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDaoDstu1", IFhirResourceDao.class); IFhirResourceDao<Patient> patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDaoDstu1", IFhirResourceDao.class);
PatientResourceProvider patientRp = new PatientResourceProvider(); PatientResourceProvider patientRp = new PatientResourceProvider();

View File

@ -20,9 +20,12 @@ import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestDstu1Config;
import ca.uhn.fhir.jpa.config.TestDstu2Config;
import ca.uhn.fhir.jpa.dao.BaseJpaTest; import ca.uhn.fhir.jpa.dao.BaseJpaTest;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.rp.dstu2.ObservationResourceProvider; import ca.uhn.fhir.jpa.rp.dstu2.ObservationResourceProvider;
@ -49,7 +52,7 @@ public class SystemProviderDstu2Test extends BaseJpaTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderDstu2Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SystemProviderDstu2Test.class);
private static Server ourServer; private static Server ourServer;
private static ClassPathXmlApplicationContext ourAppCtx; private static AnnotationConfigApplicationContext ourAppCtx;
private static FhirContext ourCtx; private static FhirContext ourCtx;
private static IGenericClient ourClient; private static IGenericClient ourClient;
private static String ourServerBase; private static String ourServerBase;
@ -210,7 +213,7 @@ public class SystemProviderDstu2Test extends BaseJpaTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
ourAppCtx = new ClassPathXmlApplicationContext("fhir-jpabase-spring-test-config.xml", "hapi-fhir-server-resourceproviders-dstu2.xml"); ourAppCtx = new AnnotationConfigApplicationContext(TestDstu2Config.class);
IFhirResourceDao<Patient> patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDaoDstu2", IFhirResourceDao.class); IFhirResourceDao<Patient> patientDao = (IFhirResourceDao<Patient>) ourAppCtx.getBean("myPatientDaoDstu2", IFhirResourceDao.class);
PatientResourceProvider patientRp = new PatientResourceProvider(); PatientResourceProvider patientRp = new PatientResourceProvider();

View File

@ -1,6 +1,6 @@
package ca.uhn.fhir.jpa.demo; package ca.uhn.fhir.jpa.demo;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -27,6 +27,7 @@ public class ExampleServerIT {
private static int ourPort; private static int ourPort;
private static Server ourServer; private static Server ourServer;
private static String ourServerBase;
@Test @Test
public void testCreateAndRead() throws IOException { public void testCreateAndRead() throws IOException {
@ -71,7 +72,8 @@ public class ExampleServerIT {
ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER); ourCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000); ourCtx.getRestfulClientFactory().setSocketTimeout(1200 * 1000);
ourClient = ourCtx.newRestfulGenericClient("http://localhost:" + ourPort + "/baseDstu2"); ourServerBase = "http://localhost:" + ourPort + "/baseDstu2";
ourClient = ourCtx.newRestfulGenericClient(ourServerBase);
ourClient.registerInterceptor(new LoggingInterceptor(true)); ourClient.registerInterceptor(new LoggingInterceptor(true));
} }

File diff suppressed because it is too large Load Diff

View File

@ -129,7 +129,7 @@
<!-- This filters provide support for Cross Origin Resource Sharing (CORS) --> <!-- This filters provide support for Cross Origin Resource Sharing (CORS) -->
<filter> <filter>
<filter-name>CORS Filter</filter-name> <filter-name>CORS Filter</filter-name>
<filter-class>org.ebaysf.web.cors.CORSFilter</filter-class> <filter-class>ca.uhn.fhirtest.CORSFilter_</filter-class>
<init-param> <init-param>
<description>A comma separated list of allowed origins. Note: An '*' cannot be used for an allowed origin when using credentials.</description> <description>A comma separated list of allowed origins. Note: An '*' cannot be used for an allowed origin when using credentials.</description>
<param-name>cors.allowed.origins</param-name> <param-name>cors.allowed.origins</param-name>

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.rest.server;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.IOException;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -10,6 +11,7 @@ import javax.servlet.DispatcherType;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.Header; import org.apache.http.Header;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
@ -32,18 +34,91 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.server.RestfulServerSelfReferenceTest.DummyPatientResourceProvider; import ca.uhn.fhir.rest.server.RestfulServerSelfReferenceTest.DummyPatientResourceProvider;
import ca.uhn.fhir.util.PortUtil; import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class CorsTest { public class CorsTest {
private static CloseableHttpClient ourClient; private static CloseableHttpClient ourClient;
private static Server ourServer;
private static String ourBaseUri;
private static final FhirContext ourCtx = FhirContext.forDstu1(); private static final FhirContext ourCtx = FhirContext.forDstu1();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CorsTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CorsTest.class);
@Test
public void testRequestWithNullOrigin() throws ClientProtocolException, IOException {
{
HttpOptions httpOpt = new HttpOptions(ourBaseUri + "/Organization/b27ed191-f62d-4128-d99d-40b5e84f2bf2");
httpOpt.addHeader("Access-Control-Request-Method", "GET");
httpOpt.addHeader("Origin", "null");
httpOpt.addHeader("Access-Control-Request-Headers", "accept, x-fhir-starter, content-type");
HttpResponse status = ourClient.execute(httpOpt);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals("GET", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_METHODS).getValue());
assertEquals("null", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN).getValue());
}
}
@Test @Test
public void testContextWithSpace() throws Exception { public void testContextWithSpace() throws Exception {
{
HttpOptions httpOpt = new HttpOptions(ourBaseUri + "/Organization/b27ed191-f62d-4128-d99d-40b5e84f2bf2");
httpOpt.addHeader("Access-Control-Request-Method", "POST");
httpOpt.addHeader("Origin", "http://www.fhir-starter.com");
httpOpt.addHeader("Access-Control-Request-Headers", "accept, x-fhir-starter, content-type");
HttpResponse status = ourClient.execute(httpOpt);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals("POST", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_METHODS).getValue());
assertEquals("http://www.fhir-starter.com", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN).getValue());
}
{
String uri = ourBaseUri + "/Patient?identifier=urn:hapitest:mrns%7C00001";
HttpGet httpGet = new HttpGet(uri);
httpGet.addHeader("X-FHIR-Starter", "urn:fhir.starter");
httpGet.addHeader("Origin", "http://www.fhir-starter.com");
HttpResponse status = ourClient.execute(httpGet);
Header origin = status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN);
assertEquals("http://www.fhir-starter.com", origin.getValue());
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.getEntries().size());
}
{
HttpPost httpOpt = new HttpPost(ourBaseUri + "/Patient");
httpOpt.addHeader("Access-Control-Request-Method", "POST");
httpOpt.addHeader("Origin", "http://www.fhir-starter.com");
httpOpt.addHeader("Access-Control-Request-Headers", "accept, x-fhir-starter, content-type");
httpOpt.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(new Patient())));
HttpResponse status = ourClient.execute(httpOpt);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response: {}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals("http://www.fhir-starter.com", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN).getValue());
}
}
public static void afterClass() throws Exception {
ourServer.stop();
ourClient.close();
}
@BeforeClass
public static void beforeClass() throws Exception {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
int port = PortUtil.findFreePort(); int port = PortUtil.findFreePort();
Server server = new Server(port); ourServer = new Server(port);
RestfulServer restServer = new RestfulServer(ourCtx); RestfulServer restServer = new RestfulServer(ourCtx);
restServer.setResourceProviders(new DummyPatientResourceProvider()); restServer.setResourceProviders(new DummyPatientResourceProvider());
@ -52,7 +127,7 @@ public class CorsTest {
ServletHolder servletHolder = new ServletHolder(restServer); ServletHolder servletHolder = new ServletHolder(restServer);
FilterHolder fh = new FilterHolder(); FilterHolder fh = new FilterHolder();
fh.setHeldClass(CORSFilter.class); fh.setHeldClass(CORSFilter_.class);
fh.setInitParameter("cors.logging.enabled", "true"); fh.setInitParameter("cors.logging.enabled", "true");
fh.setInitParameter("cors.allowed.origins", "*"); fh.setInitParameter("cors.allowed.origins", "*");
fh.setInitParameter("cors.allowed.headers", "x-fhir-starter,Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers"); fh.setInitParameter("cors.allowed.headers", "x-fhir-starter,Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers");
@ -65,69 +140,11 @@ public class CorsTest {
ch.addFilter(fh, "/*", EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST)); ch.addFilter(fh, "/*", EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST));
ContextHandlerCollection contexts = new ContextHandlerCollection(); ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts); ourServer.setHandler(contexts);
server.setHandler(ch); ourServer.setHandler(ch);
server.start(); ourServer.start();
try { ourBaseUri = "http://localhost:" + port + "/rootctx/rcp2/fhirctx/fcp2";
String baseUri = "http://localhost:" + port + "/rootctx/rcp2/fhirctx/fcp2";
{
HttpOptions httpOpt = new HttpOptions(baseUri + "/Organization/b27ed191-f62d-4128-d99d-40b5e84f2bf2");
httpOpt.addHeader("Access-Control-Request-Method", "POST");
httpOpt.addHeader("Origin", "http://www.fhir-starter.com");
httpOpt.addHeader("Access-Control-Request-Headers", "accept, x-fhir-starter, content-type");
HttpResponse status = ourClient.execute(httpOpt);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals("POST", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_METHODS).getValue());
assertEquals("http://www.fhir-starter.com", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN).getValue());
}
{
String uri = baseUri + "/Patient?identifier=urn:hapitest:mrns%7C00001";
HttpGet httpGet = new HttpGet(uri);
httpGet.addHeader("X-FHIR-Starter", "urn:fhir.starter");
httpGet.addHeader("Origin", "http://www.fhir-starter.com");
HttpResponse status = ourClient.execute(httpGet);
Header origin = status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN);
assertEquals("http://www.fhir-starter.com", origin.getValue());
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.getEntries().size());
}
{
HttpPost httpOpt = new HttpPost(baseUri + "/Patient");
httpOpt.addHeader("Access-Control-Request-Method", "POST");
httpOpt.addHeader("Origin", "http://www.fhir-starter.com");
httpOpt.addHeader("Access-Control-Request-Headers", "accept, x-fhir-starter, content-type");
httpOpt.setEntity(new StringEntity(ourCtx.newXmlParser().encodeResourceToString(new Patient())));
HttpResponse status = ourClient.execute(httpOpt);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response: {}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals("http://www.fhir-starter.com", status.getFirstHeader(Constants.HEADER_CORS_ALLOW_ORIGIN).getValue());
}
} finally {
server.stop();
}
}
@BeforeClass
public static void beforeClass() throws Exception {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
} }

View File

@ -80,7 +80,7 @@ public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>
} }
public boolean hasValue() { public boolean hasValue() {
return !isEmpty(); return !StringUtils.isBlank(getValueAsString());
} }
public String getValueAsString() { public String getValueAsString() {

View File

@ -0,0 +1,22 @@
package ca.uhn.fhir.model;
import static org.junit.Assert.*;
import org.hl7.fhir.instance.model.DecimalType;
import org.hl7.fhir.instance.model.StringType;
import org.junit.Test;
import org.thymeleaf.standard.expression.NumberTokenExpression;
public class PrimititeTest {
@Test
public void testHasValue() {
StringType type = new StringType();
assertFalse(type.hasValue());
type.addExtension().setUrl("http://foo").setValue(new DecimalType(123));
assertFalse(type.hasValue());
type.setValue("Hello");
assertTrue(type.hasValue());
}
}

View File

@ -3,10 +3,13 @@ package ca.uhn.fhir.to.mvc;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
public class AnnotationMethodHandlerAdapterConfigurer { public class AnnotationMethodHandlerAdapterConfigurer {
@Autowired @Autowired
@Qualifier("requestMappingHandlerAdapter")
private RequestMappingHandlerAdapter adapter; private RequestMappingHandlerAdapter adapter;
@PostConstruct @PostConstruct

View File

@ -258,7 +258,7 @@
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>1.1.2</version> <version>1.1.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
@ -653,7 +653,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version> <version>2.10.3</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -866,7 +866,7 @@
<dependency> <dependency>
<groupId>com.puppycrawl.tools</groupId> <groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId> <artifactId>checkstyle</artifactId>
<version>6.7</version> <version>6.11.2</version>
</dependency> </dependency>
</dependencies> </dependencies>
<configuration> <configuration>

View File

@ -49,6 +49,13 @@ public class FhirTesterConfig {
.withFhirVersion(FhirVersionEnum.DSTU2) .withFhirVersion(FhirVersionEnum.DSTU2)
.withBaseUrl("http://fhirtest.uhn.ca/baseDstu2") .withBaseUrl("http://fhirtest.uhn.ca/baseDstu2")
.withName("Public HAPI Test Server"); .withName("Public HAPI Test Server");
/*
* Use the method below to supply a client "factory" which can be used
* if your server requires authentication
*/
// retVal.setClientFactory(clientFactory);
return retVal; return retVal;
} }

View File

@ -13,6 +13,7 @@
<![CDATA[ <![CDATA[
<ul> <ul>
<li>Commons-lang3 (Core): 3.3.2 -&gt; 3.4</li> <li>Commons-lang3 (Core): 3.3.2 -&gt; 3.4</li>
<li>Logback (Core): 1.1.2 -&gt; 1.1.3</li>
<li>Springframework (JPA, Web Tester): 4.1.5 -&gt; 4.2.2</li> <li>Springframework (JPA, Web Tester): 4.1.5 -&gt; 4.2.2</li>
<li>Hibernate (JPA, Web Tester): 4.2.17 -&gt; 5.0.2</li> <li>Hibernate (JPA, Web Tester): 4.2.17 -&gt; 5.0.2</li>
<li>Hibernate Validator (JPA, Web Tester): 5.2.1 -&gt; 5.2.2</li> <li>Hibernate Validator (JPA, Web Tester): 5.2.1 -&gt; 5.2.2</li>
@ -21,6 +22,10 @@
</ul> </ul>
]]> ]]>
</action> </action>
<action type="add">
JPA and Tester Overlay now use Spring Java config files instead
of the older XML config files. All example projects have been updated.
</action>
<action type="add"> <action type="add">
JPA server removes duplicate resource index entries before storing them JPA server removes duplicate resource index entries before storing them
(e.g. if a patient has the same name twice, only one index entry is created (e.g. if a patient has the same name twice, only one index entry is created

View File

@ -48,6 +48,13 @@
<type>war</type> <type>war</type>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-testpage-overlay</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
<scope>provided</scope>
</dependency>
</dependencies>]]></source> </dependencies>]]></source>
</p> </p>
@ -75,18 +82,12 @@
</p> </p>
<p> <p>
Next, create the following directory in your project Then, create a Java source file
if it doesn't already exist:<br/> called <code>FhirTesterConfig.java</code>
<code>src/main/webapp/WEB-INF</code>
</p>
<p>
Then, create a file in that directory
called <code>hapi-fhir-tester-config.xml</code>
and copy in the following contents: and copy in the following contents:
</p> </p>
<macro name="snippet"> <macro name="snippet">
<param name="file" value="restful-server-example/src/main/webapp/WEB-INF/hapi-fhir-tester-config.xml" /> <param name="file" value="restful-server-example/src/main/java/ca/uhn/example/config/FhirTesterConfig.java" />
</macro> </macro>
<p> <p>
@ -98,37 +99,39 @@
</p> </p>
<p> <p>
Finally, in the same directory you should open you web.xml file. This file is Next, create the following directory in your project
required in order to deploy to a servlet container and you should create it if if it doesn't already exist:<br/>
it does not already exist. Place the following contents in that file. <code>src/main/webapp/WEB-INF</code>
</p> </p>
<source><![CDATA[<listener> <p>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> In this directory you should open your <code>web.xml</code> file, or create
</listener> it if it doesn't exist.
<context-param> This file is
<param-name>contextConfigLocation</param-name> required in order to deploy to a servlet container and you should create it if
<param-value> it does not already exist. Place the following contents in that file, adjusting
/WEB-INF/hapi-fhir-tester-application-context.xml the package on the <code>FhirTesterConfig</code> to match the
/WEB-INF/hapi-fhir-tester-config.xml actual package in which you placed this file.
</param-value> </p>
</context-param>
<servlet> <source><![CDATA[<servlet>
<servlet-name>spring</servlet-name> <servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param> <init-param>
<param-name>contextConfigLocation</param-name> <param-name>contextConfigLocation</param-name>
<param-value> <param-value>ca.uhn.example.config.FhirTesterConfig</param-value>
/WEB-INF/hapi-fhir-tester-application-context.xml
/WEB-INF/hapi-fhir-tester-config.xml
</param-value>
</init-param> </init-param>
<load-on-startup>2</load-on-startup> <load-on-startup>2</load-on-startup>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>
<servlet-name>spring</servlet-name> <servlet-name>spring</servlet-name>
<url-pattern>/tester/*</url-pattern> <url-pattern>/tester/*</url-pattern>
</servlet-mapping>]]></source> </servlet-mapping>
]]></source>
</subsection> </subsection>
@ -193,19 +196,6 @@
a client. a client.
</p> </p>
<p>
The following example shows an implementation of the client factory which registers
an authorization interceptor with hardcoded credentials.
</p>
<macro name="snippet">
<param name="file" value="restful-server-example/src/main/webapp/WEB-INF/hapi-fhir-tester-config.xml" />
</macro>
<p>
This client factory is then registered with the TesterConfig in the <code>hapi-fhir-tester-config.xml</code>
file, as shown above.
</p>
</section> </section>
</body> </body>