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-send
或block-on-non-durable-send
设置为true
时。阻塞也用于处理事务的数据包(例如,提交、回滚等)。抛出的ActiveMQException
将包含返回 false 的拦截器的名称。
与服务器一样,客户端拦截器类(及其依赖项)必须添加到类路径中才能正确实例化和调用。