Examples: Subscription
This page contains example interceptors that can be registered with Subscription.
The following interceptor can be used to add any authorization header, like Basic Auth or Bearer token, before calling a REST hook deliverer for each resource delivery message.
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2025 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.subscription;
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.jpa.subscription.model.CanonicalSubscription;
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
/**
* This class is a Hook Interceptor that is invoked immediately before REST HOOK
* deliveries. It injects a header into the subscription object at runtime, which
* is useful in cases where an Auth header is needed in subscriptions and this header
* is not known beforehand.
*/
@Interceptor
public class SubscriptionRestHookDynamicHeaderInterceptor {
/**
* The {@link Pointcut#SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY} is invoked immediately before each
* REST HOOK subscription delivery.
*
* @param theDeliveryMessage This object contains details about the subscription invocation, including
* the contents of the resource that will be delivered.
* @param theSubscription This object contains details about the subscription, including the delivery endpoint,
* headers to add, etc. A new copy of this object is created for every individual delivery
* so it is fine to modify it, and this will not affect other deliveries or
* subscriptions.
* @return Return <code>true</code> if the subscription should proceed, or <code>false</code> if it
* should be aborted.
*/
@Hook(Pointcut.SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY)
public boolean beforeRestHookDelivery(
ResourceDeliveryMessage theDeliveryMessage, CanonicalSubscription theSubscription) {
// In this example, we're just hardcoding an auth header, but we could just as easily be
// looking it up somewhere
String header = "Authorization: Bearer 1234567";
// Add the header to the subscription, so that it will be appended during delivery
theSubscription.addHeader(header);
// Delivery should proceed
return true;
}
}
The following example shows an interceptor that can be used as a starter Subscription interceptor, implementing a hook method for each available pointcut.
/*-
* #%L
* Smile CDR - CDR
* %%
* Copyright (C) 2016 - 2025 Smile CDR, Inc.
* %%
* All rights reserved.
* #L%
*/
package com.smilecdr.demo.subscription;
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.jpa.searchparam.matcher.InMemoryMatchResult;
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedJsonMessage;
import ca.uhn.fhir.jpa.subscription.model.ResourceModifiedMessage;
import ca.uhn.fhir.util.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Sample Subscription Interceptor implementing all SUBSCRIPTION_XXX pointcuts.
* It is intended to be used in Subscription module 'Interceptor Bean Types'.
* Can be used as a starting point for your subscription interceptor.
*/
@SuppressWarnings({"unused", "EmptyTryBlock"})
@Interceptor
public class SubscriptionInterceptorTemplate {
private static final Logger ourLog = LoggerFactory.getLogger(SubscriptionInterceptorTemplate.class);
@Hook(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED)
public void subscriptionAfterActiveSubscriptionRegistered(CanonicalSubscription theCanonicalSubscription) {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info(
"Interceptor SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_REGISTERED - ended, execution took {}",
stopWatch);
}
}
@Hook(Pointcut.SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_UNREGISTERED)
public void subscriptionAfterActiveSubscriptionUnregistered() {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_UNREGISTERED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info(
"Interceptor SUBSCRIPTION_AFTER_ACTIVE_SUBSCRIPTION_UNREGISTERED - ended, execution took {}",
stopWatch);
}
}
@Hook(Pointcut.SUBSCRIPTION_RESOURCE_MODIFIED)
public boolean subscriptionResourceModified(ResourceModifiedMessage theResourceModifiedMessage) {
ourLog.info("Interceptor SUBSCRIPTION_RESOURCE_MODIFIED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_RESOURCE_MODIFIED - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_RESOURCE_DID_NOT_MATCH_ANY_SUBSCRIPTIONS)
public void subscriptionResourceDidNotMatchAnySubscriptions(ResourceModifiedMessage theResourceModifiedMessage) {
ourLog.info("Interceptor SUBSCRIPTION_RESOURCE_DID_NOT_MATCH_ANY_SUBSCRIPTIONS - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info(
"Interceptor SUBSCRIPTION_RESOURCE_DID_NOT_MATCH_ANY_SUBSCRIPTIONS - ended, execution took {}",
stopWatch);
}
}
@Hook(Pointcut.SUBSCRIPTION_RESOURCE_MATCHED)
public boolean subscriptionResourceMatched(
CanonicalSubscription theCanonicalSubscription,
ResourceDeliveryMessage theResourceDeliveryMessage,
InMemoryMatchResult theInMemoryMatchResult) {
ourLog.info("Interceptor SUBSCRIPTION_RESOURCE_MATCHED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_RESOURCE_MATCHED - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_BEFORE_PERSISTED_RESOURCE_CHECKED)
public boolean subscriptionBeforePersistedResourceChecked(ResourceModifiedMessage theResourceModifiedMessage) {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_PERSISTED_RESOURCE_CHECKED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info(
"Interceptor SUBSCRIPTION_BEFORE_PERSISTED_RESOURCE_CHECKED - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED)
public void subscriptionAfterPersistedResourceChecked(ResourceModifiedMessage theResourceModifiedMessage) {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info(
"Interceptor SUBSCRIPTION_AFTER_PERSISTED_RESOURCE_CHECKED - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.SUBSCRIPTION_BEFORE_DELIVERY)
public boolean subscriptionBeforeDelivery(
CanonicalSubscription theCanonicalSubscription, ResourceDeliveryMessage theResourceDeliveryMessage) {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_DELIVERY - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_DELIVERY - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_AFTER_DELIVERY)
public void subscriptionAfterDelivery(
CanonicalSubscription theCanonicalSubscription, ResourceDeliveryMessage theResourceDeliveryMessage) {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_DELIVERY - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_DELIVERY - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.SUBSCRIPTION_AFTER_DELIVERY_FAILED)
public boolean subscriptionAfterDeliveryFailed(
ResourceDeliveryMessage theResourceDeliveryMessage, Exception theException) {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_DELIVERY_FAILED - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_DELIVERY_FAILED - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY)
public boolean subscriptionBeforeRestHookDelivery(
CanonicalSubscription theCanonicalSubscription, ResourceDeliveryMessage theResourceDeliveryMessage) {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_AFTER_REST_HOOK_DELIVERY)
public void subscriptionAfterRestHookDelivery(
CanonicalSubscription theCanonicalSubscription, ResourceDeliveryMessage theResourceDeliveryMessage) {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_REST_HOOK_DELIVERY - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_REST_HOOK_DELIVERY - ended, execution took {}", stopWatch);
}
}
@Hook(Pointcut.SUBSCRIPTION_BEFORE_MESSAGE_DELIVERY)
public boolean subscriptionBeforeMessageDelivery(
CanonicalSubscription theCanonicalSubscription,
ResourceDeliveryMessage theResourceDeliveryMessage,
ResourceModifiedJsonMessage theResourceModifiedJsonMessage) {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_MESSAGE_DELIVERY - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_BEFORE_MESSAGE_DELIVERY - ended, execution took {}", stopWatch);
}
return true;
}
@Hook(Pointcut.SUBSCRIPTION_AFTER_MESSAGE_DELIVERY)
public void subscriptionAfterMessageDelivery(
CanonicalSubscription theCanonicalSubscription, ResourceDeliveryMessage theResourceDeliveryMessage) {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_MESSAGE_DELIVERY - started");
StopWatch stopWatch = new StopWatch();
try {
// your implementation goes here
} finally {
ourLog.info("Interceptor SUBSCRIPTION_AFTER_MESSAGE_DELIVERY - ended, execution took {}", stopWatch);
}
}
}
You are about to leave the Smile Digital Health documentation and navigate to the Open Source HAPI-FHIR Documentation.