[ https://issues.apache.org/jira/browse/ARTEMIS-1545?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16294958#comment-16294958 ]
ASF GitHub Bot commented on ARTEMIS-1545: ----------------------------------------- Github user franz1981 commented on a diff in the pull request: https://github.com/apache/activemq-artemis/pull/1722#discussion_r157484426 --- Diff: artemis-core-client/src/main/java/org/apache/activemq/artemis/core/protocol/core/impl/ResponseCache.java --- @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.activemq.artemis.core.protocol.core.impl; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.activemq.artemis.api.core.ActiveMQInterruptedException; +import org.apache.activemq.artemis.core.protocol.core.Packet; +import org.apache.activemq.artemis.core.protocol.core.ResponseHandler; + +public class ResponseCache { + + private final AtomicInteger writerPointer = new AtomicInteger(0); + private final AtomicInteger sequence = new AtomicInteger(0); + + private final Packet[] store; + private ResponseHandler responseHandler; + + public ResponseCache(int size) { + this.store = new Packet[size]; + } + + public long add(Packet packet) { + int pointer = writerPointer.getAndUpdate(operand -> { + Packet p = store[operand]; + if (p != null) { + return operand; + } + packet.setCorrelationID(correlationID(operand, sequence.incrementAndGet())); + store[operand] = packet; + return operand + 1 == store.length ? 0 : operand + 1; + }); + + if (pointer(packet.getCorrelationID()) != pointer) { + throw new ActiveMQInterruptedException("unable to send due to buffer full"); + } + + return packet.getCorrelationID(); + } + + public void handleResponse(Packet response) { + long correlationID = response.getCorrelationID(); + int pointer = pointer(correlationID); + if (pointer > -1 && pointer < store.length) { + Packet p = store[pointer]; + if (p != null && p.getCorrelationID() == correlationID) { + store[pointer] = null; + } + if (responseHandler != null) { + responseHandler.responseHandler(p, response); + } + } + } + + public long correlationID(int pointer, int sequence) { --- End diff -- I would make this method static and uses `(pointer & 0xFFFF_FFFFL) << 32` to make explicit what is happing during the upcast > JMS MessageProducer fails to expose exception on send when message is sent > non-persistent, but not authorised > ------------------------------------------------------------------------------------------------------------- > > Key: ARTEMIS-1545 > URL: https://issues.apache.org/jira/browse/ARTEMIS-1545 > Project: ActiveMQ Artemis > Issue Type: Bug > Reporter: Michael Andre Pearce > > When sending persistent, behaviour is blocking and a Security exception is > thrown. The same behaviour that the client is exposed to the client when > sending non-persistent, so that a client could log or take action > asynchronously. > This can be recreated easily by the following: > Add the following security section , that means guest is not auth'd to send > to "guest.cannot.send" > activemq-artemis/tests/jms-tests/src/test/resources/broker.xml > <security-setting match="guest.cannot.send"> > <permission type="createDurableQueue" roles="guest,def"/> > <permission type="deleteDurableQueue" roles="guest,def"/> > <permission type="createNonDurableQueue" roles="guest,def"/> > <permission type="deleteNonDurableQueue" roles="guest,def"/> > <permission type="consume" roles="guest,def"/> > <permission type="browse" roles="guest,def"/> > <permission type="send" roles="def"/> > </security-setting> > Then add the following tests to this test (first is proving exception > correctly is thrown when persistent is sent using jms api, and second shows > behaviour difference and no error): > activemq-artemis/tests/jms-tests/src/test/java/org/apache/activemq/artemis/jms/tests/SecurityTest.java > /** > * Login with valid user and password > * But try send to address not authorised - Persistent > * Should not allow and should throw exception > */ > @Test > public void testLoginValidUserAndPasswordButNotAuthorisedToSend() throws > Exception { > ConnectionFactory connectionFactory = new > ActiveMQConnectionFactory("tcp://localhost:61616"); > Connection connection = connectionFactory.createConnection("guest", > "guest"); > Session session = connection.createSession(); > Destination destination = session.createQueue("guest.cannot.send"); > MessageProducer messageProducer = session.createProducer(destination); > try { > messageProducer.send(session.createTextMessage("hello")); > fail("JMSSecurityException expected as guest is not allowed to > send"); > } catch (JMSSecurityException activeMQSecurityException){ > //pass > } > connection.close(); > } > /** > * Login with valid user and password > * But try send to address not authorised - Non Persistent. > * Should have same behaviour as Persistent with exception on send. > */ > @Test > public void > testLoginValidUserAndPasswordButNotAuthorisedToSendNonPersistent() throws > Exception { > ConnectionFactory connectionFactory = new > ActiveMQConnectionFactory("tcp://localhost:61616"); > Connection connection = connectionFactory.createConnection("guest", > "guest"); > Session session = connection.createSession(); > Destination destination = session.createQueue("guest.cannot.send"); > MessageProducer messageProducer = session.createProducer(destination); > messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); > try { > messageProducer.send(session.createTextMessage("hello")); > fail("JMSSecurityException expected as guest is not allowed to > send"); > } catch (JMSSecurityException activeMQSecurityException){ > //pass > } > connection.close(); > } -- This message was sent by Atlassian JIRA (v6.4.14#64029)