| # Intercepting Operations |
| |
| Apache ActiveMQ Artemis supports *interceptors* to intercept packets entering |
| and exiting the server. Incoming and outgoing interceptors are be called for |
| any packet entering or exiting the server respectively. This allows custom code |
| to be executed, e.g. for auditing packets, filtering or other reasons. |
| Interceptors can change the packets they intercept. This makes interceptors |
| powerful, but also potentially dangerous. |
| |
| ## Implementing The Interceptors |
| |
| All interceptors are protocol specific. |
| |
| An interceptor for the core protocol must implement the interface |
| `Interceptor`: |
| |
| ```java |
| package org.apache.activemq.artemis.api.core.interceptor; |
| |
| public interface Interceptor |
| { |
| boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException; |
| } |
| ``` |
| |
| For stomp protocol an interceptor must implement the interface `StompFrameInterceptor`: |
| |
| ```java |
| package org.apache.activemq.artemis.core.protocol.stomp; |
| |
| public interface StompFrameInterceptor extends BaseInterceptor<StompFrame> |
| { |
| boolean intercept(StompFrame stompFrame, RemotingConnection connection); |
| } |
| ``` |
| |
| Likewise for MQTT protocol, an interceptor must implement the interface |
| `MQTTInterceptor`: |
| |
| ```java |
| package org.apache.activemq.artemis.core.protocol.mqtt; |
| |
| public interface MQTTInterceptor extends BaseInterceptor<MqttMessage> |
| { |
| boolean intercept(MqttMessage mqttMessage, RemotingConnection connection); |
| } |
| ``` |
| |
| The returned boolean value is important: |
| |
| - if `true` is returned, the process continues normally |
| |
| - if `false` is returned, the process is aborted, no other interceptors will be |
| called and the packet will not be processed further by the server. |
| |
| ## Configuring The Interceptors |
| |
| Both incoming and outgoing interceptors are configured in `broker.xml`: |
| |
| ```xml |
| <remoting-incoming-interceptors> |
| <class-name>org.apache.activemq.artemis.jms.example.LoginInterceptor</class-name> |
| <class-name>org.apache.activemq.artemis.jms.example.AdditionalPropertyInterceptor</class-name> |
| </remoting-incoming-interceptors> |
| |
| <remoting-outgoing-interceptors> |
| <class-name>org.apache.activemq.artemis.jms.example.LogoutInterceptor</class-name> |
| <class-name>org.apache.activemq.artemis.jms.example.AdditionalPropertyInterceptor</class-name> |
| </remoting-outgoing-interceptors> |
| ``` |
| |
| See the documentation on [adding runtime dependencies](using-server.md) to |
| understand how to make your interceptor available to the broker. |
| |
| ## Interceptors on the Client Side |
| |
| The interceptors can also be run on the Apache ActiveMQ Artemis client side to |
| intercept packets either sent by the client to the server or by the server to |
| the client. This is done by adding the interceptor to the `ServerLocator` with |
| the `addIncomingInterceptor(Interceptor)` or |
| `addOutgoingInterceptor(Interceptor)` methods. |
| |
| As noted above, if an interceptor returns `false` then the sending of the |
| packet is aborted which means that no other interceptors are be called and the |
| packet is not be processed further by the client. Typically this process |
| happens transparently to the client (i.e. it has no idea if a packet was |
| aborted or not). However, in the case of an outgoing packet that is sent in a |
| `blocking` fashion a `ActiveMQException` will be thrown to the caller. The |
| exception is thrown because blocking sends provide reliability and it is |
| considered an error for them not to succeed. `Blocking` sends occurs when, for |
| example, an application invokes `setBlockOnNonDurableSend(true)` or |
| `setBlockOnDurableSend(true)` on its `ServerLocator` or if an application is |
| using a JMS connection factory retrieved from JNDI that has either |
| `block-on-durable-send` or `block-on-non-durable-send` set to `true`. Blocking |
| is also used for packets dealing with transactions (e.g. commit, roll-back, |
| etc.). The `ActiveMQException` thrown will contain the name of the interceptor |
| that returned false. |
| |
| As on the server, the client interceptor classes (and their dependencies) must |
| be added to the classpath to be properly instantiated and invoked. |
| |
| ## Examples |
| |
| See the following examples which show how to use interceptors: |
| |
| - [Interceptor](examples.md#interceptor) |
| - [Interceptor AMQP](examples.md#interceptor-amqp) |
| - [Interceptor Client](examples.md#interceptor-client) |
| - [Interceptor MQTT](examples.md#interceptor-mqtt) |