Add docs, enum, remove prints
This commit is contained in:
parent
e997d49d42
commit
ad8921ac4e
|
@ -1423,6 +1423,9 @@ public enum Pointcut implements IPointcut {
|
|||
* <li>
|
||||
* Boolean - Whether this pointcut invocation was deferred or not(since 5.4.0)
|
||||
* </li>
|
||||
* <li>
|
||||
* ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum - The timing at which the invocation of the interceptor took place. Options are ACTIVE and DEFERRED.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Hooks should return <code>void</code>.
|
||||
|
@ -1433,7 +1436,7 @@ public enum Pointcut implements IPointcut {
|
|||
"ca.uhn.fhir.rest.api.server.RequestDetails",
|
||||
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails",
|
||||
"ca.uhn.fhir.rest.api.server.storage.TransactionDetails",
|
||||
Boolean.class.getName()
|
||||
"ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum"
|
||||
),
|
||||
|
||||
/**
|
||||
|
@ -1468,7 +1471,7 @@ public enum Pointcut implements IPointcut {
|
|||
* ca.uhn.fhir.rest.api.server.storage.TransactionDetails - The outer transaction details object (since 5.0.0)
|
||||
* </li>
|
||||
* <li>
|
||||
* Boolean - Whether this pointcut invocation was deferred or not(since 5.4.0)
|
||||
* ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum - The timing at which the invocation of the interceptor took place. Options are ACTIVE and DEFERRED.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
|
@ -1481,7 +1484,7 @@ public enum Pointcut implements IPointcut {
|
|||
"ca.uhn.fhir.rest.api.server.RequestDetails",
|
||||
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails",
|
||||
"ca.uhn.fhir.rest.api.server.storage.TransactionDetails",
|
||||
Boolean.class.getName()
|
||||
"ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum"
|
||||
),
|
||||
|
||||
|
||||
|
@ -1512,7 +1515,7 @@ public enum Pointcut implements IPointcut {
|
|||
* ca.uhn.fhir.rest.api.server.storage.TransactionDetails - The outer transaction details object (since 5.0.0)
|
||||
* </li>
|
||||
* <li>
|
||||
* Boolean - Whether this pointcut invocation was deferred or not(since 5.4.0)
|
||||
* ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum - The timing at which the invocation of the interceptor took place. Options are ACTIVE and DEFERRED.
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
|
@ -1524,7 +1527,7 @@ public enum Pointcut implements IPointcut {
|
|||
"ca.uhn.fhir.rest.api.server.RequestDetails",
|
||||
"ca.uhn.fhir.rest.server.servlet.ServletRequestDetails",
|
||||
"ca.uhn.fhir.rest.api.server.storage.TransactionDetails",
|
||||
Boolean.class.getName()
|
||||
"ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum"
|
||||
),
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package ca.uhn.fhir.rest.api;
|
||||
|
||||
/**
|
||||
* during invocation of certain pointcuts, it is important to know whether they are being executed in
|
||||
* active or deferred fashion. This enum allows the pointcuts to see how they were invoked.
|
||||
*/
|
||||
public enum InterceptorInvocationTimingEnum {
|
||||
ACTIVE,
|
||||
DEFERRED
|
||||
}
|
|
@ -188,12 +188,17 @@ public class BundleUtil {
|
|||
static int GRAY = 2;
|
||||
static int BLACK = 3;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param theContext
|
||||
* @param theBundle
|
||||
*/
|
||||
public static void sortEntriesIntoProcessingOrder(FhirContext theContext, IBaseBundle theBundle) {
|
||||
Map<BundleEntryParts, IBase> partsToIBaseMap = getPartsToIBaseMap(theContext, theBundle);
|
||||
LinkedHashSet<IBase> retVal = new LinkedHashSet<>();
|
||||
|
||||
//Get all deletions.
|
||||
LinkedHashSet<IBase> deleteParts = sortEntriesIntoProcessingOrder(theContext, theBundle, RequestTypeEnum.DELETE, partsToIBaseMap);
|
||||
LinkedHashSet<IBase> deleteParts = sortEntriesOfTypeIntoProcessingOrder(theContext, RequestTypeEnum.DELETE, partsToIBaseMap);
|
||||
if (deleteParts == null) {
|
||||
throw new IllegalStateException("Cycle!");
|
||||
} else {
|
||||
|
@ -201,7 +206,7 @@ public class BundleUtil {
|
|||
}
|
||||
|
||||
//Get all Creations
|
||||
LinkedHashSet<IBase> createParts= sortEntriesIntoProcessingOrder(theContext, theBundle, RequestTypeEnum.POST, partsToIBaseMap);
|
||||
LinkedHashSet<IBase> createParts= sortEntriesOfTypeIntoProcessingOrder(theContext, RequestTypeEnum.POST, partsToIBaseMap);
|
||||
if (createParts== null) {
|
||||
throw new IllegalStateException("Cycle!");
|
||||
} else {
|
||||
|
@ -209,7 +214,7 @@ public class BundleUtil {
|
|||
}
|
||||
|
||||
// Get all Updates
|
||||
LinkedHashSet<IBase> updateParts= sortEntriesIntoProcessingOrder(theContext, theBundle, RequestTypeEnum.PUT, partsToIBaseMap);
|
||||
LinkedHashSet<IBase> updateParts= sortEntriesOfTypeIntoProcessingOrder(theContext, RequestTypeEnum.PUT, partsToIBaseMap);
|
||||
if (updateParts == null) {
|
||||
throw new IllegalStateException("Cycle!");
|
||||
} else {
|
||||
|
@ -223,7 +228,7 @@ public class BundleUtil {
|
|||
TerserUtil.setField(theContext, "entry", theBundle, retVal.toArray(new IBase[0]));
|
||||
}
|
||||
|
||||
public static LinkedHashSet<IBase> sortEntriesIntoProcessingOrder(FhirContext theContext, IBaseBundle theBundle, RequestTypeEnum theRequestTypeEnum, Map<BundleEntryParts, IBase> thePartsToIBaseMap) {
|
||||
private static LinkedHashSet<IBase> sortEntriesOfTypeIntoProcessingOrder(FhirContext theContext, RequestTypeEnum theRequestTypeEnum, Map<BundleEntryParts, IBase> thePartsToIBaseMap) {
|
||||
SortLegality legality = new SortLegality();
|
||||
HashMap<String, Integer> color = new HashMap<>();
|
||||
HashMap<String, List<String>> adjList = new HashMap<>();
|
||||
|
@ -299,24 +304,10 @@ public class BundleUtil {
|
|||
}
|
||||
}
|
||||
|
||||
private static class SortLegality {
|
||||
private boolean myIsLegal;
|
||||
|
||||
SortLegality() {
|
||||
this.myIsLegal = true;
|
||||
}
|
||||
private void setLegal(boolean theLegal) {
|
||||
myIsLegal = theLegal;
|
||||
}
|
||||
|
||||
public boolean isLegal() {
|
||||
return myIsLegal;
|
||||
}
|
||||
}
|
||||
private static void depthFirstSearch(String theResourceId, HashMap<String, Integer> theResourceIdToColor, HashMap<String, List<String>> theAdjList, List<String> theTopologicalOrder, SortLegality theLegality) {
|
||||
System.out.println("RECURSING ON " + theResourceId);
|
||||
|
||||
if (!theLegality.isLegal()) {
|
||||
System.out.println("IMPOSSIBLE!");
|
||||
ourLog.debug("Found a cycle while trying to sort bundle entries. This bundle is not sortable.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -361,6 +352,13 @@ public class BundleUtil {
|
|||
return map;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a bundle, and a consumer, apply the consumer to each entry in the bundle.
|
||||
* @param theContext The FHIR Context
|
||||
* @param theBundle The bundle to have its entries processed.
|
||||
* @param theProcessor a {@link Consumer} which will operate on all the entries of a bundle.
|
||||
*/
|
||||
public static void processEntries(FhirContext theContext, IBaseBundle theBundle, Consumer<ModifiableBundleEntry> theProcessor) {
|
||||
RuntimeResourceDefinition bundleDef = theContext.getResourceDefinition(theBundle);
|
||||
BaseRuntimeChildDefinition entryChildDef = bundleDef.getChildByName("entry");
|
||||
|
@ -483,4 +481,20 @@ public class BundleUtil {
|
|||
}
|
||||
return isPatch;
|
||||
}
|
||||
|
||||
private static class SortLegality {
|
||||
private boolean myIsLegal;
|
||||
|
||||
SortLegality() {
|
||||
this.myIsLegal = true;
|
||||
}
|
||||
private void setLegal(boolean theLegal) {
|
||||
myIsLegal = theLegal;
|
||||
}
|
||||
|
||||
public boolean isLegal() {
|
||||
return myIsLegal;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ import ca.uhn.fhir.parser.DataFormatException;
|
|||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.LenientErrorHandler;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -1365,7 +1366,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
doCallHooks(theTransactionDetails, theRequestDetails, Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, hookParams);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
|||
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
||||
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
||||
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
|
||||
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
|
||||
import ca.uhn.fhir.rest.api.SearchContainedModeEnum;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster;
|
||||
|
@ -377,7 +378,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
doCallHooks(theTransactionDetails, theRequest, Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED, hookParams);
|
||||
}
|
||||
|
||||
|
@ -485,7 +486,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED));
|
||||
|
||||
|
||||
doCallHooks(theTransactionDetails, theRequestDetails, Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED, hookParams);
|
||||
|
@ -597,7 +598,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(RequestDetails.class, theRequest)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequest)
|
||||
.add(TransactionDetails.class, transactionDetails)
|
||||
.add(Boolean.class, transactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED));
|
||||
.add(InterceptorInvocationTimingEnum.class, transactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED));
|
||||
doCallHooks(transactionDetails, theRequest, Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED, hookParams);
|
||||
}
|
||||
});
|
||||
|
@ -697,7 +698,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED));
|
||||
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, preCommitParams);
|
||||
|
||||
}
|
||||
|
@ -742,7 +743,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
.add(RequestDetails.class, theRequestDetails)
|
||||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED));
|
||||
|
||||
myInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, preCommitParams);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import ca.uhn.fhir.interceptor.api.HookParams;
|
|||
import ca.uhn.fhir.interceptor.api.IInterceptorService;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
|
||||
import ca.uhn.fhir.rest.api.server.storage.DeferredInterceptorBroadcasts;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
|
@ -313,14 +314,14 @@ public class TransactionHookTest extends BaseJpaR4SystemTest {
|
|||
assertThat(createPointcutInvocations, hasSize(2));
|
||||
|
||||
IBaseResource firstCreatedResource = createPointcutInvocations.get(0).get(IBaseResource.class);
|
||||
boolean wasDeferred = createPointcutInvocations.get(0).get(Boolean.class);
|
||||
InterceptorInvocationTimingEnum timing = createPointcutInvocations.get(0).get(InterceptorInvocationTimingEnum.class);
|
||||
assertTrue(firstCreatedResource instanceof Observation);
|
||||
assertTrue(wasDeferred);
|
||||
assertTrue(timing.equals(InterceptorInvocationTimingEnum.DEFERRED));
|
||||
|
||||
IBaseResource secondCreatedResource = createPointcutInvocations.get(1).get(IBaseResource.class);
|
||||
wasDeferred = createPointcutInvocations.get(1).get(Boolean.class);
|
||||
timing = createPointcutInvocations.get(1).get(InterceptorInvocationTimingEnum.class);
|
||||
assertTrue(secondCreatedResource instanceof Patient);
|
||||
assertTrue(wasDeferred);
|
||||
assertTrue(timing.equals(InterceptorInvocationTimingEnum.DEFERRED));
|
||||
|
||||
assertThat(deferredInterceptorBroadcasts.get(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED), hasSize(1));
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.rest.api.server.storage;
|
|||
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
@ -195,12 +196,12 @@ public class TransactionDetails {
|
|||
myDeferredInterceptorBroadcasts.put(thePointcut, theHookParams);
|
||||
}
|
||||
|
||||
public Boolean isPointcutDeferred(Pointcut thePointcut) {
|
||||
public InterceptorInvocationTimingEnum getInvocationTiming(Pointcut thePointcut) {
|
||||
if (myDeferredInterceptorBroadcasts == null) {
|
||||
return false;
|
||||
return InterceptorInvocationTimingEnum.ACTIVE;
|
||||
}
|
||||
List<HookParams> hookParams = myDeferredInterceptorBroadcasts.get(thePointcut);
|
||||
return hookParams != null;
|
||||
return hookParams == null ? InterceptorInvocationTimingEnum.ACTIVE : InterceptorInvocationTimingEnum.DEFERRED;
|
||||
}
|
||||
|
||||
public void deferredBroadcastProcessingFinished() {
|
||||
|
|
|
@ -39,6 +39,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
|
|||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
|
||||
import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
|
||||
|
@ -400,7 +401,7 @@ public class HashMapResourceProvider<T extends IBaseResource> implements IResour
|
|||
.addIfMatchesType(ServletRequestDetails.class, theRequestDetails)
|
||||
.add(IBaseResource.class, theResource)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
interceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED, preCommitParams);
|
||||
|
||||
} else {
|
||||
|
@ -421,7 +422,7 @@ public class HashMapResourceProvider<T extends IBaseResource> implements IResour
|
|||
.add(IBaseResource.class, myIdToHistory.get(theIdPart).getFirst())
|
||||
.add(IBaseResource.class, theResource)
|
||||
.add(TransactionDetails.class, theTransactionDetails)
|
||||
.add(Boolean.class, theTransactionDetails.isPointcutDeferred(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
.add(InterceptorInvocationTimingEnum.class, theTransactionDetails.getInvocationTiming(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED));
|
||||
interceptorBroadcaster.callHooks(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED, preCommitParams);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue