Add expunge
This commit is contained in:
parent
07e7af746f
commit
09b1f547d0
|
@ -6,7 +6,8 @@ import org.apache.commons.lang3.time.DateUtils;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
@ -48,9 +49,8 @@ public class StopWatch {
|
||||||
private static final NumberFormat TEN_DAY_FORMAT = new DecimalFormat("0");
|
private static final NumberFormat TEN_DAY_FORMAT = new DecimalFormat("0");
|
||||||
private static Long ourNowForUnitTest;
|
private static Long ourNowForUnitTest;
|
||||||
private long myStarted = now();
|
private long myStarted = now();
|
||||||
private long myCurrentTaskStarted = -1L;
|
private TaskTiming myCurrentTask;
|
||||||
private LinkedHashMap<String, Long> myTaskTotals;
|
private LinkedList<TaskTiming> myTasks;
|
||||||
private String myCurrentTaskName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -68,9 +68,9 @@ public class StopWatch {
|
||||||
myStarted = theStart.getTime();
|
myStarted = theStart.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureTaskTotalsMapExists() {
|
private void addNewlineIfContentExists(StringBuilder theB) {
|
||||||
if (myTaskTotals == null) {
|
if (theB.length() > 0) {
|
||||||
myTaskTotals = new LinkedHashMap<>();
|
theB.append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,14 +80,17 @@ public class StopWatch {
|
||||||
* is currently started so it's ok to call it more than once.
|
* is currently started so it's ok to call it more than once.
|
||||||
*/
|
*/
|
||||||
public void endCurrentTask() {
|
public void endCurrentTask() {
|
||||||
if (isNotBlank(myCurrentTaskName)) {
|
ensureTasksListExists();
|
||||||
ensureTaskTotalsMapExists();
|
if (myCurrentTask != null) {
|
||||||
Long existingTotal = myTaskTotals.get(myCurrentTaskName);
|
myCurrentTask.setEnd(now());
|
||||||
long taskTimeElapsed = now() - myCurrentTaskStarted;
|
}
|
||||||
Long newTotal = existingTotal != null ? existingTotal + taskTimeElapsed : taskTimeElapsed;
|
myCurrentTask = null;
|
||||||
myTaskTotals.put(myCurrentTaskName, newTotal);
|
}
|
||||||
|
|
||||||
|
private void ensureTasksListExists() {
|
||||||
|
if (myTasks == null) {
|
||||||
|
myTasks = new LinkedList<>();
|
||||||
}
|
}
|
||||||
myCurrentTaskName = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,23 +98,49 @@ public class StopWatch {
|
||||||
*/
|
*/
|
||||||
public String formatTaskDurations() {
|
public String formatTaskDurations() {
|
||||||
|
|
||||||
// Flush the current task if it's ongoing
|
ensureTasksListExists();
|
||||||
String continueTask = myCurrentTaskName;
|
|
||||||
if (isNotBlank(myCurrentTaskName)) {
|
|
||||||
endCurrentTask();
|
|
||||||
startTask(continueTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
ensureTaskTotalsMapExists();
|
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
for (String nextTask : myTaskTotals.keySet()) {
|
|
||||||
if (b.length() > 0) {
|
if (myTasks.size() > 0) {
|
||||||
b.append("\n");
|
long delta = myTasks.getFirst().getStart() - myStarted;
|
||||||
|
if (delta > 10) {
|
||||||
|
addNewlineIfContentExists(b);
|
||||||
|
b.append("Before first task");
|
||||||
|
b.append(": ");
|
||||||
|
b.append(formatMillis(delta));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b.append(nextTask);
|
TaskTiming last = null;
|
||||||
|
for (TaskTiming nextTask : myTasks) {
|
||||||
|
|
||||||
|
if (last != null) {
|
||||||
|
long delta = nextTask.getStart() - last.getEnd();
|
||||||
|
if (delta > 10) {
|
||||||
|
addNewlineIfContentExists(b);
|
||||||
|
b.append("Between");
|
||||||
b.append(": ");
|
b.append(": ");
|
||||||
b.append(formatMillis(myTaskTotals.get(nextTask)));
|
b.append(formatMillis(delta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addNewlineIfContentExists(b);
|
||||||
|
b.append(nextTask.getTaskName());
|
||||||
|
b.append(": ");
|
||||||
|
long delta = nextTask.getMillis();
|
||||||
|
b.append(formatMillis(delta));
|
||||||
|
|
||||||
|
last = nextTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (myTasks.size() > 0) {
|
||||||
|
long delta = now() - myTasks.getLast().getEnd();
|
||||||
|
if (delta > 10) {
|
||||||
|
addNewlineIfContentExists(b);
|
||||||
|
b.append("After last task");
|
||||||
|
b.append(": ");
|
||||||
|
b.append(formatMillis(delta));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.toString();
|
return b.toString();
|
||||||
|
@ -214,9 +243,11 @@ public class StopWatch {
|
||||||
public void startTask(String theTaskName) {
|
public void startTask(String theTaskName) {
|
||||||
endCurrentTask();
|
endCurrentTask();
|
||||||
if (isNotBlank(theTaskName)) {
|
if (isNotBlank(theTaskName)) {
|
||||||
myCurrentTaskStarted = now();
|
myCurrentTask = new TaskTiming()
|
||||||
|
.setTaskName(theTaskName)
|
||||||
|
.setStart(now());
|
||||||
|
myTasks.add(myCurrentTask);
|
||||||
}
|
}
|
||||||
myCurrentTaskName = theTaskName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -301,4 +332,44 @@ public class StopWatch {
|
||||||
ourNowForUnitTest = theNowForUnitTest;
|
ourNowForUnitTest = theNowForUnitTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TaskTiming {
|
||||||
|
private long myStart;
|
||||||
|
private long myEnd;
|
||||||
|
private String myTaskName;
|
||||||
|
|
||||||
|
public long getEnd() {
|
||||||
|
if (myEnd == 0) {
|
||||||
|
return now();
|
||||||
|
}
|
||||||
|
return myEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskTiming setEnd(long theEnd) {
|
||||||
|
myEnd = theEnd;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMillis() {
|
||||||
|
return getEnd() - getStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getStart() {
|
||||||
|
return myStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskTiming setStart(long theStart) {
|
||||||
|
myStart = theStart;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return myTaskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskTiming setTaskName(String theTaskName) {
|
||||||
|
myTaskName = theTaskName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,7 @@ public class StopWatchTest {
|
||||||
|
|
||||||
StopWatch.setNowForUnitTestForUnitTest(1600L);
|
StopWatch.setNowForUnitTestForUnitTest(1600L);
|
||||||
String taskDurations = sw.formatTaskDurations();
|
String taskDurations = sw.formatTaskDurations();
|
||||||
|
ourLog.info(taskDurations);
|
||||||
assertEquals("TASK1: 500ms\nTASK2: 100ms", taskDurations);
|
assertEquals("TASK1: 500ms\nTASK2: 100ms", taskDurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
ourLog.debug("Beginning {} with {} resources", theActionName, theRequest.getEntry().size());
|
ourLog.debug("Beginning {} with {} resources", theActionName, theRequest.getEntry().size());
|
||||||
|
|
||||||
final Date updateTime = new Date();
|
final Date updateTime = new Date();
|
||||||
|
final StopWatch transactionStopWatch = new StopWatch();
|
||||||
|
|
||||||
final Set<IdType> allIds = new LinkedHashSet<>();
|
final Set<IdType> allIds = new LinkedHashSet<>();
|
||||||
final Map<IdType, IdType> idSubstitutions = new HashMap<>();
|
final Map<IdType, IdType> idSubstitutions = new HashMap<>();
|
||||||
|
@ -221,9 +222,14 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
Map<BundleEntryComponent, ResourceTable> entriesToProcess = txManager.execute(new TransactionCallback<Map<BundleEntryComponent, ResourceTable>>() {
|
Map<BundleEntryComponent, ResourceTable> entriesToProcess = txManager.execute(new TransactionCallback<Map<BundleEntryComponent, ResourceTable>>() {
|
||||||
@Override
|
@Override
|
||||||
public Map<BundleEntryComponent, ResourceTable> doInTransaction(TransactionStatus status) {
|
public Map<BundleEntryComponent, ResourceTable> doInTransaction(TransactionStatus status) {
|
||||||
return doTransactionWriteOperations(theRequestDetails, theRequest, theActionName, updateTime, allIds, idSubstitutions, idToPersistedOutcome, response, originalRequestOrder, entries);
|
Map<BundleEntryComponent, ResourceTable> retVal = doTransactionWriteOperations(theRequestDetails, theActionName, updateTime, allIds, idSubstitutions, idToPersistedOutcome, response, originalRequestOrder, entries, transactionStopWatch);
|
||||||
|
|
||||||
|
transactionStopWatch.startTask("Commit writes to database");
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
transactionStopWatch.endCurrentTask();
|
||||||
|
|
||||||
for (Entry<BundleEntryComponent, ResourceTable> nextEntry : entriesToProcess.entrySet()) {
|
for (Entry<BundleEntryComponent, ResourceTable> nextEntry : entriesToProcess.entrySet()) {
|
||||||
String responseLocation = nextEntry.getValue().getIdDt().toUnqualified().getValue();
|
String responseLocation = nextEntry.getValue().getIdDt().toUnqualified().getValue();
|
||||||
String responseEtag = nextEntry.getValue().getIdDt().getVersionIdPart();
|
String responseEtag = nextEntry.getValue().getIdDt().getVersionIdPart();
|
||||||
|
@ -234,6 +240,9 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
/*
|
/*
|
||||||
* Loop through the request and process any entries of type GET
|
* Loop through the request and process any entries of type GET
|
||||||
*/
|
*/
|
||||||
|
if (getEntries.size() > 0) {
|
||||||
|
transactionStopWatch.startTask("Process " + getEntries.size() + " GET entries");
|
||||||
|
}
|
||||||
for (BundleEntryComponent nextReqEntry : getEntries) {
|
for (BundleEntryComponent nextReqEntry : getEntries) {
|
||||||
Integer originalOrder = originalRequestOrder.get(nextReqEntry);
|
Integer originalOrder = originalRequestOrder.get(nextReqEntry);
|
||||||
BundleEntryComponent nextRespEntry = response.getEntry().get(originalOrder);
|
BundleEntryComponent nextRespEntry = response.getEntry().get(originalOrder);
|
||||||
|
@ -247,7 +256,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
|
|
||||||
int qIndex = url.indexOf('?');
|
int qIndex = url.indexOf('?');
|
||||||
ArrayListMultimap<String, String> paramValues = ArrayListMultimap.create();
|
ArrayListMultimap<String, String> paramValues = ArrayListMultimap.create();
|
||||||
requestDetails.setParameters(new HashMap<String, String[]>());
|
requestDetails.setParameters(new HashMap<>());
|
||||||
if (qIndex != -1) {
|
if (qIndex != -1) {
|
||||||
String params = url.substring(qIndex);
|
String params = url.substring(qIndex);
|
||||||
List<NameValuePair> parameters = translateMatchUrl(params);
|
List<NameValuePair> parameters = translateMatchUrl(params);
|
||||||
|
@ -297,13 +306,17 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
transactionStopWatch.endCurrentTask();
|
||||||
|
|
||||||
response.setType(BundleType.TRANSACTIONRESPONSE);
|
response.setType(BundleType.TRANSACTIONRESPONSE);
|
||||||
|
|
||||||
|
ourLog.info("Transaction timing:\n{}", transactionStopWatch.formatTaskDurations());
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<BundleEntryComponent, ResourceTable> doTransactionWriteOperations(ServletRequestDetails theRequestDetails, Bundle theRequest, String theActionName, Date theUpdateTime, Set<IdType> theAllIds,
|
private Map<BundleEntryComponent, ResourceTable> doTransactionWriteOperations(ServletRequestDetails theRequestDetails, String theActionName, Date theUpdateTime, Set<IdType> theAllIds,
|
||||||
Map<IdType, IdType> theIdSubstitutions, Map<IdType, DaoMethodOutcome> theIdToPersistedOutcome, Bundle theResponse, IdentityHashMap<BundleEntryComponent, Integer> theOriginalRequestOrder, List<BundleEntryComponent> theEntries) {
|
Map<IdType, IdType> theIdSubstitutions, Map<IdType, DaoMethodOutcome> theIdToPersistedOutcome, Bundle theResponse, IdentityHashMap<BundleEntryComponent, Integer> theOriginalRequestOrder, List<BundleEntryComponent> theEntries, StopWatch theTransactionStopWatch) {
|
||||||
Set<String> deletedResources = new HashSet<>();
|
Set<String> deletedResources = new HashSet<>();
|
||||||
List<DeleteConflict> deleteConflicts = new ArrayList<>();
|
List<DeleteConflict> deleteConflicts = new ArrayList<>();
|
||||||
Map<BundleEntryComponent, ResourceTable> entriesToProcess = new IdentityHashMap<>();
|
Map<BundleEntryComponent, ResourceTable> entriesToProcess = new IdentityHashMap<>();
|
||||||
|
@ -360,10 +373,11 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPVerb verb = nextReqEntry.getRequest().getMethodElement().getValue();
|
HTTPVerb verb = nextReqEntry.getRequest().getMethodElement().getValue();
|
||||||
|
|
||||||
String resourceType = res != null ? getContext().getResourceDefinition(res).getName() : null;
|
String resourceType = res != null ? getContext().getResourceDefinition(res).getName() : null;
|
||||||
BundleEntryComponent nextRespEntry = theResponse.getEntry().get(theOriginalRequestOrder.get(nextReqEntry));
|
BundleEntryComponent nextRespEntry = theResponse.getEntry().get(theOriginalRequestOrder.get(nextReqEntry));
|
||||||
|
|
||||||
|
theTransactionStopWatch.startTask("Bundle.entry[" + i + "]: " + verb.name() + " " + defaultString(resourceType));
|
||||||
|
|
||||||
switch (verb) {
|
switch (verb) {
|
||||||
case POST: {
|
case POST: {
|
||||||
// CREATE
|
// CREATE
|
||||||
|
@ -466,6 +480,8 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theTransactionStopWatch.endCurrentTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -484,6 +500,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FhirTerser terser = getContext().newTerser();
|
FhirTerser terser = getContext().newTerser();
|
||||||
|
theTransactionStopWatch.startTask("Index " + theIdToPersistedOutcome.size() + " resources");
|
||||||
for (DaoMethodOutcome nextOutcome : theIdToPersistedOutcome.values()) {
|
for (DaoMethodOutcome nextOutcome : theIdToPersistedOutcome.values()) {
|
||||||
IBaseResource nextResource = nextOutcome.getResource();
|
IBaseResource nextResource = nextOutcome.getResource();
|
||||||
if (nextResource == null) {
|
if (nextResource == null) {
|
||||||
|
@ -534,8 +551,16 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theTransactionStopWatch.endCurrentTask();
|
||||||
|
theTransactionStopWatch.startTask("Flush writes to database");
|
||||||
|
|
||||||
flushJpaSession();
|
flushJpaSession();
|
||||||
|
|
||||||
|
theTransactionStopWatch.endCurrentTask();
|
||||||
|
if (conditionalRequestUrls.size() > 0) {
|
||||||
|
theTransactionStopWatch.startTask("Check for conflicts in conditional resources");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Double check we didn't allow any duplicates we shouldn't have
|
* Double check we didn't allow any duplicates we shouldn't have
|
||||||
*/
|
*/
|
||||||
|
@ -552,6 +577,8 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theTransactionStopWatch.endCurrentTask();
|
||||||
|
|
||||||
for (IdType next : theAllIds) {
|
for (IdType next : theAllIds) {
|
||||||
IdType replacement = theIdSubstitutions.get(next);
|
IdType replacement = theIdSubstitutions.get(next);
|
||||||
if (replacement == null) {
|
if (replacement == null) {
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
||||||
@IdParam IIdType theIdParam,
|
@IdParam IIdType theIdParam,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
||||||
) {
|
) {
|
||||||
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
||||||
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
|
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
|
||||||
|
@ -97,7 +97,7 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
|
||||||
public Parameters expunge(
|
public Parameters expunge(
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
||||||
) {
|
) {
|
||||||
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
||||||
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
|
return JpaSystemProviderDstu2.toExpungeResponse(retVal);
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
|
||||||
@IdParam IIdType theIdParam,
|
@IdParam IIdType theIdParam,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
|
@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_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanDt theExpungeOldVersions,
|
@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
|
||||||
) {
|
) {
|
||||||
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);
|
||||||
|
@ -79,7 +79,7 @@ public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundl
|
||||||
public Parameters expunge(
|
public Parameters expunge(
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerDt theLimit,
|
@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_DELETED_RESOURCES) BooleanDt theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanDt theExpungeOldVersions,
|
@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
|
||||||
) {
|
) {
|
||||||
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);
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
|
||||||
@IdParam IIdType theIdParam,
|
@IdParam IIdType theIdParam,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
||||||
) {
|
) {
|
||||||
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
||||||
try {
|
try {
|
||||||
|
@ -105,7 +105,7 @@ public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaRes
|
||||||
public Parameters expunge(
|
public Parameters expunge(
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) org.hl7.fhir.r4.model.IntegerType theLimit,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES) org.hl7.fhir.r4.model.BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) org.hl7.fhir.r4.model.BooleanType theExpungeOldVersions
|
||||||
) {
|
) {
|
||||||
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
org.hl7.fhir.r4.model.Parameters retVal = super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
|
||||||
@IdParam IIdType theIdParam,
|
@IdParam IIdType theIdParam,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
|
@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_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
|
@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
|
||||||
) {
|
) {
|
||||||
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);
|
||||||
|
@ -79,7 +79,7 @@ public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundl
|
||||||
public Parameters expunge(
|
public Parameters expunge(
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
|
@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_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
|
@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
|
||||||
) {
|
) {
|
||||||
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);
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
|
||||||
@IdParam IIdType theIdParam,
|
@IdParam IIdType theIdParam,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
|
@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_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions
|
||||||
) {
|
) {
|
||||||
return super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
return super.doExpunge(theIdParam, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class JpaResourceProviderR4<T extends IAnyResource> extends BaseJpaResour
|
||||||
public Parameters expunge(
|
public Parameters expunge(
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
|
@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_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions
|
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS) BooleanType theExpungeOldVersions
|
||||||
) {
|
) {
|
||||||
return super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
return super.doExpunge(null, theLimit, theExpungeDeletedResources, theExpungeOldVersions, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
|
||||||
@IdParam IIdType theIdParam,
|
@IdParam IIdType theIdParam,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
|
@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_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
|
@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
|
||||||
) {
|
) {
|
||||||
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
|
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
|
||||||
|
@ -71,7 +71,7 @@ public class JpaSystemProviderR4 extends BaseJpaSystemProviderDstu2Plus<Bundle,
|
||||||
public Parameters expunge(
|
public Parameters expunge(
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_LIMIT) IntegerType theLimit,
|
@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_DELETED_RESOURCES) BooleanType theExpungeDeletedResources,
|
||||||
@OperationParam(name = JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS) BooleanType theExpungeOldVersions,
|
@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
|
||||||
) {
|
) {
|
||||||
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
|
return super.doExpunge(theLimit, theExpungeDeletedResources, theExpungeOldVersions, theExpungeEverything);
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class JpaConstants {
|
||||||
/**
|
/**
|
||||||
* Parameter name for the $expunge operation
|
* Parameter name for the $expunge operation
|
||||||
*/
|
*/
|
||||||
public static final String OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS = "expungeOldVersions";
|
public static final String OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS = "expungePreviousVersions";
|
||||||
/**
|
/**
|
||||||
* Parameter name for the $expunge operation
|
* Parameter name for the $expunge operation
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -121,7 +121,7 @@ public class ResourceProviderExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES)
|
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES)
|
||||||
.setValue(new BooleanType(true));
|
.setValue(new BooleanType(true));
|
||||||
input.addParameter()
|
input.addParameter()
|
||||||
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS)
|
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS)
|
||||||
.setValue(new BooleanType(true));
|
.setValue(new BooleanType(true));
|
||||||
|
|
||||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
|
||||||
|
@ -193,7 +193,7 @@ public class ResourceProviderExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES)
|
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES)
|
||||||
.setValue(new BooleanType(true));
|
.setValue(new BooleanType(true));
|
||||||
input.addParameter()
|
input.addParameter()
|
||||||
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS)
|
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS)
|
||||||
.setValue(new BooleanType(true));
|
.setValue(new BooleanType(true));
|
||||||
|
|
||||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
|
||||||
|
@ -239,7 +239,7 @@ public class ResourceProviderExpungeR4Test extends BaseResourceProviderR4Test {
|
||||||
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES)
|
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_DELETED_RESOURCES)
|
||||||
.setValue(new BooleanType(true));
|
.setValue(new BooleanType(true));
|
||||||
input.addParameter()
|
input.addParameter()
|
||||||
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_OLD_VERSIONS)
|
.setName(JpaConstants.OPERATION_EXPUNGE_PARAM_EXPUNGE_PREVIOUS_VERSIONS)
|
||||||
.setValue(new BooleanType(true));
|
.setValue(new BooleanType(true));
|
||||||
|
|
||||||
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
|
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(input));
|
||||||
|
|
|
@ -38,7 +38,7 @@ public interface IAuthRuleBuilderOperationNamed {
|
||||||
/**
|
/**
|
||||||
* Rule applies to invocations of this operation at the <code>type</code> level on any type
|
* Rule applies to invocations of this operation at the <code>type</code> level on any type
|
||||||
*/
|
*/
|
||||||
IAuthRuleFinished onAnyType();
|
IAuthRuleBuilderRuleOpClassifierFinished onAnyType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rule applies to invocations of this operation at the <code>instance</code> level
|
* Rule applies to invocations of this operation at the <code>instance</code> level
|
||||||
|
@ -53,6 +53,11 @@ public interface IAuthRuleBuilderOperationNamed {
|
||||||
/**
|
/**
|
||||||
* Rule applies to invocations of this operation at the <code>instance</code> level on any instance
|
* Rule applies to invocations of this operation at the <code>instance</code> level on any instance
|
||||||
*/
|
*/
|
||||||
IAuthRuleFinished onAnyInstance();
|
IAuthRuleBuilderRuleOpClassifierFinished onAnyInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rule applies to invocations of this operation at any level (server, type or instance)
|
||||||
|
*/
|
||||||
|
IAuthRuleBuilderRuleOpClassifierFinished atAnyLevel();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,16 @@ class OperationRule extends BaseRule implements IAuthRule {
|
||||||
private HashSet<Class<? extends IBaseResource>> myAppliesToInstancesOfType;
|
private HashSet<Class<? extends IBaseResource>> myAppliesToInstancesOfType;
|
||||||
private boolean myAppliesToAnyType;
|
private boolean myAppliesToAnyType;
|
||||||
private boolean myAppliesToAnyInstance;
|
private boolean myAppliesToAnyInstance;
|
||||||
|
private boolean myAppliesAtAnyLevel;
|
||||||
|
|
||||||
public OperationRule(String theRuleName) {
|
public OperationRule(String theRuleName) {
|
||||||
super(theRuleName);
|
super(theRuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void appliesAtAnyLevel(boolean theAppliesAtAnyLevel) {
|
||||||
|
myAppliesAtAnyLevel = theAppliesAtAnyLevel;
|
||||||
|
}
|
||||||
|
|
||||||
public void appliesToAnyInstance() {
|
public void appliesToAnyInstance() {
|
||||||
myAppliesToAnyInstance = true;
|
myAppliesToAnyInstance = true;
|
||||||
}
|
}
|
||||||
|
@ -82,12 +87,12 @@ class OperationRule extends BaseRule implements IAuthRule {
|
||||||
boolean applies = false;
|
boolean applies = false;
|
||||||
switch (theOperation) {
|
switch (theOperation) {
|
||||||
case EXTENDED_OPERATION_SERVER:
|
case EXTENDED_OPERATION_SERVER:
|
||||||
if (myAppliesToServer) {
|
if (myAppliesToServer || myAppliesAtAnyLevel) {
|
||||||
applies = true;
|
applies = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXTENDED_OPERATION_TYPE:
|
case EXTENDED_OPERATION_TYPE:
|
||||||
if (myAppliesToAnyType) {
|
if (myAppliesToAnyType || myAppliesAtAnyLevel) {
|
||||||
applies = true;
|
applies = true;
|
||||||
} else if (myAppliesToTypes != null) {
|
} else if (myAppliesToTypes != null) {
|
||||||
// TODO: Convert to a map of strings and keep the result
|
// TODO: Convert to a map of strings and keep the result
|
||||||
|
@ -101,7 +106,7 @@ class OperationRule extends BaseRule implements IAuthRule {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXTENDED_OPERATION_INSTANCE:
|
case EXTENDED_OPERATION_INSTANCE:
|
||||||
if (myAppliesToAnyInstance) {
|
if (myAppliesToAnyInstance || myAppliesAtAnyLevel) {
|
||||||
applies = true;
|
applies = true;
|
||||||
} else if (theInputResourceId != null) {
|
} else if (theInputResourceId != null) {
|
||||||
if (myAppliesToIds != null) {
|
if (myAppliesToIds != null) {
|
||||||
|
|
|
@ -451,7 +451,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IAuthRuleFinished onAnyInstance() {
|
public IAuthRuleBuilderRuleOpClassifierFinished onAnyInstance() {
|
||||||
OperationRule rule = createRule();
|
OperationRule rule = createRule();
|
||||||
rule.appliesToAnyInstance();
|
rule.appliesToAnyInstance();
|
||||||
myRules.add(rule);
|
myRules.add(rule);
|
||||||
|
@ -459,7 +459,15 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IAuthRuleFinished onAnyType() {
|
public IAuthRuleBuilderRuleOpClassifierFinished atAnyLevel() {
|
||||||
|
OperationRule rule = createRule();
|
||||||
|
rule.appliesAtAnyLevel(true);
|
||||||
|
myRules.add(rule);
|
||||||
|
return new RuleBuilderFinished(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IAuthRuleBuilderRuleOpClassifierFinished onAnyType() {
|
||||||
OperationRule rule = createRule();
|
OperationRule rule = createRule();
|
||||||
rule.appliesToAnyType();
|
rule.appliesToAnyType();
|
||||||
myRules.add(rule);
|
myRules.add(rule);
|
||||||
|
@ -473,7 +481,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
||||||
Validate.notBlank(theInstanceId.getIdPart(), "theInstanceId does not have an ID part");
|
Validate.notBlank(theInstanceId.getIdPart(), "theInstanceId does not have an ID part");
|
||||||
|
|
||||||
OperationRule rule = createRule();
|
OperationRule rule = createRule();
|
||||||
ArrayList<IIdType> ids = new ArrayList<IIdType>();
|
ArrayList<IIdType> ids = new ArrayList<>();
|
||||||
ids.add(theInstanceId);
|
ids.add(theInstanceId);
|
||||||
rule.appliesToInstances(ids);
|
rule.appliesToInstances(ids);
|
||||||
myRules.add(rule);
|
myRules.add(rule);
|
||||||
|
@ -509,7 +517,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashSet<Class<? extends IBaseResource>> toTypeSet(Class<? extends IBaseResource> theType) {
|
private HashSet<Class<? extends IBaseResource>> toTypeSet(Class<? extends IBaseResource> theType) {
|
||||||
HashSet<Class<? extends IBaseResource>> appliesToTypes = new HashSet<Class<? extends IBaseResource>>();
|
HashSet<Class<? extends IBaseResource>> appliesToTypes = new HashSet<>();
|
||||||
appliesToTypes.add(theType);
|
appliesToTypes.add(theType);
|
||||||
return appliesToTypes;
|
return appliesToTypes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1158,6 +1158,119 @@ public class AuthorizationInterceptorR4Test {
|
||||||
assertFalse(ourHitMethod);
|
assertFalse(ourHitMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOperationAppliesAtAnyLevel() throws Exception {
|
||||||
|
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||||
|
@Override
|
||||||
|
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||||
|
return new RuleBuilder()
|
||||||
|
.allow("RULE 1").operation().named("opName").atAnyLevel().andThen()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
HttpGet httpGet;
|
||||||
|
HttpResponse status;
|
||||||
|
String response;
|
||||||
|
|
||||||
|
// Server
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createObservation(10, "Patient/2"));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertTrue(ourHitMethod);
|
||||||
|
|
||||||
|
// Type
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createPatient(2));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
ourLog.info(response);
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertTrue(ourHitMethod);
|
||||||
|
|
||||||
|
// Instance
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createPatient(2));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
ourLog.info(response);
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertTrue(ourHitMethod);
|
||||||
|
|
||||||
|
// Instance Version
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createPatient(2));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/_history/2/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
ourLog.info(response);
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertTrue(ourHitMethod);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOperationAppliesAtAnyLevelWrongOpName() throws Exception {
|
||||||
|
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||||
|
@Override
|
||||||
|
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||||
|
return new RuleBuilder()
|
||||||
|
.allow("RULE 1").operation().named("opNameBadOp").atAnyLevel().andThen()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
HttpGet httpGet;
|
||||||
|
HttpResponse status;
|
||||||
|
String response;
|
||||||
|
|
||||||
|
// Server
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createObservation(10, "Patient/2"));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||||
|
assertFalse(ourHitMethod);
|
||||||
|
|
||||||
|
// Type
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createPatient(2));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
ourLog.info(response);
|
||||||
|
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||||
|
assertFalse(ourHitMethod);
|
||||||
|
|
||||||
|
// Instance
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createPatient(2));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
ourLog.info(response);
|
||||||
|
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||||
|
assertFalse(ourHitMethod);
|
||||||
|
|
||||||
|
// Instance Version
|
||||||
|
ourHitMethod = false;
|
||||||
|
ourReturn = Collections.singletonList(createPatient(2));
|
||||||
|
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/_history/2/$opName");
|
||||||
|
status = ourClient.execute(httpGet);
|
||||||
|
response = extractResponseAndClose(status);
|
||||||
|
ourLog.info(response);
|
||||||
|
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||||
|
assertFalse(ourHitMethod);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOperationTypeLevel() throws Exception {
|
public void testOperationTypeLevel() throws Exception {
|
||||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||||
|
|
|
@ -71,6 +71,13 @@
|
||||||
source IPs, or to only allow operations with specific
|
source IPs, or to only allow operations with specific
|
||||||
parameter values.
|
parameter values.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
A new qualifier has been added to the AuthorizationInterceptor
|
||||||
|
RuleBuilder that allows a rule on an operation to match
|
||||||
|
<![CDATA[<code>atAnyLevel()</code>]]>, meaning that the rule
|
||||||
|
applies to the operation by name whether it is at the
|
||||||
|
server, type, or instance level.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.3.0" date="2018-03-29">
|
<release version="3.3.0" date="2018-03-29">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue