Apache ActiveMQ Artemis 支持拦截器来拦截进出服务器的数据包。对于任何进入或退出服务器的数据包,都会调用传入和传出拦截器。这允许执行自定义代码,例如用于审计数据包、过滤或其他原因。拦截器可以更改它们拦截的数据包。这使得拦截器功能强大,但也可能很危险。

1. 实现拦截器

所有拦截器都是特定于协议的。

核心协议的拦截器必须实现Interceptor接口

package org.apache.activemq.artemis.api.core.interceptor;

public interface Interceptor {
   boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException;
}

对于 stomp 协议,拦截器必须实现StompFrameInterceptor接口

package org.apache.activemq.artemis.core.protocol.stomp;

public interface StompFrameInterceptor extends BaseInterceptor<StompFrame> {
   boolean intercept(StompFrame stompFrame, RemotingConnection connection);
}

同样对于 MQTT 协议,拦截器必须实现MQTTInterceptor接口

package org.apache.activemq.artemis.core.protocol.mqtt;

public interface MQTTInterceptor extends BaseInterceptor<MqttMessage> {
    boolean intercept(MqttMessage mqttMessage, RemotingConnection connection);
}

返回的布尔值很重要

  • 如果返回true,则进程正常继续

  • 如果返回false,则进程中止,不会调用其他拦截器,并且服务器不会进一步处理数据包。

2. 配置拦截器

传入和传出拦截器都在broker.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>

有关如何使您的拦截器可用于代理的说明,请参阅有关添加运行时依赖项的文档。

3. 客户端拦截器

拦截器也可以在 Apache ActiveMQ Artemis 客户端运行,以拦截客户端发送到服务器或服务器发送到客户端的数据包。这是通过使用addIncomingInterceptor(Interceptor)addOutgoingInterceptor(Interceptor)方法将拦截器添加到ServerLocator来完成的。

如上所述,如果拦截器返回false,则发送数据包将中止,这意味着不会调用其他拦截器,并且客户端不会进一步处理数据包。通常,此过程对客户端来说是透明的(即,它不知道数据包是否中止)。但是,对于以阻塞方式发送的传出数据包,将向调用者抛出ActiveMQException。抛出异常是因为阻塞发送提供可靠性,并且它们不成功被认为是错误。阻塞发送发生在,例如,应用程序在其ServerLocator上调用setBlockOnNonDurableSend(true)setBlockOnDurableSend(true),或者应用程序使用从 JNDI 获取的 JMS 连接工厂,该工厂的block-on-durable-sendblock-on-non-durable-send设置为true时。阻塞也用于处理事务的数据包(例如,提交、回滚等)。抛出的ActiveMQException将包含返回 false 的拦截器的名称。

与服务器一样,客户端拦截器类(及其依赖项)必须添加到类路径中才能正确实例化和调用。

4. 示例

以下示例展示了如何使用拦截器