Support lastupdate filtering and sorting on JPA everything operation
This commit is contained in:
parent
1cc6a05273
commit
ca8c257833
|
@ -24,6 +24,7 @@ import java.lang.reflect.Method;
|
|||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -47,6 +48,7 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
|
|||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.param.CollectionBinder;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.ResourceParameter;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -66,6 +68,7 @@ public class OperationParameter implements IParameter {
|
|||
private Class<?> myParameterType;
|
||||
private String myParamType;
|
||||
private FhirContext myContext;
|
||||
private boolean myAllowGet;
|
||||
|
||||
public OperationParameter(FhirContext theCtx, String theOperationName, OperationParam theOperationParam) {
|
||||
this(theCtx, theOperationName, theOperationParam.name(), theOperationParam.min(), theOperationParam.max());
|
||||
|
@ -107,6 +110,8 @@ public class OperationParameter implements IParameter {
|
|||
myMax = 1;
|
||||
}
|
||||
|
||||
myAllowGet = IPrimitiveType.class.isAssignableFrom(myParameterType);
|
||||
|
||||
/*
|
||||
* The parameter can be of type string for validation methods - This is a bit
|
||||
* weird. See ValidateDstu2Test. We should probably clean this up..
|
||||
|
@ -114,6 +119,10 @@ public class OperationParameter implements IParameter {
|
|||
if (!myParameterType.equals(IBase.class) && !myParameterType.equals(String.class)) {
|
||||
if (IBaseResource.class.isAssignableFrom(myParameterType) && myParameterType.isInterface()) {
|
||||
myParamType = "Resource";
|
||||
} else if (DateRangeParam.class.isAssignableFrom(myParameterType)) {
|
||||
myParamType = "date";
|
||||
myMax = 2;
|
||||
myAllowGet = true;
|
||||
} else if (!IBase.class.isAssignableFrom(myParameterType) || myParameterType.isInterface() || Modifier.isAbstract(myParameterType.getModifiers())) {
|
||||
throw new ConfigurationException("Invalid type for @OperationParam: " + myParameterType.getName());
|
||||
} else if (myParameterType.equals(ValidationModeEnum.class)) {
|
||||
|
@ -153,13 +162,25 @@ public class OperationParameter implements IParameter {
|
|||
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
|
||||
String[] paramValues = theRequest.getParameters().get(myName);
|
||||
if (paramValues != null && paramValues.length > 0) {
|
||||
if (IPrimitiveType.class.isAssignableFrom(myParameterType)) {
|
||||
for (String nextValue : paramValues) {
|
||||
FhirContext ctx = theRequest.getServer().getFhirContext();
|
||||
RuntimePrimitiveDatatypeDefinition def = (RuntimePrimitiveDatatypeDefinition) ctx.getElementDefinition((Class<? extends IBase>) myParameterType);
|
||||
IPrimitiveType<?> instance = def.newInstance();
|
||||
instance.setValueAsString(nextValue);
|
||||
matchingParamValues.add(instance);
|
||||
if (myAllowGet) {
|
||||
|
||||
if (DateRangeParam.class.isAssignableFrom(myParameterType)) {
|
||||
List<QualifiedParamList> parameters = new ArrayList<QualifiedParamList>();
|
||||
parameters.add(QualifiedParamList.singleton(paramValues[0]));
|
||||
if (paramValues.length > 1) {
|
||||
parameters.add(QualifiedParamList.singleton(paramValues[1]));
|
||||
}
|
||||
DateRangeParam dateRangeParam = new DateRangeParam();
|
||||
dateRangeParam.setValuesAsQueryTokens(parameters);
|
||||
matchingParamValues.add(dateRangeParam);
|
||||
} else {
|
||||
for (String nextValue : paramValues) {
|
||||
FhirContext ctx = theRequest.getServer().getFhirContext();
|
||||
RuntimePrimitiveDatatypeDefinition def = (RuntimePrimitiveDatatypeDefinition) ctx.getElementDefinition((Class<? extends IBase>) myParameterType);
|
||||
IPrimitiveType<?> instance = def.newInstance();
|
||||
instance.setValueAsString(nextValue);
|
||||
matchingParamValues.add(instance);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HapiLocalizer localizer = theRequest.getServer().getFhirContext().getLocalizer();
|
||||
|
|
|
@ -1615,7 +1615,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
/**
|
||||
* THIS SHOULD RETURN HASHSET and not jsut Set because we add to it later (so it can't be Collections.emptySet())
|
||||
*/
|
||||
private HashSet<Long> loadReverseIncludes(List<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode) {
|
||||
private HashSet<Long> loadReverseIncludes(Collection<Long> theMatches, Set<Include> theRevIncludes, boolean theReverseMode) {
|
||||
if (theMatches.size() == 0) {
|
||||
return new HashSet<Long>();
|
||||
}
|
||||
|
@ -2020,6 +2020,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
}
|
||||
|
||||
// Load _include and _revinclude before filter and sort in everything mode
|
||||
if (theParams.isEverythingMode() == true) {
|
||||
if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
|
||||
loadPids.addAll(loadReverseIncludes(loadPids, theParams.getRevIncludes(), true));
|
||||
loadPids.addAll(loadReverseIncludes(loadPids, theParams.getIncludes(), false));
|
||||
}
|
||||
}
|
||||
|
||||
// Handle _lastUpdated
|
||||
DateRangeParam lu = theParams.getLastUpdated();
|
||||
if (lu != null && (lu.getLowerBoundAsInstant() != null || lu.getUpperBoundAsInstant() != null)) {
|
||||
|
@ -2051,52 +2059,15 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
}
|
||||
|
||||
// Handle sorting if any was provided
|
||||
final List<Long> pids;
|
||||
if (theParams.getSort() != null && isNotBlank(theParams.getSort().getParamName())) {
|
||||
List<Order> orders = new ArrayList<Order>();
|
||||
List<Predicate> predicates = new ArrayList<Predicate>();
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> cq = builder.createTupleQuery();
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
predicates.add(from.get("myId").in(loadPids));
|
||||
createSort(builder, from, theParams.getSort(), orders, predicates);
|
||||
if (orders.size() > 0) {
|
||||
Set<Long> originalPids = loadPids;
|
||||
loadPids = new LinkedHashSet<Long>();
|
||||
cq.multiselect(from.get("myId").as(Long.class));
|
||||
cq.where(predicates.toArray(new Predicate[0]));
|
||||
cq.orderBy(orders);
|
||||
|
||||
TypedQuery<Tuple> query = myEntityManager.createQuery(cq);
|
||||
|
||||
for (Tuple next : query.getResultList()) {
|
||||
loadPids.add(next.get(0, Long.class));
|
||||
}
|
||||
|
||||
ourLog.debug("Sort PID order is now: {}", loadPids);
|
||||
|
||||
pids = new ArrayList<Long>(loadPids);
|
||||
|
||||
// Any ressources which weren't matched by the sort get added to the bottom
|
||||
for (Long next : originalPids) {
|
||||
if (loadPids.contains(next) == false) {
|
||||
pids.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
pids = new ArrayList<Long>(loadPids);
|
||||
}
|
||||
} else {
|
||||
pids = new ArrayList<Long>(loadPids);
|
||||
}
|
||||
final List<Long> pids = processSort(theParams, loadPids);
|
||||
|
||||
// Load _revinclude resources
|
||||
final Set<Long> revIncludedPids;
|
||||
if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
|
||||
revIncludedPids = loadReverseIncludes(pids, theParams.getRevIncludes(), true);
|
||||
if (theParams.isEverythingMode()) {
|
||||
revIncludedPids.addAll(loadReverseIncludes(pids, theParams.getIncludes(), false));
|
||||
if (theParams.isEverythingMode() == false) {
|
||||
if (theParams.getRevIncludes() != null && theParams.getRevIncludes().isEmpty() == false) {
|
||||
revIncludedPids = loadReverseIncludes(pids, theParams.getRevIncludes(), true);
|
||||
} else {
|
||||
revIncludedPids = new HashSet<Long>();
|
||||
}
|
||||
} else {
|
||||
revIncludedPids = new HashSet<Long>();
|
||||
|
@ -2152,6 +2123,49 @@ public abstract class BaseHapiFhirResourceDao<T extends IResource> extends BaseH
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private List<Long> processSort(final SearchParameterMap theParams, Set<Long> loadPids) {
|
||||
final List<Long> pids;
|
||||
if (theParams.getSort() != null && isNotBlank(theParams.getSort().getParamName())) {
|
||||
List<Order> orders = new ArrayList<Order>();
|
||||
List<Predicate> predicates = new ArrayList<Predicate>();
|
||||
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Tuple> cq = builder.createTupleQuery();
|
||||
Root<ResourceTable> from = cq.from(ResourceTable.class);
|
||||
predicates.add(from.get("myId").in(loadPids));
|
||||
createSort(builder, from, theParams.getSort(), orders, predicates);
|
||||
if (orders.size() > 0) {
|
||||
Set<Long> originalPids = loadPids;
|
||||
loadPids = new LinkedHashSet<Long>();
|
||||
cq.multiselect(from.get("myId").as(Long.class));
|
||||
cq.where(predicates.toArray(new Predicate[0]));
|
||||
cq.orderBy(orders);
|
||||
|
||||
TypedQuery<Tuple> query = myEntityManager.createQuery(cq);
|
||||
|
||||
for (Tuple next : query.getResultList()) {
|
||||
loadPids.add(next.get(0, Long.class));
|
||||
}
|
||||
|
||||
ourLog.debug("Sort PID order is now: {}", loadPids);
|
||||
|
||||
pids = new ArrayList<Long>(loadPids);
|
||||
|
||||
// Any ressources which weren't matched by the sort get added to the bottom
|
||||
for (Long next : originalPids) {
|
||||
if (loadPids.contains(next) == false) {
|
||||
pids.add(next);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
pids = new ArrayList<Long>(loadPids);
|
||||
}
|
||||
} else {
|
||||
pids = new ArrayList<Long>(loadPids);
|
||||
}
|
||||
return pids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider search(String theParameterName, IQueryParameterType theValue) {
|
||||
return search(Collections.singletonMap(theParameterName, theValue));
|
||||
|
|
|
@ -8,13 +8,15 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>implements IFhirResourceDaoPatient<Patient> {
|
||||
|
||||
@Override
|
||||
public IBundleProvider everything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount) {
|
||||
public IBundleProvider everything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdated, SortSpec theSort) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
|
@ -23,6 +25,8 @@ public class FhirResourceDaoPatientDstu2 extends FhirResourceDaoDstu2<Patient>im
|
|||
paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(true);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
ca.uhn.fhir.rest.server.IBundleProvider retVal = search(paramMap);
|
||||
return retVal;
|
||||
|
|
|
@ -26,10 +26,12 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
|||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
|
||||
public interface IFhirResourceDaoPatient<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider everything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount);
|
||||
IBundleProvider everything(HttpServletRequest theServletRequest, IdDt theId, UnsignedIntDt theCount, DateRangeParam theLastUpdate, SortSpec theSort);
|
||||
|
||||
}
|
||||
|
|
|
@ -51,12 +51,12 @@ public class JpaValidationSupportDstu2 implements IValidationSupport {
|
|||
private FhirContext myDstu2Ctx;
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(ConceptSetComponent theInclude) {
|
||||
public ValueSetExpansionComponent expandValueSet(FhirContext theCtx, ConceptSetComponent theInclude) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet fetchCodeSystem(String theSystem) {
|
||||
public ValueSet fetchCodeSystem(FhirContext theCtx, String theSystem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -85,20 +85,19 @@ public class JpaValidationSupportDstu2 implements IValidationSupport {
|
|||
/*
|
||||
* Validator wants RI structures and not HAPI ones, so convert
|
||||
*
|
||||
* TODO: we really need a more efficient way of converting.. Or maybe this will
|
||||
* just go away when we move to RI structures
|
||||
* TODO: we really need a more efficient way of converting.. Or maybe this will just go away when we move to RI structures
|
||||
*/
|
||||
String encoded = myDstu2Ctx.newJsonParser().encodeResourceToString(res);
|
||||
return myRiCtx.newJsonParser().parseResource(theClass, encoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(String theSystem) {
|
||||
public boolean isCodeSystemSupported(FhirContext theCtx, String theSystem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeValidationResult validateCode(String theCodeSystem, String theCode, String theDisplay) {
|
||||
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ import ca.uhn.fhir.model.dstu2.resource.Patient;
|
|||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu2<Patient> {
|
||||
|
||||
|
@ -18,12 +22,21 @@ public class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu
|
|||
ca.uhn.fhir.model.primitive.IdDt theId,
|
||||
|
||||
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
|
||||
@OperationParam(name = "_count")
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount) {
|
||||
@OperationParam(name = Constants.PARAM_COUNT)
|
||||
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
|
||||
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
// @OperationParam(name = Constants.PARAM_SORT, min=0, max=1)
|
||||
@Sort
|
||||
SortSpec theSortSpec
|
||||
) {
|
||||
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
return ((IFhirResourceDaoPatient<Patient>)getDao()).everything(theServletRequest, theId, theCount);
|
||||
return ((IFhirResourceDaoPatient<Patient>)getDao()).everything(theServletRequest, theId, theCount, theLastUpdated, theSortSpec);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
|
|
|
@ -602,6 +602,96 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEverythingWithLastUpdatedAndSort() throws Exception {
|
||||
String methodName = "testEverythingWithLastUpdatedAndSort";
|
||||
|
||||
long time0 = System.currentTimeMillis();
|
||||
Thread.sleep(10);
|
||||
|
||||
Organization org = new Organization();
|
||||
org.setName(methodName);
|
||||
IIdType oId = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
long time1 = System.currentTimeMillis();
|
||||
Thread.sleep(10);
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addName().addFamily(methodName);
|
||||
p.getManagingOrganization().setReference(oId);
|
||||
IIdType pId = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
long time2 = System.currentTimeMillis();
|
||||
Thread.sleep(10);
|
||||
|
||||
Condition c = new Condition();
|
||||
c.getCode().setText(methodName);
|
||||
c.getPatient().setReference(pId);
|
||||
IIdType cId = ourClient.create().resource(c).execute().getId().toUnqualifiedVersionless();
|
||||
|
||||
Thread.sleep(10);
|
||||
long time3 = System.currentTimeMillis();
|
||||
|
||||
// %3E=> %3C=<
|
||||
|
||||
HttpGet get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantDt(new Date(time1)).getValueAsString());
|
||||
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
List<IdDt> ids = toIdListUnqualifiedVersionless(myFhirCtx.newXmlParser().parseBundle(output));
|
||||
ourLog.info(ids.toString());
|
||||
assertThat(ids, containsInAnyOrder(pId, cId));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantDt(new Date(time2)).getValueAsString() + "&_lastUpdated=%3C" + new InstantDt(new Date(time3)).getValueAsString());
|
||||
response = ourHttpClient.execute(get);
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
List<IdDt> ids = toIdListUnqualifiedVersionless(myFhirCtx.newXmlParser().parseBundle(output));
|
||||
ourLog.info(ids.toString());
|
||||
assertThat(ids, containsInAnyOrder(cId));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_lastUpdated=%3E" + new InstantDt(new Date(time1)).getValueAsString() + "&_sort=_lastUpdated");
|
||||
response = ourHttpClient.execute(get);
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
List<IdDt> ids = toIdListUnqualifiedVersionless(myFhirCtx.newXmlParser().parseBundle(output));
|
||||
ourLog.info(ids.toString());
|
||||
assertThat(ids, contains(pId, cId));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
get = new HttpGet(ourServerBase + "/Patient/" + pId.getIdPart() + "/$everything?_sort:desc=_lastUpdated");
|
||||
response = ourHttpClient.execute(get);
|
||||
try {
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
String output = IOUtils.toString(response.getEntity().getContent());
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
ourLog.info(output);
|
||||
List<IdDt> ids = toIdListUnqualifiedVersionless(myFhirCtx.newXmlParser().parseBundle(output));
|
||||
ourLog.info(ids.toString());
|
||||
assertThat(ids, contains(cId, pId, oId));
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #148
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,9 @@ package ca.uhn.fhir.validation;
|
|||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -116,7 +118,7 @@ public class FhirInstanceValidatorTest {
|
|||
@Override
|
||||
public ValueSet answer(InvocationOnMock theInvocation) throws Throwable {
|
||||
ValueSet retVal = myDefaultValidationSupport.fetchCodeSystem((FhirContext) theInvocation.getArguments()[0],(String) theInvocation.getArguments()[1]);
|
||||
ourLog.info("fetchCodeSystem({}) : {}", new Object[] { (String) theInvocation.getArguments()[0], retVal });
|
||||
ourLog.info("fetchCodeSystem({}) : {}", new Object[] { (String) theInvocation.getArguments()[1], retVal });
|
||||
return retVal;
|
||||
}
|
||||
});
|
||||
|
@ -378,7 +380,9 @@ public class FhirInstanceValidatorTest {
|
|||
|
||||
ValidationResult output = myVal.validateWithResult(input);
|
||||
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
|
||||
assertEquals(errors.toString(), 0, errors.size());
|
||||
assertEquals(errors.toString(), 1, errors.size());
|
||||
assertEquals("Unable to validate code \"1234\" in code system \"http://loinc.org\"", errors.get(0).getMessage());
|
||||
assertEquals(ResultSeverityEnum.WARNING, errors.get(0).getSeverity());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -91,6 +91,10 @@
|
|||
Profile validator now works for valuesets which use
|
||||
v2 tables
|
||||
</action>
|
||||
<action type="add">
|
||||
JPA server Patient/[id]/$everything operation now supports
|
||||
_lastUpdated filtering and _sort'ing of results.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue