de.otto.synapse.endpoint.InterceptorChain Maven / Gradle / Ivy
Show all versions of synapse-core Show documentation
package de.otto.synapse.endpoint;
import com.google.common.collect.ImmutableList;
import de.otto.synapse.endpoint.sender.AbstractMessageSenderEndpoint;
import de.otto.synapse.message.TextMessage;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
/**
* Implementation of the Composite pattern for {@link MessageInterceptor message interceptors} that
* can be used to build chains of interceptors.
*
* Just like any other {@link MessageInterceptor}, the InterceptorChain is used to process
* a message before it is consumed by {@link de.otto.synapse.consumer.MessageConsumer message consumers}
* on the receiver-side, or before it is sent by a {@link AbstractMessageSenderEndpoint message sender}
* to the channel infrastructure.
*
*
* The interceptors of the InterceptorChain will be called in order. The result of the first
* interceptor is propagated to the next interceptor, and so on.
*
*
* If an interceptor returns null, the chain will return null without further processing of the message.
*
*
* @see Composite Pattern
*/
public final class InterceptorChain implements MessageInterceptor {
private static final Logger LOG = getLogger(InterceptorChain.class);
private final ImmutableList interceptors;
/**
* Creates an empty InterceptorChain.
*/
public InterceptorChain() {
this.interceptors = ImmutableList.of();
}
public InterceptorChain(final ImmutableList messageInterceptors) {
this.interceptors = messageInterceptors;
}
/**
* Returns the immutable list of registered {@link MessageInterceptor message interceptors}.
*
* @return registered message interceptors
*/
public ImmutableList getInterceptors() {
return interceptors;
}
/**
* Intercepts a message using all registered interceptors and returns the resulting message.
*
* The interceptors are called in order. The result of one interceptor is propagated to the
* next interceptor in the chain, until the end of the chain is reached, or one interceptor
* has returned null.
*
*
* If {@code null} is returned, the message must be dropped by the {@link AbstractMessageEndpoint}.
*
*
* Every interceptor may transform the message, or may take additional actions like, for example,
* logging, monitoring or other things.
*
*
* @param message the message to intercept
* @return the (possibly modified) message, or null if the message should be dropped.
*/
@Nullable
public TextMessage intercept(final @Nonnull TextMessage message) {
TextMessage interceptedMessage = message;
for (final MessageInterceptor interceptor : interceptors) {
if (interceptedMessage == null) {
break;
}
interceptedMessage = interceptor.intercept(interceptedMessage);
}
if (interceptedMessage != null) {
LOG.debug("Intercepted message '{}' converted to {}", message, interceptedMessage);
} else {
LOG.debug("Intercepted message '{}' converted to - dropping message", message);
}
return interceptedMessage;
}
}