Merge pull request #1379 from jamesagnew/expunge-hooks

Expunge hooks
This commit is contained in:
Ken Stevens 2019-07-12 17:16:06 -04:00 committed by GitHub
commit e54af48964
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 183 additions and 100 deletions

View File

@ -1163,6 +1163,43 @@ public enum Pointcut {
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails"
),
/**
* Invoked before expungeEverything is called.
* <p>
* Hooks will be passed a reference to a counter containing the current number of records that have been deleted.
* If the hook deletes any records, the hook is expected to increment this counter by the number of records deleted.
* </p>
* Hooks may accept the following parameters:
* <ul>
* <li>java.util.concurrent.atomic.AtomicInteger - The counter holding the number of records deleted.</li>
* <li>
* ca.uhn.fhir.rest.api.server.RequestDetails - A bean containing details about the request that is about to be processed, including details such as the
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
* pulled out of the servlet request. Note that the bean
* properties are not all guaranteed to be populated, depending on how early during processing the
* exception occurred.
* </li>
* <li>
* ca.uhn.fhir.rest.server.servlet.ServletRequestDetails - A bean containing details about the request that is about to be processed, including details such as the
* resource type and logical ID (if any) and other FHIR-specific aspects of the request which have been
* pulled out of the servlet request. This parameter is identical to the RequestDetails parameter above but will
* only be populated when operating in a RestfulServer implementation. It is provided as a convenience.
* </li>
* </ul>
* <p>
* Hooks should return void.
* </p>
*/
STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING(
// Return type
void.class,
// Params
"java.util.concurrent.atomic.AtomicInteger",
"ca.uhn.fhir.rest.api.server.RequestDetails",
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails"
),
/**
* Note that this is a performance tracing hook. Use with caution in production
* systems, since calling it may (or may not) carry a cost.

View File

@ -555,18 +555,18 @@ 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 myExpungeService.expunge(getResourceName(), entity.getResourceId(), entity.getVersion(), theExpungeOptions);
return myExpungeService.expunge(getResourceName(), entity.getResourceId(), entity.getVersion(), theExpungeOptions, theRequest);
}
return myExpungeService.expunge(getResourceName(), entity.getResourceId(), null, theExpungeOptions);
return myExpungeService.expunge(getResourceName(), entity.getResourceId(), null, theExpungeOptions ,theRequest);
}
@Override
@Transactional(propagation = Propagation.NEVER)
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions) {
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
ourLog.info("Beginning TYPE[{}] expunge operation", getResourceName());
return myExpungeService.expunge(getResourceName(), null, null, theExpungeOptions);
return myExpungeService.expunge(getResourceName(), null, null, theExpungeOptions, theRequestDetails);
}
public String getResourceName() {

View File

@ -49,8 +49,8 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
@Override
@Transactional(propagation = Propagation.NEVER)
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions) {
return myExpungeService.expunge(null, null, null, theExpungeOptions);
public ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
return myExpungeService.expunge(null, null, null, theExpungeOptions, theRequestDetails);
}
@Transactional(propagation = Propagation.REQUIRED)

View File

@ -29,7 +29,6 @@ import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.PatchTypeEnum;
@ -105,7 +104,7 @@ public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
*/
DeleteMethodOutcome deleteByUrl(String theString, RequestDetails theRequestDetails);
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions);
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails);
ExpungeOutcome expunge(IIdType theIIdType, ExpungeOptions theExpungeOptions, RequestDetails theRequest);

View File

@ -37,7 +37,7 @@ import java.util.Map;
*/
public interface IFhirSystemDao<T, MT> extends IDao {
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions);
ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails);
@SuppressWarnings("unchecked")
<R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType);

View File

@ -20,8 +20,14 @@ package ca.uhn.fhir.jpa.dao.expunge;
* #L%
*/
import ca.uhn.fhir.interceptor.api.HookParams;
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,6 +37,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
@ -47,59 +54,74 @@ public class ExpungeEverythingService {
protected EntityManager myEntityManager;
@Autowired
private PlatformTransactionManager myPlatformTransactionManager;
@Autowired
protected IInterceptorBroadcaster myInterceptorBroadcaster;
void expungeEverything() {
private TransactionTemplate myTxTemplate;
@PostConstruct
public void initTxTemplate() {
myTxTemplate = new TransactionTemplate(myPlatformTransactionManager);
}
void expungeEverything(RequestDetails theRequest) {
final AtomicInteger counter = new AtomicInteger();
// Notify Interceptors about pre-action call
HookParams hooks = new HookParams()
.add(AtomicInteger.class, counter)
.add(RequestDetails.class, theRequest)
.addIfMatchesType(ServletRequestDetails.class, theRequest);
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING, hooks);
ourLog.info("BEGINNING GLOBAL $expunge");
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
txTemplate.execute(t -> {
myTxTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
myTxTemplate.execute(t -> {
counter.addAndGet(doExpungeEverythingQuery("UPDATE " + ResourceHistoryTable.class.getSimpleName() + " d SET d.myForcedId = null"));
counter.addAndGet(doExpungeEverythingQuery("UPDATE " + ResourceTable.class.getSimpleName() + " d SET d.myForcedId = null"));
counter.addAndGet(doExpungeEverythingQuery("UPDATE " + TermCodeSystem.class.getSimpleName() + " d SET d.myCurrentVersion = null"));
return null;
});
counter.addAndGet(doExpungeEverythingQuery(txTemplate, SearchParamPresent.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ForcedId.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamDate.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamNumber.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamQuantity.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamString.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamToken.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamUri.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedSearchParamCoords.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceIndexedCompositeStringUnique.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceLink.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, SearchResult.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, SearchInclude.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermValueSetCode.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermValueSet.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptParentChildLink.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptMapGroupElementTarget.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptMapGroupElement.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptMapGroup.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptMap.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptProperty.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConceptDesignation.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermConcept.class));
txTemplate.execute(t -> {
counter.addAndGet(expungeEverythingByType(SearchParamPresent.class));
counter.addAndGet(expungeEverythingByType(ForcedId.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamDate.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamNumber.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamQuantity.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamString.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamToken.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamUri.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedSearchParamCoords.class));
counter.addAndGet(expungeEverythingByType(ResourceIndexedCompositeStringUnique.class));
counter.addAndGet(expungeEverythingByType(ResourceLink.class));
counter.addAndGet(expungeEverythingByType(SearchResult.class));
counter.addAndGet(expungeEverythingByType(SearchInclude.class));
counter.addAndGet(expungeEverythingByType(TermValueSetCode.class));
counter.addAndGet(expungeEverythingByType(TermValueSet.class));
counter.addAndGet(expungeEverythingByType(TermConceptParentChildLink.class));
counter.addAndGet(expungeEverythingByType(TermConceptMapGroupElementTarget.class));
counter.addAndGet(expungeEverythingByType(TermConceptMapGroupElement.class));
counter.addAndGet(expungeEverythingByType(TermConceptMapGroup.class));
counter.addAndGet(expungeEverythingByType(TermConceptMap.class));
counter.addAndGet(expungeEverythingByType(TermConceptProperty.class));
counter.addAndGet(expungeEverythingByType(TermConceptDesignation.class));
counter.addAndGet(expungeEverythingByType(TermConcept.class));
myTxTemplate.execute(t -> {
for (TermCodeSystem next : myEntityManager.createQuery("SELECT c FROM " + TermCodeSystem.class.getName() + " c", TermCodeSystem.class).getResultList()) {
next.setCurrentVersion(null);
myEntityManager.merge(next);
}
return null;
});
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermCodeSystemVersion.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TermCodeSystem.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, SubscriptionTable.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceHistoryTag.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceTag.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, TagDefinition.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceHistoryTable.class));
counter.addAndGet(doExpungeEverythingQuery(txTemplate, ResourceTable.class));
txTemplate.execute(t -> {
counter.addAndGet(expungeEverythingByType(TermCodeSystemVersion.class));
counter.addAndGet(expungeEverythingByType(TermCodeSystem.class));
counter.addAndGet(expungeEverythingByType(SubscriptionTable.class));
counter.addAndGet(expungeEverythingByType(ResourceHistoryTag.class));
counter.addAndGet(expungeEverythingByType(ResourceTag.class));
counter.addAndGet(expungeEverythingByType(TagDefinition.class));
counter.addAndGet(expungeEverythingByType(ResourceHistoryTable.class));
counter.addAndGet(expungeEverythingByType(ResourceTable.class));
myTxTemplate.execute(t -> {
counter.addAndGet(doExpungeEverythingQuery("DELETE from " + org.hibernate.search.jpa.Search.class.getSimpleName() + " d"));
return null;
});
@ -107,14 +129,14 @@ public class ExpungeEverythingService {
ourLog.info("COMPLETED GLOBAL $expunge - Deleted {} rows", counter.get());
}
private int doExpungeEverythingQuery(TransactionTemplate txTemplate, Class<?> theEntityType) {
public int expungeEverythingByType(Class<?> theEntityType) {
int outcome = 0;
while (true) {
StopWatch sw = new StopWatch();
@SuppressWarnings("ConstantConditions")
int count = txTemplate.execute(t -> {
int count = myTxTemplate.execute(t -> {
CriteriaBuilder cb = myEntityManager.getCriteriaBuilder();
CriteriaQuery<?> cq = cb.createQuery(theEntityType);
cq.from(theEntityType);

View File

@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.dao.expunge;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -49,13 +50,15 @@ public class ExpungeRun implements Callable<ExpungeOutcome> {
private final Long myResourceId;
private final Long myVersion;
private final ExpungeOptions myExpungeOptions;
private final RequestDetails myRequestDetails;
private final AtomicInteger myRemainingCount;
public ExpungeRun(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
public ExpungeRun(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails) {
myResourceName = theResourceName;
myResourceId = theResourceId;
myVersion = theVersion;
myExpungeOptions = theExpungeOptions;
myRequestDetails = theRequestDetails;
myRemainingCount = new AtomicInteger(myExpungeOptions.getLimit());
}

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.dao.expunge;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.util.ExpungeOptions;
import ca.uhn.fhir.jpa.util.ExpungeOutcome;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import org.slf4j.Logger;
@ -43,9 +44,9 @@ public abstract class ExpungeService {
private IResourceExpungeService myExpungeDaoService;
@Lookup
protected abstract ExpungeRun getExpungeRun(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions);
protected abstract ExpungeRun getExpungeRun(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails);
public ExpungeOutcome expunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions) {
public ExpungeOutcome expunge(String theResourceName, Long theResourceId, Long theVersion, ExpungeOptions theExpungeOptions, RequestDetails theRequest) {
ourLog.info("Expunge: ResourceName[{}] Id[{}] Version[{}] Options[{}]", theResourceName, theResourceId, theVersion, theExpungeOptions);
if (!myConfig.isExpungeEnabled()) {
@ -58,11 +59,11 @@ public abstract class ExpungeService {
if (theResourceName == null && theResourceId == null && theVersion == null) {
if (theExpungeOptions.isExpungeEverything()) {
myExpungeEverythingService.expungeEverything();
myExpungeEverythingService.expungeEverything(theRequest);
}
}
ExpungeRun expungeRun = getExpungeRun(theResourceName, theResourceId, theVersion, theExpungeOptions);
ExpungeRun expungeRun = getExpungeRun(theResourceName, theResourceId, theVersion, theExpungeOptions, theRequest);
return expungeRun.call();
}

View File

@ -57,6 +57,14 @@ public class IdHelperService {
myForcedIdDao.delete(forcedId);
}
/**
* @throws ResourceNotFoundException If the ID can not be found
*/
@Nonnull
public Long translateForcedIdToPid(IIdType theId, RequestDetails theRequestDetails) {
return translateForcedIdToPid(theId.getResourceType(), theId.getIdPart(), theRequestDetails);
}
/**
* @throws ResourceNotFoundException If the ID can not be found
*/

View File

@ -42,7 +42,7 @@ public class TermCodeSystem implements Serializable {
private static final long serialVersionUID = 1L;
private static final int MAX_NAME_LENGTH = 200;
static final int MAX_URL_LENGTH = 200;
public static final int MAX_URL_LENGTH = 200;
@Column(name = "CODE_SYSTEM_URI", nullable = false, length = MAX_URL_LENGTH)
private String myCodeSystemUri;

View File

@ -54,8 +54,8 @@ public class TermConcept implements Serializable {
private static final long serialVersionUID = 1L;
static final int MAX_CODE_LENGTH = 500;
static final int MAX_DESC_LENGTH = 400;
public static final int MAX_CODE_LENGTH = 500;
public static final int MAX_DESC_LENGTH = 400;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "myParent", cascade = {})
private Collection<TermConceptParentChildLink> myChildren;

View File

@ -43,8 +43,8 @@ import static org.apache.commons.lang3.StringUtils.length;
public class TermValueSet implements Serializable {
private static final long serialVersionUID = 1L;
private static final int MAX_NAME_LENGTH = 200;
static final int MAX_URL_LENGTH = 200;
public static final int MAX_NAME_LENGTH = 200;
public static final int MAX_URL_LENGTH = 200;
@Id()
@SequenceGenerator(name = "SEQ_VALUESET_PID", sequenceName = "SEQ_VALUESET_PID")

View File

@ -62,7 +62,7 @@ public abstract class BaseJpaResourceProvider<T extends IBaseResource> extends B
if (theIdParam != null) {
outcome = getDao().expunge(theIdParam, options, theRequest);
} else {
outcome = getDao().expunge(options);
outcome = getDao().expunge(options, theRequest);
}
return createExpungeResponse(outcome);

View File

@ -55,9 +55,9 @@ public class BaseJpaSystemProvider<T, MT> extends BaseJpaProvider implements IJp
return myResourceReindexingSvc;
}
protected Parameters doExpunge(IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything) {
protected Parameters doExpunge(IPrimitiveType<? extends Integer> theLimit, IPrimitiveType<? extends Boolean> theExpungeDeletedResources, IPrimitiveType<? extends Boolean> theExpungeOldVersions, IPrimitiveType<? extends Boolean> theExpungeEverything, RequestDetails theRequestDetails) {
ExpungeOptions options = createExpungeOptions(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
ExpungeOutcome outcome = getDao().expunge(options);
ExpungeOutcome outcome = getDao().expunge(options, theRequestDetails);
return createExpungeResponse(outcome);
}

View File

@ -71,9 +71,10 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanDt theExpungeOldVersions,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanDt theExpungeEverything
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanDt theExpungeEverything,
RequestDetails theRequestDetails
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything, theRequestDetails);
return toExpungeResponse(retVal);
}
@ -84,9 +85,10 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanDt theExpungeOldVersions,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanDt theExpungeEverything
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanDt theExpungeEverything,
RequestDetails theRequestDetails
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything, theRequestDetails);
return toExpungeResponse(retVal);
}

View File

@ -67,9 +67,10 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything,
RequestDetails theRequestDetails
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything, theRequestDetails);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {
@ -84,9 +85,10 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything,
RequestDetails theRequestDetails
) {
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything, theRequestDetails);
try {
return VersionConvertor_30_40.convertParameters(retVal);
} catch (FHIRException e) {

View File

@ -64,9 +64,10 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything,
RequestDetails theRequestDetails
) {
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything, theRequestDetails);
}
@Operation(name = JpaConstants.OPERATION_EXPUNGE, idempotent = false, returnParameters = {
@ -76,9 +77,10 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions,
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_EVERYTHING) BooleanType theExpungeEverything,
RequestDetails theRequestDetails
) {
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything, theRequestDetails);
}
// This is generated by hand:

View File

@ -391,7 +391,7 @@ public abstract class BaseJpaTest {
for (int count = 0; ; count++) {
try {
theSystemDao.expunge(new ExpungeOptions().setExpungeEverything(true));
theSystemDao.expunge(new ExpungeOptions().setExpungeEverything(true), null);
break;
} catch (Exception e) {
if (count >= 3) {

View File

@ -194,7 +194,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
@Test
public void testExpungeSystemEverything() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
.setExpungeEverything(true), null);
// Everything deleted
assertExpunged(myOneVersionPatientId);
@ -214,7 +214,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
public void testExpungeSystemOldVersionsAndDeleted() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -233,7 +233,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
public void testExpungeTypeDeletedResources() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(false));
.setExpungeOldVersions(false), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -252,7 +252,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
public void testExpungeTypeOldVersions() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(false)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -272,7 +272,7 @@ public class ResourceProviderExpungeDstu2Test extends BaseResourceProviderDstu2T
public void testExpungeTypeOldVersionsAndDeleted() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);

View File

@ -199,7 +199,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
@Test
public void testExpungeSystemEverything() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
.setExpungeEverything(true), null);
// Everything deleted
assertExpunged(myOneVersionPatientId);
@ -219,7 +219,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
public void testExpungeSystemOldVersionsAndDeleted() {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -238,7 +238,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
public void testExpungeTypeDeletedResources() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(false));
.setExpungeOldVersions(false), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -257,7 +257,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
public void testExpungeTypeOldVersions() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(false)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -277,7 +277,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
public void testExpungeTypeOldVersionsAndDeleted() {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -298,7 +298,7 @@ public class ResourceProviderExpungeDstu3Test extends BaseResourceProviderDstu3T
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true)
.setLimit(0));
.setLimit(0), null);
fail();
} catch (InvalidRequestException e) {
assertEquals("Expunge limit may not be less than 1. Received expunge limit 0.", e.getMessage());

View File

@ -177,7 +177,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
runInTransaction(() -> assertThat(myResourceTableDao.findAll(), empty()));
runInTransaction(() -> assertThat(myResourceHistoryTableDao.findAll(), empty()));
@ -234,7 +234,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -255,7 +255,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(false));
.setExpungeOldVersions(false), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -276,7 +276,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(false)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -297,7 +297,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
createStandardPatients();
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
.setExpungeEverything(true), null);
// Everything deleted
assertExpunged(myOneVersionPatientId);
@ -319,7 +319,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
myPatientDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true)
.setExpungeOldVersions(true));
.setExpungeOldVersions(true), null);
// Only deleted and prior patients
assertStillThere(myOneVersionPatientId);
@ -349,7 +349,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
});
mySystemDao.expunge(new ExpungeOptions()
.setExpungeEverything(true));
.setExpungeEverything(true), null);
// Everything deleted
assertExpunged(myOneVersionPatientId);
@ -380,7 +380,7 @@ public class ExpungeR4Test extends BaseResourceProviderR4Test {
mySystemDao.expunge(new ExpungeOptions()
.setExpungeDeletedResources(true));
.setExpungeDeletedResources(true), null);
// Everything deleted
assertExpunged(myOneVersionPatientId);

View File

@ -102,7 +102,7 @@ public abstract class BaseTableColumnTypeTask<T extends BaseTableTask> extends B
Validate.notNull(myNullable);
if (myColumnType == ColumnTypeEnum.STRING) {
Validate.notNull(myColumnLength);
Validate.notNull(myColumnLength, "No length specified for " + ColumnTypeEnum.STRING + " column {}.", getColumnName());
} else {
Validate.isTrue(myColumnLength == null);
}

View File

@ -20,6 +20,9 @@ package ca.uhn.fhir.jpa.migrate.tasks;
* #L%
*/
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
import ca.uhn.fhir.jpa.entity.TermConcept;
import ca.uhn.fhir.jpa.entity.TermValueSet;
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
import ca.uhn.fhir.jpa.migrate.taskdef.AddColumnTask;
import ca.uhn.fhir.jpa.migrate.taskdef.ArbitrarySqlTask;
@ -56,7 +59,7 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
init400();
}
private void init400() {
protected void init400() {
Builder version = forVersion(VersionEnum.V4_0_0);
version.onTable("TRM_CONCEPT_MAP_GROUP")
@ -81,7 +84,7 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
version.addIdGenerator("SEQ_VALUESET_PID");
Builder.BuilderAddTableByColumns termValueSetTable = version.addTableByColumns("TRM_VALUESET", "PID");
termValueSetTable.addColumn("PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
termValueSetTable.addColumn("URL").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING);
termValueSetTable.addColumn("URL").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSet.MAX_URL_LENGTH);
termValueSetTable
.addIndex("IDX_VALUESET_URL")
.unique(true)
@ -91,7 +94,7 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
.addForeignKey("FK_TRMVALUESET_RES")
.toColumn("RES_ID")
.references("HFJ_RESOURCE", "RES_ID");
termValueSetTable.addColumn("NAME").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING);
termValueSetTable.addColumn("NAME").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermValueSet.MAX_NAME_LENGTH);
// TermValueSetCode
version.startSectionWithMessage("Processing table: TRM_VALUESET_CODE");
@ -103,13 +106,13 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
.addForeignKey("FK_TRM_VALUESET_PID")
.toColumn("VALUESET_PID")
.references("TRM_VALUESET", "PID");
termValueSetCodeTable.addColumn("SYSTEM").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING);
termValueSetCodeTable.addColumn("CODE").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING);
termValueSetCodeTable.addColumn("SYSTEM").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermCodeSystem.MAX_URL_LENGTH);
termValueSetCodeTable.addColumn("CODE").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermConcept.MAX_CODE_LENGTH);
termValueSetCodeTable
.addIndex("IDX_VALUESET_CODE_CS_CD")
.unique(false)
.withColumns("SYSTEM", "CODE");
termValueSetCodeTable.addColumn("DISPLAY").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING);
termValueSetCodeTable.addColumn("DISPLAY").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, TermConcept.MAX_DESC_LENGTH);
}

View File

@ -270,6 +270,10 @@
The <![CDATA[<code>_summary</code>]]> element was not always respected when encoding
JSON resources.
</action>
<action type="add">
Added a new Pointcut STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING that is called at the start of
the expungeEverything operation.
</action>
</release>
<release version="3.8.0" date="2019-05-30" description="Hippo">
<action type="fix">