Add expunge method

This commit is contained in:
James Agnew 2018-04-22 18:34:56 -04:00
parent 51216c0010
commit 591539cf13
35 changed files with 2312 additions and 895 deletions

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.rest.gclient;
import org.hl7.fhir.instance.model.api.IIdType;
/*
* #%L
* HAPI FHIR - Core Library
@ -9,9 +11,9 @@ package ca.uhn.fhir.rest.gclient;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -21,38 +23,42 @@ package ca.uhn.fhir.rest.gclient;
*/
public interface IOperation extends IBaseOn<IOperationUnnamed> {
/**
* This operation is called <b><a href="https://www.hl7.org/fhir/messaging.html">$process-message</a></b> as defined by the FHIR
* specification.<br><br>
* Usage :<br>
* <code>
* <pre>
* Bundle response = client
* .operation()
* .processMessage()
* .synchronous(Bundle.class)
* .setResponseUrlParam("http://myserver/fhir")
* .setMessageBundle(msgBundle)
* .execute();
*
* //if you want to send an async message
*
* OperationOutcome response = client
* .operation()
* .processMessage()
* .asynchronous(OperationOutcome.class)
* .setResponseUrlParam("http://myserver/fhir")
* .setMessageBundle(msgBundle)
* .execute();
*
* </pre>
* </code>
*
* @see <a href="https://www.hl7.org/fhir/messaging.html">2.4 Messaging
* using FHIR Resources</a>
*
* @return An interface that defines the operation related to sending
* Messages to a Messaging Server
*/
IOperationProcessMsg processMessage();
/**
* This operation operates on a specific version of a resource
*/
IOperationUnnamed onInstanceVersion(IIdType theId);
/**
* This operation is called <b><a href="https://www.hl7.org/fhir/messaging.html">$process-message</a></b> as defined by the FHIR
* specification.<br><br>
* Usage :<br>
* <code>
* <pre>
* Bundle response = client
* .operation()
* .processMessage()
* .synchronous(Bundle.class)
* .setResponseUrlParam("http://myserver/fhir")
* .setMessageBundle(msgBundle)
* .execute();
*
* //if you want to send an async message
*
* OperationOutcome response = client
* .operation()
* .processMessage()
* .asynchronous(OperationOutcome.class)
* .setResponseUrlParam("http://myserver/fhir")
* .setMessageBundle(msgBundle)
* .execute();
*
* </pre>
* </code>
*
* @return An interface that defines the operation related to sending
* Messages to a Messaging Server
* @see <a href="https://www.hl7.org/fhir/messaging.html">2.4 Messaging
* using FHIR Resources</a>
*/
IOperationProcessMsg processMessage();
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.rest.client.impl;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -19,35 +19,45 @@ package ca.uhn.fhir.rest.client.impl;
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.IHttpClient;
import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.client.method.*;
import ca.uhn.fhir.rest.gclient.*;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.NotModifiedException;
import ca.uhn.fhir.util.ICallable;
import ca.uhn.fhir.util.ParametersUtil;
import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.client.api.*;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.client.method.*;
import ca.uhn.fhir.rest.gclient.*;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.util.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/**
* @author James Agnew
@ -87,7 +97,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches, Boolean thePrettyPrint,
SummaryEnum theSummary, EncodingEnum theEncoding, Set<String> theSubsetElements) {
SummaryEnum theSummary, EncodingEnum theEncoding, Set<String> theSubsetElements) {
String resName = toResourceName(theType);
IIdType id = theId;
if (!id.hasBaseUrl()) {
@ -149,6 +159,13 @@ public class GenericClient extends BaseClient implements IGenericClient {
return myLastRequest;
}
/**
* For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
*/
public void setLastRequest(IHttpRequest theLastRequest) {
myLastRequest = theLastRequest;
}
protected String getPreferredId(IBaseResource theResource, String theId) {
if (isNotBlank(theId)) {
return theId;
@ -163,14 +180,20 @@ public class GenericClient extends BaseClient implements IGenericClient {
/**
* @deprecated Use {@link LoggingInterceptor} as a client interceptor registered to your
* client instead, as this provides much more fine-grained control over what is logged. This
* method will be removed at some point (deprecated in HAPI 1.6 - 2016-06-16)
* client instead, as this provides much more fine-grained control over what is logged. This
* method will be removed at some point (deprecated in HAPI 1.6 - 2016-06-16)
*/
@Deprecated
public boolean isLogRequestAndResponse() {
return myLogRequestAndResponse;
}
@Deprecated // override deprecated method
@Override
public void setLogRequestAndResponse(boolean theLogRequestAndResponse) {
myLogRequestAndResponse = theLogRequestAndResponse;
}
@Override
public IGetPage loadPage() {
return new LoadPageInternal();
@ -221,25 +244,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
return read(def.getImplementingClass(), id);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
@Override
public IUntypedQuery search() {
return new SearchInternal();
}
/**
* For now, this is a part of the internal API of HAPI - Use with caution as this method may change!
*/
public void setLastRequest(IHttpRequest theLastRequest) {
myLastRequest = theLastRequest;
}
@Deprecated // override deprecated method
@Override
public void setLogRequestAndResponse(boolean theLogRequestAndResponse) {
myLogRequestAndResponse = theLogRequestAndResponse;
}
private String toResourceName(Class<? extends IBaseResource> theType) {
return myContext.getResourceDefinition(theType).getName();
}
@ -332,30 +342,36 @@ public class GenericClient extends BaseClient implements IGenericClient {
b.append(nextChar);
} else {
switch (nextChar) {
case '|':
case '?':
case '$':
case ':':
b.append(UrlUtil.escapeUrlParam(Character.toString(nextChar)));
break;
default:
b.append(nextChar);
break;
case '|':
case '?':
case '$':
case ':':
b.append(UrlUtil.escapeUrlParam(Character.toString(nextChar)));
break;
default:
b.append(nextChar);
break;
}
}
}
return b.toString();
}
private enum MetaOperation {
ADD,
DELETE,
GET
}
private abstract class BaseClientExecutable<T extends IClientExecutable<?, Y>, Y> implements IClientExecutable<T, Y> {
protected EncodingEnum myParamEncoding;
private List<Class<? extends IBaseResource>> myPreferResponseTypes;
protected Boolean myPrettyPrint;
private boolean myQueryLogRequestAndResponse;
private HashSet<String> mySubsetElements;
protected SummaryEnum mySummaryMode;
protected CacheControlDirective myCacheControlDirective;
private List<Class<? extends IBaseResource>> myPreferResponseTypes;
private boolean myQueryLogRequestAndResponse;
private HashSet<String> mySubsetElements;
@Deprecated // override deprecated method
@SuppressWarnings("unchecked")
@ -382,13 +398,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public T encodedJson() {
myParamEncoding = EncodingEnum.JSON;
return (T) this;
}
@Override
public T encoded(EncodingEnum theEncoding) {
Validate.notNull(theEncoding, "theEncoding must not be null");
@ -396,6 +405,13 @@ public class GenericClient extends BaseClient implements IGenericClient {
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public T encodedJson() {
myParamEncoding = EncodingEnum.JSON;
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public T encodedXml() {
@ -672,7 +688,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
private class FetchConformanceInternal extends BaseClientExecutable implements IFetchConformanceUntyped, IFetchConformanceTyped {
private RuntimeResourceDefinition myType;
@ -696,7 +712,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
private class GetPageInternal extends BaseClientExecutable<IGetPageTyped<Object>, Object> implements IGetPageTyped<Object> {
private Class<? extends IBaseBundle> myBundleType;
@ -804,7 +820,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
private final class LoadPageInternal implements IGetPage, IGetPageUntyped {
private static final String PREV = "prev";
@ -895,23 +911,23 @@ public class GenericClient extends BaseClient implements IGenericClient {
IBaseParameters parameters = ParametersUtil.newInstance(myContext);
switch (myOperation) {
case ADD:
ParametersUtil.addParameterToParameters(myContext, parameters, "meta", myMeta);
invocation = OperationMethodBinding.createOperationInvocation(myContext, myId.getResourceType(), myId.getIdPart(), "$meta-add", parameters, false);
break;
case DELETE:
ParametersUtil.addParameterToParameters(myContext, parameters, "meta", myMeta);
invocation = OperationMethodBinding.createOperationInvocation(myContext, myId.getResourceType(), myId.getIdPart(), "$meta-delete", parameters, false);
break;
case GET:
if (myId != null) {
invocation = OperationMethodBinding.createOperationInvocation(myContext, myOnType, myId.getIdPart(), "$meta", parameters, true);
} else if (myOnType != null) {
invocation = OperationMethodBinding.createOperationInvocation(myContext, myOnType, null, "$meta", parameters, true);
} else {
invocation = OperationMethodBinding.createOperationInvocation(myContext, null, null, "$meta", parameters, true);
}
break;
case ADD:
ParametersUtil.addParameterToParameters(myContext, parameters, "meta", myMeta);
invocation = OperationMethodBinding.createOperationInvocation(myContext, myId.getResourceType(), myId.getIdPart(), null, "$meta-add", parameters, false);
break;
case DELETE:
ParametersUtil.addParameterToParameters(myContext, parameters, "meta", myMeta);
invocation = OperationMethodBinding.createOperationInvocation(myContext, myId.getResourceType(), myId.getIdPart(), null, "$meta-delete", parameters, false);
break;
case GET:
if (myId != null) {
invocation = OperationMethodBinding.createOperationInvocation(myContext, myOnType, myId.getIdPart(), null, "$meta", parameters, true);
} else if (myOnType != null) {
invocation = OperationMethodBinding.createOperationInvocation(myContext, myOnType, null, null, "$meta", parameters, true);
} else {
invocation = OperationMethodBinding.createOperationInvocation(myContext, null, null, null, "$meta", parameters, true);
}
break;
}
// Should not happen
@ -974,12 +990,6 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
private enum MetaOperation {
ADD,
DELETE,
GET
}
private final class MetaParametersResponseHandler<T extends IBaseMetaType> implements IClientResponseHandler<T> {
private Class<T> myType;
@ -1018,7 +1028,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
@SuppressWarnings("rawtypes")
private class OperationInternal extends BaseClientExecutable
implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput, IOperationUntypedWithInputAndPartialOutput, IOperationProcessMsg, IOperationProcessMsgMode {
implements IOperation, IOperationUnnamed, IOperationUntyped, IOperationUntypedWithInput, IOperationUntypedWithInputAndPartialOutput, IOperationProcessMsg, IOperationProcessMsgMode {
private IIdType myId;
private Boolean myIsAsync;
@ -1115,18 +1125,22 @@ public class GenericClient extends BaseClient implements IGenericClient {
String resourceName;
String id;
String version;
if (myType != null) {
resourceName = myContext.getResourceDefinition(myType).getName();
id = null;
version = null;
} else if (myId != null) {
resourceName = myId.getResourceType();
id = myId.getIdPart();
version = myId.getVersionIdPart();
} else {
resourceName = null;
id = null;
version = null;
}
BaseHttpClientInvocation invocation = OperationMethodBinding.createOperationInvocation(myContext, resourceName, id, myOperationName, myParameters, myUseHttpGet);
BaseHttpClientInvocation invocation = OperationMethodBinding.createOperationInvocation(myContext, resourceName, id, version, myOperationName, myParameters, myUseHttpGet);
if (myReturnResourceType != null) {
ResourceResponseHandler handler;
@ -1165,6 +1179,12 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IOperationUnnamed onInstance(IIdType theId) {
myId = theId.toVersionless();
return this;
}
@Override
public IOperationUnnamed onInstanceVersion(IIdType theId) {
myId = theId;
return this;
}
@ -1242,7 +1262,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
if (!"Parameters".equals(def.getName())) {
throw new IllegalArgumentException("theOutputParameterType must refer to a HAPI FHIR Resource type for a resource named " + "Parameters" + " - " + theOutputParameterType.getName()
+ " is a resource named: " + def.getName());
+ " is a resource named: " + def.getName());
}
myParameters = (IBaseParameters) def.newInstance();
return this;
@ -1263,7 +1283,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
return this;
}
@SuppressWarnings({ "unchecked" })
@SuppressWarnings({"unchecked"})
@Override
public IOperationUntypedWithInput withParameters(IBaseParameters theParameters) {
Validate.notNull(theParameters, "theParameters can not be null");
@ -1292,7 +1312,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override
public IBaseOperationOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders)
throws BaseServerResponseException {
throws BaseServerResponseException {
EncodingEnum respType = EncodingEnum.forContentType(theResponseMimeType);
if (respType == null) {
return null;
@ -1458,7 +1478,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
private class ReadInternal extends BaseClientExecutable implements IRead, IReadTyped, IReadExecutable {
private IIdType myId;
private String myIfVersionMatches;
@ -1594,7 +1614,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
@SuppressWarnings("unchecked")
@Override
public List<IBaseResource> invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders)
throws BaseServerResponseException {
throws BaseServerResponseException {
Class<? extends IBaseResource> bundleType = myContext.getResourceDefinition("Bundle").getImplementingClass();
ResourceResponseHandler<IBaseResource> handler = new ResourceResponseHandler<IBaseResource>((Class<IBaseResource>) bundleType);
IBaseResource response = handler.invokeClient(theResponseMimeType, theResponseReader, theResponseStatusCode, theHeaders);
@ -1604,7 +1624,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@SuppressWarnings({"rawtypes", "unchecked"})
private class SearchInternal<OUTPUT> extends BaseSearch<IQuery<OUTPUT>, IQuery<OUTPUT>, OUTPUT> implements IQuery<OUTPUT>, IUntypedQuery<IQuery<OUTPUT>> {
private String myCompartmentName;
@ -1682,7 +1702,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
for (Collection<String> profileUris : myProfiles) {
StringBuilder builder = new StringBuilder();
for (Iterator<String> profileItr = profileUris.iterator(); profileItr.hasNext();) {
for (Iterator<String> profileItr = profileUris.iterator(); profileItr.hasNext(); ) {
builder.append(profileItr.next());
if (profileItr.hasNext()) {
builder.append(',');
@ -1870,77 +1890,11 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@SuppressWarnings("rawtypes")
private static class SortInternal implements ISort {
private SortOrderEnum myDirection;
private SearchInternal myFor;
private String myParamName;
private String myParamValue;
public SortInternal(SearchInternal theFor) {
myFor = theFor;
}
@Override
public IQuery ascending(IParam theParam) {
myParamName = Constants.PARAM_SORT_ASC;
myDirection = SortOrderEnum.ASC;
myParamValue = theParam.getParamName();
return myFor;
}
@Override
public IQuery ascending(String theParam) {
myParamName = Constants.PARAM_SORT_ASC;
myDirection = SortOrderEnum.ASC;
myParamValue = theParam;
return myFor;
}
@Override
public IQuery defaultOrder(IParam theParam) {
myParamName = Constants.PARAM_SORT;
myDirection = null;
myParamValue = theParam.getParamName();
return myFor;
}
@Override
public IQuery descending(IParam theParam) {
myParamName = Constants.PARAM_SORT_DESC;
myDirection = SortOrderEnum.DESC;
myParamValue = theParam.getParamName();
return myFor;
}
@Override
public IQuery descending(String theParam) {
myParamName = Constants.PARAM_SORT_DESC;
myDirection = SortOrderEnum.DESC;
myParamValue = theParam;
return myFor;
}
public SortOrderEnum getDirection() {
return myDirection;
}
public String getParamName() {
return myParamName;
}
public String getParamValue() {
return myParamValue;
}
}
private final class StringResponseHandler implements IClientResponseHandler<String> {
@Override
public String invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders)
throws IOException, BaseServerResponseException {
throws IOException, BaseServerResponseException {
return IOUtils.toString(theResponseReader);
}
}
@ -1968,7 +1922,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public T execute() {
Map<String, List<String>> params = new HashMap<String, List<String>>();
@ -2022,7 +1976,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
private class UpdateInternal extends BaseSearch<IUpdateExecutable, IUpdateWithQueryTyped, MethodOutcome>
implements IUpdate, IUpdateTyped, IUpdateExecutable, IUpdateWithQuery, IUpdateWithQueryTyped {
implements IUpdate, IUpdateTyped, IUpdateExecutable, IUpdateWithQuery, IUpdateWithQueryTyped {
private boolean myConditional;
private IIdType myId;
@ -2155,16 +2109,82 @@ public class GenericClient extends BaseClient implements IGenericClient {
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType"));
}
switch (enc) {
case XML:
encodedXml();
break;
case JSON:
encodedJson();
break;
case XML:
encodedXml();
break;
case JSON:
encodedJson();
break;
}
return this;
}
}
@SuppressWarnings("rawtypes")
private static class SortInternal implements ISort {
private SortOrderEnum myDirection;
private SearchInternal myFor;
private String myParamName;
private String myParamValue;
public SortInternal(SearchInternal theFor) {
myFor = theFor;
}
@Override
public IQuery ascending(IParam theParam) {
myParamName = Constants.PARAM_SORT_ASC;
myDirection = SortOrderEnum.ASC;
myParamValue = theParam.getParamName();
return myFor;
}
@Override
public IQuery ascending(String theParam) {
myParamName = Constants.PARAM_SORT_ASC;
myDirection = SortOrderEnum.ASC;
myParamValue = theParam;
return myFor;
}
@Override
public IQuery defaultOrder(IParam theParam) {
myParamName = Constants.PARAM_SORT;
myDirection = null;
myParamValue = theParam.getParamName();
return myFor;
}
@Override
public IQuery descending(IParam theParam) {
myParamName = Constants.PARAM_SORT_DESC;
myDirection = SortOrderEnum.DESC;
myParamValue = theParam.getParamName();
return myFor;
}
@Override
public IQuery descending(String theParam) {
myParamName = Constants.PARAM_SORT_DESC;
myDirection = SortOrderEnum.DESC;
myParamValue = theParam;
return myFor;
}
public SortOrderEnum getDirection() {
return myDirection;
}
public String getParamName() {
return myParamName;
}
public String getParamValue() {
return myParamValue;
}
}
}

View File

@ -194,7 +194,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
}
}
return createOperationInvocation(getContext(), getResourceName(), id, myName, parameters, false);
return createOperationInvocation(getContext(), getResourceName(), id, null, myName, parameters, false);
}
public boolean isCanOperateAtInstanceLevel() {
@ -217,7 +217,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
myDescription = theDescription;
}
public static BaseHttpClientInvocation createOperationInvocation(FhirContext theContext, String theResourceName, String theId, String theOperationName, IBaseParameters theInput,
public static BaseHttpClientInvocation createOperationInvocation(FhirContext theContext, String theResourceName, String theId, String theVersion, String theOperationName, IBaseParameters theInput,
boolean theUseHttpGet) {
StringBuilder b = new StringBuilder();
if (theResourceName != null) {
@ -225,6 +225,10 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
if (isNotBlank(theId)) {
b.append('/');
b.append(theId);
if (isNotBlank(theVersion)) {
b.append("/_history/");
b.append(theVersion);
}
}
}
if (b.length() > 0) {

View File

@ -75,7 +75,7 @@ public class ValidateMethodBindingDstu2Plus extends OperationMethodBinding {
String resourceName = theContext.getResourceDefinition(theResource).getName();
String resourceId = theResource.getIdElement().getIdPart();
BaseHttpClientInvocation retVal = createOperationInvocation(theContext, resourceName, resourceId, Constants.EXTOP_VALIDATE, parameters, false);
BaseHttpClientInvocation retVal = createOperationInvocation(theContext, resourceName, resourceId, null,Constants.EXTOP_VALIDATE, parameters, false);
return retVal;
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -29,6 +29,8 @@ import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.util.DeleteConflict;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
@ -71,7 +73,14 @@ import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
@ -85,6 +94,7 @@ import java.io.UnsupportedEncodingException;
import java.text.Normalizer;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.commons.lang3.StringUtils.*;
@ -161,6 +171,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
protected ISearchParamRegistry mySerarchParamRegistry;
@Autowired()
protected IHapiTerminologySvc myTerminologySvc;
@Autowired
protected IResourceHistoryTableDao myResourceHistoryTableDao;
@Autowired
protected IResourceHistoryTagDao myResourceHistoryTagDao;
@Autowired
protected IResourceTableDao myResourceTableDao;
@Autowired
protected IResourceTagDao myResourceTagDao;
@Autowired(required = true)
private DaoConfig myConfig;
private FhirContext myContext;
@ -168,8 +186,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
private PlatformTransactionManager myPlatformTransactionManager;
@Autowired
private List<IFhirResourceDao<?>> myResourceDaos;
@Autowired
private IResourceHistoryTableDao myResourceHistoryTableDao;
private Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> myResourceTypeToDao;
@Autowired
private ISearchDao mySearchDao;
@ -204,6 +220,200 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
}
}
protected ExpungeOutcome doExpunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
AtomicInteger remainingCount = new AtomicInteger(theExpungeOptions.getLimit());
if (theResourceName == null && theResourceId == null && theVersion == null) {
if (theExpungeOptions.isExpungeEverything()) {
doExpungeEverything();
}
}
if (theExpungeOptions.isExpungeDeletedResources() && theVersion == null) {
/*
* Delete historical versions of deleted resources
*/
Pageable page = new PageRequest(0, remainingCount.get());
Slice<Long> resourceIds;
if (theResourceId != null) {
resourceIds = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId, theResourceName);
} else {
if (theResourceName != null) {
resourceIds = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceName);
} else {
resourceIds = myResourceTableDao.findIdsOfDeletedResources(page);
}
}
for (Long next : resourceIds) {
expungeHistoricalVersionsOfId(next, remainingCount);
if (remainingCount.get() <= 0) {
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
}
/*
* Delete current versions of deleted resources
*/
for (Long next : resourceIds) {
expungeCurrentVersionOfResource(next);
if (remainingCount.get() <= 0) {
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
}
}
if (theExpungeOptions.isExpungeOldVersions()) {
/*
* Delete historical versions of non-deleted resources
*/
Pageable page = new PageRequest(0, remainingCount.get());
Slice<Long> historicalIds;
if (theResourceId != null && theVersion != null) {
historicalIds = toSlice(myResourceHistoryTableDao.findForIdAndVersion(theResourceId, theVersion));
} else {
if (theResourceName != null) {
historicalIds = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResources(page, theResourceName);
} else {
historicalIds = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResources(page);
}
}
for (Long next : historicalIds) {
expungeHistoricalVersion(next);
if (remainingCount.decrementAndGet() <= 0) {
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
}
}
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
private void doExpungeEverything() {
ourLog.info("** BEGINNING GLOBAL EXPUNGE **");
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
myEntityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
myEntityManager.createQuery("UPDATE " + TermCodeSystem.class.getSimpleName() + " d SET d.myCurrentVersion = null").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("DELETE from " + SearchParamPresent.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + SearchParam.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamQuantity.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamString.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamToken.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamUri.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedSearchParamCoords.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceIndexedCompositeStringUnique.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceLink.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + SearchResult.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + SearchInclude.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + TermConceptParentChildLink.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("DELETE from " + TermConceptProperty.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + TermConceptDesignation.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + TermConcept.class.getSimpleName() + " d").executeUpdate();
for (TermCodeSystem next : myEntityManager.createQuery("SELECT c FROM " + TermCodeSystem.class.getName() + " c", TermCodeSystem.class).getResultList()) {
next.setCurrentVersion(null);
myEntityManager.merge(next);
}
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("DELETE from " + TermCodeSystemVersion.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + TermCodeSystem.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
myEntityManager.createQuery("DELETE from " + SubscriptionTable.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceHistoryTable.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + ResourceTable.class.getSimpleName() + " d").executeUpdate();
myEntityManager.createQuery("DELETE from " + org.hibernate.search.jpa.Search.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
}
private void expungeCurrentVersionOfResource(Long theResourceId) {
ResourceTable resource = myResourceTableDao.findOne(theResourceId);
ResourceHistoryTable currentVersion = myResourceHistoryTableDao.findForIdAndVersion(resource.getId(), resource.getVersion());
expungeHistoricalVersion(currentVersion.getId());
ourLog.info("Deleting current version of resource {}", resource.getIdDt().getValue());
myResourceIndexedSearchParamUriDao.delete(resource.getParamsUri());
myResourceIndexedSearchParamCoordsDao.delete(resource.getParamsCoords());
myResourceIndexedSearchParamDateDao.delete(resource.getParamsDate());
myResourceIndexedSearchParamNumberDao.delete(resource.getParamsNumber());
myResourceIndexedSearchParamQuantityDao.delete(resource.getParamsQuantity());
myResourceIndexedSearchParamStringDao.delete(resource.getParamsString());
myResourceIndexedSearchParamTokenDao.delete(resource.getParamsToken());
myResourceTagDao.delete(resource.getTags());
resource.getTags().clear();
if (resource.getForcedId() != null) {
ForcedId forcedId = resource.getForcedId();
resource.setForcedId(null);
myResourceTableDao.saveAndFlush(resource);
myForcedIdDao.delete(forcedId);
}
myResourceTableDao.delete(resource);
}
protected void expungeHistoricalVersion(Long theNextVersionId) {
ResourceHistoryTable version = myResourceHistoryTableDao.findOne(theNextVersionId);
ourLog.info("Deleting resource version {}", version.getIdDt().getValue());
myResourceHistoryTagDao.delete(version.getTags());
myResourceHistoryTableDao.delete(version);
}
protected void expungeHistoricalVersionsOfId(Long theResourceId, AtomicInteger theRemainingCount) {
ResourceTable resource = myResourceTableDao.findOne(theResourceId);
Pageable page = new PageRequest(0, theRemainingCount.get());
Slice<Long> versionIds = myResourceHistoryTableDao.findForResourceId(page, resource.getId(), resource.getVersion());
for (Long nextVersionId : versionIds) {
expungeHistoricalVersion(nextVersionId);
if (theRemainingCount.decrementAndGet() <= 0) {
return;
}
}
}
private Set<ResourceIndexedCompositeStringUnique> extractCompositeStringUniques(ResourceTable theEntity, Set<ResourceIndexedSearchParamString> theStringParams, Set<ResourceIndexedSearchParamToken> theTokenParams, Set<ResourceIndexedSearchParamNumber> theNumberParams, Set<ResourceIndexedSearchParamQuantity> theQuantityParams, Set<ResourceIndexedSearchParamDate> theDateParams, Set<ResourceIndexedSearchParamUri> theUriParams, Set<ResourceLink> theLinks) {
Set<ResourceIndexedCompositeStringUnique> compositeStringUniques;
compositeStringUniques = new HashSet<>();
@ -1290,6 +1500,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return false;
}
private ExpungeOutcome toExpungeOutcome(ExpungeOptions theExpungeOptions, AtomicInteger theRemainingCount) {
return new ExpungeOutcome()
.setDeletedCount(theExpungeOptions.getLimit() - theRemainingCount.get());
}
@Override
public IBaseResource toResource(BaseHasResource theEntity, boolean theForHistoryOperation) {
RuntimeResourceDefinition type = myContext.getResourceDefinition(theEntity.getResourceType());
@ -1401,6 +1616,11 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return myContext.getResourceDefinition(theResource).getName();
}
private Slice<Long> toSlice(ResourceHistoryTable theVersion) {
Validate.notNull(theVersion);
return new SliceImpl<>(Collections.singletonList(theVersion.getId()));
}
Long translateForcedIdToPid(String theResourceName, String theResourceId) {
return translateForcedIdToPids(new IdDt(theResourceName, theResourceId), myForcedIdDao).get(0);
}

View File

@ -24,7 +24,8 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.jpa.dao.data.*;
import ca.uhn.fhir.jpa.dao.data.IResourceLinkDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
@ -50,10 +51,6 @@ import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.lang.NonNull;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
@ -68,7 +65,6 @@ import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -78,8 +74,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseHapiFhirResourceDao.class);
@Autowired
protected PlatformTransactionManager myPlatformTransactionManager;
@Autowired
protected IResourceTableDao myResourceTableDao;
@Autowired(required = false)
protected IFulltextSearchSvc mySearchDao;
@Autowired()
@ -87,12 +81,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
@Autowired
protected DaoConfig myDaoConfig;
@Autowired
private IResourceHistoryTableDao myResourceHistoryTableDao;
@Autowired
private IResourceHistoryTagDao myResourceHistoryTagDao;
@Autowired
private IResourceTagDao myResourceTagDao;
@Autowired
private IResourceLinkDao myResourceLinkDao;
private String myResourceName;
private Class<T> myResourceType;
@ -470,62 +458,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return outcome;
}
private ExpungeOutcome doExpunge(Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
AtomicInteger remainingCount = new AtomicInteger(theExpungeOptions.getLimit());
if (theExpungeOptions.isExpungeDeletedResources() && theVersion == null) {
/*
* Delete historical versions of deleted resources
*/
Pageable page = new PageRequest(0, remainingCount.get());
Slice<Long> resourceIds;
if (theResourceId != null) {
resourceIds = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, theResourceId, getResourceName());
} else {
resourceIds = myResourceTableDao.findIdsOfDeletedResourcesOfType(page, getResourceName());
}
for (Long next : resourceIds) {
expungeHistoricalVersionsOfId(next, remainingCount);
if (remainingCount.get() <= 0) {
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
}
/*
* Delete current versions of deleted resources
*/
for (Long next : resourceIds) {
expungeCurrentVersionOfResource(next);
if (remainingCount.get() <= 0) {
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
}
}
if (theExpungeOptions.isExpungeOldVersions()) {
/*
* Delete historical versions of non-deleted resources
*/
Pageable page = new PageRequest(0, remainingCount.get());
Slice<Long> historicalIds;
if (theResourceId != null && theVersion != null) {
historicalIds = toSlice(myResourceHistoryTableDao.findForIdAndVersion(theResourceId, theVersion));
} else {
historicalIds = myResourceHistoryTableDao.findIdsOfPreviousVersionsOfResources(page, getResourceName());
}
for (Long next : historicalIds) {
expungeHistoricalVersion(next);
if (remainingCount.decrementAndGet() <= 0) {
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
}
}
return toExpungeOutcome(theExpungeOptions, remainingCount);
}
private <MT extends IBaseMetaType> void doMetaAdd(MT theMetaAdd, BaseHasResource entity) {
List<TagDefinition> tags = toTagList(theMetaAdd);
@ -592,70 +524,19 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
throw new PreconditionFailedException("Can not perform version-specific expunge of resource " + theId.toUnqualified().getValue() + " as this is the current version");
}
return doExpunge(entity.getResourceId(), entity.getVersion(), theExpungeOptions);
return doExpunge(getResourceName(), entity.getResourceId(), entity.getVersion(), theExpungeOptions);
}
return doExpunge(entity.getResourceId(), null, theExpungeOptions);
return doExpunge(getResourceName(), entity.getResourceId(), null, theExpungeOptions);
}
@Override
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions) {
ourLog.info("Beginning TYPE[{}] expunge operation", getResourceName());
return doExpunge(null, null, theExpungeOptions);
return doExpunge(getResourceName(), null, null, theExpungeOptions);
}
private void expungeCurrentVersionOfResource(Long theResourceId) {
ResourceTable resource = myResourceTableDao.findOne(theResourceId);
ResourceHistoryTable currentVersion = myResourceHistoryTableDao.findForIdAndVersion(resource.getId(), resource.getVersion());
expungeHistoricalVersion(currentVersion.getId());
ourLog.info("Deleting current version of resource {}", resource.getIdDt().getValue());
myResourceIndexedSearchParamUriDao.delete(resource.getParamsUri());
myResourceIndexedSearchParamCoordsDao.delete(resource.getParamsCoords());
myResourceIndexedSearchParamDateDao.delete(resource.getParamsDate());
myResourceIndexedSearchParamNumberDao.delete(resource.getParamsNumber());
myResourceIndexedSearchParamQuantityDao.delete(resource.getParamsQuantity());
myResourceIndexedSearchParamStringDao.delete(resource.getParamsString());
myResourceIndexedSearchParamTokenDao.delete(resource.getParamsToken());
myResourceTagDao.delete(resource.getTags());
resource.getTags().clear();
if (resource.getForcedId() != null) {
ForcedId forcedId = resource.getForcedId();
resource.setForcedId(null);
myResourceTableDao.saveAndFlush(resource);
myForcedIdDao.delete(forcedId);
}
myResourceTableDao.delete(resource);
}
protected void expungeHistoricalVersion(Long theNextVersionId) {
ResourceHistoryTable version = myResourceHistoryTableDao.findOne(theNextVersionId);
ourLog.info("Deleting resource version {}", version.getIdDt().getValue());
myResourceHistoryTagDao.delete(version.getTags());
myResourceHistoryTableDao.delete(version);
}
protected void expungeHistoricalVersionsOfId(Long theResourceId, AtomicInteger theRemainingCount) {
ResourceTable resource = myResourceTableDao.findOne(theResourceId);
Pageable page = new PageRequest(0, theRemainingCount.get());
Slice<Long> versionIds = myResourceHistoryTableDao.findForResourceId(page, resource.getId(), resource.getVersion());
for (Long nextVersionId : versionIds) {
expungeHistoricalVersion(nextVersionId);
if (theRemainingCount.decrementAndGet() <= 0) {
return;
}
}
}
@Override
public TagList getAllResourceTags(RequestDetails theRequestDetails) {
@ -1183,11 +1064,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
mySecondaryPrimaryKeyParamName = theSecondaryPrimaryKeyParamName;
}
private ExpungeOutcome toExpungeOutcome(ExpungeOptions theExpungeOptions, AtomicInteger theRemainingCount) {
return new ExpungeOutcome()
.setDeletedCount(theExpungeOptions.getLimit() - theRemainingCount.get());
}
protected <MT extends IBaseMetaType> MT toMetaDt(Class<MT> theType, Collection<TagDefinition> tagDefinitions) {
MT retVal;
try {
@ -1239,11 +1115,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
return retVal;
}
private Slice<Long> toSlice(ResourceHistoryTable theVersion) {
Validate.notNull(theVersion);
return new SliceImpl<>(Collections.singletonList(theVersion.getId()));
}
private ArrayList<TagDefinition> toTagList(IBaseMetaType theMeta) {
ArrayList<TagDefinition> retVal = new ArrayList<TagDefinition>();

View File

@ -5,6 +5,8 @@ import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
import ca.uhn.fhir.jpa.entity.ForcedId;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.jpa.util.ReindexFailureException;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
@ -154,6 +156,12 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
});
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions) {
return doExpunge(null, null, null, theExpungeOptions);
}
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
@Override
public Map<String, Long> getResourceCounts() {

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,6 +20,8 @@ package ca.uhn.fhir.jpa.dao;
* #L%
*/
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
@ -28,13 +30,13 @@ import java.util.Date;
import java.util.Map;
/**
* @param <T>
* The bundle type
* @param <MT>
* The Meta datatype type
* @param <T> The bundle type
* @param <MT> The Meta datatype type
*/
public interface IFhirSystemDao<T, MT> extends IDao {
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions);
<R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType);
Map<String, Long> getResourceCounts();
@ -43,16 +45,15 @@ public interface IFhirSystemDao<T, MT> extends IDao {
/**
* Marks all indexes as needing fresh indexing
*
*
* @return Returns the number of affected rows
*/
int markAllResourcesForReindexing();
/**
* Not supported for DSTU1
*
* @param theRequestDetails
* TODO
*
* @param theRequestDetails TODO
*/
MT metaGetOperation(RequestDetails theRequestDetails);

View File

@ -76,4 +76,10 @@ public interface IResourceHistoryTableDao extends JpaRepository<ResourceHistoryT
"WHERE v.myResourceVersion != t.myVersion AND " +
"t.myResourceType = :restype")
Slice<Long> findIdsOfPreviousVersionsOfResources(Pageable thePage, @Param("restype") String theResourceName);
@Query("" +
"SELECT v.myId FROM ResourceHistoryTable v " +
"LEFT OUTER JOIN ResourceTable t ON (v.myResourceId = t.myId) " +
"WHERE v.myResourceVersion != t.myVersion")
Slice<Long> findIdsOfPreviousVersionsOfResources(Pageable thePage);
}

View File

@ -30,6 +30,9 @@ import org.springframework.data.repository.query.Param;
public interface IResourceTableDao extends JpaRepository<ResourceTable, Long> {
@Query("SELECT t.myId FROM ResourceTable t WHERE t.myDeleted IS NOT NULL")
Slice<Long> findIdsOfDeletedResources(Pageable thePageable);
@Query("SELECT t.myId FROM ResourceTable t WHERE t.myResourceType = :restype AND t.myDeleted IS NOT NULL")
Slice<Long> findIdsOfDeletedResourcesOfType(Pageable thePageable, @Param("restype") String theResourceName);

View File

@ -1,6 +1,23 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.provider.r4.JpaResourceProviderR4;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.IntegerType;
import org.hl7.fhir.r4.model.Parameters;
import org.jboss.logging.MDC;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Enumeration;
import java.util.Set;
import java.util.TreeSet;
/*
* #%L
@ -11,9 +28,9 @@ import java.util.Date;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -22,30 +39,43 @@ import java.util.Date;
* #L%
*/
import java.util.Enumeration;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.jboss.logging.MDC;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
public class BaseJpaProvider {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaProvider.class);
public static final String REMOTE_ADDR = "req.remoteAddr";
public static final String REMOTE_UA = "req.userAgent";
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaProvider.class);
private FhirContext myContext;
protected ExpungeOptions createExpungeOptions(IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything) {
ExpungeOptions options = new ExpungeOptions();
if (theLimit != null && theLimit.getValue() != null) {
options.setLimit(theLimit.getValue());
}
if (theExpungeOldVersions != null && theExpungeOldVersions.getValue() != null) {
options.setExpungeOldVersions(theExpungeOldVersions.getValue());
}
if (theExpungeDeletedResources != null && theExpungeDeletedResources.getValue() != null) {
options.setExpungeDeletedResources(theExpungeDeletedResources.getValue());
}
if (theExpungeEverything != null && theExpungeEverything.getValue() != null) {
options.setExpungeEverything(theExpungeEverything.getValue());
}
return options;
}
protected Parameters createExpungeResponse(ExpungeOutcome theOutcome) {
Parameters retVal = new Parameters();
retVal
.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_COUNT)
.setValue(new IntegerType(theOutcome.getDeletedCount()));
return retVal;
}
/**
* @param theRequest The servlet request
* @param theRequest The servlet request
*/
public void endRequest(HttpServletRequest theRequest) {
MDC.remove(REMOTE_ADDR);
@ -60,39 +90,38 @@ public class BaseJpaProvider {
return myContext;
}
public void setContext(FhirContext theContext) {
myContext = theContext;
}
protected DateRangeParam processSinceOrAt(Date theSince, DateRangeParam theAt) {
boolean haveAt = theAt != null && (theAt.getLowerBoundAsInstant() != null || theAt.getUpperBoundAsInstant() != null);
if (haveAt && theSince != null) {
String msg = getContext().getLocalizer().getMessage(BaseJpaProvider.class, "cantCombintAtAndSince");
throw new InvalidRequestException(msg);
}
if (haveAt) {
return theAt;
}
return new DateRangeParam(theSince, null);
}
public void setContext(FhirContext theContext) {
myContext = theContext;
}
public void startRequest(HttpServletRequest theRequest) {
if (theRequest == null) {
return;
}
Set<String> headerNames = new TreeSet<String>();
for (Enumeration<String> enums = theRequest.getHeaderNames(); enums.hasMoreElements();) {
for (Enumeration<String> enums = theRequest.getHeaderNames(); enums.hasMoreElements(); ) {
headerNames.add(enums.nextElement());
}
ourLog.debug("Request headers: {}", headerNames);
Enumeration<String> forwardedFors = theRequest.getHeaders("x-forwarded-for");
StringBuilder b = new StringBuilder();
for (Enumeration<String> enums = forwardedFors; enums != null && enums.hasMoreElements();) {
for (Enumeration<String> enums = forwardedFors; enums != null && enums.hasMoreElements(); ) {
if (b.length() > 0) {
b.append(" / ");
}
@ -118,4 +147,5 @@ public class BaseJpaProvider {
startRequest(theRequest.getServletRequest());
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,16 +20,10 @@ package ca.uhn.fhir.jpa.provider;
* #L%
*/
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Required;
import ca.uhn.fhir.jpa.dao.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.PatchTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@ -37,6 +31,14 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.util.CoverageIgnore;
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.hl7.fhir.r4.model.Parameters;
import org.springframework.beans.factory.annotation.Required;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends BaseJpaProvider implements IResourceProvider {
@ -51,17 +53,37 @@ public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends B
myDao = theDao;
}
protected Parameters doExpunge(IIdType theIdParam, IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything) {
ExpungeOptions options = createExpungeOptions(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
ExpungeOutcome outcome;
if (theIdParam != null) {
outcome = getDao().expunge(theIdParam, options);
} else {
outcome = getDao().expunge(options);
}
return createExpungeResponse(outcome);
}
public IFhirResourceDao<T> getDao() {
return myDao;
}
@Required
public void setDao(IFhirResourceDao<T> theDao) {
myDao = theDao;
}
@History
public IBundleProvider getHistoryForResourceInstance(
HttpServletRequest theRequest,
@IdParam IIdType theId,
@Since Date theSince,
@At DateRangeParam theAt,
RequestDetails theRequestDetails) {
HttpServletRequest theRequest,
@IdParam IIdType theId,
@Since Date theSince,
@At DateRangeParam theAt,
RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
@ -74,10 +96,10 @@ public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends B
@History
public IBundleProvider getHistoryForResourceType(
HttpServletRequest theRequest,
@Since Date theSince,
@At DateRangeParam theAt,
RequestDetails theRequestDetails) {
HttpServletRequest theRequest,
@Since Date theSince,
@At DateRangeParam theAt,
RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
DateRangeParam sinceOrAt = processSinceOrAt(theSince, theAt);
@ -92,16 +114,6 @@ public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends B
return myDao.getResourceType();
}
@Read(version = true)
public T read(HttpServletRequest theRequest, @IdParam IIdType theId, RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
return myDao.read(theId, theRequestDetails);
} finally {
endRequest(theRequest);
}
}
@Patch
public DaoMethodOutcome patch(HttpServletRequest theRequest, @IdParam IIdType theId, RequestDetails theRequestDetails, @ResourceParam String theBody, PatchTypeEnum thePatchType) {
startRequest(theRequest);
@ -112,9 +124,14 @@ public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends B
}
}
@Required
public void setDao(IFhirResourceDao<T> theDao) {
myDao = theDao;
@Read(version = true)
public T read(HttpServletRequest theRequest, @IdParam IIdType theId, RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
return myDao.read(theId, theRequestDetails);
} finally {
endRequest(theRequest);
}
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,17 +20,21 @@ package ca.uhn.fhir.jpa.provider;
* #L%
*/
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Required;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.annotation.At;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Parameters;
import org.springframework.beans.factory.annotation.Required;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
public class BaseJpaSystemProvider<T, MT> extends BaseJpaProvider {
@ -43,10 +47,21 @@ public class BaseJpaSystemProvider<T, MT> extends BaseJpaProvider {
// nothing
}
protected Parameters doExpunge(IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything) {
ExpungeOptions options = createExpungeOptions(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
ExpungeOutcome outcome = getDao().expunge(options);
return createExpungeResponse(outcome);
}
protected IFhirSystemDao<T, MT> getDao() {
return myDao;
}
@Required
public void setDao(IFhirSystemDao<T, MT> theDao) {
myDao = theDao;
}
@History
public IBundleProvider historyServer(HttpServletRequest theRequest, @Since Date theDate, @At DateRangeParam theAt, RequestDetails theRequestDetails) {
startRequest(theRequest);
@ -58,9 +73,4 @@ public class BaseJpaSystemProvider<T, MT> extends BaseJpaProvider {
}
}
@Required
public void setDao(IFhirSystemDao<T, MT> theDao) {
myDao = theDao;
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,32 +20,32 @@ package ca.uhn.fhir.jpa.provider;
* #L%
*/
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.util.ParametersUtil;
public abstract class BaseJpaSystemProviderDstu2Plus<T, MT> extends BaseJpaSystemProvider<T, MT> {
@Operation(name=MARK_ALL_RESOURCES_FOR_REINDEXING, idempotent=true, returnParameters= {
@OperationParam(name="status")
@Operation(name = MARK_ALL_RESOURCES_FOR_REINDEXING, idempotent = true, returnParameters = {
@OperationParam(name = "status")
})
public IBaseResource markAllResourcesForReindexing() {
Integer count = getDao().markAllResourcesForReindexing();
IBaseParameters retVal = ParametersUtil.newInstance(getContext());
IPrimitiveType<?> string = ParametersUtil.createString(getContext(), "Marked " + count + " resources");
ParametersUtil.addParameterToParameters(getContext(), retVal, "status", string);
return retVal;
}
@Operation(name=PERFORM_REINDEXING_PASS, idempotent=true, returnParameters= {
@OperationParam(name="status")
@Operation(name = PERFORM_REINDEXING_PASS, idempotent = true, returnParameters = {
@OperationParam(name = "status")
})
public IBaseResource performReindexingPass() {
Integer count = getDao().performReindexingPass(1000);

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,17 +20,21 @@ package ca.uhn.fhir.jpa.provider;
* #L%
*/
import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.r4.JpaResourceProviderR4;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.servlet.http.HttpServletRequest;
public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResourceProvider<T> {
@ -61,7 +65,7 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
}
@Delete()
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdDt theResource, @ConditionalUrlParam(supportsMultiple=true) String theConditional, RequestDetails theRequestDetails) {
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdDt theResource, @ConditionalUrlParam(supportsMultiple = true) String theConditional, RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
if (theConditional != null) {
@ -74,9 +78,34 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
}
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = org.hl7.fhir.r4.model.IntegerType.class)
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = org.hl7.fhir.r4.model.IntegerType.class)
})
public Parameters expunge(
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
}
//@formatter:off
@Operation(name=OPERATION_NAME_META, idempotent=true, returnParameters= {
@OperationParam(name="return", type=MetaDt.class)
@Operation(name = OPERATION_NAME_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class)
})
//@formatter:on
public Parameters meta(RequestDetails theRequestDetails) {
@ -87,8 +116,8 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
}
//@formatter:off
@Operation(name=OPERATION_NAME_META, idempotent=true, returnParameters= {
@OperationParam(name="return", type=MetaDt.class)
@Operation(name = OPERATION_NAME_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class)
})
//@formatter:on
public Parameters meta(@IdParam IdDt theId, RequestDetails theRequestDetails) {
@ -98,8 +127,8 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
return parameters;
}
@Operation(name=OPERATION_NAME_META_ADD, idempotent=true, returnParameters= {
@OperationParam(name="return", type=MetaDt.class)
@Operation(name = OPERATION_NAME_META_ADD, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class)
})
public Parameters metaAdd(@IdParam IdDt theId, @OperationParam(name = "meta") MetaDt theMeta, RequestDetails theRequestDetails) {
if (theMeta == null) {
@ -111,8 +140,8 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
return parameters;
}
@Operation(name=OPERATION_NAME_META_DELETE, idempotent=true, returnParameters= {
@OperationParam(name="return", type=MetaDt.class)
@Operation(name = OPERATION_NAME_META_DELETE, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class)
})
public Parameters metaDelete(@IdParam IdDt theId, @OperationParam(name = "meta") MetaDt theMeta, RequestDetails theRequestDetails) {
if (theMeta == null) {
@ -140,13 +169,13 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
return validate(theResource, null, theRawResource, theEncoding, theMode, theProfile, theRequestDetails);
}
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @IdParam IdDt theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
return getDao().validate(theResource, theId, theRawResource, theEncoding, theMode, theProfile, theRequestDetails);
}

View File

@ -1,5 +1,33 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaResourceProviderR4;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.Parameters.Parameter;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.IntegerType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import static org.apache.commons.lang3.StringUtils.isBlank;
/*
@ -11,9 +39,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -21,26 +49,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* limitations under the License.
* #L%
*/
import java.util.*;
import java.util.Map.Entry;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.Parameters.Parameter;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundle, MetaDt> {
@ -50,121 +58,147 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
@Autowired(required = false)
private IFulltextSearchSvc mySearchDao;
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = IntegerDt.class)
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerDt theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanDt theExpungeOldVersions,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_EVERYTHING) BooleanDt theExpungeEverything
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
return toExpungeResponse(retVal);
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = IntegerDt.class)
})
public Parameters expunge(
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerDt theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanDt theExpungeOldVersions,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_EVERYTHING) BooleanDt theExpungeEverything
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
return toExpungeResponse(retVal);
}
//@formatter:off
// This is generated by hand:
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerDt.class, min=0, max=1),/"
@Operation(name="$get-resource-counts", idempotent=true, returnParameters= {
@OperationParam(name="AllergyIntolerance", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Appointment", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="AppointmentResponse", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="AuditEvent", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Basic", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Binary", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="BodySite", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Bundle", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="CarePlan", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="CarePlan2", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Claim", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ClaimResponse", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ClinicalImpression", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Communication", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="CommunicationRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Composition", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ConceptMap", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Condition", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Conformance", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Contract", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Contraindication", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Coverage", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DataElement", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Device", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DeviceComponent", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DeviceMetric", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DeviceUseRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DeviceUseStatement", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DiagnosticOrder", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DiagnosticReport", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DocumentManifest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="DocumentReference", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="EligibilityRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="EligibilityResponse", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Encounter", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="EnrollmentRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="EnrollmentResponse", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="EpisodeOfCare", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ExplanationOfBenefit", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="FamilyMemberHistory", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Flag", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Goal", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Group", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="HealthcareService", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ImagingObjectSelection", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ImagingStudy", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Immunization", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ImmunizationRecommendation", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ListResource", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Location", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Media", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Medication", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="MedicationAdministration", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="MedicationDispense", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="MedicationPrescription", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="MedicationStatement", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="MessageHeader", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="NamingSystem", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="NutritionOrder", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Observation", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="OperationDefinition", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="OperationOutcome", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Order", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="OrderResponse", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Organization", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Parameters", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Patient", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="PaymentNotice", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="PaymentReconciliation", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Person", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Practitioner", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Procedure", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ProcedureRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ProcessRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ProcessResponse", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Provenance", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Questionnaire", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="QuestionnaireAnswers", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ReferralRequest", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="RelatedPerson", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="RiskAssessment", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Schedule", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="SearchParameter", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Slot", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Specimen", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="StructureDefinition", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Subscription", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Substance", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="Supply", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="ValueSet", type=IntegerDt.class, min=0, max=1),
@OperationParam(name="VisionPrescription", type=IntegerDt.class, min=0, max=1)
@Operation(name = "$get-resource-counts", idempotent = true, returnParameters = {
@OperationParam(name = "AllergyIntolerance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Appointment", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "AppointmentResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "AuditEvent", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Basic", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Binary", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "BodySite", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Bundle", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "CarePlan", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "CarePlan2", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Claim", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ClaimResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ClinicalImpression", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Communication", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "CommunicationRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Composition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ConceptMap", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Condition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Conformance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Contract", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Contraindication", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Coverage", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DataElement", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Device", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceComponent", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceMetric", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseStatement", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticOrder", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticReport", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DocumentManifest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DocumentReference", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EligibilityRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EligibilityResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Encounter", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EpisodeOfCare", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ExplanationOfBenefit", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "FamilyMemberHistory", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Flag", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Goal", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Group", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "HealthcareService", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ImagingObjectSelection", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ImagingStudy", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Immunization", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ImmunizationRecommendation", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ListResource", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Location", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Media", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Medication", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationAdministration", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationDispense", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationPrescription", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationStatement", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MessageHeader", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "NamingSystem", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "NutritionOrder", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Observation", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "OperationDefinition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "OperationOutcome", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Order", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "OrderResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Organization", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Parameters", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Patient", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "PaymentNotice", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "PaymentReconciliation", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Person", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Practitioner", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Procedure", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ProcedureRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ProcessRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ProcessResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Provenance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Questionnaire", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "QuestionnaireAnswers", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ReferralRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "RelatedPerson", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "RiskAssessment", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Schedule", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "SearchParameter", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Slot", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Specimen", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "StructureDefinition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Subscription", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Substance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Supply", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ValueSet", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "VisionPrescription", type = IntegerDt.class, min = 0, max = 1)
})
@Description(shortDefinition="Provides the number of resources currently stored on the server, broken down by resource type")
@Description(shortDefinition = "Provides the number of resources currently stored on the server, broken down by resource type")
//@formatter:on
public Parameters getResourceCounts() {
Parameters retVal = new Parameters();
Map<String, Long> counts = mySystemDao.getResourceCounts();
counts = new TreeMap<String, Long>(counts);
for (Entry<String, Long> nextEntry : counts.entrySet()) {
retVal.addParameter().setName(new StringDt(nextEntry.getKey())).setValue(new IntegerDt(nextEntry.getValue().intValue()));
}
return retVal;
}
//@formatter:off
@Operation(name="$meta", idempotent=true, returnParameters= {
@OperationParam(name="return", type=MetaDt.class)
@Operation(name = "$meta", idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class)
})
//@formatter:on
public Parameters meta(RequestDetails theRequestDetails) {
@ -172,13 +206,13 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
parameters.addParameter().setName("return").setValue(getDao().metaGetOperation(theRequestDetails));
return parameters;
}
@Operation(name="$suggest-keywords", idempotent=true)
@Operation(name = "$suggest-keywords", idempotent = true)
public Parameters suggestKeywords(
@OperationParam(name="context", min=1, max=1) String theContext,
@OperationParam(name="searchParam", min=1, max=1) String theSearchParam,
@OperationParam(name="text", min=1, max=1) String theText
) {
@OperationParam(name = "context", min = 1, max = 1) String theContext,
@OperationParam(name = "searchParam", min = 1, max = 1) String theSearchParam,
@OperationParam(name = "text", min = 1, max = 1) String theText
) {
JpaSystemProviderDstu3.validateFulltextSearchEnabled(mySearchDao);
if (isBlank(theContext)) {
@ -192,17 +226,17 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {
retVal.addParameter()
.addPart(new Parameter().setName("keyword").setValue(new StringDt(next.getTerm())))
.addPart(new Parameter().setName("score").setValue(new DecimalDt(next.getScore())));
.addPart(new Parameter().setName("keyword").setValue(new StringDt(next.getTerm())))
.addPart(new Parameter().setName("score").setValue(new DecimalDt(next.getScore())));
}
return retVal;
}
@Transaction
public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
@ -213,4 +247,10 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
}
}
public static Parameters toExpungeResponse(org.hl7.fhir.r4.model.Parameters theRetVal) {
Integer count = ((IntegerType) theRetVal.getParameterFirstRep().getValue()).getValue();
return new Parameters()
.addParameter(new Parameter().setName("count").setValue(new IntegerDt(count)));
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,17 +20,25 @@ package ca.uhn.fhir.jpa.provider.dstu3;
* #L%
*/
import javax.servlet.http.HttpServletRequest;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.instance.model.api.IAnyResource;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import ca.uhn.fhir.jpa.provider.r4.JpaResourceProviderR4;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import javax.servlet.http.HttpServletRequest;
public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> {
@ -61,7 +69,7 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
}
@Delete()
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdType theResource, @ConditionalUrlParam(supportsMultiple=true) String theConditional, RequestDetails theRequestDetails) {
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdType theResource, @ConditionalUrlParam(supportsMultiple = true) String theConditional, RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
if (theConditional != null) {
@ -74,9 +82,42 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
}
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = org.hl7.fhir.r4.model.IntegerType.class)
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = org.hl7.fhir.r4.model.IntegerType.class)
})
public Parameters expunge(
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
}
//@formatter:off
@Operation(name=OPERATION_NAME_META, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters meta(RequestDetails theRequestDetails) {
@ -87,8 +128,8 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
}
//@formatter:off
@Operation(name=OPERATION_NAME_META, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters meta(@IdParam IdType theId, RequestDetails theRequestDetails) {
@ -99,8 +140,8 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
}
//@formatter:off
@Operation(name=OPERATION_NAME_META_ADD, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META_ADD, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters metaAdd(@IdParam IdType theId, @OperationParam(name = "meta") Meta theMeta, RequestDetails theRequestDetails) {
@ -114,8 +155,8 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
}
//@formatter:off
@Operation(name=OPERATION_NAME_META_DELETE, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META_DELETE, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters metaDelete(@IdParam IdType theId, @OperationParam(name = "meta") Meta theMeta, RequestDetails theRequestDetails) {
@ -143,13 +184,13 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
return validate(theResource, null, theRawResource, theEncoding, theMode, theProfile, theRequestDetails);
}
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @IdParam IdType theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
return getDao().validate(theResource, theId, theRawResource, theEncoding, theMode, theProfile, theRequestDetails);
}

View File

@ -4,16 +4,18 @@ import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.jpa.provider.r4.JpaResourceProviderR4;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@ -33,9 +35,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -53,6 +55,41 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
@Autowired(required = false)
private IFulltextSearchSvc mySearchDao;
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = IntegerType.class)
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = IntegerType.class)
})
public Parameters expunge(
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {
throw new InternalErrorException(e);
}
}
//@formatter:off
// This is generated by hand:
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerType.class, min=0, max=1),/"

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.provider.r4;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,23 +20,31 @@ package ca.uhn.fhir.jpa.provider.r4;
* #L%
*/
import javax.servlet.http.HttpServletRequest;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.instance.model.api.IAnyResource;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.ValidationModeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import javax.servlet.http.HttpServletRequest;
public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResourceProvider<T> {
public static final String OPERATION_NAME_META = "$meta";
public static final String OPERATION_NAME_META_DELETE = "$meta-delete";
public static final String OPERATION_NAME_META_ADD = "$meta-add";
public static final String EXPUNGE = "$expunge";
public static final String EXPUNGE_LIMIT = "limit";
public static final String EXPUNGE_DELETED_RESOURCES = "expungeDeletedResources";
public static final String EXPUNGE_OLD_VERSIONS = "expungeOldVersions";
public static final String EXPUNGE_COUNT = "count";
public static final String EXPUNGE_EVERYTHING = "expungeEverything";
public JpaResourceProviderR4() {
// nothing
@ -61,7 +69,7 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
}
@Delete()
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdType theResource, @ConditionalUrlParam(supportsMultiple=true) String theConditional, RequestDetails theRequestDetails) {
public MethodOutcome delete(HttpServletRequest theRequest, @IdParam IdType theResource, @ConditionalUrlParam(supportsMultiple = true) String theConditional, RequestDetails theRequestDetails) {
startRequest(theRequest);
try {
if (theConditional != null) {
@ -74,11 +82,32 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
}
}
//@formatter:off
@Operation(name=OPERATION_NAME_META, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = EXPUNGE_COUNT, type = IntegerType.class)
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions
) {
return super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
}
@Operation(name = EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = EXPUNGE_COUNT, type = IntegerType.class)
})
public Parameters expunge(
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions
) {
return super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
}
@Operation(name = OPERATION_NAME_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters meta(RequestDetails theRequestDetails) {
Parameters parameters = new Parameters();
Meta metaGetOperation = getDao().metaGetOperation(Meta.class, theRequestDetails);
@ -87,8 +116,8 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
}
//@formatter:off
@Operation(name=OPERATION_NAME_META, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters meta(@IdParam IdType theId, RequestDetails theRequestDetails) {
@ -99,8 +128,8 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
}
//@formatter:off
@Operation(name=OPERATION_NAME_META_ADD, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META_ADD, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters metaAdd(@IdParam IdType theId, @OperationParam(name = "meta") Meta theMeta, RequestDetails theRequestDetails) {
@ -114,8 +143,8 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
}
//@formatter:off
@Operation(name=OPERATION_NAME_META_DELETE, idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = OPERATION_NAME_META_DELETE, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters metaDelete(@IdParam IdType theId, @OperationParam(name = "meta") Meta theMeta, RequestDetails theRequestDetails) {
@ -143,13 +172,13 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
return validate(theResource, null, theRawResource, theEncoding, theMode, theProfile, theRequestDetails);
}
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @IdParam IdType theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
@Validate.Profile String theProfile, RequestDetails theRequestDetails) {
return getDao().validate(theResource, theId, theRawResource, theEncoding, theMode, theProfile, theRequestDetails);
}

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import static org.apache.commons.lang3.StringUtils.isBlank;
/*
@ -11,9 +31,9 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -21,23 +41,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
* limitations under the License.
* #L%
*/
import java.util.*;
import java.util.Map.Entry;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl.Suggestion;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle, Meta> {
@ -47,136 +50,158 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
@Autowired(required = false)
private IFulltextSearchSvc mySearchDao;
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = IntegerType.class)
})
public Parameters expunge(
@IdParam IIdType theIdParam,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
) {
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
}
@Operation(name = JpaResourceProviderR4.EXPUNGE, idempotent = false, returnParameters = {
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_COUNT, type = IntegerType.class)
})
public Parameters expunge(
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaResourceProviderR4.EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
) {
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
}
//@formatter:off
// This is generated by hand:
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerType.class, min=0, max=1),/"
@Operation(name="$get-resource-counts", idempotent=true, returnParameters= {
@OperationParam(name="AllergyIntolerance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Appointment", type=IntegerType.class, min=0, max=1),
@OperationParam(name="AppointmentResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="AuditEvent", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Basic", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Binary", type=IntegerType.class, min=0, max=1),
@OperationParam(name="BodySite", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Bundle", type=IntegerType.class, min=0, max=1),
@OperationParam(name="CarePlan", type=IntegerType.class, min=0, max=1),
@OperationParam(name="CarePlan2", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Claim", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ClaimResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ClinicalImpression", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Communication", type=IntegerType.class, min=0, max=1),
@OperationParam(name="CommunicationRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Composition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ConceptMap", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Condition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Conformance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Contract", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Contraindication", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Coverage", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DataElement", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Device", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceComponent", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceMetric", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceUseRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DeviceUseStatement", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DiagnosticOrder", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DiagnosticReport", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DocumentManifest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="DocumentReference", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EligibilityRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EligibilityResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Encounter", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EnrollmentRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EnrollmentResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="EpisodeOfCare", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ExplanationOfBenefit", type=IntegerType.class, min=0, max=1),
@OperationParam(name="FamilyMemberHistory", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Flag", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Goal", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Group", type=IntegerType.class, min=0, max=1),
@OperationParam(name="HealthcareService", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ImagingObjectSelection", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ImagingStudy", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Immunization", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ImmunizationRecommendation", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ListResource", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Location", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Media", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Medication", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationAdministration", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationDispense", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationPrescription", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MedicationStatement", type=IntegerType.class, min=0, max=1),
@OperationParam(name="MessageHeader", type=IntegerType.class, min=0, max=1),
@OperationParam(name="NamingSystem", type=IntegerType.class, min=0, max=1),
@OperationParam(name="NutritionOrder", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Observation", type=IntegerType.class, min=0, max=1),
@OperationParam(name="OperationDefinition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="OperationOutcome", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Order", type=IntegerType.class, min=0, max=1),
@OperationParam(name="OrderResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Organization", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Parameters", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Patient", type=IntegerType.class, min=0, max=1),
@OperationParam(name="PaymentNotice", type=IntegerType.class, min=0, max=1),
@OperationParam(name="PaymentReconciliation", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Person", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Practitioner", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Procedure", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ProcedureRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ProcessRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ProcessResponse", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Provenance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Questionnaire", type=IntegerType.class, min=0, max=1),
@OperationParam(name="QuestionnaireAnswers", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ReferralRequest", type=IntegerType.class, min=0, max=1),
@OperationParam(name="RelatedPerson", type=IntegerType.class, min=0, max=1),
@OperationParam(name="RiskAssessment", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Schedule", type=IntegerType.class, min=0, max=1),
@OperationParam(name="SearchParameter", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Slot", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Specimen", type=IntegerType.class, min=0, max=1),
@OperationParam(name="StructureDefinition", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Subscription", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Substance", type=IntegerType.class, min=0, max=1),
@OperationParam(name="Supply", type=IntegerType.class, min=0, max=1),
@OperationParam(name="ValueSet", type=IntegerType.class, min=0, max=1),
@OperationParam(name="VisionPrescription", type=IntegerType.class, min=0, max=1)
@Operation(name = "$get-resource-counts", idempotent = true, returnParameters = {
@OperationParam(name = "AllergyIntolerance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Appointment", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "AppointmentResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "AuditEvent", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Basic", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Binary", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "BodySite", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Bundle", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CarePlan", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CarePlan2", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Claim", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ClaimResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ClinicalImpression", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Communication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CommunicationRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Composition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ConceptMap", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Condition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Conformance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Contract", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Contraindication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Coverage", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DataElement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Device", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceComponent", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceMetric", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseStatement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticOrder", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticReport", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DocumentManifest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DocumentReference", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EligibilityRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EligibilityResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Encounter", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EpisodeOfCare", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ExplanationOfBenefit", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "FamilyMemberHistory", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Flag", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Goal", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Group", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "HealthcareService", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImagingObjectSelection", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImagingStudy", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Immunization", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImmunizationRecommendation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ListResource", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Location", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Media", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Medication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationAdministration", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationDispense", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationPrescription", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationStatement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MessageHeader", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "NamingSystem", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "NutritionOrder", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Observation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OperationDefinition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OperationOutcome", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Order", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OrderResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Organization", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Parameters", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Patient", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "PaymentNotice", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "PaymentReconciliation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Person", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Practitioner", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Procedure", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcedureRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcessRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcessResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Provenance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Questionnaire", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "QuestionnaireAnswers", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ReferralRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "RelatedPerson", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "RiskAssessment", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Schedule", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "SearchParameter", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Slot", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Specimen", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "StructureDefinition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Subscription", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Substance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Supply", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ValueSet", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "VisionPrescription", type = IntegerType.class, min = 0, max = 1)
})
@Description(shortDefinition="Provides the number of resources currently stored on the server, broken down by resource type")
//@formatter:on
@Description(shortDefinition = "Provides the number of resources currently stored on the server, broken down by resource type")
public Parameters getResourceCounts() {
Parameters retVal = new Parameters();
Map<String, Long> counts = mySystemDao.getResourceCounts();
counts = new TreeMap<String, Long>(counts);
for (Entry<String, Long> nextEntry : counts.entrySet()) {
retVal.addParameter().setName((nextEntry.getKey())).setValue(new IntegerType(nextEntry.getValue().intValue()));
}
return retVal;
}
//@formatter:off
@Operation(name="$meta", idempotent=true, returnParameters= {
@OperationParam(name="return", type=Meta.class)
@Operation(name = "$meta", idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
//@formatter:on
public Parameters meta(RequestDetails theRequestDetails) {
Parameters parameters = new Parameters();
parameters.addParameter().setName("return").setValue(getDao().metaGetOperation(theRequestDetails));
return parameters;
}
@Operation(name="$suggest-keywords", idempotent=true)
@Operation(name = "$suggest-keywords", idempotent = true)
public Parameters suggestKeywords(
@OperationParam(name="context", min=1, max=1) String theContext,
@OperationParam(name="searchParam", min=1, max=1) String theSearchParam,
@OperationParam(name="text", min=1, max=1) String theText
) {
@OperationParam(name = "context", min = 1, max = 1) String theContext,
@OperationParam(name = "searchParam", min = 1, max = 1) String theSearchParam,
@OperationParam(name = "text", min = 1, max = 1) String theText
) {
ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3.validateFulltextSearchEnabled(mySearchDao);
if (isBlank(theContext)) {
throw new InvalidRequestException("Parameter 'context' must be provided");
}
@ -186,21 +211,21 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
if (isBlank(theText)) {
throw new InvalidRequestException("Parameter 'text' must be provided");
}
List<Suggestion> keywords = mySearchDao.suggestKeywords(theContext, theSearchParam, theText);
Parameters retVal = new Parameters();
for (Suggestion next : keywords) {
//@formatter:off
retVal.addParameter()
.addPart(new ParametersParameterComponent().setName("keyword").setValue(new StringType(next.getTerm())))
.addPart(new ParametersParameterComponent().setName("score").setValue(new DecimalType(next.getScore())));
.addPart(new ParametersParameterComponent().setName("keyword").setValue(new StringType(next.getTerm())))
.addPart(new ParametersParameterComponent().setName("score").setValue(new DecimalType(next.getScore())));
//@formatter:on
}
return retVal;
}
@Transaction
public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());

View File

@ -4,6 +4,7 @@ public class ExpungeOptions {
private int myLimit = 1000;
private boolean myExpungeOldVersions;
private boolean myExpungeDeletedResources;
private boolean myExpungeEverything;
/**
* The maximum number of resources versions to expunge
@ -12,6 +13,15 @@ public class ExpungeOptions {
return myLimit;
}
public boolean isExpungeEverything() {
return myExpungeEverything;
}
public ExpungeOptions setExpungeEverything(boolean theExpungeEverything) {
myExpungeEverything = theExpungeEverything;
return this;
}
/**
* The maximum number of resource versions to expunge
*/

View File

@ -6,6 +6,7 @@ import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
@ -241,76 +242,11 @@ public abstract class BaseJpaTest {
return bundleStr;
}
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager, ISearchParamPresenceSvc theSearchParamPresenceSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc, ISearchParamRegistry theSearchParamRegistry) {
public static void purgeDatabase(IFhirSystemDao<?,?> theSystemDao, ISearchParamPresenceSvc theSearchParamPresenceSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc, ISearchParamRegistry theSearchParamRegistry) {
theSearchCoordinatorSvc.cancelAllActiveSearches();
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
entityManager.createQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null").executeUpdate();
entityManager.createQuery("UPDATE " + TermCodeSystem.class.getSimpleName() + " d SET d.myCurrentVersion = null").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + SearchParamPresent.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SearchParam.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ForcedId.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamDate.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamNumber.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamQuantity.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamString.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamToken.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamUri.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedSearchParamCoords.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceIndexedCompositeStringUnique.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceLink.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SearchResult.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + SearchInclude.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermConceptParentChildLink.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + TermConceptProperty.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermConceptDesignation.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermConcept.class.getSimpleName() + " d").executeUpdate();
for (TermCodeSystem next : entityManager.createQuery("SELECT c FROM " + TermCodeSystem.class.getName() + " c", TermCodeSystem.class).getResultList()) {
next.setCurrentVersion(null);
entityManager.merge(next);
}
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + TermCodeSystemVersion.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TermCodeSystem.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
txTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus theStatus) {
entityManager.createQuery("DELETE from " + SubscriptionTable.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceHistoryTag.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceTag.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + TagDefinition.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceHistoryTable.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + ResourceTable.class.getSimpleName() + " d").executeUpdate();
entityManager.createQuery("DELETE from " + Search.class.getSimpleName() + " d").executeUpdate();
return null;
}
});
theSystemDao.expunge(new ExpungeOptions().setExpungeEverything(true));
theSearchParamPresenceSvc.flushCachesForUnitTest();
theSearchParamRegistry.forceRefresh();

View File

@ -189,8 +189,7 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
@Before
@Transactional()
public void beforePurgeDatabase() {
final EntityManager entityManager = this.myEntityManager;
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegistry);
purgeDatabase(mySystemDao, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegistry);
}
@Before

View File

@ -262,9 +262,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@Before
@Transactional()
public void beforePurgeDatabase() {
final EntityManager entityManager = this.myEntityManager;
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegsitry);
purgeDatabase(mySystemDao, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegsitry);
}
@Before

View File

@ -152,8 +152,7 @@ public class FhirResourceDaoDstu3SearchWithLuceneDisabledTest extends BaseJpaTes
@Before
@Transactional()
public void beforePurgeDatabase() {
final EntityManager entityManager = this.myEntityManager;
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegistry);
purgeDatabase(mySystemDao, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegistry);
}
@Before

View File

@ -273,7 +273,7 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
@Transactional()
public void beforePurgeDatabase() {
final EntityManager entityManager = this.myEntityManager;
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegsitry);
purgeDatabase(mySystemDao, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegsitry);
}
@Before

View File

@ -1,14 +1,19 @@
package ca.uhn.fhir.jpa.dao.r4;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import javax.persistence.EntityManager;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestR4WithoutLuceneConfig;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.model.*;
import org.junit.*;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@ -17,21 +22,24 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.TestR4WithoutLuceneConfig;
import ca.uhn.fhir.jpa.dao.*;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.TestUtil;
import javax.persistence.EntityManager;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestR4WithoutLuceneConfig.class })
@ContextConfiguration(classes = {TestR4WithoutLuceneConfig.class})
public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4SearchWithLuceneDisabledTest.class);
@Autowired
protected DaoConfig myDaoConfig;
@Autowired
protected PlatformTransactionManager myTxManager;
@Autowired
protected ISearchParamPresenceSvc mySearchParamPresenceSvc;
@Autowired
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
@Autowired
protected ISearchParamRegistry mySearchParamRegistry;
@Autowired
@Qualifier("myAllergyIntoleranceDaoR4")
private IFhirResourceDao<AllergyIntolerance> myAllergyIntoleranceDao;
@ -60,8 +68,6 @@ public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
@Qualifier("myConditionDaoR4")
private IFhirResourceDao<Condition> myConditionDao;
@Autowired
protected DaoConfig myDaoConfig;
@Autowired
@Qualifier("myDeviceDaoR4")
private IFhirResourceDao<Device> myDeviceDao;
@Autowired
@ -78,25 +84,16 @@ public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
@Autowired
@Qualifier("myOrganizationDaoR4")
private IFhirResourceDao<Organization> myOrganizationDao;
@Autowired
protected PlatformTransactionManager myTxManager;
@Autowired
protected ISearchParamPresenceSvc mySearchParamPresenceSvc;
@Autowired
@Qualifier("myJpaValidationSupportChainR4")
private IValidationSupport myValidationSupport;
@Autowired
protected ISearchCoordinatorSvc mySearchCoordinatorSvc;
@Autowired
protected ISearchParamRegistry mySearchParamRegistry;
private IFhirSystemDao<Bundle, Meta> mySystemDao;
@Before
@Transactional()
public void beforePurgeDatabase() {
final EntityManager entityManager = this.myEntityManager;
purgeDatabase(entityManager, myTxManager, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegistry);
purgeDatabase(mySystemDao, mySearchParamPresenceSvc, mySearchCoordinatorSvc, mySearchParamRegistry);
}
@Before
@ -111,20 +108,6 @@ public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
return myFhirCtx;
}
@Test
public void testSearchWithRegularParam() {
String methodName = "testEverythingIncludesBackReferences";
Organization org = new Organization();
org.setName(methodName);
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap();
map.add(Organization.SP_NAME, new StringParam(methodName));
myOrganizationDao.search(map);
}
@Test
public void testSearchWithContent() {
String methodName = "testEverythingIncludesBackReferences";
@ -143,6 +126,20 @@ public class FhirResourceDaoR4SearchWithLuceneDisabledTest extends BaseJpaTest {
}
}
@Test
public void testSearchWithRegularParam() {
String methodName = "testEverythingIncludesBackReferences";
Organization org = new Organization();
org.setName(methodName);
IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap map = new SearchParameterMap();
map.add(Organization.SP_NAME, new StringParam(methodName));
myOrganizationDao.search(map);
}
@Test
public void testSearchWithText() {
String methodName = "testEverythingIncludesBackReferences";

View File

@ -0,0 +1,284 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.model.dstu2.resource.Observation;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum;
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.util.TestUtil;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class ExpungeProviderDstu2Test extends BaseResourceProviderDstu2Test {
private IIdType myOneVersionPatientId;
private IIdType myTwoVersionPatientId;
private IIdType myDeletedPatientId;
private IIdType myOneVersionObservationId;
private IIdType myTwoVersionObservationId;
private IIdType myDeletedObservationId;
private void assertExpunged(IIdType theId) {
try {
getDao(theId).read(theId);
fail();
} catch (ResourceNotFoundException e) {
// good
}
}
private void assertGone(IIdType theId) {
try {
getDao(theId).read(theId);
fail();
} catch (ResourceGoneException e) {
// good
}
}
private void assertStillThere(IIdType theId) {
getDao(theId).read(theId);
}
@Override
@Before
public void before() throws Exception {
super.before();
Patient p = new Patient();
p.setId("PT-ONEVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addIdentifier().setSystem("foo").setValue("bar");
p.addName().addFamily("FAM");
myOneVersionPatientId = myPatientDao.update(p).getId();
p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
myTwoVersionPatientId = myPatientDao.update(p).getId();
p.setActive(false);
myTwoVersionPatientId = myPatientDao.update(p).getId();
p = new Patient();
p.setId("PT-DELETED");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
myDeletedPatientId = myPatientDao.update(p).getId();
myDeletedPatientId = myPatientDao.delete(myDeletedPatientId).getId();
assertStillThere(myDeletedPatientId.withVersion("1"));
assertGone(myDeletedPatientId.withVersion("2"));
// Observation
Observation o = new Observation();
o.setStatus(ObservationStatusEnum.FINAL);
myOneVersionObservationId = myObservationDao.create(o).getId();
o.setStatus(ObservationStatusEnum.FINAL);
o = new Observation();
myTwoVersionObservationId = myObservationDao.create(o).getId();
o.setStatus(ObservationStatusEnum.AMENDED);
myTwoVersionObservationId = myObservationDao.update(o).getId();
o = new Observation();
o.setStatus(ObservationStatusEnum.FINAL);
myDeletedObservationId = myObservationDao.create(o).getId();
myDeletedObservationId = myObservationDao.delete(myDeletedObservationId).getId();
}
private IFhirResourceDao<?> getDao(IIdType theId) {
IFhirResourceDao<?> dao;
switch (theId.getResourceType()) {
case "Patient":
dao = myPatientDao;
break;
case "Observation":
dao = myObservationDao;
break;
default:
fail("Restype: " + theId.getResourceType());
dao = myPatientDao;
}
return dao;
}
@Test
public void testExpungeInstanceOldVersionsAndDeleted() {
Patient p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addName().addFamily("FOO");
myPatientDao.update(p).getId();
myPatientDao.expunge(myTwoVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertStillThere(myTwoVersionPatientId.withVersion("3"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeInstanceVersionCurrentVersion() {
try {
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
fail();
} catch (PreconditionFailedException e) {
assertEquals("Can not perform version-specific expunge of resource Patient/PT-TWOVERSION/_history/2 as this is the current version", e.getMessage());
}
}
@Test
public void testExpungeInstanceVersionOldVersionsAndDeleted() {
Patient p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addName().addFamily("FOO");
myPatientDao.update(p).getId();
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Patients
assertStillThere(myOneVersionPatientId);
assertStillThere(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertStillThere(myTwoVersionPatientId.withVersion("3"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeSystemEverything() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
// Everything deleted
assertExpunged(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId.withVersion("1"));
assertExpunged(myDeletedPatientId);
// Everything deleted
assertExpunged(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertExpunged(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeSystemOldVersionsAndDeleted() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// Also observations deleted
assertStillThere(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeTypeDeletedResources() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(false));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertStillThere(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeTypeOldVersions() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(false)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId.withVersion("1"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeTypeOldVersionsAndDeleted() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -0,0 +1,283 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
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.util.TestUtil;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class ExpungeProviderDstu3Test extends BaseResourceProviderDstu3Test {
private IIdType myOneVersionPatientId;
private IIdType myTwoVersionPatientId;
private IIdType myDeletedPatientId;
private IIdType myOneVersionObservationId;
private IIdType myTwoVersionObservationId;
private IIdType myDeletedObservationId;
private void assertExpunged(IIdType theId) {
try {
getDao(theId).read(theId);
fail();
} catch (ResourceNotFoundException e) {
// good
}
}
private void assertGone(IIdType theId) {
try {
getDao(theId).read(theId);
fail();
} catch (ResourceGoneException e) {
// good
}
}
private void assertStillThere(IIdType theId) {
getDao(theId).read(theId);
}
@Override
@Before
public void before() throws Exception {
super.before();
Patient p = new Patient();
p.setId("PT-ONEVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addIdentifier().setSystem("foo").setValue("bar");
p.addName().setFamily("FAM");
myOneVersionPatientId = myPatientDao.update(p).getId();
p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
myTwoVersionPatientId = myPatientDao.update(p).getId();
p.setActive(false);
myTwoVersionPatientId = myPatientDao.update(p).getId();
p = new Patient();
p.setId("PT-DELETED");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
myDeletedPatientId = myPatientDao.update(p).getId();
myDeletedPatientId = myPatientDao.delete(myDeletedPatientId).getId();
assertStillThere(myDeletedPatientId.withVersion("1"));
assertGone(myDeletedPatientId.withVersion("2"));
// Observation
Observation o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
myOneVersionObservationId = myObservationDao.create(o).getId();
o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
myTwoVersionObservationId = myObservationDao.create(o).getId();
o.setStatus(Observation.ObservationStatus.AMENDED);
myTwoVersionObservationId = myObservationDao.update(o).getId();
o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
myDeletedObservationId = myObservationDao.create(o).getId();
myDeletedObservationId = myObservationDao.delete(myDeletedObservationId).getId();
}
private IFhirResourceDao<?> getDao(IIdType theId) {
IFhirResourceDao<?> dao;
switch (theId.getResourceType()) {
case "Patient":
dao = myPatientDao;
break;
case "Observation":
dao = myObservationDao;
break;
default:
fail("Restype: " + theId.getResourceType());
dao = myPatientDao;
}
return dao;
}
@Test
public void testExpungeInstanceOldVersionsAndDeleted() {
Patient p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addName().setFamily("FOO");
myPatientDao.update(p).getId();
myPatientDao.expunge(myTwoVersionPatientId.toUnqualifiedVersionless(), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertStillThere(myTwoVersionPatientId.withVersion("3"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeInstanceVersionCurrentVersion() {
try {
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
fail();
} catch (PreconditionFailedException e) {
assertEquals("Can not perform version-specific expunge of resource Patient/PT-TWOVERSION/_history/2 as this is the current version", e.getMessage());
}
}
@Test
public void testExpungeInstanceVersionOldVersionsAndDeleted() {
Patient p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addName().setFamily("FOO");
myPatientDao.update(p).getId();
myPatientDao.expunge(myTwoVersionPatientId.withVersion("2"), new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Patients
assertStillThere(myOneVersionPatientId);
assertStillThere(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertStillThere(myTwoVersionPatientId.withVersion("3"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeSystemEverything() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
// Everything deleted
assertExpunged(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId.withVersion("1"));
assertExpunged(myDeletedPatientId);
// Everything deleted
assertExpunged(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertExpunged(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeSystemOldVersionsAndDeleted() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// Also observations deleted
assertStillThere(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeTypeDeletedResources() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(false));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertStillThere(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeTypeOldVersions() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(false)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId.withVersion("1"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeTypeOldVersionsAndDeleted() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -179,6 +179,25 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeSystemOldVersionsAndDeleted() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// Also observations deleted
assertStillThere(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeTypeDeletedResources() {
myPatientDao.expunge(new ExpungeOptions()
@ -218,6 +237,25 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeSystemEverything() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
// Everything deleted
assertExpunged(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId.withVersion("1"));
assertExpunged(myDeletedPatientId);
// Everything deleted
assertExpunged(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertExpunged(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeTypeOldVersionsAndDeleted() {
myPatientDao.expunge(new ExpungeOptions()

View File

@ -0,0 +1,275 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class ResourceProviderExpungeR4Test extends BaseResourceProviderR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderExpungeR4Test.class);
private IIdType myOneVersionPatientId;
private IIdType myTwoVersionPatientId;
private IIdType myDeletedPatientId;
private IIdType myOneVersionObservationId;
private IIdType myTwoVersionObservationId;
private IIdType myDeletedObservationId;
private void assertExpunged(IIdType theId) {
try {
getDao(theId).read(theId);
fail();
} catch (ResourceNotFoundException e) {
// good
}
}
private void assertGone(IIdType theId) {
try {
getDao(theId).read(theId);
fail();
} catch (ResourceGoneException e) {
// good
}
}
private void assertStillThere(IIdType theId) {
getDao(theId).read(theId);
}
@Override
@Before
public void before() throws Exception {
super.before();
Patient p = new Patient();
p.setId("PT-ONEVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addIdentifier().setSystem("foo").setValue("bar");
p.addName().setFamily("FAM");
myOneVersionPatientId = myPatientDao.update(p).getId();
p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
myTwoVersionPatientId = myPatientDao.update(p).getId();
p.setActive(false);
myTwoVersionPatientId = myPatientDao.update(p).getId();
p = new Patient();
p.setId("PT-DELETED");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
myDeletedPatientId = myPatientDao.update(p).getId();
myDeletedPatientId = myPatientDao.delete(myDeletedPatientId).getId();
assertStillThere(myDeletedPatientId.withVersion("1"));
assertGone(myDeletedPatientId.withVersion("2"));
// Observation
Observation o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
myOneVersionObservationId = myObservationDao.create(o).getId();
o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
myTwoVersionObservationId = myObservationDao.create(o).getId();
o.setStatus(Observation.ObservationStatus.AMENDED);
myTwoVersionObservationId = myObservationDao.update(o).getId();
o = new Observation();
o.setStatus(Observation.ObservationStatus.FINAL);
myDeletedObservationId = myObservationDao.create(o).getId();
myDeletedObservationId = myObservationDao.delete(myDeletedObservationId).getId();
}
private IFhirResourceDao<?> getDao(IIdType theId) {
IFhirResourceDao<?> dao;
switch (theId.getResourceType()) {
case "Patient":
dao = myPatientDao;
break;
case "Observation":
dao = myObservationDao;
break;
default:
fail("Restype: " + theId.getResourceType());
dao = myPatientDao;
}
return dao;
}
@Test
public void testExpungeInstanceOldVersionsAndDeleted() {
Parameters input = new Parameters();
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_LIMIT)
.setValue(new IntegerType(1000));
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES)
.setValue(new BooleanType(true));
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS)
.setValue(new BooleanType(true));
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
Parameters output = myClient
.operation()
.onInstance(myTwoVersionPatientId)
.named("expunge")
.withParameters(input)
.execute();
assertEquals("count", output.getParameter().get(0).getName());
assertEquals(3, ((IntegerType) output.getParameter().get(0).getValue()).getValue().intValue());
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertGone(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeSystemEverything() {
Parameters input = new Parameters();
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_EVERYTHING)
.setValue(new BooleanType(true));
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
Parameters output = myClient
.operation()
.onServer()
.named("expunge")
.withParameters(input)
.execute();
assertEquals("count", output.getParameter().get(0).getName());
assertEquals(3, ((IntegerType) output.getParameter().get(0).getValue()).getValue().intValue());
// All patients deleted
assertExpunged(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertExpunged(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// All observations deleted
assertExpunged(myOneVersionObservationId);
assertExpunged(myTwoVersionObservationId.withVersion("1"));
assertExpunged(myTwoVersionObservationId.withVersion("2"));
assertExpunged(myDeletedObservationId);
}
@Test
public void testExpungeTypeOldVersionsAndDeleted() {
Parameters input = new Parameters();
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_LIMIT)
.setValue(new IntegerType(1000));
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES)
.setValue(new BooleanType(true));
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS)
.setValue(new BooleanType(true));
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
Parameters output = myClient
.operation()
.onType(Patient.class)
.named("expunge")
.withParameters(input)
.execute();
assertEquals("count", output.getParameter().get(0).getName());
assertEquals(3, ((IntegerType) output.getParameter().get(0).getValue()).getValue().intValue());
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@Test
public void testExpungeVersion() {
Patient p = new Patient();
p.setId("PT-TWOVERSION");
p.getMeta().addTag().setSystem("http://foo").setCode("bar");
p.setActive(true);
p.addName().setFamily("FOO");
myPatientDao.update(p).getId();
Parameters input = new Parameters();
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_LIMIT)
.setValue(new IntegerType(1000));
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_DELETED_RESOURCES)
.setValue(new BooleanType(true));
input.addParameter()
.setName(JpaResourceProviderR4.EXPUNGE_OLD_VERSIONS)
.setValue(new BooleanType(true));
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
Parameters output = myClient
.operation()
.onType(Patient.class)
.named("expunge")
.withParameters(input)
.execute();
assertEquals("count", output.getParameter().get(0).getName());
assertEquals(3, ((IntegerType) output.getParameter().get(0).getValue()).getValue().intValue());
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
assertExpunged(myTwoVersionPatientId.withVersion("1"));
assertStillThere(myTwoVersionPatientId.withVersion("2"));
assertExpunged(myDeletedPatientId);
// No observations deleted
assertStillThere(myOneVersionObservationId);
assertStillThere(myTwoVersionObservationId.withVersion("1"));
assertStillThere(myTwoVersionObservationId.withVersion("2"));
assertGone(myDeletedObservationId);
}
@AfterClass
public static void afterClassClearContext() {
TestUtil.clearAllStaticFieldsForUnitTest();
}
}

View File

@ -4742,6 +4742,8 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
}
private String toStr(Date theDate) {
return new InstantDt(theDate).getValueAsString();
}

View File

@ -26,6 +26,7 @@ import org.apache.http.client.methods.*;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.junit.*;
@ -215,7 +216,185 @@ public class GenericClientR4Test {
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">A PATIENT</div>", outputPt.getText().getDivAsString());
}
@Test
@Test
public void testOperationServer() throws Exception {
IParser p = ourCtx.newXmlParser();
Parameters inputParams = new Parameters();
inputParams.addParameter().setName("name").setValue(new BooleanType(true));
Parameters outputParams = new Parameters();
outputParams.addParameter().setName("name").setValue(new BooleanType(false));
final String respString = p.encodeResourceToString(outputParams);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
Parameters result = client
.operation()
.onServer()
.named("opname")
.withParameters(inputParams)
.execute();
assertEquals("name", result.getParameterFirstRep().getName());
assertEquals("false", ((IPrimitiveType<?>)result.getParameterFirstRep().getValue()).getValueAsString());
assertEquals("http://example.com/fhir/$opname", capt.getAllValues().get(0).getURI().toASCIIString());
validateUserAgent(capt);
assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
Parameters output = ourCtx.newXmlParser().parseResource(Parameters.class, extractBodyAsString(capt));
assertEquals("name", output.getParameterFirstRep().getName());
assertEquals("true", ((IPrimitiveType<?>)output.getParameterFirstRep().getValue()).getValueAsString());
}
@Test
public void testOperationType() throws Exception {
IParser p = ourCtx.newXmlParser();
Parameters inputParams = new Parameters();
inputParams.addParameter().setName("name").setValue(new BooleanType(true));
Parameters outputParams = new Parameters();
outputParams.addParameter().setName("name").setValue(new BooleanType(false));
final String respString = p.encodeResourceToString(outputParams);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
Parameters result = client
.operation()
.onType(Patient.class)
.named("opname")
.withParameters(inputParams)
.execute();
assertEquals("name", result.getParameterFirstRep().getName());
assertEquals("false", ((IPrimitiveType<?>)result.getParameterFirstRep().getValue()).getValueAsString());
assertEquals("http://example.com/fhir/Patient/$opname", capt.getAllValues().get(0).getURI().toASCIIString());
validateUserAgent(capt);
assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
Parameters output = ourCtx.newXmlParser().parseResource(Parameters.class, extractBodyAsString(capt));
assertEquals("name", output.getParameterFirstRep().getName());
assertEquals("true", ((IPrimitiveType<?>)output.getParameterFirstRep().getValue()).getValueAsString());
}
@Test
public void testOperationInstance() throws Exception {
IParser p = ourCtx.newXmlParser();
Parameters inputParams = new Parameters();
inputParams.addParameter().setName("name").setValue(new BooleanType(true));
Parameters outputParams = new Parameters();
outputParams.addParameter().setName("name").setValue(new BooleanType(false));
final String respString = p.encodeResourceToString(outputParams);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
Parameters result = client
.operation()
.onInstance(new IdType("Patient/123/_history/456"))
.named("opname")
.withParameters(inputParams)
.execute();
assertEquals("name", result.getParameterFirstRep().getName());
assertEquals("false", ((IPrimitiveType<?>)result.getParameterFirstRep().getValue()).getValueAsString());
assertEquals("http://example.com/fhir/Patient/123/$opname", capt.getAllValues().get(0).getURI().toASCIIString());
validateUserAgent(capt);
assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
Parameters output = ourCtx.newXmlParser().parseResource(Parameters.class, extractBodyAsString(capt));
assertEquals("name", output.getParameterFirstRep().getName());
assertEquals("true", ((IPrimitiveType<?>)output.getParameterFirstRep().getValue()).getValueAsString());
}
@Test
public void testOperationInstanceVersion() throws Exception {
IParser p = ourCtx.newXmlParser();
Parameters inputParams = new Parameters();
inputParams.addParameter().setName("name").setValue(new BooleanType(true));
Parameters outputParams = new Parameters();
outputParams.addParameter().setName("name").setValue(new BooleanType(false));
final String respString = p.encodeResourceToString(outputParams);
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
when(myHttpResponse.getEntity().getContent()).thenAnswer(new Answer<ReaderInputStream>() {
@Override
public ReaderInputStream answer(InvocationOnMock theInvocation) throws Throwable {
return new ReaderInputStream(new StringReader(respString), Charset.forName("UTF-8"));
}
});
IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir");
Parameters result = client
.operation()
.onInstanceVersion(new IdType("Patient/123/_history/456"))
.named("opname")
.withParameters(inputParams)
.execute();
assertEquals("name", result.getParameterFirstRep().getName());
assertEquals("false", ((IPrimitiveType<?>)result.getParameterFirstRep().getValue()).getValueAsString());
assertEquals("http://example.com/fhir/Patient/123/_history/456/$opname", capt.getAllValues().get(0).getURI().toASCIIString());
validateUserAgent(capt);
assertEquals("application/fhir+xml;charset=utf-8", capt.getAllValues().get(0).getHeaders("Content-Type")[0].getValue().toLowerCase().replace(" ", ""));
assertEquals(Constants.HEADER_ACCEPT_VALUE_XML_NON_LEGACY, capt.getAllValues().get(0).getHeaders("Accept")[0].getValue());
Parameters output = ourCtx.newXmlParser().parseResource(Parameters.class, extractBodyAsString(capt));
assertEquals("name", output.getParameterFirstRep().getName());
assertEquals("true", ((IPrimitiveType<?>)output.getParameterFirstRep().getValue()).getValueAsString());
}
@Test
public void testBinaryCreateWithNoContentType() throws Exception {
IParser p = ourCtx.newXmlParser();

View File

@ -71,7 +71,7 @@ public class OperationServerR4Test {
@Test
public void testConformance() throws Exception {
public void testConformance() {
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
loggingInterceptor.setLogResponseBody(true);
myFhirClient.registerInterceptor(loggingInterceptor);
@ -153,13 +153,29 @@ public class OperationServerR4Test {
}
@Test
public void testInstanceEverythingHapiClient() throws Exception {
public void testInstanceEverythingHapiClient() {
ourCtx.newRestfulGenericClient("http://localhost:" + ourPort).operation().onInstance(new IdType("Patient/123")).named("$everything").withParameters(new Parameters()).execute();
assertEquals("instance $everything", ourLastMethod);
assertEquals("Patient/123", ourLastId.toUnqualifiedVersionless().getValue());
}
@Test
public void testInstanceVersionEverythingHapiClient() {
ourCtx
.newRestfulGenericClient("http://localhost:" + ourPort)
.operation()
.onInstanceVersion(new IdType("Patient/123/_history/456"))
.named("$everything")
.withParameters(new Parameters())
.execute();
assertEquals("instance $everything", ourLastMethod);
assertEquals("Patient/123/_history/456", ourLastId.toUnqualified().getValue());
}
@Test

View File

@ -53,6 +53,10 @@
a local ID that already existed, making the resulting
serialization invalid. This has been corrected.
</action>
<action type="add">
The REST Generic Client now supports invoking an operation
on a specific version of a resource instance.
</action>
</release>
<release version="3.3.0" date="2018-03-29">
<action type="add">