Я использую ActiveMQ 5.3.0 в среде OSGi два года без каких-либо заметных проблем.
Теперь мне нужно добавить управление авторизацией для пользователей, которые публикуют / подписываются на определенные темы.
Для этой цели я разработал плагин, который реализует org.apache.activemq.security.MessageAuthorizationPolicy: в методе
public boolean isAllowedToConsume(ConnectionContext context, Message message)
где я читаю входящее сообщение, я проверяю, что текущему пользователю разрешено использовать такое сообщение, и я возвращаю true / false в соответствии с этой проверкой.
В частности, я использую текстовые сообщения (короткие фрагменты XML ...), поэтому я использую этот фрагмент для чтения текущего TextMessage:
if (message instanceof TextMessage) {
String xmlText = "";
try {
xmlText = xml.getText();
System.out.println(xmlText);
... //parse the message and check for permission...
} catch (JMSException e) {
... //manage exception
}
}
Мне кажется (но возможно я ошибаюсь !!), что этот код создает гонку с кодом, содержащимся в org.apache.activemq.openwire.v5.MessageMarshaller:
public void tightMarshal2(OpenWireFormat wireFormat, Object o, DataOutput dataOut, BooleanStream bs) throws IOException {
...
tightMarshalByteSequence2(info.getContent(), dataOut, bs); //here, info.getContent() is null!!
...
}
и фактически я получаю исключение NullPointerException со стековой трассировкой:
Exception in thread "BrokerService"
java.lang.NullPointerException
at org.apache.activemq.openwire.v5.BaseDataStreamMarshaller.tightMarshalByteSequence2(BaseDataStreamMarshaller.java:431)
at org.apache.activemq.openwire.v5.MessageMarshaller.tightMarshal2(MessageMarshaller.java:180)
at org.apache.activemq.openwire.v5.ActiveMQMessageMarshaller.tightMarshal2(ActiveMQMessageMarshaller.java:89)
at org.apache.activemq.openwire.v5.ActiveMQTextMessageMarshaller.tightMarshal2(ActiveMQTextMessageMarshaller.java:89)
at org.apache.activemq.openwire.OpenWireFormat.tightMarshalNestedObject2(OpenWireFormat.java:430)
at org.apache.activemq.openwire.v5.BaseDataStreamMarshaller.tightMarshalNestedObject2(BaseDataStreamMarshaller.java:136)
at org.apache.activemq.openwire.v5.MessageDispatchMarshaller.tightMarshal2(MessageDispatchMarshaller.java:105)
at org.apache.activemq.openwire.OpenWireFormat.marshal(OpenWireFormat.java:240)
at org.apache.activemq.transport.tcp.TcpTransport.oneway(TcpTransport.java:166)
at org.apache.activemq.transport.InactivityMonitor.oneway(InactivityMonitor.java:237)
at org.apache.activemq.transport.TransportFilter.oneway(TransportFilter.java:83)
at org.apache.activemq.transport.WireFormatNegotiator.oneway(WireFormatNegotiator.java:104)
at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40)
at org.apache.activemq.broker.TransportConnection.dispatch(TransportConnection.java:1190)
at org.apache.activemq.broker.TransportConnection.processDispatch(TransportConnection.java:779)
at org.apache.activemq.broker.TransportConnection.iterate(TransportConnection.java:815)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Теперь, если я удалю фрагмент, чтобы прочитать содержимое сообщения XML в isAllowedToConsume (...), все элементы будут возвращаться нормально, но мне нужен такой элемент управления !!!
Итак, есть ли способ правильно прочитать TextMessage, не затрагивая других потребителей?
Большое спасибо и простите за длинный вопрос !!
Bye
cghersi
Редакция 1 (@nico_ekito):
Здесь есть полный метод isAllowedToConsume ():
public boolean isAllowedToConsume(ConnectionContext context, Message message) {
String msgFrom = message.getDestination().getPhysicalName();
String textOfMsg = "";
if(message instanceof TextMessage){
TextMessage xml = (TextMessage)message;
try {
textOfMsg = xml.getText();
} catch (JMSException e) {
return false;
}
} else
return false;
//do my checks on textOfMsg returning true/false...
}