Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
d28122ff3e
|
@ -1889,7 +1889,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Include next : myRevInclude) {
|
for (Include next : myRevInclude) {
|
||||||
addParam(params, Constants.PARAM_REVINCLUDE, next.getValue());
|
if (next.isRecurse()) {
|
||||||
|
addParam(params, Constants.PARAM_REVINCLUDE_RECURSE, next.getValue());
|
||||||
|
} else {
|
||||||
|
addParam(params, Constants.PARAM_REVINCLUDE, next.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2)) {
|
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2)) {
|
||||||
|
|
|
@ -40,11 +40,13 @@ public class Constants {
|
||||||
public static final String CT_HTML = "text/html";
|
public static final String CT_HTML = "text/html";
|
||||||
public static final String CT_HTML_WITH_UTF8 = "text/html" + CHARSET_UTF8_CTSUFFIX;
|
public static final String CT_HTML_WITH_UTF8 = "text/html" + CHARSET_UTF8_CTSUFFIX;
|
||||||
public static final String CT_JSON = "application/json";
|
public static final String CT_JSON = "application/json";
|
||||||
|
public static final String CT_JSON_PATCH = "application/json-patch+json";
|
||||||
public static final String CT_OCTET_STREAM = "application/octet-stream";
|
public static final String CT_OCTET_STREAM = "application/octet-stream";
|
||||||
public static final String CT_TEXT = "text/plain";
|
public static final String CT_TEXT = "text/plain";
|
||||||
public static final String CT_TEXT_WITH_UTF8 = CT_TEXT + CHARSET_UTF8_CTSUFFIX;
|
public static final String CT_TEXT_WITH_UTF8 = CT_TEXT + CHARSET_UTF8_CTSUFFIX;
|
||||||
public static final String CT_X_FORM_URLENCODED = "application/x-www-form-urlencoded";
|
public static final String CT_X_FORM_URLENCODED = "application/x-www-form-urlencoded";
|
||||||
public static final String CT_XML = "application/xml";
|
public static final String CT_XML = "application/xml";
|
||||||
|
public static final String CT_XML_PATCH = "application/xml-patch+xml";
|
||||||
public static final String ENCODING_GZIP = "gzip";
|
public static final String ENCODING_GZIP = "gzip";
|
||||||
public static final String EXTOP_VALIDATE = "$validate";
|
public static final String EXTOP_VALIDATE = "$validate";
|
||||||
public static final String EXTOP_VALIDATE_MODE = "mode";
|
public static final String EXTOP_VALIDATE_MODE = "mode";
|
||||||
|
@ -61,10 +63,10 @@ public class Constants {
|
||||||
public static final String FORMATS_HTML_XML = "html/xml";
|
public static final String FORMATS_HTML_XML = "html/xml";
|
||||||
public static final String HEADER_ACCEPT = "Accept";
|
public static final String HEADER_ACCEPT = "Accept";
|
||||||
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
||||||
|
public static final String HEADER_ACCEPT_VALUE_JSON_NON_LEGACY = CT_FHIR_JSON_NEW + ";q=1.0, " + CT_FHIR_JSON + ";q=0.9";
|
||||||
|
public static final String HEADER_ACCEPT_VALUE_XML_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_XML + ";q=0.9";
|
||||||
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
||||||
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_JSON_NEW + ";q=1.0, " + HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY.replace("1.0", "0.9");
|
public static final String HEADER_ACCEPT_VALUE_XML_OR_JSON_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_JSON_NEW + ";q=1.0, " + HEADER_ACCEPT_VALUE_XML_OR_JSON_LEGACY.replace("1.0", "0.9");
|
||||||
public static final String HEADER_ACCEPT_VALUE_XML_NON_LEGACY = CT_FHIR_XML_NEW + ";q=1.0, " + CT_FHIR_XML + ";q=0.9";
|
|
||||||
public static final String HEADER_ACCEPT_VALUE_JSON_NON_LEGACY = CT_FHIR_JSON_NEW + ";q=1.0, " + CT_FHIR_JSON + ";q=0.9";
|
|
||||||
public static final String HEADER_ALLOW = "Allow";
|
public static final String HEADER_ALLOW = "Allow";
|
||||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||||
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
||||||
|
@ -127,10 +129,12 @@ public class Constants {
|
||||||
public static final String PARAM_PAGINGACTION = "_getpages";
|
public static final String PARAM_PAGINGACTION = "_getpages";
|
||||||
public static final String PARAM_PAGINGOFFSET = "_getpagesoffset";
|
public static final String PARAM_PAGINGOFFSET = "_getpagesoffset";
|
||||||
public static final String PARAM_PRETTY = "_pretty";
|
public static final String PARAM_PRETTY = "_pretty";
|
||||||
|
public static final String PARAM_PRETTY_VALUE_FALSE = "false";
|
||||||
public static final String PARAM_PRETTY_VALUE_TRUE = "true";
|
public static final String PARAM_PRETTY_VALUE_TRUE = "true";
|
||||||
public static final String PARAM_PROFILE = "_profile";
|
public static final String PARAM_PROFILE = "_profile";
|
||||||
public static final String PARAM_QUERY = "_query";
|
public static final String PARAM_QUERY = "_query";
|
||||||
public static final String PARAM_REVINCLUDE = "_revinclude";
|
public static final String PARAM_REVINCLUDE = "_revinclude";
|
||||||
|
public static final String PARAM_REVINCLUDE_RECURSE = PARAM_REVINCLUDE+PARAM_INCLUDE_QUALIFIER_RECURSE;
|
||||||
public static final String PARAM_SEARCH = "_search";
|
public static final String PARAM_SEARCH = "_search";
|
||||||
public static final String PARAM_SECURITY = "_security";
|
public static final String PARAM_SECURITY = "_security";
|
||||||
public static final String PARAM_SINCE = "_since";
|
public static final String PARAM_SINCE = "_since";
|
||||||
|
@ -156,11 +160,11 @@ public class Constants {
|
||||||
public static final int STATUS_HTTP_401_CLIENT_UNAUTHORIZED = 401;
|
public static final int STATUS_HTTP_401_CLIENT_UNAUTHORIZED = 401;
|
||||||
public static final int STATUS_HTTP_403_FORBIDDEN = 403;
|
public static final int STATUS_HTTP_403_FORBIDDEN = 403;
|
||||||
public static final int STATUS_HTTP_404_NOT_FOUND = 404;
|
public static final int STATUS_HTTP_404_NOT_FOUND = 404;
|
||||||
|
|
||||||
public static final int STATUS_HTTP_405_METHOD_NOT_ALLOWED = 405;
|
public static final int STATUS_HTTP_405_METHOD_NOT_ALLOWED = 405;
|
||||||
public static final int STATUS_HTTP_409_CONFLICT = 409;
|
public static final int STATUS_HTTP_409_CONFLICT = 409;
|
||||||
public static final int STATUS_HTTP_410_GONE = 410;
|
public static final int STATUS_HTTP_410_GONE = 410;
|
||||||
public static final int STATUS_HTTP_412_PRECONDITION_FAILED = 412;
|
public static final int STATUS_HTTP_412_PRECONDITION_FAILED = 412;
|
||||||
|
|
||||||
public static final int STATUS_HTTP_422_UNPROCESSABLE_ENTITY = 422;
|
public static final int STATUS_HTTP_422_UNPROCESSABLE_ENTITY = 422;
|
||||||
public static final int STATUS_HTTP_500_INTERNAL_ERROR = 500;
|
public static final int STATUS_HTTP_500_INTERNAL_ERROR = 500;
|
||||||
public static final int STATUS_HTTP_501_NOT_IMPLEMENTED = 501;
|
public static final int STATUS_HTTP_501_NOT_IMPLEMENTED = 501;
|
||||||
|
@ -168,9 +172,6 @@ public class Constants {
|
||||||
public static final String TAG_SUBSETTED_SYSTEM = "http://hl7.org/fhir/v3/ObservationValue";
|
public static final String TAG_SUBSETTED_SYSTEM = "http://hl7.org/fhir/v3/ObservationValue";
|
||||||
public static final String URL_TOKEN_HISTORY = "_history";
|
public static final String URL_TOKEN_HISTORY = "_history";
|
||||||
public static final String URL_TOKEN_METADATA = "metadata";
|
public static final String URL_TOKEN_METADATA = "metadata";
|
||||||
public static final String CT_JSON_PATCH = "application/json-patch+json";
|
|
||||||
public static final String CT_XML_PATCH = "application/xml-patch+xml";
|
|
||||||
public static final String PARAM_PRETTY_VALUE_FALSE = "false";
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CHARSET_UTF8 = Charset.forName(CHARSET_NAME_UTF8);
|
CHARSET_UTF8 = Charset.forName(CHARSET_NAME_UTF8);
|
||||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.util;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.IBase;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
|
@ -84,6 +85,7 @@ public class ParametersUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IBaseParameters newInstance(FhirContext theContext) {
|
public static IBaseParameters newInstance(FhirContext theContext) {
|
||||||
|
Validate.notNull(theContext, "theContext must not be null");
|
||||||
return (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance();
|
return (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public class BaseDstu2Config extends BaseConfig {
|
||||||
public ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2 systemProviderDstu2() {
|
public ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2 systemProviderDstu2() {
|
||||||
ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2 retVal = new ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2();
|
ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2 retVal = new ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2();
|
||||||
retVal.setDao(systemDaoDstu2());
|
retVal.setDao(systemDaoDstu2());
|
||||||
|
retVal.setContext(fhirContextDstu2());
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,29 +22,15 @@ package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import org.hl7.fhir.dstu3.model.IdType;
|
import org.hl7.fhir.dstu3.model.IdType;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseMetaType;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Required;
|
import org.springframework.beans.factory.annotation.Required;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
@ -59,42 +45,21 @@ import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseTag;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceLink;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
|
||||||
import ca.uhn.fhir.jpa.interceptor.IJpaServerInterceptor;
|
import ca.uhn.fhir.jpa.interceptor.IJpaServerInterceptor;
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||||
import ca.uhn.fhir.jpa.util.DeleteConflict;
|
import ca.uhn.fhir.jpa.util.DeleteConflict;
|
||||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||||
import ca.uhn.fhir.jpa.util.jsonpatch.JsonPatchUtils;
|
import ca.uhn.fhir.jpa.util.jsonpatch.JsonPatchUtils;
|
||||||
import ca.uhn.fhir.jpa.util.xmlpatch.XmlPatchUtils;
|
import ca.uhn.fhir.jpa.util.xmlpatch.XmlPatchUtils;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
import ca.uhn.fhir.model.api.*;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
|
||||||
import ca.uhn.fhir.model.api.Include;
|
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
|
||||||
import ca.uhn.fhir.model.api.TagList;
|
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.api.PatchTypeEnum;
|
import ca.uhn.fhir.rest.api.PatchTypeEnum;
|
||||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
import ca.uhn.fhir.rest.method.MethodUtil;
|
import ca.uhn.fhir.rest.method.*;
|
||||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
|
||||||
import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
|
||||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
|
||||||
import ca.uhn.fhir.rest.method.SearchMethodBinding.QualifierDetails;
|
import ca.uhn.fhir.rest.method.SearchMethodBinding.QualifierDetails;
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.*;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||||
import ca.uhn.fhir.util.FhirTerser;
|
import ca.uhn.fhir.util.FhirTerser;
|
||||||
|
@ -110,14 +75,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
@Autowired
|
@Autowired
|
||||||
private DaoConfig myDaoConfig;
|
private DaoConfig myDaoConfig;
|
||||||
@Autowired
|
@Autowired
|
||||||
protected IResourceTableDao myResourceTableDao;
|
|
||||||
@Autowired
|
|
||||||
protected PlatformTransactionManager myPlatformTransactionManager;
|
protected PlatformTransactionManager myPlatformTransactionManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IResourceHistoryTableDao myResourceHistoryTableDao;
|
private IResourceHistoryTableDao myResourceHistoryTableDao;
|
||||||
@Autowired()
|
@Autowired()
|
||||||
protected IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
|
protected IResourceIndexedSearchParamUriDao myResourceIndexedSearchParamUriDao;
|
||||||
private String myResourceName;
|
private String myResourceName;
|
||||||
|
@Autowired
|
||||||
|
protected IResourceTableDao myResourceTableDao;
|
||||||
private Class<T> myResourceType;
|
private Class<T> myResourceType;
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
protected IFulltextSearchSvc mySearchDao;
|
protected IFulltextSearchSvc mySearchDao;
|
||||||
|
@ -226,7 +191,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
T resourceToDelete = toResource(myResourceType, entity, false);
|
T resourceToDelete = toResource(myResourceType, entity, false);
|
||||||
|
|
||||||
validateOkToDelete(deleteConflicts, entity);
|
validateOkToDelete(deleteConflicts, entity);
|
||||||
|
|
||||||
|
preDelete(resourceToDelete);
|
||||||
|
|
||||||
// Notify interceptors
|
// Notify interceptors
|
||||||
if (theRequestDetails != null) {
|
if (theRequestDetails != null) {
|
||||||
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getContext(), theId.getResourceType(), theId);
|
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getContext(), theId.getResourceType(), theId);
|
||||||
|
@ -259,10 +226,18 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
|
|
||||||
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
||||||
|
|
||||||
|
IBaseOperationOutcome oo = OperationOutcomeUtil.newInstance(getContext());
|
||||||
|
String message = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulDeletes", 1, w.getMillis());
|
||||||
|
String severity = "information";
|
||||||
|
String code = "informational";
|
||||||
|
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
||||||
|
|
||||||
ourLog.info("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
|
ourLog.info("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
|
||||||
return toMethodOutcome(savedEntity, null);
|
DaoMethodOutcome retVal = toMethodOutcome(savedEntity, null);
|
||||||
|
retVal.setOperationOutcome(oo);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ResourceTable> deleteByUrl(String theUrl, List<DeleteConflict> deleteConflicts, RequestDetails theRequestDetails) {
|
public List<ResourceTable> deleteByUrl(String theUrl, List<DeleteConflict> deleteConflicts, RequestDetails theRequestDetails) {
|
||||||
Set<Long> resource = processMatchUrl(theUrl, myResourceType);
|
Set<Long> resource = processMatchUrl(theUrl, myResourceType);
|
||||||
|
@ -301,7 +276,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DaoMethodOutcome deleteByUrl(String theUrl, RequestDetails theRequestDetails) {
|
public DaoMethodOutcome deleteByUrl(String theUrl, RequestDetails theRequestDetails) {
|
||||||
StopWatch w = new StopWatch();
|
StopWatch w = new StopWatch();
|
||||||
|
@ -320,7 +295,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
||||||
} else {
|
} else {
|
||||||
oo = OperationOutcomeUtil.newInstance(getContext());
|
oo = OperationOutcomeUtil.newInstance(getContext());
|
||||||
String message = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulDeletes", theUrl, deletedResources.size(), w.getMillis());
|
String message = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulDeletes", deletedResources.size(), w.getMillis());
|
||||||
String severity = "information";
|
String severity = "information";
|
||||||
String code = "informational";
|
String code = "informational";
|
||||||
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
||||||
|
@ -553,6 +528,38 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <MT extends IBaseMetaType> MT metaDeleteOperation(IIdType theResourceId, MT theMetaDel, RequestDetails theRequestDetails) {
|
||||||
|
// Notify interceptors
|
||||||
|
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theResourceId);
|
||||||
|
notifyInterceptors(RestOperationTypeEnum.META_DELETE, requestDetails);
|
||||||
|
|
||||||
|
StopWatch w = new StopWatch();
|
||||||
|
BaseHasResource entity = readEntity(theResourceId);
|
||||||
|
if (entity == null) {
|
||||||
|
throw new ResourceNotFoundException(theResourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceTable latestVersion = readEntityLatestVersion(theResourceId);
|
||||||
|
if (latestVersion.getVersion() != entity.getVersion()) {
|
||||||
|
doMetaDelete(theMetaDel, entity);
|
||||||
|
} else {
|
||||||
|
doMetaDelete(theMetaDel, latestVersion);
|
||||||
|
|
||||||
|
// Also update history entry
|
||||||
|
ResourceHistoryTable history = myResourceHistoryTableDao.findForIdAndVersion(entity.getId(), entity.getVersion());
|
||||||
|
doMetaDelete(theMetaDel, history);
|
||||||
|
}
|
||||||
|
|
||||||
|
myEntityManager.flush();
|
||||||
|
|
||||||
|
ourLog.info("Processed metaDeleteOperation on {} in {}ms", new Object[] { theResourceId.getValue(), w.getMillisAndRestart() });
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
MT retVal = (MT) metaGetOperation(theMetaDel.getClass(), theResourceId, theRequestDetails);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// public IBundleProvider everything(IIdType theId) {
|
// public IBundleProvider everything(IIdType theId) {
|
||||||
// Search search = new Search();
|
// Search search = new Search();
|
||||||
|
@ -635,38 +642,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
// };
|
// };
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@Override
|
|
||||||
public <MT extends IBaseMetaType> MT metaDeleteOperation(IIdType theResourceId, MT theMetaDel, RequestDetails theRequestDetails) {
|
|
||||||
// Notify interceptors
|
|
||||||
ActionRequestDetails requestDetails = new ActionRequestDetails(theRequestDetails, getResourceName(), theResourceId);
|
|
||||||
notifyInterceptors(RestOperationTypeEnum.META_DELETE, requestDetails);
|
|
||||||
|
|
||||||
StopWatch w = new StopWatch();
|
|
||||||
BaseHasResource entity = readEntity(theResourceId);
|
|
||||||
if (entity == null) {
|
|
||||||
throw new ResourceNotFoundException(theResourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceTable latestVersion = readEntityLatestVersion(theResourceId);
|
|
||||||
if (latestVersion.getVersion() != entity.getVersion()) {
|
|
||||||
doMetaDelete(theMetaDel, entity);
|
|
||||||
} else {
|
|
||||||
doMetaDelete(theMetaDel, latestVersion);
|
|
||||||
|
|
||||||
// Also update history entry
|
|
||||||
ResourceHistoryTable history = myResourceHistoryTableDao.findForIdAndVersion(entity.getId(), entity.getVersion());
|
|
||||||
doMetaDelete(theMetaDel, history);
|
|
||||||
}
|
|
||||||
|
|
||||||
myEntityManager.flush();
|
|
||||||
|
|
||||||
ourLog.info("Processed metaDeleteOperation on {} in {}ms", new Object[] { theResourceId.getValue(), w.getMillisAndRestart() });
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
MT retVal = (MT) metaGetOperation(theMetaDel.getClass(), theResourceId, theRequestDetails);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <MT extends IBaseMetaType> MT metaGetOperation(Class<MT> theType, IIdType theId, RequestDetails theRequestDetails) {
|
public <MT extends IBaseMetaType> MT metaGetOperation(Class<MT> theType, IIdType theId, RequestDetails theRequestDetails) {
|
||||||
// Notify interceptors
|
// Notify interceptors
|
||||||
|
@ -743,6 +718,14 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses may override to provide behaviour. Invoked within a delete
|
||||||
|
* transaction with the resource that is about to be deleted.
|
||||||
|
*/
|
||||||
|
protected void preDelete(T theResourceToDelete) {
|
||||||
|
// nothing by default
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* May be overridden by subclasses to validate resources prior to storage
|
* May be overridden by subclasses to validate resources prior to storage
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import javax.persistence.Query;
|
import javax.persistence.Query;
|
||||||
import javax.persistence.Tuple;
|
import javax.persistence.Tuple;
|
||||||
|
@ -64,15 +65,17 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirSystemDao.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirSystemDao.class);
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PlatformTransactionManager myTxManager;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IForcedIdDao myForcedIdDao;
|
private IForcedIdDao myForcedIdDao;
|
||||||
|
|
||||||
|
private ReentrantLock myReindexLock = new ReentrantLock(false);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ITermConceptDao myTermConceptDao;
|
private ITermConceptDao myTermConceptDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformTransactionManager myTxManager;
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
@Override
|
@Override
|
||||||
public void deleteAllTagsOnServer(RequestDetails theRequestDetails) {
|
public void deleteAllTagsOnServer(RequestDetails theRequestDetails) {
|
||||||
|
@ -205,8 +208,14 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
|
||||||
@Transactional()
|
@Transactional()
|
||||||
@Override
|
@Override
|
||||||
public int markAllResourcesForReindexing() {
|
public int markAllResourcesForReindexing() {
|
||||||
|
|
||||||
|
ourLog.info("Marking all resources as needing reindexing");
|
||||||
int retVal = myEntityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " t SET t.myIndexStatus = null").executeUpdate();
|
int retVal = myEntityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " t SET t.myIndexStatus = null").executeUpdate();
|
||||||
|
|
||||||
|
ourLog.info("Marking all concepts as needing reindexing");
|
||||||
retVal += myTermConceptDao.markAllForReindexing();
|
retVal += myTermConceptDao.markAllForReindexing();
|
||||||
|
|
||||||
|
ourLog.info("Done marking reindexing");
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,16 +275,21 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||||
public int performReindexingPass(final Integer theCount) {
|
public int performReindexingPass(final Integer theCount) {
|
||||||
|
if (!myReindexLock.tryLock()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return doPerformReindexingPass(theCount);
|
return doPerformReindexingPass(theCount);
|
||||||
} catch (ReindexFailureException e) {
|
} catch (ReindexFailureException e) {
|
||||||
ourLog.warn("Reindexing failed for resource {}", e.getResourceId());
|
ourLog.warn("Reindexing failed for resource {}", e.getResourceId());
|
||||||
markResourceAsIndexingFailed(e.getResourceId());
|
markResourceAsIndexingFailed(e.getResourceId());
|
||||||
return -1;
|
return -1;
|
||||||
|
} finally {
|
||||||
|
myReindexLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ca.uhn.fhir.jpa.dao.data;
|
package ca.uhn.fhir.jpa.dao.data;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR JPA Server
|
* HAPI FHIR JPA Server
|
||||||
|
@ -32,5 +34,8 @@ public interface ITermConceptParentChildLinkDao extends JpaRepository<TermConcep
|
||||||
@Query("DELETE FROM TermConceptParentChildLink t WHERE t.myCodeSystem.myId = :cs_pid")
|
@Query("DELETE FROM TermConceptParentChildLink t WHERE t.myCodeSystem.myId = :cs_pid")
|
||||||
@Modifying
|
@Modifying
|
||||||
void deleteByCodeSystemVersion(@Param("cs_pid") Long thePid);
|
void deleteByCodeSystemVersion(@Param("cs_pid") Long thePid);
|
||||||
|
|
||||||
|
@Query("SELECT t FROM TermConceptParentChildLink t WHERE t.myChildPid = :child_pid")
|
||||||
|
Collection<TermConceptParentChildLink> findAllWithChild(@Param("child_pid") Long theConceptPid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
|
||||||
|
import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
@ -187,6 +188,9 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ITermCodeSystemVersionDao myCsvDao;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ResourceTable updateEntity(IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
protected ResourceTable updateEntity(IBaseResource theResource, ResourceTable theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||||
boolean theUpdateVersion, Date theUpdateTime) {
|
boolean theUpdateVersion, Date theUpdateTime) {
|
||||||
|
@ -198,12 +202,22 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
|
||||||
String codeSystemUrl = cs.getUrl();
|
String codeSystemUrl = cs.getUrl();
|
||||||
if (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == null) {
|
if (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == null) {
|
||||||
ourLog.info("CodeSystem {} has a status of {}, going to store concepts in terminology tables", retVal.getIdDt().getValue(), cs.getContentElement().getValueAsString());
|
ourLog.info("CodeSystem {} has a status of {}, going to store concepts in terminology tables", retVal.getIdDt().getValue(), cs.getContentElement().getValueAsString());
|
||||||
TermCodeSystemVersion persCs = new TermCodeSystemVersion();
|
|
||||||
persCs.setResource(retVal);
|
Long codeSystemResourcePid = retVal.getId();
|
||||||
persCs.setResourceVersionId(retVal.getVersion());
|
TermCodeSystemVersion persCs = myCsvDao.findByCodeSystemResourceAndVersion(codeSystemResourcePid, retVal.getVersion());
|
||||||
persCs.getConcepts().addAll(toPersistedConcepts(cs.getConcept(), persCs));
|
if (persCs != null) {
|
||||||
|
ourLog.info("Code system version already exists in database");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
persCs = new TermCodeSystemVersion();
|
||||||
|
persCs.setResource(retVal);
|
||||||
|
persCs.setResourceVersionId(retVal.getVersion());
|
||||||
|
persCs.getConcepts().addAll(toPersistedConcepts(cs.getConcept(), persCs));
|
||||||
|
ourLog.info("Code system has {} concepts", persCs.getConcepts().size());
|
||||||
|
myTerminologySvc.storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, persCs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
myTerminologySvc.storeNewCodeSystemVersion(retVal.getId(), codeSystemUrl, persCs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR JPA Server
|
* HAPI FHIR JPA Server
|
||||||
|
@ -33,6 +35,7 @@ import ca.uhn.fhir.jpa.dao.BaseSearchParamExtractor;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSearchParameter;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSearchParameter;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
|
import ca.uhn.fhir.jpa.util.DeleteConflict;
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
|
@ -45,13 +48,16 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3<Se
|
||||||
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
||||||
|
|
||||||
private void markAffectedResources(SearchParameter theResource) {
|
private void markAffectedResources(SearchParameter theResource) {
|
||||||
String xpath = theResource.getXpath();
|
if (theResource != null) {
|
||||||
String resourceType = xpath.substring(0, xpath.indexOf('.'));
|
String expression = theResource.getExpression();
|
||||||
ourLog.info("Marking all resources of type {} for reindexing due to updated search parameter with path: {}", xpath);
|
String resourceType = expression.substring(0, expression.indexOf('.'));
|
||||||
int updatedCount = myResourceTableDao.markResourcesOfTypeAsRequiringReindexing(resourceType);
|
ourLog.info("Marking all resources of type {} for reindexing due to updated search parameter with path: {}", expression);
|
||||||
ourLog.info("Marked {} resources for reindexing", updatedCount);
|
int updatedCount = myResourceTableDao.markResourcesOfTypeAsRequiringReindexing(resourceType);
|
||||||
|
ourLog.info("Marked {} resources for reindexing", updatedCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called once per minute to perform any required re-indexing. During most passes this will
|
* This method is called once per minute to perform any required re-indexing. During most passes this will
|
||||||
* just check and find that there are no resources requiring re-indexing. In that case the method just returns
|
* just check and find that there are no resources requiring re-indexing. In that case the method just returns
|
||||||
|
@ -77,13 +83,22 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3<Se
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void preDelete(SearchParameter theResourceToDelete) {
|
||||||
|
super.preDelete(theResourceToDelete);
|
||||||
|
markAffectedResources(theResourceToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postPersist(ResourceTable theEntity, SearchParameter theResource) {
|
protected void postPersist(ResourceTable theEntity, SearchParameter theResource) {
|
||||||
|
super.postPersist(theEntity, theResource);
|
||||||
markAffectedResources(theResource);
|
markAffectedResources(theResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource) {
|
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource) {
|
||||||
|
super.postUpdate(theEntity, theResource);
|
||||||
markAffectedResources(theResource);
|
markAffectedResources(theResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,37 +107,37 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3<Se
|
||||||
super.validateResourceForStorage(theResource, theEntityToSave);
|
super.validateResourceForStorage(theResource, theEntityToSave);
|
||||||
|
|
||||||
if (theResource.getStatus() == null) {
|
if (theResource.getStatus() == null) {
|
||||||
throw new UnprocessableEntityException("Resource.status is missing or invalid: " + theResource.getStatusElement().getValueAsString());
|
throw new UnprocessableEntityException("SearchParameter.status is missing or invalid: " + theResource.getStatusElement().getValueAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
String xpath = theResource.getXpath();
|
String expression = theResource.getExpression();
|
||||||
if (isBlank(xpath)) {
|
if (isBlank(expression)) {
|
||||||
throw new UnprocessableEntityException("Resource.xpath is missing");
|
throw new UnprocessableEntityException("SearchParameter.expression is missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] xpathSplit = BaseSearchParamExtractor.SPLIT.split(xpath);
|
String[] expressionSplit = BaseSearchParamExtractor.SPLIT.split(expression);
|
||||||
String allResourceName = null;
|
String allResourceName = null;
|
||||||
for (String nextPath : xpathSplit) {
|
for (String nextPath : expressionSplit) {
|
||||||
int dotIdx = nextPath.indexOf('.');
|
int dotIdx = nextPath.indexOf('.');
|
||||||
if (dotIdx == -1) {
|
if (dotIdx == -1) {
|
||||||
throw new UnprocessableEntityException("Invalid path value \"" + nextPath + "\". Must start with a resource name");
|
throw new UnprocessableEntityException("Invalid SearchParameter.expression value \"" + nextPath + "\". Must start with a resource name");
|
||||||
}
|
}
|
||||||
|
|
||||||
String resourceName = nextPath.substring(0, dotIdx);
|
String resourceName = nextPath.substring(0, dotIdx);
|
||||||
try {
|
try {
|
||||||
getContext().getResourceDefinition(resourceName);
|
getContext().getResourceDefinition(resourceName);
|
||||||
} catch (DataFormatException e) {
|
} catch (DataFormatException e) {
|
||||||
throw new UnprocessableEntityException("Invalid path value \"" + nextPath + "\": " + e.getMessage());
|
throw new UnprocessableEntityException("Invalid SearchParameter.expression value \"" + nextPath + "\": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allResourceName == null) {
|
if (allResourceName == null) {
|
||||||
allResourceName = resourceName;
|
allResourceName = resourceName;
|
||||||
} else {
|
} else {
|
||||||
if (!allResourceName.equals(resourceName)) {
|
if (!allResourceName.equals(resourceName)) {
|
||||||
throw new UnprocessableEntityException("Invalid path value \"" + nextPath + "\". All paths in a single SearchParameter must match the same resource type");
|
throw new UnprocessableEntityException("Invalid SearchParameter.expression value \"" + nextPath + "\". All paths in a single SearchParameter must match the same resource type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ public class SearchParamRegistryDstu3 extends BaseSearchParamRegistry {
|
||||||
private RuntimeSearchParam toRuntimeSp(SearchParameter theNextSp) {
|
private RuntimeSearchParam toRuntimeSp(SearchParameter theNextSp) {
|
||||||
String name = theNextSp.getCode();
|
String name = theNextSp.getCode();
|
||||||
String description = theNextSp.getDescription();
|
String description = theNextSp.getDescription();
|
||||||
String path = theNextSp.getXpath();
|
String path = theNextSp.getExpression();
|
||||||
RestSearchParameterTypeEnum paramType = null;
|
RestSearchParameterTypeEnum paramType = null;
|
||||||
RuntimeSearchParamStatusEnum status = null;
|
RuntimeSearchParamStatusEnum status = null;
|
||||||
switch (theNextSp.getType()) {
|
switch (theNextSp.getType()) {
|
||||||
|
|
|
@ -233,12 +233,14 @@ public class TermConcept implements Serializable {
|
||||||
@PreUpdate
|
@PreUpdate
|
||||||
@PrePersist
|
@PrePersist
|
||||||
public void prePersist() {
|
public void prePersist() {
|
||||||
Set<Long> parentPids = new HashSet<Long>();
|
if (myParentPids == null) {
|
||||||
TermConcept entity = this;
|
Set<Long> parentPids = new HashSet<Long>();
|
||||||
parentPids(entity, parentPids);
|
TermConcept entity = this;
|
||||||
entity.setParentPids(parentPids);
|
parentPids(entity, parentPids);
|
||||||
|
entity.setParentPids(parentPids);
|
||||||
ourLog.trace("Code {}/{} has parents {}", entity.getId(), entity.getCode(), entity.getParentPidsAsString());
|
|
||||||
|
ourLog.trace("Code {}/{} has parents {}", entity.getId(), entity.getCode(), entity.getParentPidsAsString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCode(String theCode) {
|
public void setCode(String theCode) {
|
||||||
|
@ -280,6 +282,10 @@ public class TermConcept implements Serializable {
|
||||||
myParentPids = b.toString();
|
myParentPids = b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setParentPids(String theParentPids) {
|
||||||
|
myParentPids = theParentPids;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("code", myCode).append("display", myDisplay).build();
|
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("code", myCode).append("display", myDisplay).build();
|
||||||
|
|
|
@ -10,7 +10,7 @@ package ca.uhn.fhir.jpa.entity;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -36,77 +36,38 @@ import javax.persistence.SequenceGenerator;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name="TRM_CONCEPT_PC_LINK")
|
@Table(name = "TRM_CONCEPT_PC_LINK")
|
||||||
public class TermConceptParentChildLink implements Serializable {
|
public class TermConceptParentChildLink implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@ManyToOne()
|
@ManyToOne()
|
||||||
@JoinColumn(name="CHILD_PID", nullable=false, referencedColumnName="PID", foreignKey=@ForeignKey(name="FK_TERM_CONCEPTPC_CHILD"))
|
@JoinColumn(name = "CHILD_PID", nullable = false, referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_TERM_CONCEPTPC_CHILD"))
|
||||||
private TermConcept myChild;
|
private TermConcept myChild;
|
||||||
|
|
||||||
|
@Column(name = "CHILD_PID", insertable = false, updatable = false)
|
||||||
|
private Long myChildPid;
|
||||||
|
|
||||||
@ManyToOne()
|
@ManyToOne()
|
||||||
@JoinColumn(name="CODESYSTEM_PID", nullable=false, foreignKey=@ForeignKey(name="FK_TERM_CONCEPTPC_CS"))
|
@JoinColumn(name = "CODESYSTEM_PID", nullable = false, foreignKey = @ForeignKey(name = "FK_TERM_CONCEPTPC_CS"))
|
||||||
private TermCodeSystemVersion myCodeSystem;
|
private TermCodeSystemVersion myCodeSystem;
|
||||||
|
|
||||||
@ManyToOne(cascade= {})
|
@ManyToOne(cascade = {})
|
||||||
@JoinColumn(name="PARENT_PID", nullable=false, referencedColumnName="PID", foreignKey=@ForeignKey(name="FK_TERM_CONCEPTPC_PARENT"))
|
@JoinColumn(name = "PARENT_PID", nullable = false, referencedColumnName = "PID", foreignKey = @ForeignKey(name = "FK_TERM_CONCEPTPC_PARENT"))
|
||||||
private TermConcept myParent;
|
private TermConcept myParent;
|
||||||
|
|
||||||
|
@Column(name = "PARENT_PID", insertable = false, updatable = false)
|
||||||
|
private Long myParentPid;
|
||||||
|
|
||||||
@Id()
|
@Id()
|
||||||
@SequenceGenerator(name="SEQ_CONCEPT_PC_PID", sequenceName="SEQ_CONCEPT_PC_PID")
|
@SequenceGenerator(name = "SEQ_CONCEPT_PC_PID", sequenceName = "SEQ_CONCEPT_PC_PID")
|
||||||
@GeneratedValue(strategy=GenerationType.AUTO, generator="SEQ_CONCEPT_PC_PID")
|
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_PC_PID")
|
||||||
@Column(name="PID")
|
@Column(name = "PID")
|
||||||
private Long myPid;
|
private Long myPid;
|
||||||
|
|
||||||
@Enumerated(EnumType.ORDINAL)
|
@Enumerated(EnumType.ORDINAL)
|
||||||
@Column(name="REL_TYPE", length=5, nullable=true)
|
@Column(name = "REL_TYPE", length = 5, nullable = true)
|
||||||
private RelationshipTypeEnum myRelationshipType;
|
private RelationshipTypeEnum myRelationshipType;
|
||||||
|
|
||||||
public TermConcept getChild() {
|
|
||||||
return myChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RelationshipTypeEnum getRelationshipType() {
|
|
||||||
return myRelationshipType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TermCodeSystemVersion getCodeSystem() {
|
|
||||||
return myCodeSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TermConcept getParent() {
|
|
||||||
return myParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChild(TermConcept theChild) {
|
|
||||||
myChild = theChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCodeSystem(TermCodeSystemVersion theCodeSystem) {
|
|
||||||
myCodeSystem = theCodeSystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParent(TermConcept theParent) {
|
|
||||||
myParent = theParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setRelationshipType(RelationshipTypeEnum theRelationshipType) {
|
|
||||||
myRelationshipType = theRelationshipType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((myChild == null) ? 0 : myChild.hashCode());
|
|
||||||
result = prime * result + ((myCodeSystem == null) ? 0 : myCodeSystem.hashCode());
|
|
||||||
result = prime * result + ((myParent == null) ? 0 : myParent.hashCode());
|
|
||||||
result = prime * result + ((myRelationshipType == null) ? 0 : myRelationshipType.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
|
@ -136,15 +97,64 @@ public class TermConceptParentChildLink implements Serializable {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TermConcept getChild() {
|
||||||
public enum RelationshipTypeEnum{
|
return myChild;
|
||||||
// ********************************************
|
|
||||||
// IF YOU ADD HERE MAKE SURE ORDER IS PRESERVED
|
|
||||||
ISA
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getChildPid() {
|
||||||
|
return myChildPid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermCodeSystemVersion getCodeSystem() {
|
||||||
|
return myCodeSystem;
|
||||||
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return myPid;
|
return myPid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TermConcept getParent() {
|
||||||
|
return myParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getParentPid() {
|
||||||
|
return myParentPid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RelationshipTypeEnum getRelationshipType() {
|
||||||
|
return myRelationshipType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((myChild == null) ? 0 : myChild.hashCode());
|
||||||
|
result = prime * result + ((myCodeSystem == null) ? 0 : myCodeSystem.hashCode());
|
||||||
|
result = prime * result + ((myParent == null) ? 0 : myParent.hashCode());
|
||||||
|
result = prime * result + ((myRelationshipType == null) ? 0 : myRelationshipType.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChild(TermConcept theChild) {
|
||||||
|
myChild = theChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCodeSystem(TermCodeSystemVersion theCodeSystem) {
|
||||||
|
myCodeSystem = theCodeSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(TermConcept theParent) {
|
||||||
|
myParent = theParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRelationshipType(RelationshipTypeEnum theRelationshipType) {
|
||||||
|
myRelationshipType = theRelationshipType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RelationshipTypeEnum {
|
||||||
|
// ********************************************
|
||||||
|
// IF YOU ADD HERE MAKE SURE ORDER IS PRESERVED
|
||||||
|
ISA
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,11 @@ package ca.uhn.fhir.jpa.term;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ import javax.persistence.EntityManager;
|
||||||
import javax.persistence.PersistenceContext;
|
import javax.persistence.PersistenceContext;
|
||||||
import javax.persistence.PersistenceContextType;
|
import javax.persistence.PersistenceContextType;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
@ -45,7 +48,10 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.Multimaps;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||||
|
@ -66,6 +72,7 @@ import ca.uhn.fhir.util.ObjectUtil;
|
||||||
import ca.uhn.fhir.util.ValidateUtil;
|
import ca.uhn.fhir.util.ValidateUtil;
|
||||||
|
|
||||||
public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
|
private static boolean ourForceSaveDeferredAlwaysForUnitTest;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiTerminologySvc.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiTerminologySvc.class);
|
||||||
private static final Object PLACEHOLDER_OBJECT = new Object();
|
private static final Object PLACEHOLDER_OBJECT = new Object();
|
||||||
|
|
||||||
|
@ -94,8 +101,11 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
||||||
protected EntityManager myEntityManager;
|
protected EntityManager myEntityManager;
|
||||||
|
|
||||||
private boolean myProcessDeferred = true;
|
|
||||||
private long myNextReindexPass;
|
private long myNextReindexPass;
|
||||||
|
private boolean myProcessDeferred = true;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformTransactionManager myTransactionMgr;
|
||||||
|
|
||||||
private boolean addToSet(Set<TermConcept> theSetToPopulate, TermConcept theConcept) {
|
private boolean addToSet(Set<TermConcept> theSetToPopulate, TermConcept theConcept) {
|
||||||
boolean retVal = theSetToPopulate.add(theConcept);
|
boolean retVal = theSetToPopulate.add(theConcept);
|
||||||
|
@ -108,6 +118,25 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int ensureParentsSaved(Collection<TermConceptParentChildLink> theParents) {
|
||||||
|
ourLog.trace("Checking {} parents", theParents.size());
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
for (TermConceptParentChildLink nextLink : theParents) {
|
||||||
|
if (nextLink.getRelationshipType() == RelationshipTypeEnum.ISA) {
|
||||||
|
TermConcept nextParent = nextLink.getParent();
|
||||||
|
retVal += ensureParentsSaved(nextParent.getParents());
|
||||||
|
if (nextParent.getId() == null) {
|
||||||
|
myConceptDao.saveAndFlush(nextParent);
|
||||||
|
retVal++;
|
||||||
|
ourLog.debug("Saved parent code {} and got id {}", nextParent.getCode(), nextParent.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
private void fetchChildren(TermConcept theConcept, Set<TermConcept> theSetToPopulate) {
|
private void fetchChildren(TermConcept theConcept, Set<TermConcept> theSetToPopulate) {
|
||||||
for (TermConceptParentChildLink nextChildLink : theConcept.getChildren()) {
|
for (TermConceptParentChildLink nextChildLink : theConcept.getChildren()) {
|
||||||
TermConcept nextChild = nextChildLink.getChild();
|
TermConcept nextChild = nextChildLink.getChild();
|
||||||
|
@ -175,6 +204,15 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses may override
|
||||||
|
* @param theSystem The code system
|
||||||
|
* @param theCode The code
|
||||||
|
*/
|
||||||
|
protected List<VersionIndependentConcept> findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRED)
|
@Transactional(propagation = Propagation.REQUIRED)
|
||||||
@Override
|
@Override
|
||||||
public Set<TermConcept> findCodesBelow(Long theCodeSystemResourcePid, Long theCodeSystemVersionPid, String theCode) {
|
public Set<TermConcept> findCodesBelow(Long theCodeSystemResourcePid, Long theCodeSystemVersionPid, String theCode) {
|
||||||
|
@ -206,7 +244,6 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
ArrayList<VersionIndependentConcept> retVal = toVersionIndependentConcepts(theSystem, codes);
|
ArrayList<VersionIndependentConcept> retVal = toVersionIndependentConcepts(theSystem, codes);
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclasses may override
|
* Subclasses may override
|
||||||
* @param theSystem The code system
|
* @param theSystem The code system
|
||||||
|
@ -215,16 +252,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
protected List<VersionIndependentConcept> findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) {
|
protected List<VersionIndependentConcept> findCodesBelowUsingBuiltInSystems(String theSystem, String theCode) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclasses may override
|
|
||||||
* @param theSystem The code system
|
|
||||||
* @param theCode The code
|
|
||||||
*/
|
|
||||||
protected List<VersionIndependentConcept> findCodesAboveUsingBuiltInSystems(String theSystem, String theCode) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TermCodeSystemVersion findCurrentCodeSystemVersionForSystem(String theCodeSystem) {
|
private TermCodeSystemVersion findCurrentCodeSystemVersionForSystem(String theCodeSystem) {
|
||||||
TermCodeSystem cs = getCodeSystem(theCodeSystem);
|
TermCodeSystem cs = getCodeSystem(theCodeSystem);
|
||||||
if (cs == null || cs.getCurrentVersion() == null) {
|
if (cs == null || cs.getCurrentVersion() == null) {
|
||||||
|
@ -233,11 +261,12 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
TermCodeSystemVersion csv = cs.getCurrentVersion();
|
TermCodeSystemVersion csv = cs.getCurrentVersion();
|
||||||
return csv;
|
return csv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TermCodeSystem getCodeSystem(String theSystem) {
|
private TermCodeSystem getCodeSystem(String theSystem) {
|
||||||
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(theSystem);
|
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(theSystem);
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void persistChildren(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, IdentityHashMap<TermConcept, Object> theConceptsStack, int theTotalConcepts) {
|
private void persistChildren(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, IdentityHashMap<TermConcept, Object> theConceptsStack, int theTotalConcepts) {
|
||||||
if (theConceptsStack.put(theConcept, PLACEHOLDER_OBJECT) != null) {
|
if (theConceptsStack.put(theConcept, PLACEHOLDER_OBJECT) != null) {
|
||||||
return;
|
return;
|
||||||
|
@ -271,15 +300,99 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveConceptLink(TermConceptParentChildLink next) {
|
private void populateVersion(TermConcept theNext, TermCodeSystemVersion theCodeSystemVersion) {
|
||||||
if (next.getId() == null) {
|
if (theNext.getCodeSystem() != null) {
|
||||||
myConceptParentChildLinkDao.save(next);
|
return;
|
||||||
}
|
}
|
||||||
|
theNext.setCodeSystem(theCodeSystemVersion);
|
||||||
|
for (TermConceptParentChildLink next : theNext.getChildren()) {
|
||||||
|
populateVersion(next.getChild(), theCodeSystemVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayListMultimap<Long, Long> myChildToParentPidCache;
|
||||||
|
|
||||||
|
private void processReindexing() {
|
||||||
|
if (System.currentTimeMillis() < myNextReindexPass && !ourForceSaveDeferredAlwaysForUnitTest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransactionTemplate tt = new TransactionTemplate(myTransactionMgr);
|
||||||
|
tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
||||||
|
tt.execute(new TransactionCallbackWithoutResult() {
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
|
||||||
|
int maxResult = 1000;
|
||||||
|
Page<TermConcept> concepts = myConceptDao.findResourcesRequiringReindexing(new PageRequest(0, maxResult));
|
||||||
|
if (concepts.hasContent() == false) {
|
||||||
|
myNextReindexPass = System.currentTimeMillis() + DateUtils.MILLIS_PER_MINUTE;
|
||||||
|
myChildToParentPidCache = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myChildToParentPidCache == null) {
|
||||||
|
myChildToParentPidCache = ArrayListMultimap.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLog.info("Indexing {} / {} concepts", concepts.getContent().size(), concepts.getTotalElements());
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
StopWatch stopwatch = new StopWatch();
|
||||||
|
|
||||||
|
for (TermConcept nextConcept : concepts) {
|
||||||
|
|
||||||
|
StringBuilder parentsBuilder = new StringBuilder();
|
||||||
|
createParentsString(parentsBuilder, nextConcept.getId());
|
||||||
|
nextConcept.setParentPids(parentsBuilder.toString());
|
||||||
|
|
||||||
|
saveConcept(nextConcept);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLog.info("Indexed {} / {} concepts in {}ms - Avg {}ms / resource", new Object[] { count, concepts.getContent().size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(count) });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createParentsString(StringBuilder theParentsBuilder, Long theConceptPid) {
|
||||||
|
Validate.notNull(theConceptPid, "theConceptPid must not be null");
|
||||||
|
List<Long> parents = myChildToParentPidCache.get(theConceptPid);
|
||||||
|
if (parents.contains(-1L)) {
|
||||||
|
return;
|
||||||
|
} else if (parents.isEmpty()) {
|
||||||
|
Collection<TermConceptParentChildLink> parentLinks = myConceptParentChildLinkDao.findAllWithChild(theConceptPid);
|
||||||
|
if (parentLinks.isEmpty()) {
|
||||||
|
myChildToParentPidCache.put(theConceptPid, -1L);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
for (TermConceptParentChildLink next : parentLinks) {
|
||||||
|
myChildToParentPidCache.put(theConceptPid, next.getParentPid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (Long nextParent : parents) {
|
||||||
|
if (theParentsBuilder.length() > 0) {
|
||||||
|
theParentsBuilder.append(' ');
|
||||||
|
}
|
||||||
|
theParentsBuilder.append(nextParent);
|
||||||
|
createParentsString(theParentsBuilder, nextParent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int saveConcept(TermConcept theConcept) {
|
private int saveConcept(TermConcept theConcept) {
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
retVal += ensureParentsSaved(theConcept.getParents());
|
|
||||||
|
/*
|
||||||
|
* If the concept has an ID, we're reindexing, so there's no need to
|
||||||
|
* save parent concepts first (it's way too slow to do that)
|
||||||
|
*/
|
||||||
|
if (theConcept.getId() == null) {
|
||||||
|
retVal += ensureParentsSaved(theConcept.getParents());
|
||||||
|
}
|
||||||
|
|
||||||
if (theConcept.getId() == null || theConcept.getIndexStatus() == null) {
|
if (theConcept.getId() == null || theConcept.getIndexStatus() == null) {
|
||||||
retVal++;
|
retVal++;
|
||||||
theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
|
theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
|
||||||
|
@ -289,33 +402,10 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
ourLog.trace("Saved {} and got PID {}", theConcept.getCode(), theConcept.getId());
|
ourLog.trace("Saved {} and got PID {}", theConcept.getCode(), theConcept.getId());
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int ensureParentsSaved(Collection<TermConceptParentChildLink> theParents) {
|
private void saveConceptLink(TermConceptParentChildLink next) {
|
||||||
ourLog.trace("Checking {} parents", theParents.size());
|
if (next.getId() == null) {
|
||||||
int retVal = 0;
|
myConceptParentChildLinkDao.save(next);
|
||||||
|
|
||||||
for (TermConceptParentChildLink nextLink : theParents) {
|
|
||||||
if (nextLink.getRelationshipType() == RelationshipTypeEnum.ISA) {
|
|
||||||
TermConcept nextParent = nextLink.getParent();
|
|
||||||
retVal += ensureParentsSaved(nextParent.getParents());
|
|
||||||
if (nextParent.getId() == null) {
|
|
||||||
myConceptDao.saveAndFlush(nextParent);
|
|
||||||
retVal++;
|
|
||||||
ourLog.debug("Saved parent code {} and got id {}", nextParent.getCode(), nextParent.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateVersion(TermConcept theNext, TermCodeSystemVersion theCodeSystemVersion) {
|
|
||||||
if (theNext.getCodeSystem() != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
theNext.setCodeSystem(theCodeSystemVersion);
|
|
||||||
for (TermConceptParentChildLink next : theNext.getChildren()) {
|
|
||||||
populateVersion(next.getChild(), theCodeSystemVersion);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,43 +458,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
ourLog.info("All deferred concepts and relationships have now been synchronized to the database");
|
ourLog.info("All deferred concepts and relationships have now been synchronized to the database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PlatformTransactionManager myTransactionMgr;
|
|
||||||
|
|
||||||
private void processReindexing() {
|
|
||||||
if (System.currentTimeMillis() < myNextReindexPass) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TransactionTemplate tt = new TransactionTemplate(myTransactionMgr);
|
|
||||||
tt.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
|
|
||||||
tt.execute(new TransactionCallbackWithoutResult() {
|
|
||||||
@Override
|
|
||||||
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
|
|
||||||
int maxResult = 1000;
|
|
||||||
Page<TermConcept> resources = myConceptDao.findResourcesRequiringReindexing(new PageRequest(0, maxResult));
|
|
||||||
if (resources.hasContent() == false) {
|
|
||||||
myNextReindexPass = System.currentTimeMillis() + DateUtils.MILLIS_PER_MINUTE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ourLog.info("Indexing {} / {} concepts", resources.getContent().size(), resources.getTotalElements());
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
StopWatch stopwatch = new StopWatch();
|
|
||||||
|
|
||||||
for (TermConcept resourceTable : resources) {
|
|
||||||
saveConcept(resourceTable);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ourLog.info("Indexed {} / {} concepts in {}ms - Avg {}ms / resource", new Object[] { count, resources.getContent().size(), stopwatch.getMillis(), stopwatch.getMillisPerOperation(count) });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProcessDeferred(boolean theProcessDeferred) {
|
public void setProcessDeferred(boolean theProcessDeferred) {
|
||||||
myProcessDeferred = theProcessDeferred;
|
myProcessDeferred = theProcessDeferred;
|
||||||
|
@ -470,7 +524,7 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
totalCodeCount += validateConceptForStorage(next, theCodeSystemVersion, conceptsStack, allConcepts);
|
totalCodeCount += validateConceptForStorage(next, theCodeSystemVersion, conceptsStack, allConcepts);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Saving version");
|
ourLog.info("Saving version containing {} concepts", totalCodeCount);
|
||||||
|
|
||||||
TermCodeSystemVersion codeSystemVersion = myCodeSystemVersionDao.saveAndFlush(theCodeSystemVersion);
|
TermCodeSystemVersion codeSystemVersion = myCodeSystemVersionDao.saveAndFlush(theCodeSystemVersion);
|
||||||
|
|
||||||
|
@ -503,13 +557,13 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
ourLog.info("Note that some concept saving was deferred - still have {} concepts and {} relationships", myConceptsToSaveLater.size(), myConceptLinksToSaveLater.size());
|
ourLog.info("Note that some concept saving was deferred - still have {} concepts and {} relationships", myConceptsToSaveLater.size(), myConceptLinksToSaveLater.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsSystem(String theSystem) {
|
public boolean supportsSystem(String theSystem) {
|
||||||
TermCodeSystem cs = getCodeSystem(theSystem);
|
TermCodeSystem cs = getCodeSystem(theSystem);
|
||||||
return cs != null;
|
return cs != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<VersionIndependentConcept> toVersionIndependentConcepts(String theSystem, Set<TermConcept> codes) {
|
private ArrayList<VersionIndependentConcept> toVersionIndependentConcepts(String theSystem, Set<TermConcept> codes) {
|
||||||
ArrayList<VersionIndependentConcept> retVal = new ArrayList<VersionIndependentConcept>(codes.size());
|
ArrayList<VersionIndependentConcept> retVal = new ArrayList<VersionIndependentConcept>(codes.size());
|
||||||
for (TermConcept next : codes) {
|
for (TermConcept next : codes) {
|
||||||
|
@ -547,4 +601,12 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is present only for unit tests, do not call from client code
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public static void setForceSaveDeferredAlwaysForUnitTest(boolean theForceSaveDeferredAlwaysForUnitTest) {
|
||||||
|
ourForceSaveDeferredAlwaysForUnitTest = theForceSaveDeferredAlwaysForUnitTest;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -12,7 +13,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -64,6 +65,7 @@ import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
@ -79,7 +81,7 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IValidationSupport myValidationSupport;
|
private IValidationSupport myValidationSupport;
|
||||||
|
|
||||||
private void addCodeIfNotAlreadyAdded(String system, ValueSetExpansionComponent retVal, Set<String> addedCodes, TermConcept nextConcept) {
|
private void addCodeIfNotAlreadyAdded(String system, ValueSetExpansionComponent retVal, Set<String> addedCodes, TermConcept nextConcept) {
|
||||||
if (addedCodes.add(nextConcept.getCode())) {
|
if (addedCodes.add(nextConcept.getCode())) {
|
||||||
ValueSetExpansionContainsComponent contains = retVal.addContains();
|
ValueSetExpansionContainsComponent contains = retVal.addContains();
|
||||||
|
@ -126,12 +128,12 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||||
for (ConceptDefinitionComponent nextChild : theNext.getConcept()) {
|
for (ConceptDefinitionComponent nextChild : theNext.getConcept()) {
|
||||||
foundCodeInChild |= addTreeIfItContainsCode(theSystemString, nextChild, theCode, theListToPopulate);
|
foundCodeInChild |= addTreeIfItContainsCode(theSystemString, nextChild, theCode, theListToPopulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theCode.equals(theNext.getCode()) || foundCodeInChild) {
|
if (theCode.equals(theNext.getCode()) || foundCodeInChild) {
|
||||||
theListToPopulate.add(new VersionIndependentConcept(theSystemString, theNext.getCode()));
|
theListToPopulate.add(new VersionIndependentConcept(theSystemString, theNext.getCode()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,17 +161,15 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDisplayFilterInexact(QueryBuilder qb, BooleanJunction<?> bool, ConceptSetFilterComponent nextFilter) {
|
private void addDisplayFilterInexact(QueryBuilder qb, BooleanJunction<?> bool, ConceptSetFilterComponent nextFilter) {
|
||||||
//@formatter:off
|
|
||||||
Query textQuery = qb
|
Query textQuery = qb
|
||||||
.phrase()
|
.phrase()
|
||||||
.withSlop(2)
|
.withSlop(2)
|
||||||
.onField("myDisplay").boostedTo(4.0f)
|
.onField("myDisplay").boostedTo(4.0f)
|
||||||
.andField("myDisplayEdgeNGram").boostedTo(2.0f)
|
.andField("myDisplayEdgeNGram").boostedTo(2.0f)
|
||||||
//.andField("myDisplayNGram").boostedTo(1.0f)
|
// .andField("myDisplayNGram").boostedTo(1.0f)
|
||||||
//.andField("myDisplayPhonetic").boostedTo(0.5f)
|
// .andField("myDisplayPhonetic").boostedTo(0.5f)
|
||||||
.sentence(nextFilter.getValue().toLowerCase()).createQuery();
|
.sentence(nextFilter.getValue().toLowerCase()).createQuery();
|
||||||
bool.must(textQuery);
|
bool.must(textQuery);
|
||||||
//@formatter:on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -216,26 +216,33 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||||
bool.must(qb.keyword().onField("myCodeSystemVersionPid").matching(csv.getPid()).createQuery());
|
bool.must(qb.keyword().onField("myCodeSystemVersionPid").matching(csv.getPid()).createQuery());
|
||||||
|
|
||||||
for (ConceptSetFilterComponent nextFilter : theInclude.getFilter()) {
|
for (ConceptSetFilterComponent nextFilter : theInclude.getFilter()) {
|
||||||
if (isNotBlank(nextFilter.getValue())) {
|
if (isBlank(nextFilter.getValue()) && nextFilter.getOp() == null && isBlank(nextFilter.getProperty())) {
|
||||||
if (nextFilter.getProperty().equals("display:exact") && nextFilter.getOp() == FilterOperator.EQUAL) {
|
continue;
|
||||||
addDisplayFilterExact(qb, bool, nextFilter);
|
}
|
||||||
} else if (nextFilter.getProperty().equals("display") && nextFilter.getOp() == FilterOperator.EQUAL) {
|
|
||||||
if (nextFilter.getValue().trim().contains(" ")) {
|
|
||||||
addDisplayFilterExact(qb, bool, nextFilter);
|
|
||||||
} else {
|
|
||||||
addDisplayFilterInexact(qb, bool, nextFilter);
|
|
||||||
}
|
|
||||||
} else if ((nextFilter.getProperty().equals("concept") || nextFilter.getProperty().equals("code")) && nextFilter.getOp() == FilterOperator.ISA) {
|
|
||||||
TermConcept code = super.findCode(system, nextFilter.getValue());
|
|
||||||
if (code == null) {
|
|
||||||
throw new InvalidRequestException("Invalid filter criteria - code does not exist: {" + system + "}" + nextFilter.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
ourLog.info(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
|
if (isBlank(nextFilter.getValue()) || nextFilter.getOp() == null || isBlank(nextFilter.getProperty())) {
|
||||||
bool.must(qb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
throw new InvalidRequestException("Invalid filter, must have fields populated: property op value");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (nextFilter.getProperty().equals("display:exact") && nextFilter.getOp() == FilterOperator.EQUAL) {
|
||||||
|
addDisplayFilterExact(qb, bool, nextFilter);
|
||||||
|
} else if ("display".equals(nextFilter.getProperty()) && nextFilter.getOp() == FilterOperator.EQUAL) {
|
||||||
|
if (nextFilter.getValue().trim().contains(" ")) {
|
||||||
|
addDisplayFilterExact(qb, bool, nextFilter);
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidRequestException("Unknown filter property[" + nextFilter + "] + op[" + nextFilter.getOpElement().getValueAsString() + "]");
|
addDisplayFilterInexact(qb, bool, nextFilter);
|
||||||
}
|
}
|
||||||
|
} else if ((nextFilter.getProperty().equals("concept") || nextFilter.getProperty().equals("code")) && nextFilter.getOp() == FilterOperator.ISA) {
|
||||||
|
TermConcept code = super.findCode(system, nextFilter.getValue());
|
||||||
|
if (code == null) {
|
||||||
|
throw new InvalidRequestException("Invalid filter criteria - code does not exist: {" + system + "}" + nextFilter.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLog.info(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
|
||||||
|
bool.must(qb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
|
||||||
|
} else {
|
||||||
|
throw new InvalidRequestException("Unknown filter property[" + nextFilter + "] + op[" + nextFilter.getOpElement().getValueAsString() + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,12 +250,17 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||||
FullTextQuery jpaQuery = em.createFullTextQuery(luceneQuery, TermConcept.class);
|
FullTextQuery jpaQuery = em.createFullTextQuery(luceneQuery, TermConcept.class);
|
||||||
jpaQuery.setMaxResults(1000);
|
jpaQuery.setMaxResults(1000);
|
||||||
|
|
||||||
|
StopWatch sw = new StopWatch();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<TermConcept> result = jpaQuery.getResultList();
|
List<TermConcept> result = jpaQuery.getResultList();
|
||||||
|
|
||||||
|
ourLog.info("Expansion completed in {}ms", sw.getMillis());
|
||||||
|
|
||||||
for (TermConcept nextConcept : result) {
|
for (TermConcept nextConcept : result) {
|
||||||
addCodeIfNotAlreadyAdded(system, retVal, addedCodes, nextConcept);
|
addCodeIfNotAlreadyAdded(system, retVal, addedCodes, nextConcept);
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal.setTotal(jpaQuery.getResultSize());
|
retVal.setTotal(jpaQuery.getResultSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +271,6 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.term.BaseHapiTerminologySvc;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
|
||||||
|
public class FhirResourceDaoDstu3CodeSystemTest extends BaseJpaDstu3Test {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3CodeSystemTest.class);
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClassClearContext() {
|
||||||
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
BaseHapiTerminologySvc.setForceSaveDeferredAlwaysForUnitTest(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIndexContained() throws Exception {
|
||||||
|
BaseHapiTerminologySvc.setForceSaveDeferredAlwaysForUnitTest(true);
|
||||||
|
|
||||||
|
String input = IOUtils.toString(getClass().getResource("/dstu3_codesystem_complete.json"), StandardCharsets.UTF_8);
|
||||||
|
CodeSystem cs = myFhirCtx.newJsonParser().parseResource(CodeSystem.class, input);
|
||||||
|
myCodeSystemDao.create(cs, mySrd);
|
||||||
|
|
||||||
|
|
||||||
|
mySystemDao.markAllResourcesForReindexing();
|
||||||
|
|
||||||
|
int outcome = mySystemDao.performReindexingPass(100);
|
||||||
|
assertNotEquals(-1, outcome); // -1 means there was a failure
|
||||||
|
|
||||||
|
myTermSvc.saveDeferred();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,5 @@
|
||||||
package ca.uhn.fhir.jpa.dao.dstu3;
|
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
import org.hl7.fhir.dstu3.model.Observation;
|
import org.hl7.fhir.dstu3.model.Observation;
|
||||||
import org.hl7.fhir.dstu3.model.Patient;
|
import org.hl7.fhir.dstu3.model.Patient;
|
||||||
import org.hl7.fhir.dstu3.model.Reference;
|
import org.hl7.fhir.dstu3.model.Reference;
|
||||||
|
@ -11,9 +8,6 @@ import org.junit.AfterClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
|
||||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
|
||||||
public class FhirResourceDaoDstu3ContainedTest extends BaseJpaDstu3Test {
|
public class FhirResourceDaoDstu3ContainedTest extends BaseJpaDstu3Test {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ca.uhn.fhir.jpa.dao.dstu3;
|
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
@ -18,6 +19,7 @@ import org.junit.Test;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
|
||||||
|
@ -30,14 +32,14 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("PatientFoo.gender");
|
fooSp.setExpression("PatientFoo.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
try {
|
try {
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
fail();
|
fail();
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("Invalid path value \"PatientFoo.gender\": Unknown resource name \"PatientFoo\" (this name is not known in FHIR version \"DSTU3\")", e.getMessage());
|
assertEquals("Invalid SearchParameter.expression value \"PatientFoo.gender\": Unknown resource name \"PatientFoo\" (this name is not known in FHIR version \"DSTU3\")", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,14 +49,14 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender or Observation.code");
|
fooSp.setExpression("Patient.gender or Observation.code");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
try {
|
try {
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
fail();
|
fail();
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("Invalid path value \"Observation.code\". All paths in a single SearchParameter must match the same resource type", e.getMessage());
|
assertEquals("Invalid SearchParameter.expression value \"Observation.code\". All paths in a single SearchParameter must match the same resource type", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +72,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
fail();
|
fail();
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("Resource.xpath is missing", e.getMessage());
|
assertEquals("SearchParameter.expression is missing", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,14 +82,14 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("gender");
|
fooSp.setExpression("gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
try {
|
try {
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
fail();
|
fail();
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("Invalid path value \"gender\". Must start with a resource name", e.getMessage());
|
assertEquals("Invalid SearchParameter.expression value \"gender\". Must start with a resource name", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,14 +100,14 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(null);
|
fooSp.setStatus(null);
|
||||||
try {
|
try {
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
fail();
|
fail();
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("Resource.status is missing or invalid: null", e.getMessage());
|
assertEquals("SearchParameter.status is missing or invalid: null", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -117,10 +119,10 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
IIdType spId = mySearchParameterDao.create(fooSp, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
mySearchParamRegsitry.forceRefresh();
|
mySearchParamRegsitry.forceRefresh();
|
||||||
|
|
||||||
|
@ -150,6 +152,17 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
foundResources = toUnqualifiedVersionlessIdValues(results);
|
foundResources = toUnqualifiedVersionlessIdValues(results);
|
||||||
assertThat(foundResources, contains(patId.getValue()));
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
|
||||||
|
// Delete the param
|
||||||
|
mySearchParameterDao.delete(spId, mySrd);
|
||||||
|
|
||||||
|
mySearchParamRegsitry.forceRefresh();
|
||||||
|
mySystemDao.performReindexingPass(100);
|
||||||
|
|
||||||
|
// Try with custom gender SP
|
||||||
|
map = new SearchParameterMap();
|
||||||
|
map.add("foo", new TokenParam(null, "male"));
|
||||||
|
IBundleProvider res = myPatientDao.search(map);
|
||||||
|
assertEquals(0, res.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -159,7 +172,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.DRAFT);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.DRAFT);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
|
|
@ -26,7 +26,9 @@ import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
|
@ -34,6 +36,8 @@ import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
|
||||||
|
import ca.uhn.fhir.jpa.term.BaseHapiTerminologySvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
||||||
|
@ -52,6 +56,8 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
||||||
@After
|
@After
|
||||||
public void after() {
|
public void after() {
|
||||||
myDaoConfig.setDeferIndexingForCodesystemsOfSize(new DaoConfig().getDeferIndexingForCodesystemsOfSize());
|
myDaoConfig.setDeferIndexingForCodesystemsOfSize(new DaoConfig().getDeferIndexingForCodesystemsOfSize());
|
||||||
|
|
||||||
|
BaseHapiTerminologySvc.setForceSaveDeferredAlwaysForUnitTest(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -318,6 +324,71 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandWithIsAInExternalValueSet() {
|
||||||
|
createExternalCsAndLocalVs();
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||||
|
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||||
|
include.addFilter().setOp(FilterOperator.ISA).setValue("childAA").setProperty("concept");
|
||||||
|
|
||||||
|
ValueSet result = myValueSetDao.expand(vs, null);
|
||||||
|
logAndValidateValueSet(result);
|
||||||
|
|
||||||
|
ArrayList<String> codes = toCodesContains(result.getExpansion().getContains());
|
||||||
|
assertThat(codes, containsInAnyOrder("childAAA", "childAAB"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IHapiTerminologySvc myHapiTerminologySvc;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandWithIsAInExternalValueSetReindex() {
|
||||||
|
BaseHapiTerminologySvc.setForceSaveDeferredAlwaysForUnitTest(true);
|
||||||
|
|
||||||
|
createExternalCsAndLocalVs();
|
||||||
|
|
||||||
|
mySystemDao.markAllResourcesForReindexing();
|
||||||
|
|
||||||
|
mySystemDao.performReindexingPass(100);
|
||||||
|
mySystemDao.performReindexingPass(100);
|
||||||
|
myHapiTerminologySvc.saveDeferred();
|
||||||
|
myHapiTerminologySvc.saveDeferred();
|
||||||
|
myHapiTerminologySvc.saveDeferred();
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||||
|
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||||
|
include.addFilter().setOp(FilterOperator.ISA).setValue("childAA").setProperty("concept");
|
||||||
|
|
||||||
|
ValueSet result = myValueSetDao.expand(vs, null);
|
||||||
|
logAndValidateValueSet(result);
|
||||||
|
|
||||||
|
ArrayList<String> codes = toCodesContains(result.getExpansion().getContains());
|
||||||
|
assertThat(codes, containsInAnyOrder("childAAA", "childAAB"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandInvalid() {
|
||||||
|
createExternalCsAndLocalVs();
|
||||||
|
|
||||||
|
ValueSet vs = new ValueSet();
|
||||||
|
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||||
|
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||||
|
include.addFilter();
|
||||||
|
include.addFilter().setOp(FilterOperator.ISA).setValue("childAA");
|
||||||
|
|
||||||
|
try {
|
||||||
|
myValueSetDao.expand(vs, null);
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
assertEquals("Invalid filter, must have fields populated: property op value", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpandWithSystemAndCodesInExternalValueSet() {
|
public void testExpandWithSystemAndCodesInExternalValueSet() {
|
||||||
createExternalCsAndLocalVs();
|
createExternalCsAndLocalVs();
|
||||||
|
|
|
@ -10,6 +10,7 @@ import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
@ -139,7 +140,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
get.addHeader("Accept", "application/xml, text/html");
|
get.addHeader("Accept", "application/xml, text/html");
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
String response = IOUtils.toString(http.getEntity().getContent());
|
String response = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
assertThat(response, (containsString("_format=json")));
|
assertThat(response, (containsString("_format=json")));
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
|
@ -167,7 +168,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
get.addHeader("Accept", "application/xml+fhir");
|
get.addHeader("Accept", "application/xml+fhir");
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
String response = IOUtils.toString(http.getEntity().getContent());
|
String response = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
assertThat(response, not(containsString("_format")));
|
assertThat(response, not(containsString("_format")));
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
|
@ -216,7 +217,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
|
|
||||||
Parameters parameters = ourCtx.newXmlParser().parseResource(Parameters.class, output);
|
Parameters parameters = ourCtx.newXmlParser().parseResource(Parameters.class, output);
|
||||||
|
@ -246,7 +247,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(400, http.getStatusLine().getStatusCode());
|
assertEquals(400, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertThat(output, containsString("Parameter 'context' must be provided"));
|
assertThat(output, containsString("Parameter 'context' must be provided"));
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -257,7 +258,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
http = ourHttpClient.execute(get);
|
http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(400, http.getStatusLine().getStatusCode());
|
assertEquals(400, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertThat(output, containsString("Parameter 'searchParam' must be provided"));
|
assertThat(output, containsString("Parameter 'searchParam' must be provided"));
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -268,7 +269,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
http = ourHttpClient.execute(get);
|
http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(400, http.getStatusLine().getStatusCode());
|
assertEquals(400, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertThat(output, containsString("Parameter 'text' must be provided"));
|
assertThat(output, containsString("Parameter 'text' must be provided"));
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -286,7 +287,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle() throws Exception {
|
public void testTransactionFromBundle() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
}
|
}
|
||||||
|
@ -295,7 +296,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
public void testTransactionFromBundle2() throws Exception {
|
public void testTransactionFromBundle2() throws Exception {
|
||||||
|
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
|
|
||||||
|
@ -311,7 +312,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
||||||
bundle = IOUtils.toString(bundleRes);
|
bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
|
|
||||||
|
@ -335,7 +336,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
public void testTransactionFromBundle3() throws Exception {
|
public void testTransactionFromBundle3() throws Exception {
|
||||||
|
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/grahame-transaction.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/grahame-transaction.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
}
|
}
|
||||||
|
@ -343,7 +344,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle4() throws Exception {
|
public void testTransactionFromBundle4() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
|
Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
|
||||||
|
@ -358,7 +359,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle5() throws Exception {
|
public void testTransactionFromBundle5() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle2.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle2.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
try {
|
try {
|
||||||
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
fail();
|
fail();
|
||||||
|
@ -372,7 +373,7 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle6() throws Exception {
|
public void testTransactionFromBundle6() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle3.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/simone_bundle3.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
// try {
|
// try {
|
||||||
// fail();
|
// fail();
|
||||||
|
@ -427,5 +428,18 @@ public class SystemProviderDstu2Test extends BaseJpaDstu2Test {
|
||||||
assertEquals(0, respSub.getEntry().size());
|
assertEquals(0, respSub.getEntry().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarkResourcesForReindexing() throws Exception {
|
||||||
|
HttpGet get = new HttpGet(ourServerBase + "/$mark-all-resources-for-reindexing");
|
||||||
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
|
try {
|
||||||
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
ourLog.info(output);
|
||||||
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(http);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
public void saveCreateSearchParamInvalidWithMissingStatus() throws IOException {
|
public void saveCreateSearchParamInvalidWithMissingStatus() throws IOException {
|
||||||
SearchParameter sp = new SearchParameter();
|
SearchParameter sp = new SearchParameter();
|
||||||
sp.setCode("foo");
|
sp.setCode("foo");
|
||||||
sp.setXpath("Patient.gender");
|
sp.setExpression("Patient.gender");
|
||||||
sp.setXpathUsage(XPathUsageType.NORMAL);
|
sp.setXpathUsage(XPathUsageType.NORMAL);
|
||||||
sp.setTitle("Foo Param");
|
sp.setTitle("Foo Param");
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
ourClient.create().resource(sp).execute();
|
ourClient.create().resource(sp).execute();
|
||||||
fail();
|
fail();
|
||||||
} catch (UnprocessableEntityException e) {
|
} catch (UnprocessableEntityException e) {
|
||||||
assertEquals("HTTP 422 Unprocessable Entity: Resource.status is missing or invalid: null", e.getMessage());
|
assertEquals("HTTP 422 Unprocessable Entity: SearchParameter.status is missing or invalid: null", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
@ -110,7 +110,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("gender");
|
fooSp.setCode("gender");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("Gender");
|
fooSp.setTitle("Gender");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.RETIRED);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.RETIRED);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
@ -152,7 +152,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
@ -162,7 +162,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("gender");
|
fooSp.setCode("gender");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("Gender");
|
fooSp.setTitle("Gender");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.RETIRED);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.RETIRED);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
@ -206,7 +206,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
@ -232,6 +232,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
.where(new TokenClientParam("foo").exactly().code("male"))
|
.where(new TokenClientParam("foo").exactly().code("male"))
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
foundResources = toUnqualifiedVersionlessIdValues(result);
|
foundResources = toUnqualifiedVersionlessIdValues(result);
|
||||||
assertThat(foundResources, contains(patId.getValue()));
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
|
||||||
|
@ -256,7 +257,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Patient.gender");
|
fooSp.setExpression("Patient.gender");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
@ -276,7 +277,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
|
||||||
fooSp.setCode("foo");
|
fooSp.setCode("foo");
|
||||||
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE);
|
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE);
|
||||||
fooSp.setTitle("FOO SP");
|
fooSp.setTitle("FOO SP");
|
||||||
fooSp.setXpath("Observation.subject");
|
fooSp.setExpression("Observation.subject");
|
||||||
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
mySearchParameterDao.create(fooSp, mySrd);
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
|
|
@ -149,7 +149,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
@After
|
@After
|
||||||
public void after() throws Exception {
|
public void after() throws Exception {
|
||||||
super.after();
|
super.after();
|
||||||
|
|
||||||
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
myDaoConfig.setAllowMultipleDelete(new DaoConfig().isAllowMultipleDelete());
|
||||||
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
myDaoConfig.setAllowExternalReferences(new DaoConfig().isAllowExternalReferences());
|
||||||
}
|
}
|
||||||
|
@ -160,15 +160,14 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
myDaoConfig.setAllowMultipleDelete(true);
|
myDaoConfig.setAllowMultipleDelete(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
|
private void checkParamMissing(String paramName) throws IOException, ClientProtocolException {
|
||||||
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
|
HttpGet get = new HttpGet(ourServerBase + "/Observation?" + paramName + ":missing=false");
|
||||||
CloseableHttpResponse resp = ourHttpClient.execute(get);
|
CloseableHttpResponse resp = ourHttpClient.execute(get);
|
||||||
IOUtils.closeQuietly(resp.getEntity().getContent());
|
IOUtils.closeQuietly(resp.getEntity().getContent());
|
||||||
assertEquals(200, resp.getStatusLine().getStatusCode());
|
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<IBaseResource> genResourcesOfType(Bundle theRes, Class<? extends IBaseResource> theClass) {
|
private ArrayList<IBaseResource> genResourcesOfType(Bundle theRes, Class<? extends IBaseResource> theClass) {
|
||||||
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
ArrayList<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||||
for (BundleEntryComponent next : theRes.getEntry()) {
|
for (BundleEntryComponent next : theRes.getEntry()) {
|
||||||
|
@ -197,7 +196,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
List<Extension> exts = basic.getExtensionsByUrl("http://localhost:1080/hapi-fhir-jpaserver-example/baseDstu2/StructureDefinition/DateID");
|
List<Extension> exts = basic.getExtensionsByUrl("http://localhost:1080/hapi-fhir-jpaserver-example/baseDstu2/StructureDefinition/DateID");
|
||||||
assertEquals(1, exts.size());
|
assertEquals(1, exts.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> searchAndReturnUnqualifiedIdValues(String uri) throws IOException, ClientProtocolException {
|
private List<String> searchAndReturnUnqualifiedIdValues(String uri) throws IOException, ClientProtocolException {
|
||||||
List<String> ids;
|
List<String> ids;
|
||||||
HttpGet get = new HttpGet(uri);
|
HttpGet get = new HttpGet(uri);
|
||||||
|
@ -339,9 +338,9 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
Binary binary = new Binary();
|
Binary binary = new Binary();
|
||||||
binary.setContent(arr);
|
binary.setContent(arr);
|
||||||
binary.setContentType("dansk");
|
binary.setContentType("dansk");
|
||||||
|
|
||||||
IIdType resource = ourClient.create().resource(binary).execute().getId();
|
IIdType resource = ourClient.create().resource(binary).execute().getId();
|
||||||
|
|
||||||
Binary fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
Binary fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
||||||
assertEquals("1", fromDB.getIdElement().getVersionIdPart());
|
assertEquals("1", fromDB.getIdElement().getVersionIdPart());
|
||||||
|
|
||||||
|
@ -355,7 +354,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(resp);
|
IOUtils.closeQuietly(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
||||||
assertEquals("2", fromDB.getIdElement().getVersionIdPart());
|
assertEquals("2", fromDB.getIdElement().getVersionIdPart());
|
||||||
|
|
||||||
|
@ -370,12 +369,12 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(resp);
|
IOUtils.closeQuietly(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
||||||
assertEquals("3", fromDB.getIdElement().getVersionIdPart());
|
assertEquals("3", fromDB.getIdElement().getVersionIdPart());
|
||||||
|
|
||||||
// Now an update with the wrong ID in the body
|
// Now an update with the wrong ID in the body
|
||||||
|
|
||||||
arr[0] = 4;
|
arr[0] = 4;
|
||||||
binary.setId("");
|
binary.setId("");
|
||||||
encoded = myFhirCtx.newJsonParser().encodeResourceToString(binary);
|
encoded = myFhirCtx.newJsonParser().encodeResourceToString(binary);
|
||||||
|
@ -387,7 +386,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
} finally {
|
} finally {
|
||||||
IOUtils.closeQuietly(resp);
|
IOUtils.closeQuietly(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
fromDB = ourClient.read().resource(Binary.class).withId(resource.toVersionless()).execute();
|
||||||
assertEquals("3", fromDB.getIdElement().getVersionIdPart());
|
assertEquals("3", fromDB.getIdElement().getVersionIdPart());
|
||||||
|
|
||||||
|
@ -674,7 +673,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
String encoded = myFhirCtx.newXmlParser().encodeResourceToString(response);
|
String encoded = myFhirCtx.newXmlParser().encodeResourceToString(response);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
assertThat(encoded, containsString(
|
assertThat(encoded, containsString(
|
||||||
"<issue><severity value=\"information\"/><code value=\"informational\"/><diagnostics value=\"Successfully deleted Patient?identifier=testDeleteConditionalMultiple resource(s) in 2ms\"/></issue>"));
|
"<issue><severity value=\"information\"/><code value=\"informational\"/><diagnostics value=\"Successfully deleted 2 resource(s) in "));
|
||||||
try {
|
try {
|
||||||
ourClient.read().resource("Patient").withId(id1).execute();
|
ourClient.read().resource("Patient").withId(id1).execute();
|
||||||
fail();
|
fail();
|
||||||
|
@ -726,7 +725,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
* Test for #345
|
* Test for #345
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteNormal() throws IOException {
|
public void testDeleteNormal() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.addName().setFamily("FAM");
|
p.addName().setFamily("FAM");
|
||||||
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||||
|
@ -743,6 +742,17 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteReturnsOperationOutcome() {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().setFamily("FAM");
|
||||||
|
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
IBaseOperationOutcome resp = ourClient.delete().resourceById(id).execute();
|
||||||
|
OperationOutcome oo = (OperationOutcome) resp;
|
||||||
|
assertThat(oo.getIssueFirstRep().getDiagnostics(), startsWith("Successfully deleted 1 resource(s) in "));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteResourceConditional1() throws IOException {
|
public void testDeleteResourceConditional1() throws IOException {
|
||||||
String methodName = "testDeleteResourceConditional1";
|
String methodName = "testDeleteResourceConditional1";
|
||||||
|
@ -768,6 +778,10 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
response = ourHttpClient.execute(delete);
|
response = ourHttpClient.execute(delete);
|
||||||
try {
|
try {
|
||||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
|
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
ourLog.info(resp);
|
||||||
|
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, resp);
|
||||||
|
assertThat(oo.getIssueFirstRep().getDiagnostics(), startsWith("Successfully deleted 1 resource(s) in "));
|
||||||
} finally {
|
} finally {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
@ -777,6 +791,24 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
try {
|
try {
|
||||||
ourLog.info(response.toString());
|
ourLog.info(response.toString());
|
||||||
assertEquals(Constants.STATUS_HTTP_410_GONE, response.getStatusLine().getStatusCode());
|
assertEquals(Constants.STATUS_HTTP_410_GONE, response.getStatusLine().getStatusCode());
|
||||||
|
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
ourLog.info(resp);
|
||||||
|
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, resp);
|
||||||
|
assertThat(oo.getIssueFirstRep().getDiagnostics(), startsWith("Resource was deleted at"));
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete should now have no matches
|
||||||
|
|
||||||
|
delete = new HttpDelete(ourServerBase + "/Patient?name=" + methodName);
|
||||||
|
response = ourHttpClient.execute(delete);
|
||||||
|
try {
|
||||||
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
|
String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
ourLog.info(resp);
|
||||||
|
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, resp);
|
||||||
|
assertThat(oo.getIssueFirstRep().getDiagnostics(), startsWith("Unable to find resource matching URL \"Patient?name=testDeleteResourceConditional1\". Deletion failed."));
|
||||||
} finally {
|
} finally {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1813,10 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
ourLog.info("Response: {}", respString);
|
ourLog.info("Response: {}", respString);
|
||||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||||
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, respString);
|
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, respString);
|
||||||
assertEquals("Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"AAA\" does not match URL ID of \"" + id.getIdPart() + "\"", oo.getIssue().get(0).getDiagnostics());
|
assertEquals(
|
||||||
|
"Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"AAA\" does not match URL ID of \""
|
||||||
|
+ id.getIdPart() + "\"",
|
||||||
|
oo.getIssue().get(0).getDiagnostics());
|
||||||
} finally {
|
} finally {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
@ -1809,12 +1844,11 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
@Test
|
@Test
|
||||||
public void testIncludeWithExternalReferences() {
|
public void testIncludeWithExternalReferences() {
|
||||||
myDaoConfig.setAllowExternalReferences(true);
|
myDaoConfig.setAllowExternalReferences(true);
|
||||||
|
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
p.getManagingOrganization().setReference("http://example.com/Organization/123");
|
p.getManagingOrganization().setReference("http://example.com/Organization/123");
|
||||||
ourClient.create().resource(p).execute();
|
ourClient.create().resource(p).execute();
|
||||||
|
|
||||||
|
|
||||||
Bundle b = ourClient.search().forResource("Patient").include(Patient.INCLUDE_ORGANIZATION).returnBundle(Bundle.class).execute();
|
Bundle b = ourClient.search().forResource("Patient").include(Patient.INCLUDE_ORGANIZATION).returnBundle(Bundle.class).execute();
|
||||||
assertEquals(1, b.getEntry().size());
|
assertEquals(1, b.getEntry().size());
|
||||||
}
|
}
|
||||||
|
@ -1834,7 +1868,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMetadataSuperParamsAreIncluded() throws IOException {
|
public void testMetadataSuperParamsAreIncluded() throws IOException {
|
||||||
StructureDefinition p = new StructureDefinition();
|
StructureDefinition p = new StructureDefinition();
|
||||||
|
@ -1843,12 +1876,12 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
IIdType id = ourClient.create().resource(p).execute().getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
Bundle resp = ourClient
|
Bundle resp = ourClient
|
||||||
.search()
|
.search()
|
||||||
.forResource(StructureDefinition.class)
|
.forResource(StructureDefinition.class)
|
||||||
.where(StructureDefinition.URL.matches().value("http://example.com/foo"))
|
.where(StructureDefinition.URL.matches().value("http://example.com/foo"))
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals(1, resp.getTotal());
|
assertEquals(1, resp.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2101,9 +2134,10 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
String input = IOUtils.toString(getClass().getResourceAsStream("/two_questionnaires.json"), StandardCharsets.UTF_8);
|
String input = IOUtils.toString(getClass().getResourceAsStream("/two_questionnaires.json"), StandardCharsets.UTF_8);
|
||||||
String respString = ourClient.transaction().withBundle(input).prettyPrint().execute();
|
String respString = ourClient.transaction().withBundle(input).prettyPrint().execute();
|
||||||
ourLog.info(respString);
|
ourLog.info(respString);
|
||||||
|
|
||||||
ourHttpClient.execute(new HttpGet("http://localhost:" + ourPort + "/QuestionnaireResponse?patient=QR3295&questionnaire=profile&_sort:desc=authored&_count=5&_include=QuestionnaireResponse:questionnaire&_include=QuestionnaireResponse:subject"));
|
ourHttpClient.execute(new HttpGet("http://localhost:" + ourPort
|
||||||
// Bundle bundle =
|
+ "/QuestionnaireResponse?patient=QR3295&questionnaire=profile&_sort:desc=authored&_count=5&_include=QuestionnaireResponse:questionnaire&_include=QuestionnaireResponse:subject"));
|
||||||
|
// Bundle bundle =
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -2284,14 +2318,14 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
Bundle found = ourClient
|
Bundle found = ourClient
|
||||||
.search()
|
.search()
|
||||||
.forResource(Patient.class)
|
.forResource(Patient.class)
|
||||||
.where(BaseResource.RES_ID.exactly().systemAndValues(null, id1.getIdPart(), id2.getIdPart()))
|
.where(BaseResource.RES_ID.exactly().systemAndValues(null, id1.getIdPart(), id2.getIdPart()))
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertThat(toUnqualifiedVersionlessIds(found), empty());
|
assertThat(toUnqualifiedVersionlessIds(found), empty());
|
||||||
|
|
||||||
found = ourClient
|
found = ourClient
|
||||||
.search()
|
.search()
|
||||||
.forResource(Patient.class)
|
.forResource(Patient.class)
|
||||||
|
@ -2319,14 +2353,14 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertThat(toUnqualifiedVersionlessIds(found), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(found), containsInAnyOrder(id1));
|
||||||
|
|
||||||
found = ourClient
|
found = ourClient
|
||||||
.search()
|
.search()
|
||||||
.forResource(Patient.class)
|
.forResource(Patient.class)
|
||||||
.where(BaseResource.RES_ID.exactly().codes(Arrays.asList(id1.getIdPart(), id2.getIdPart(), "FOOOOO")))
|
.where(BaseResource.RES_ID.exactly().codes(Arrays.asList(id1.getIdPart(), id2.getIdPart(), "FOOOOO")))
|
||||||
.and(BaseResource.RES_ID.exactly().code(id1.getIdPart()))
|
.and(BaseResource.RES_ID.exactly().code(id1.getIdPart()))
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertThat(toUnqualifiedVersionlessIds(found), containsInAnyOrder(id1));
|
assertThat(toUnqualifiedVersionlessIds(found), containsInAnyOrder(id1));
|
||||||
|
|
||||||
|
@ -3445,7 +3479,9 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
ourLog.info(responseString);
|
ourLog.info(responseString);
|
||||||
assertEquals(400, response.getStatusLine().getStatusCode());
|
assertEquals(400, response.getStatusLine().getStatusCode());
|
||||||
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, responseString);
|
OperationOutcome oo = myFhirCtx.newXmlParser().parseResource(OperationOutcome.class, responseString);
|
||||||
assertEquals("Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"333\" does not match URL ID of \"A2\"", oo.getIssue().get(0).getDiagnostics());
|
assertEquals(
|
||||||
|
"Can not update resource, resource body must contain an ID element which matches the request URL for update (PUT) operation - Resource body ID of \"333\" does not match URL ID of \"A2\"",
|
||||||
|
oo.getIssue().get(0).getDiagnostics());
|
||||||
} finally {
|
} finally {
|
||||||
response.close();
|
response.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
CloseableHttpResponse resp = ourHttpClient.execute(req);
|
CloseableHttpResponse resp = ourHttpClient.execute(req);
|
||||||
try {
|
try {
|
||||||
String encoded = IOUtils.toString(resp.getEntity().getContent());
|
String encoded = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
|
|
||||||
assertThat(encoded, containsString("transaction-response"));
|
assertThat(encoded, containsString("transaction-response"));
|
||||||
|
@ -162,7 +162,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
CloseableHttpResponse resp = ourHttpClient.execute(req);
|
CloseableHttpResponse resp = ourHttpClient.execute(req);
|
||||||
try {
|
try {
|
||||||
String encoded = IOUtils.toString(resp.getEntity().getContent());
|
String encoded = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
|
|
||||||
assertThat(encoded, containsString("transaction-response"));
|
assertThat(encoded, containsString("transaction-response"));
|
||||||
|
@ -271,14 +271,14 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/questionnaire-sdc-profile-example-ussg-fht.xml");
|
InputStream bundleRes = SystemProviderDstu2Test.class.getResourceAsStream("/questionnaire-sdc-profile-example-ussg-fht.xml");
|
||||||
String bundleStr = IOUtils.toString(bundleRes);
|
String bundleStr = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
HttpPost req = new HttpPost(ourServerBase);
|
HttpPost req = new HttpPost(ourServerBase);
|
||||||
req.setEntity(new StringEntity(bundleStr, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8")));
|
req.setEntity(new StringEntity(bundleStr, ContentType.parse(Constants.CT_FHIR_XML + "; charset=utf-8")));
|
||||||
|
|
||||||
CloseableHttpResponse resp = ourHttpClient.execute(req);
|
CloseableHttpResponse resp = ourHttpClient.execute(req);
|
||||||
try {
|
try {
|
||||||
String encoded = IOUtils.toString(resp.getEntity().getContent());
|
String encoded = IOUtils.toString(resp.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(encoded);
|
ourLog.info(encoded);
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -314,7 +314,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = IOUtils.toString(http.getEntity().getContent());
|
String response = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
assertThat(response, containsString("_format=json"));
|
assertThat(response, containsString("_format=json"));
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
|
@ -342,7 +342,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
get.addHeader("Accept", "application/xml+fhir");
|
get.addHeader("Accept", "application/xml+fhir");
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
String response = IOUtils.toString(http.getEntity().getContent());
|
String response = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
assertThat(response, not(containsString("_format")));
|
assertThat(response, not(containsString("_format")));
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
|
@ -373,7 +373,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
HttpGet get = new HttpGet(ourServerBase + "/$mark-all-resources-for-reindexing");
|
HttpGet get = new HttpGet(ourServerBase + "/$mark-all-resources-for-reindexing");
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -404,7 +404,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(200, http.getStatusLine().getStatusCode());
|
assertEquals(200, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
|
|
||||||
Parameters parameters = ourCtx.newXmlParser().parseResource(Parameters.class, output);
|
Parameters parameters = ourCtx.newXmlParser().parseResource(Parameters.class, output);
|
||||||
|
@ -434,7 +434,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
CloseableHttpResponse http = ourHttpClient.execute(get);
|
CloseableHttpResponse http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(400, http.getStatusLine().getStatusCode());
|
assertEquals(400, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertThat(output, containsString("Parameter 'context' must be provided"));
|
assertThat(output, containsString("Parameter 'context' must be provided"));
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -445,7 +445,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
http = ourHttpClient.execute(get);
|
http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(400, http.getStatusLine().getStatusCode());
|
assertEquals(400, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertThat(output, containsString("Parameter 'searchParam' must be provided"));
|
assertThat(output, containsString("Parameter 'searchParam' must be provided"));
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -456,7 +456,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
http = ourHttpClient.execute(get);
|
http = ourHttpClient.execute(get);
|
||||||
try {
|
try {
|
||||||
assertEquals(400, http.getStatusLine().getStatusCode());
|
assertEquals(400, http.getStatusLine().getStatusCode());
|
||||||
String output = IOUtils.toString(http.getEntity().getContent());
|
String output = IOUtils.toString(http.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
ourLog.info(output);
|
ourLog.info(output);
|
||||||
assertThat(output, containsString("Parameter 'text' must be provided"));
|
assertThat(output, containsString("Parameter 'text' must be provided"));
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -500,7 +500,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
public void testTransactionFromBundle2() throws Exception {
|
public void testTransactionFromBundle2() throws Exception {
|
||||||
|
|
||||||
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
|
|
||||||
|
@ -516,7 +516,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/transaction_link_patient_eve_temp.xml");
|
||||||
bundle = IOUtils.toString(bundleRes);
|
bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
public void testTransactionFromBundle3() throws Exception {
|
public void testTransactionFromBundle3() throws Exception {
|
||||||
|
|
||||||
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/grahame-transaction.xml");
|
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/grahame-transaction.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle4() throws Exception {
|
public void testTransactionFromBundle4() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/simone_bundle.xml");
|
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/simone_bundle.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
String response = ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
ourLog.info(response);
|
ourLog.info(response);
|
||||||
Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
|
Bundle bundleResp = ourCtx.newXmlParser().parseResource(Bundle.class, response);
|
||||||
|
@ -563,7 +563,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle5() throws Exception {
|
public void testTransactionFromBundle5() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/simone_bundle2.xml");
|
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/simone_bundle2.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
try {
|
try {
|
||||||
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
fail();
|
fail();
|
||||||
|
@ -577,7 +577,7 @@ public class SystemProviderDstu3Test extends BaseJpaDstu3Test {
|
||||||
@Test
|
@Test
|
||||||
public void testTransactionFromBundle6() throws Exception {
|
public void testTransactionFromBundle6() throws Exception {
|
||||||
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/simone_bundle3.xml");
|
InputStream bundleRes = SystemProviderDstu3Test.class.getResourceAsStream("/simone_bundle3.xml");
|
||||||
String bundle = IOUtils.toString(bundleRes);
|
String bundle = IOUtils.toString(bundleRes, StandardCharsets.UTF_8);
|
||||||
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
ourClient.transaction().withBundle(bundle).prettyPrint().execute();
|
||||||
// try {
|
// try {
|
||||||
// fail();
|
// fail();
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"resourceType": "CodeSystem",
|
||||||
|
"id": "22472",
|
||||||
|
"meta": {
|
||||||
|
"versionId": "3",
|
||||||
|
"lastUpdated": "2017-01-27T10:53:39.457-05:00"
|
||||||
|
},
|
||||||
|
"url": "xvalue://dedalus.eu/mci/CodeSystem/AddressUse",
|
||||||
|
"name": "AddressUse",
|
||||||
|
"status": "active",
|
||||||
|
"publisher": "x1v1-mci",
|
||||||
|
"date": "2016-04-07",
|
||||||
|
"description": "AddressUse",
|
||||||
|
"caseSensitive": true,
|
||||||
|
"compositional": false,
|
||||||
|
"versionNeeded": false,
|
||||||
|
"content": "complete",
|
||||||
|
"concept": {
|
||||||
|
"code": "work",
|
||||||
|
"display": "Work",
|
||||||
|
"definition": "An office address. First choice for business related contacts during business hours.",
|
||||||
|
"designation": {
|
||||||
|
"language": "IT",
|
||||||
|
"value": "Lavoro"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -98,7 +98,7 @@ public class GenericClientDstu3Test {
|
||||||
byte[] body = IOUtils.toByteArray(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent());
|
byte[] body = IOUtils.toByteArray(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent());
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractBodyAsString(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
private String extractBodyAsString(ArgumentCaptor<HttpUriRequest> capt) throws IOException {
|
||||||
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8");
|
String body = IOUtils.toString(((HttpEntityEnclosingRequestBase) capt.getAllValues().get(0)).getEntity().getContent(), "UTF-8");
|
||||||
return body;
|
return body;
|
||||||
|
@ -120,6 +120,26 @@ public class GenericClientDstu3Test {
|
||||||
return capt;
|
return capt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevIncludeRecursive() throws ClientProtocolException, IOException {
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = prepareClientForSearchResponse();
|
||||||
|
|
||||||
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
client.search()
|
||||||
|
.forResource(EpisodeOfCare.class)
|
||||||
|
.where(EpisodeOfCare.PATIENT.hasId("123"))
|
||||||
|
.revInclude(Encounter.INCLUDE_EPISODEOFCARE)
|
||||||
|
.revInclude(Observation.INCLUDE_ENCOUNTER.asRecursive())
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
assertEquals("http://example.com/fhir/EpisodeOfCare?patient=123&_revinclude=Encounter%3Aepisodeofcare&_revinclude%3Arecurse=Observation%3Aencounter", capt.getAllValues().get(idx).getURI().toString());
|
||||||
|
idx++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchJsonByIdString() throws Exception {
|
public void testPatchJsonByIdString() throws Exception {
|
||||||
OperationOutcome conf = new OperationOutcome();
|
OperationOutcome conf = new OperationOutcome();
|
||||||
|
@ -143,20 +163,21 @@ public class GenericClientDstu3Test {
|
||||||
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||||
|
|
||||||
MethodOutcome outcome = client
|
MethodOutcome outcome = client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody(patch)
|
.withBody(patch)
|
||||||
.withId("Patient/123")
|
.withId("Patient/123")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
||||||
assertEquals(patch, extractBodyAsString(capt));
|
assertEquals(patch, extractBodyAsString(capt));
|
||||||
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||||
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchJsonByIdType() throws Exception {
|
public void testPatchJsonByIdType() throws Exception {
|
||||||
OperationOutcome conf = new OperationOutcome();
|
OperationOutcome conf = new OperationOutcome();
|
||||||
|
@ -180,20 +201,21 @@ public class GenericClientDstu3Test {
|
||||||
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||||
|
|
||||||
MethodOutcome outcome = client
|
MethodOutcome outcome = client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody(patch)
|
.withBody(patch)
|
||||||
.withId(new IdType("http://localhost/fhir/Patient/123/_history/234"))
|
.withId(new IdType("http://localhost/fhir/Patient/123/_history/234"))
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
||||||
assertEquals(patch, extractBodyAsString(capt));
|
assertEquals(patch, extractBodyAsString(capt));
|
||||||
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||||
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchJsonByConditionalString() throws Exception {
|
public void testPatchJsonByConditionalString() throws Exception {
|
||||||
OperationOutcome conf = new OperationOutcome();
|
OperationOutcome conf = new OperationOutcome();
|
||||||
|
@ -217,20 +239,21 @@ public class GenericClientDstu3Test {
|
||||||
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||||
|
|
||||||
MethodOutcome outcome = client
|
MethodOutcome outcome = client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody(patch)
|
.withBody(patch)
|
||||||
.conditionalByUrl("Patient?foo=bar")
|
.conditionalByUrl("Patient?foo=bar")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient?foo=bar", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Patient?foo=bar", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
||||||
assertEquals(patch, extractBodyAsString(capt));
|
assertEquals(patch, extractBodyAsString(capt));
|
||||||
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||||
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchJsonByConditionalParam() throws Exception {
|
public void testPatchJsonByConditionalParam() throws Exception {
|
||||||
OperationOutcome conf = new OperationOutcome();
|
OperationOutcome conf = new OperationOutcome();
|
||||||
|
@ -254,21 +277,22 @@ public class GenericClientDstu3Test {
|
||||||
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||||
|
|
||||||
MethodOutcome outcome = client
|
MethodOutcome outcome = client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody(patch)
|
.withBody(patch)
|
||||||
.conditional("Patient").where(Patient.NAME.matches().value("TEST"))
|
.conditional("Patient").where(Patient.NAME.matches().value("TEST"))
|
||||||
.and(Patient.FAMILY.matches().value("TEST2"))
|
.and(Patient.FAMILY.matches().value("TEST2"))
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient?name=TEST&family=TEST2", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Patient?name=TEST&family=TEST2", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
||||||
assertEquals(patch, extractBodyAsString(capt));
|
assertEquals(patch, extractBodyAsString(capt));
|
||||||
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||||
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchJsonByConditionalParamResourceType() throws Exception {
|
public void testPatchJsonByConditionalParamResourceType() throws Exception {
|
||||||
OperationOutcome conf = new OperationOutcome();
|
OperationOutcome conf = new OperationOutcome();
|
||||||
|
@ -292,21 +316,22 @@ public class GenericClientDstu3Test {
|
||||||
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
String patch = "[ { \"op\":\"replace\", \"path\":\"/active\", \"value\":false } ]";
|
||||||
|
|
||||||
MethodOutcome outcome = client
|
MethodOutcome outcome = client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody(patch)
|
.withBody(patch)
|
||||||
.conditional(Patient.class).where(Patient.NAME.matches().value("TEST"))
|
.conditional(Patient.class).where(Patient.NAME.matches().value("TEST"))
|
||||||
.and(Patient.FAMILY.matches().value("TEST2"))
|
.and(Patient.FAMILY.matches().value("TEST2"))
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient?name=TEST&family=TEST2", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Patient?name=TEST&family=TEST2", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
||||||
assertEquals(patch, extractBodyAsString(capt));
|
assertEquals(patch, extractBodyAsString(capt));
|
||||||
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_JSON_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||||
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchXmlByIdString() throws Exception {
|
public void testPatchXmlByIdString() throws Exception {
|
||||||
OperationOutcome conf = new OperationOutcome();
|
OperationOutcome conf = new OperationOutcome();
|
||||||
|
@ -330,31 +355,31 @@ public class GenericClientDstu3Test {
|
||||||
String patch = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><diff xmlns:fhir=\"http://hl7.org/fhir\"><replace sel=\"fhir:Patient/fhir:active/@value\">false</replace></diff>";
|
String patch = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><diff xmlns:fhir=\"http://hl7.org/fhir\"><replace sel=\"fhir:Patient/fhir:active/@value\">false</replace></diff>";
|
||||||
|
|
||||||
MethodOutcome outcome = client
|
MethodOutcome outcome = client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody(patch)
|
.withBody(patch)
|
||||||
.withId("Patient/123")
|
.withId("Patient/123")
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Patient/123", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
assertEquals("PATCH", capt.getAllValues().get(0).getRequestLine().getMethod());
|
||||||
assertEquals(patch, extractBodyAsString(capt));
|
assertEquals(patch, extractBodyAsString(capt));
|
||||||
assertEquals(Constants.CT_XML_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_XML_PATCH, capt.getAllValues().get(idx).getFirstHeader("Content-Type").getValue().replaceAll(";.*", ""));
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||||
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
assertThat(oo.getText().getDivAsString(), containsString("OK!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatchInvalid() throws Exception {
|
public void testPatchInvalid() throws Exception {
|
||||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client
|
client
|
||||||
.patch()
|
.patch()
|
||||||
.withBody("AA")
|
.withBody("AA")
|
||||||
.withId("Patient/123")
|
.withId("Patient/123")
|
||||||
.execute();
|
.execute();
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
assertEquals("Unable to determine encoding of patch", e.getMessage());
|
assertEquals("Unable to determine encoding of patch", e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -388,7 +413,7 @@ public class GenericClientDstu3Test {
|
||||||
assertEquals("http://example.com/fhir/Device?_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Device?_format=json", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
assertEquals("application/fhir+json;q=1.0, application/json+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
client.setEncoding(EncodingEnum.XML);
|
client.setEncoding(EncodingEnum.XML);
|
||||||
client.search()
|
client.search()
|
||||||
|
@ -399,7 +424,7 @@ public class GenericClientDstu3Test {
|
||||||
assertEquals("http://example.com/fhir/Device?_format=xml", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
assertEquals("http://example.com/fhir/Device?_format=xml", UrlUtil.unescape(capt.getAllValues().get(idx).getURI().toString()));
|
||||||
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
assertEquals("application/fhir+xml;q=1.0, application/xml+fhir;q=0.9", capt.getAllValues().get(idx).getFirstHeader(Constants.HEADER_ACCEPT).getValue());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -480,9 +505,7 @@ public class GenericClientDstu3Test {
|
||||||
assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)).getContent());
|
assertArrayEquals(new byte[] { 0, 1, 2, 3, 4 }, ourCtx.newXmlParser().parseResource(Binary.class, extractBodyAsString(capt)).getContent());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Test
|
@Test
|
||||||
public void testClientFailures() throws Exception {
|
public void testClientFailures() throws Exception {
|
||||||
|
@ -592,7 +615,7 @@ public class GenericClientDstu3Test {
|
||||||
assertEquals(myAnswerCount, capt.getAllValues().size());
|
assertEquals(myAnswerCount, capt.getAllValues().size());
|
||||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||||
assertEquals(Constants.CT_FHIR_XML_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
assertEquals(Constants.CT_FHIR_XML_NEW, capt.getAllValues().get(0).getFirstHeader("content-type").getValue().replaceAll(";.*", ""));
|
||||||
|
|
||||||
assertEquals("http://foo.com/base/Patient/222/_history/3", capt.getAllValues().get(1).getURI().toASCIIString());
|
assertEquals("http://foo.com/base/Patient/222/_history/3", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,7 +1050,7 @@ public class GenericClientDstu3Test {
|
||||||
|
|
||||||
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient", capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
client
|
client
|
||||||
.search()
|
.search()
|
||||||
|
@ -1053,22 +1076,22 @@ public class GenericClientDstu3Test {
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPutDoesntForceAllIdsJson() throws Exception {
|
public void testPutDoesntForceAllIdsJson() throws Exception {
|
||||||
IParser p = ourCtx.newJsonParser();
|
IParser p = ourCtx.newJsonParser();
|
||||||
|
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
patient.setId("PATIENT1");
|
patient.setId("PATIENT1");
|
||||||
patient.addName().setFamily("PATIENT1");
|
patient.addName().setFamily("PATIENT1");
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.setId("BUNDLE1");
|
bundle.setId("BUNDLE1");
|
||||||
bundle.addEntry().setResource(patient);
|
bundle.addEntry().setResource(patient);
|
||||||
|
|
||||||
final String encoded = p.encodeResourceToString(bundle);
|
final String encoded = p.encodeResourceToString(bundle);
|
||||||
assertEquals("{\"resourceType\":\"Bundle\",\"id\":\"BUNDLE1\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"PATIENT1\",\"name\":[{\"family\":\"PATIENT1\"}]}}]}", encoded);
|
assertEquals("{\"resourceType\":\"Bundle\",\"id\":\"BUNDLE1\",\"entry\":[{\"resource\":{\"resourceType\":\"Patient\",\"id\":\"PATIENT1\",\"name\":[{\"family\":\"PATIENT1\"}]}}]}", encoded);
|
||||||
|
|
||||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||||
|
@ -1251,7 +1274,7 @@ public class GenericClientDstu3Test {
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
assertEquals("http://example.com/fhir/Patient?birthdate=gt"+dateString, capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient?birthdate=gt" + dateString, capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -1261,7 +1284,7 @@ public class GenericClientDstu3Test {
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
assertEquals("http://example.com/fhir/Patient?birthdate=gt"+dateString, capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient?birthdate=gt" + dateString, capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -1271,7 +1294,7 @@ public class GenericClientDstu3Test {
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
assertEquals("http://example.com/fhir/Patient?birthdate=ge"+dateString, capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient?birthdate=ge" + dateString, capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -1281,7 +1304,7 @@ public class GenericClientDstu3Test {
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
assertEquals("http://example.com/fhir/Patient?birthdate=lt"+dateString, capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient?birthdate=lt" + dateString, capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -1291,7 +1314,7 @@ public class GenericClientDstu3Test {
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
assertEquals("http://example.com/fhir/Patient?birthdate=le"+dateString, capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient?birthdate=le" + dateString, capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -1301,7 +1324,7 @@ public class GenericClientDstu3Test {
|
||||||
.returnBundle(Bundle.class)
|
.returnBundle(Bundle.class)
|
||||||
.execute();
|
.execute();
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
assertEquals("http://example.com/fhir/Patient?birthdate="+dateString, capt.getAllValues().get(idx).getURI().toString());
|
assertEquals("http://example.com/fhir/Patient?birthdate=" + dateString, capt.getAllValues().get(idx).getURI().toString());
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
@ -1639,7 +1662,7 @@ public class GenericClientDstu3Test {
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
Collection<String> values = Arrays.asList("VAL1", "VAL2", "VAL3A,B");
|
Collection<String> values = Arrays.asList("VAL1", "VAL2", "VAL3A,B");
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
client.search()
|
client.search()
|
||||||
.forResource("Patient")
|
.forResource("Patient")
|
||||||
|
@ -1743,7 +1766,6 @@ public class GenericClientDstu3Test {
|
||||||
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
assertEquals("Unable to determing encoding of request (body does not appear to be valid XML or JSON)", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -2012,7 +2034,7 @@ public class GenericClientDstu3Test {
|
||||||
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
||||||
patient.setId("123");
|
patient.setId("123");
|
||||||
patient.getText().setDivAsString("OK!");
|
patient.getText().setDivAsString("OK!");
|
||||||
|
|
||||||
final String respString = p.encodeResourceToString(patient);
|
final String respString = p.encodeResourceToString(patient);
|
||||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
@ -2028,7 +2050,7 @@ public class GenericClientDstu3Test {
|
||||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
MyPatientWithExtensions read = client.read().resource(MyPatientWithExtensions.class).withId(new IdType("1")).execute();
|
MyPatientWithExtensions read = client.read().resource(MyPatientWithExtensions.class).withId(new IdType("1")).execute();
|
||||||
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", read.getText().getDivAsString());
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">OK!</div>", read.getText().getDivAsString());
|
||||||
|
|
||||||
// Ensure that we haven't overridden the default type for the name
|
// Ensure that we haven't overridden the default type for the name
|
||||||
assertFalse(MyPatientWithExtensions.class.isAssignableFrom(Patient.class));
|
assertFalse(MyPatientWithExtensions.class.isAssignableFrom(Patient.class));
|
||||||
assertFalse(Patient.class.isAssignableFrom(MyPatientWithExtensions.class));
|
assertFalse(Patient.class.isAssignableFrom(MyPatientWithExtensions.class));
|
||||||
|
@ -2037,7 +2059,7 @@ public class GenericClientDstu3Test {
|
||||||
IParser parser = ourCtx.newXmlParser();
|
IParser parser = ourCtx.newXmlParser();
|
||||||
String encoded = parser.encodeResourceToString(pt);
|
String encoded = parser.encodeResourceToString(pt);
|
||||||
pt = (Patient) parser.parseResource(encoded);
|
pt = (Patient) parser.parseResource(encoded);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -2045,13 +2067,12 @@ public class GenericClientDstu3Test {
|
||||||
IParser p = ourCtx.newXmlParser();
|
IParser p = ourCtx.newXmlParser();
|
||||||
|
|
||||||
Bundle b = new Bundle();
|
Bundle b = new Bundle();
|
||||||
|
|
||||||
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
MyPatientWithExtensions patient = new MyPatientWithExtensions();
|
||||||
patient.setId("123");
|
patient.setId("123");
|
||||||
patient.getText().setDivAsString("OK!");
|
patient.getText().setDivAsString("OK!");
|
||||||
b.addEntry().setResource(patient);
|
b.addEntry().setResource(patient);
|
||||||
|
|
||||||
|
|
||||||
final String respString = p.encodeResourceToString(b);
|
final String respString = p.encodeResourceToString(b);
|
||||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
|
||||||
|
@ -2066,7 +2087,7 @@ public class GenericClientDstu3Test {
|
||||||
|
|
||||||
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
|
||||||
Bundle bundle = client.search().forResource(MyPatientWithExtensions.class).returnBundle(Bundle.class).execute();
|
Bundle bundle = client.search().forResource(MyPatientWithExtensions.class).returnBundle(Bundle.class).execute();
|
||||||
|
|
||||||
assertEquals(1, bundle.getEntry().size());
|
assertEquals(1, bundle.getEntry().size());
|
||||||
assertEquals(MyPatientWithExtensions.class, bundle.getEntry().get(0).getResource().getClass());
|
assertEquals(MyPatientWithExtensions.class, bundle.getEntry().get(0).getResource().getClass());
|
||||||
}
|
}
|
||||||
|
@ -2082,8 +2103,6 @@ public class GenericClientDstu3Test {
|
||||||
assertEquals(expectedUserAgent(), capt.getAllValues().get(0).getHeaders("User-Agent")[0].getValue());
|
assertEquals(expectedUserAgent(), capt.getAllValues().get(0).getHeaders("User-Agent")[0].getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
@ -2093,5 +2112,5 @@ public class GenericClientDstu3Test {
|
||||||
public static void beforeClass() {
|
public static void beforeClass() {
|
||||||
ourCtx = FhirContext.forDstu3();
|
ourCtx = FhirContext.forDstu3();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,14 @@
|
||||||
with the passed in body. Thanks to Artem Sopin for reporting and providing a test
|
with the passed in body. Thanks to Artem Sopin for reporting and providing a test
|
||||||
case for this!
|
case for this!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
Client revincludes did not include the :recurse modifier. Thanks to
|
||||||
|
Jenny Meinsma for pointing this out on Zulip!
|
||||||
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
JPA server did not return an OperationOutcome in the response for
|
||||||
|
a normal delete operation.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.2" date="2016-12-20">
|
<release version="2.2" date="2016-12-20">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue