This page contains example interceptors that can be registered with the FHIR Storage module.
The following example shows an interceptor that can be used to enhance resources that are submitted for update by a client. In this example, for every time that a Patient resource is created or updated, we are calling a REST MDM service to fetch an EUID (an enterprise identifier for a Patient). We are then adding this EUID as an additional identifier on the list of patient identifiers.
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2024 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.fhirstorage;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.Patient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
import java.util.HashMap;
import java.util.Objects;
/**
* This example interceptor fetches a set of attributes from a third-party
* REST service and uses them to enhance the resource being submitted.
*/
@SuppressWarnings("unchecked")
public class ExampleAttributeEnhancingInterceptor {
private static final Logger ourLog = LoggerFactory.getLogger(ExampleAttributeEnhancingInterceptor.class);
/**
* We are going to treat creates and updates the same way in this example, so the
* create method redirects to the update method.
*/
@Hook(Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED)
public void resourcePreCreate(RequestDetails theRequest, IBaseResource theResource) {
handleResource(theResource);
}
/**
* For this example we are overriding the <code>resourcePreUpdate</code>
* method, which will be called when a resource is being updated. There
* are many other methods that can be overridden, but this one is
* appropriate for the desired functionality.
*
* @param theRequest Contains details about the incoming request. You may wish to cast this
* object to a {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails},
* which is always possible when running interceptors inside Smile CDR.
* @param theOldResource The previous version of the resource, before this update was
* requested by the client.
* @param theNewResource The new version of the resource as submitted by the client. This
* object can be modified.
*/
@Hook(Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED)
public void resourcePreUpdate(RequestDetails theRequest, IBaseResource theOldResource, IBaseResource theNewResource) {
handleResource(theNewResource);
}
private void handleResource(IBaseResource theResource) {
// This interceptor only cares about Patient resources
if (!(theResource instanceof Patient)) {
return;
}
Patient patient = (Patient) theResource;
/*
* We want to know the primary identifier, which is the first instance of
* Patient.identifier where identifier.system = "http://example.com/mrn". If the
* client has submitted a resource that does not have such an identifier, this
* is an error, and we will throw a PreconditionFailedException (HTTP 412)
*/
String primaryIdentifier = patient
.getIdentifier()
.stream()
.filter(t -> t.getSystem().equals("http://example.com/mrn"))
.map(Identifier::getValue)
.findFirst()
.orElseThrow(() -> new PreconditionFailedException("No MRN supplied with request"));
// We'll use a system property to pull the port number for this example. If the port
// number won't change across deployments you don't need to do this.
int port = Integer.parseInt(System.getProperty("mqm_query_port"));
// We're going to make a web service call to a simple web service that
// returns a JSON response. There are lots of ways of doing this, but
// in our example we'll make a call using the Spring RestTemplate
RestTemplate restTempate = new RestTemplate();
restTempate.setMessageConverters(Collections.singletonList(new GsonHttpMessageConverter()));
HashMap<String, Object> response = restTempate.getForObject("http://localhost:" + port + "/mdmquery?mrn=" + primaryIdentifier, HashMap.class);
Objects.requireNonNull(response);
// We'll log the response. Generally this isn't a good idea in a real
// production system, but it's handy for debugging at first.
ourLog.info("Response: {}", response);
// Grab the existing EUID (identifier with a system of "http://example.com/euid")
// and create one if it doesn't exist
Identifier euidIdentifier = patient
.getIdentifier()
.stream()
.filter(t -> t.getSystem().equals("http://example.com/euid"))
.findFirst()
.orElseGet(patient::addIdentifier);
// Set the identifier value using the web service response
euidIdentifier.setSystem("http://example.com/euid");
euidIdentifier.setValue((String) response.get("euid"));
}
}
The following example shows an interceptor that implements reserved tags. For this example, a reserved tag is a tag that can only be set or removed by the server itself. These tags can not be added or removed by a client, and are hidden from the client as well.
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2024 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.fhirstorage;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
/**
* This interceptor implements the concept of "reserved tags", which are resource tags (tags in
* <code>Resource.meta.tag</code>) that are reserved for internal system use. This means that:
* <ul>
* <li>Clients can not add these tags manually</li>
* <li>Reserved tags are preserved between updates of resources that have them</li>
* <li>The reserved tags are not shown to clients and are filtered before serialization</li>
* </ul>
* <p>
* The assumption with this interceptor is that there is a separate process that manages resource tags.
* This could be a second interceptor, or some other non-client-facing process.
* <p>
* Note that each of the hook methods are annotated with {@literal @Hook(..., order=100)}. The assumption
* here is that a separate interceptor is managing the reserved tags. That interceptor could use
* {@literal @Hook(..., order=101)} to ensure that it comes afterward so that it can add or remove
* the reserved tags as necessary.
*/
@SuppressWarnings("unchecked")
public class TagPreservingInterceptor {
private static final Logger ourLog = LoggerFactory.getLogger(TagPreservingInterceptor.class);
private Set<Pair> myTagsToPreserve;
/**
* Constructor
*/
public TagPreservingInterceptor() {
// This is the list of tags we want to preserve
myTagsToPreserve = Collections.unmodifiableSet(Sets.newHashSet(
Pair.of("http://my-tags", "tag1"),
Pair.of("http://my-tags", "tag2")
));
}
/**
* When a new resource is being created, don't allow the client to include any reserved tags
*
* @param theRequest Contains details about the incoming request. You may wish to cast this
* object to a {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails},
* which is always possible when running interceptors inside Smile CDR.
* @param theResource The previous resource being created
*/
@Hook(value = Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED, order = 100)
public void resourcePreCreate(RequestDetails theRequest, IBaseResource theResource) {
removeReservedTags(theResource);
}
/**
* For this example we are overriding the <code>resourcePreUpdate</code>
* method, which will be called when a resource is being updated. There
* are many other methods that can be overridden, but this one is
* appropriate for the desired functionality.
*
* @param theRequest Contains details about the incoming request. You may wish to cast this
* object to a {@link ca.uhn.fhir.rest.server.servlet.ServletRequestDetails},
* which is always possible when running interceptors inside Smile CDR.
* @param theOldResource The previous version of the resource, before this update was
* requested by the client.
* @param theNewResource The new version of the resource as submitted by the client. This
* object can be modified.
*/
@Hook(value = Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED, order = 100)
public void resourcePreUpdate(RequestDetails theRequest, IBaseResource theOldResource, IBaseResource theNewResource) {
// Filter out any reserved tags
removeReservedTags(theNewResource);
// Copy tags forward
theOldResource
.getMeta()
.getTag()
.stream()
.filter(t -> myTagsToPreserve.contains(Pair.of(t.getSystem(), t.getCode())))
.forEach(t -> theNewResource.getMeta().addTag()
.setSystem(t.getSystem())
.setCode(t.getCode())
.setDisplay(t.getDisplay()));
}
/**
* Before returning any resource to the client, strip the reserved tags
*/
@Hook(value = Pointcut.STORAGE_PRESHOW_RESOURCES)
public void preShow(IPreResourceShowDetails thePreShowDetails) {
for (IBaseResource nextResource : thePreShowDetails) {
removeReservedTags(nextResource);
}
}
private void removeReservedTags(IBaseResource theResource) {
for (Iterator<? extends IBaseCoding> iter = theResource.getMeta().getTag().iterator(); iter.hasNext(); ) {
IBaseCoding nextTag = iter.next();
String system = nextTag.getSystem();
String code = nextTag.getCode();
if (myTagsToPreserve.contains(Pair.of(system, code))) {
iter.remove();
}
}
}
}
function fhirResourcePreCreate(theRequestDetails, theResource) {
if (theResource.name[0].family === "initial-family-name") {
theResource.name[0].family = "after-pre-create";
}
}
function fhirResourceCreated(theRequestDetails, theResource) {
if (theResource.name[0].family === "after-pre-create") {
throw "the resource was created";
}
}
function fhirResourcePreUpdate(theRequestDetails, theOldResource, theNewResource) {
if (theNewResource.resourceType === 'Patient') {
if (theOldResource.name[0].family === 'old-name' && theNewResource.name[0].family === 'new-name') {
theNewResource.name[0].given[0] = 'a-given-name';
}
} else {
Log.info("Unknown resource type " + theNewResource.resourceType);
}
}
function fhirResourceUpdated(theRequestDetails, theOldResource, theNewResource) {
if (theOldResource.name[0].family === 'old-name' && theNewResource.name[0].given[0].toString() === "a-given-name") {
throw "the resource was updated";
}
}
function fhirResourcePreDelete(theRequestDetails, theResource) {
if (theResource.name[0].family === 'removed-family-name') {
theResource.name[0].given[0] = 'b-given-name';
}
}
function fhirResourceDeleted(theRequestDetails, theResource) {
if (theResource.resourceType === 'Patient') {
throw "This patient was deleted";
}
}
The following example shows an interceptor that is used to provide connection details for a FHIR Storage module configured in MegaScale mode.
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2024 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.fhirstorage;
import ca.cdr.api.fhir.interceptor.CdrHook;
import ca.cdr.api.fhir.interceptor.CdrPointcut;
import ca.cdr.api.persistence.megascale.MegaScaleCredentialRequestJson;
import ca.cdr.api.persistence.megascale.MegaScaleCredentialResponseJson;
import ca.uhn.fhir.interceptor.api.Interceptor;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.apache.commons.lang3.StringUtils;
/**
* This interceptor is invoked when initiating a request for a MegaScale
* connection for a specific partition. It returns the associated JDBC
* URL, username and password to use for that partition.
*
* Responses are cached, so this pointcut will not be repeatedly invoked
* every time a partition is accessed and this interceptor is therefore
* not considered performance critical if latency is incurred.
*/
@Interceptor
public class MegaScaleConnectionProvidingInterceptor {
@CdrHook(CdrPointcut.STORAGE_MEGASCALE_PROVIDE_DB_INFO)
public MegaScaleCredentialResponseJson provideMegaScaleCredentials(MegaScaleCredentialRequestJson theRequest) {
MegaScaleCredentialResponseJson response;
if (theRequest.getPartitionId() != 0) {
response = determinePartitionById(theRequest.getPartitionId());
} else if (!StringUtils.isBlank(theRequest.getPartitionName())){
response = determinePartitionByName(theRequest.getPartitionName());
} else {
throw new InvalidRequestException("No way to identify this partition!");
}
/*
* If any additional SQL should be executed in the database when it is
* first initialized, it may be added here. The example below shows a
* no-op query which does not do anything (and this should be removed
* in a real deployment), but you could replace this with a script that
* sets permissions or adds placeholders.
*/
response.addDatabaseInitializationStatement("SELECT 1");
return response;
}
/**
* You can elect to determine data source selection by tenant name, instead of by partition ID, if you so desire.
*/
private MegaScaleCredentialResponseJson determinePartitionByName(String partitionName) {
/*
* In this example, we'll use one connection URL for tenants "TENANT-A" & "TENANT-C", and
* a different connection URL for partitions "TENANT-B" & "TENANT-D". You can group partitions
* any way you would like.
*/
MegaScaleCredentialResponseJson retVal = new MegaScaleCredentialResponseJson();
switch (partitionName) {
case "TENANT-A":
case "TENANT-C":
setConnectionToFirstDatabase(retVal);
break;
case "TENANT-B":
case "TENANT-D":
setConnectionToSecondDatabase(retVal);
break;
default:
// Shouldn't happen, and will cause an error if it does
}
return retVal;
}
private void setConnectionToSecondDatabase(MegaScaleCredentialResponseJson retVal) {
retVal.setDatabaseUrl("jdbc:h2:mem:ds2");
retVal.setDatabaseUsername("SA");
retVal.setDatabasePassword("SA");
}
private void setConnectionToFirstDatabase(MegaScaleCredentialResponseJson retVal) {
retVal.setDatabaseUrl("jdbc:h2:mem:ds1");
retVal.setDatabaseUsername("SA");
retVal.setDatabasePassword("SA");
}
private MegaScaleCredentialResponseJson determinePartitionById(int partitionId) {
/*
* In this example, we'll use one connection URL for partitions 1 & 3, and
* a different connection URL for partitions 2 & 4. You can group partitions
* any way you would like.
*/
MegaScaleCredentialResponseJson retVal = new MegaScaleCredentialResponseJson();
switch (partitionId) {
case 1:
case 3:
setConnectionToFirstDatabase(retVal);
break;
case 2:
case 4:
setConnectionToSecondDatabase(retVal);
break;
default:
// Shouldn't happen, and will cause an error if it does
}
/*
* If any additional SQL should be executed in the database when it is
* first initialized, it may be added here. The example below shows a
* no-op query which does not do anything (and this should be removed
* in a real deployment), but you could replace this with a script that
* sets permissions or adds placeholders.
*/
retVal.addDatabaseInitializationStatement("SELECT 1");
return retVal;
}
}
The following example shows an interceptor that can be used as a starter Storage interceptor, implementing a hook method for each available pointcut.
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2024 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.fhirstorage;
import ca.cdr.api.broker.IPublicBrokerSender;
import ca.cdr.api.i18n.ILocalizer;
import ca.cdr.api.transactionlog.ITransactionLogFetchingSvc;
import ca.cdr.api.transactionlog.ITransactionLogStoringSvc;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Interceptor;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.interceptor.model.ReadPartitionIdRequestDetails;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.interceptor.model.TransactionWriteOperationsDetails;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
import ca.uhn.fhir.jpa.api.model.ResourceVersionConflictResolutionStrategy;
import ca.uhn.fhir.jpa.interceptor.validation.RepositoryValidatingRuleBuilder;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.InterceptorInvocationTimingEnum;
import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.bulk.BulkExportJobParameters;
import ca.uhn.fhir.rest.api.server.storage.DeferredInterceptorBroadcasts;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.rest.server.util.ICachedSearchDetails;
import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.validation.ValidationResult;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Sample Storage Interceptor implementing all STORAGE_XXX pointcuts.
* It is indented to be used in FHIR Storage Persistence module 'Interceptor Bean Types'.
* Can be used as a starting point for your storage interceptor.
*/
@SuppressWarnings({"unused", "EmptyTryBlock"})
@Interceptor
public class StorageInterceptorTemplate {
private static final Logger ourLog = LoggerFactory.getLogger(StorageInterceptorTemplate.class);
@Autowired
private IPublicBrokerSender myBrokerSender;
@Autowired
private ITransactionLogFetchingSvc myTransactionLogFetchingSvc;
@Autowired
private ITransactionLogStoringSvc myTransactionLogStoringSvc;
@Autowired
private ILocalizer myLocalizer;
@Autowired
private FhirContext myFhirContext;
@Autowired
private DaoRegistry myDaoRegistry;
@Autowired
private RepositoryValidatingRuleBuilder myRuleBuilder;
@Autowired
private JpaStorageSettings myStorageSettings;
@Autowired
private PlatformTransactionManager myTransactionManager;
@Hook(Pointcut.STORAGE_PRESEARCH_REGISTERED)
public void storagePreSearchRegistered(
ICachedSearchDetails theCachedSearchDetails,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
SearchParameterMap theSearchParameterMap) {
ourLog.info("Interceptor STORAGE_PRESEARCH_REGISTERED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESEARCH_REGISTERED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRECHECK_FOR_CACHED_SEARCH)
public boolean storagePreCheckForCachedSearch(
SearchParameterMap theSearchParameterMap,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PRECHECK_FOR_CACHED_SEARCH - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRECHECK_FOR_CACHED_SEARCH - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.STORAGE_PREACCESS_RESOURCES)
public void storagePreAccessResources(
IPreResourceAccessDetails thePreResourceAccessDetails,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PREACCESS_RESOURCES - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PREACCESS_RESOURCES - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESHOW_RESOURCES)
public void storagePreShowResources(
IPreResourceShowDetails thePreResourceShowDetails,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PRESHOW_RESOURCES - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESHOW_RESOURCES - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESTORAGE_RESOURCE_CREATED)
public void storagePreStorageResourceCreated(
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails,
RequestPartitionId theRequestPartitionId) {
ourLog.info("Interceptor STORAGE_PRESTORAGE_RESOURCE_CREATED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESTORAGE_RESOURCE_CREATED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED)
public void storagePreStorageResourceUpdated(
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails) {
ourLog.info("Interceptor STORAGE_PRESTORAGE_RESOURCE_UPDATED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESTORAGE_RESOURCE_UPDATED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESTORAGE_RESOURCE_DELETED)
public void storagePreStorageResourceDeleted(
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails) {
ourLog.info("Interceptor STORAGE_PRESTORAGE_RESOURCE_DELETED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESTORAGE_RESOURCE_DELETED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_CREATED)
public void storagePreCommitResourceCreated(
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails,
InterceptorInvocationTimingEnum theInterceptorInvocationTimingEnum) {
ourLog.info("Interceptor STORAGE_PRECOMMIT_RESOURCE_CREATED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRECOMMIT_RESOURCE_CREATED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_UPDATED)
public void storagePreCommitResourceUpdated(
IBaseResource thePreviousContentBaseResource,
IBaseResource theProposedBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails,
InterceptorInvocationTimingEnum theInterceptorInvocationTimingEnum) {
ourLog.info("Interceptor STORAGE_PRECOMMIT_RESOURCE_UPDATED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRECOMMIT_RESOURCE_UPDATED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRECOMMIT_RESOURCE_DELETED)
public void storagePreCommitResourceDeleted(
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails,
InterceptorInvocationTimingEnum theInterceptorInvocationTimingEnum) {
ourLog.info("Interceptor STORAGE_PRECOMMIT_RESOURCE_DELETED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRECOMMIT_RESOURCE_DELETED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESTORAGE_EXPUNGE_RESOURCE)
public void storagePreStorageExpungeResource(
AtomicInteger theAtomicInteger,
IIdType theIdType,
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PRESTORAGE_EXPUNGE_RESOURCE - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESTORAGE_EXPUNGE_RESOURCE - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING)
public void storagePartitionSelected(
AtomicInteger theAtomicInteger,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESTORAGE_EXPUNGE_EVERYTHING - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRE_DELETE_EXPUNGE_PID_LIST)
public void storagePreDeleteExpungePidList(
String theResourceType,
List<Long> theResourcePidList,
AtomicLong theAtomicLong,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PRE_DELETE_EXPUNGE_PID_LIST - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRE_DELETE_EXPUNGE_PID_LIST - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRE_DELETE_EXPUNGE)
public void storagePreDeleteExpunge(
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
String theUrl) {
ourLog.info("Interceptor STORAGE_PRE_DELETE_EXPUNGE - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRE_DELETE_EXPUNGE - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_CASCADE_DELETE)
public void storageCascadeDelete(
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
DeleteConflictList theDeleteConflictList,
IBaseResource theBaseResource) {
ourLog.info("Interceptor STORAGE_CASCADE_DELETE - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_CASCADE_DELETE - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PARTITION_IDENTIFY_CREATE)
public RequestPartitionId storagePartitionIdentifyCreate(
IBaseResource theBaseResource,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_PARTITION_IDENTIFY_CREATE - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PARTITION_IDENTIFY_CREATE - ended, execution took {}", stopWatch);
}
return null;
}
@Hook(Pointcut.STORAGE_PARTITION_IDENTIFY_READ)
public RequestPartitionId storagePartitionIdentifyRead(
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
ReadPartitionIdRequestDetails theReadPartitionIdRequestDetails) {
ourLog.info("Interceptor STORAGE_PARTITION_IDENTIFY_READ - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PARTITION_IDENTIFY_READ - ended, execution took {}", stopWatch);
}
return null;
}
@Hook(Pointcut.STORAGE_PARTITION_SELECTED)
public void storagePartitionSelected(
RequestPartitionId theRequestPartitionId,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
RuntimeResourceDefinition theRuntimeResourceDefinition) {
ourLog.info("Interceptor STORAGE_PARTITION_SELECTED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PARTITION_SELECTED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_TRANSACTION_PROCESSED)
public void storageTransactionProcessed(
IBaseBundle theBaseBundle,
DeferredInterceptorBroadcasts theDeferredInterceptorBroadcasts,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails,
TransactionDetails theTransactionDetails) {
ourLog.info("Interceptor STORAGE_TRANSACTION_PROCESSED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_TRANSACTION_PROCESSED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_INITIATE_BULK_EXPORT)
public void storageInitiateBulkExport(
BulkExportJobParameters theBulkDataExportOptions,
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_INITIATE_BULK_EXPORT - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_INITIATE_BULK_EXPORT - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_PRESTORAGE_CLIENT_ASSIGNED_ID)
public void storagePreStorageClientAssignedId(
IBaseResource theBaseResource,
RequestDetails theRequestDetails) {
ourLog.info("Interceptor STORAGE_PRESTORAGE_CLIENT_ASSIGNED_ID - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_PRESTORAGE_CLIENT_ASSIGNED_ID - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE)
public void storageTransactionWriteOperationsPre(
TransactionWriteOperationsDetails theTransactionWriteOperationsDetails,
TransactionDetails theTransactionDetails) {
ourLog.info("Interceptor STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_TRANSACTION_WRITE_OPERATIONS_PRE - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_TRANSACTION_WRITE_OPERATIONS_POST)
public void storageTransactionWriteOperationsPost(
TransactionWriteOperationsDetails theTransactionWriteOperationsDetails,
TransactionDetails theTransactionDetails) {
ourLog.info("Interceptor STORAGE_TRANSACTION_WRITE_OPERATIONS_POST - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_TRANSACTION_WRITE_OPERATIONS_POST - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.STORAGE_VERSION_CONFLICT)
public ResourceVersionConflictResolutionStrategy storageVersionConflict(
RequestDetails theRequestDetails,
ServletRequestDetails theServletRequestDetails) {
ourLog.info("Interceptor STORAGE_VERSION_CONFLICT - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor STORAGE_VERSION_CONFLICT - ended, execution took {}", stopWatch);
}
return null;
}
// should be called when repository validation is enabled
@Hook(Pointcut.VALIDATION_COMPLETED)
public ValidationResult validationCompleted(
IBaseResource theBaseResource,
String theRawBaseResource,
ValidationResult theValidationResult) {
ourLog.info("Interceptor VALIDATION_COMPLETED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
}
finally {
ourLog.info("Interceptor VALIDATION_COMPLETED - ended, execution took {}", stopWatch);
}
return null;
}
@Hook(Pointcut.INTERCEPTOR_REGISTERED)
public void interceptorRegistered() {
ourLog.info("Interceptor INTERCEPTOR_REGISTERED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor INTERCEPTOR_REGISTERED - ended, execution took {}", stopWatch);
}
}
}