Search in sources :

Example 1 with ResourceAllocationException

use of javax.jms.ResourceAllocationException in project activemq-artemis by apache.

the class AMQSession method send.

public void send(final ProducerInfo producerInfo, final Message messageSend, final boolean sendProducerAck) throws Exception {
    messageSend.setBrokerInTime(System.currentTimeMillis());
    final ActiveMQDestination destination = messageSend.getDestination();
    final ActiveMQDestination[] actualDestinations;
    final int actualDestinationsCount;
    if (destination.isComposite()) {
        actualDestinations = destination.getCompositeDestinations();
        messageSend.setOriginalDestination(destination);
        actualDestinationsCount = actualDestinations.length;
    } else {
        actualDestinations = null;
        actualDestinationsCount = 1;
    }
    final org.apache.activemq.artemis.api.core.Message originalCoreMsg = OpenWireMessageConverter.inbound(messageSend, protocolManagerWireFormat, coreMessageObjectPools);
    assert clientId.toString().equals(this.connection.getState().getInfo().getClientId()) : "Session cached clientId must be the same of the connection";
    originalCoreMsg.putStringProperty(MessageUtil.CONNECTION_ID_PROPERTY_NAME, clientId);
    /* ActiveMQ failover transport will attempt to reconnect after connection failure.  Any sent messages that did
      * not receive acks will be resent.  (ActiveMQ broker handles this by returning a last sequence id received to
      * the client).  To handle this in Artemis we use a duplicate ID cache.  To do this we check to see if the
      * message comes from failover connection.  If so we add a DUPLICATE_ID to handle duplicates after a resend. */
    if (connection.getContext().isFaultTolerant() && !messageSend.getProperties().containsKey(org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID.toString())) {
        originalCoreMsg.putStringProperty(org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID, SimpleString.toSimpleString(messageSend.getMessageId().toString()));
    }
    final boolean shouldBlockProducer = producerInfo.getWindowSize() > 0 || messageSend.isResponseRequired();
    final AtomicInteger count = actualDestinations != null ? new AtomicInteger(actualDestinationsCount) : null;
    if (shouldBlockProducer) {
        connection.getContext().setDontSendReponse(true);
    }
    for (int i = 0; i < actualDestinationsCount; i++) {
        final ActiveMQDestination dest = actualDestinations != null ? actualDestinations[i] : destination;
        final String physicalName = dest.getPhysicalName();
        final SimpleString address = SimpleString.toSimpleString(physicalName, coreMessageObjectPools.getAddressStringSimpleStringPool());
        // the last coreMsg could be directly the original one -> it avoid 1 copy if actualDestinations > 1 and ANY copy if actualDestinations == 1
        final org.apache.activemq.artemis.api.core.Message coreMsg = (i == actualDestinationsCount - 1) ? originalCoreMsg : originalCoreMsg.copy();
        coreMsg.setAddress(address);
        if (dest.isQueue()) {
            checkCachedExistingQueues(address, physicalName, dest.isTemporary());
            coreMsg.setRoutingType(RoutingType.ANYCAST);
        } else {
            coreMsg.setRoutingType(RoutingType.MULTICAST);
        }
        final PagingStore store = server.getPagingManager().getPageStore(address);
        this.connection.disableTtl();
        if (shouldBlockProducer) {
            sendShouldBlockProducer(producerInfo, messageSend, sendProducerAck, store, dest, count, coreMsg, address);
        } else {
            // non-persistent messages goes here, by default we stop reading from
            // transport
            connection.getTransportConnection().setAutoRead(false);
            if (!store.checkMemory(enableAutoReadAndTtl)) {
                enableAutoReadAndTtl();
                throw new ResourceAllocationException("Queue is full " + address);
            }
            getCoreSession().send(coreMsg, false, dest.isTemporary());
            if (count == null || count.decrementAndGet() == 0) {
                if (sendProducerAck) {
                    final ProducerAck ack = new ProducerAck(producerInfo.getProducerId(), messageSend.getSize());
                    connection.dispatchAsync(ack);
                }
            }
        }
    }
}
Also used : SimpleString(org.apache.activemq.artemis.api.core.SimpleString) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) ProducerAck(org.apache.activemq.command.ProducerAck) ActiveMQDestination(org.apache.activemq.command.ActiveMQDestination) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ResourceAllocationException(javax.jms.ResourceAllocationException) PagingStore(org.apache.activemq.artemis.core.paging.PagingStore)

Example 2 with ResourceAllocationException

use of javax.jms.ResourceAllocationException in project activemq-artemis by apache.

the class AmqpSupport method convertToException.

// ----- Utility Methods --------------------------------------------------//
/**
 * Given an ErrorCondition instance create a new Exception that best matches
 * the error type.
 *
 * @param errorCondition The ErrorCondition returned from the remote peer.
 * @return a new Exception instance that best matches the ErrorCondition value.
 */
public static Exception convertToException(ErrorCondition errorCondition) {
    Exception remoteError = null;
    if (errorCondition != null && errorCondition.getCondition() != null) {
        Symbol error = errorCondition.getCondition();
        String message = extractErrorMessage(errorCondition);
        if (error.equals(AmqpError.UNAUTHORIZED_ACCESS)) {
            remoteError = new JMSSecurityException(message);
        } else if (error.equals(AmqpError.RESOURCE_LIMIT_EXCEEDED)) {
            remoteError = new ResourceAllocationException(message);
        } else if (error.equals(AmqpError.NOT_FOUND)) {
            remoteError = new InvalidDestinationException(message);
        } else if (error.equals(TransactionErrors.TRANSACTION_ROLLBACK)) {
            remoteError = new TransactionRolledBackException(message);
        } else if (error.equals(ConnectionError.REDIRECT)) {
            remoteError = createRedirectException(error, message, errorCondition);
        } else if (error.equals(AmqpError.INVALID_FIELD)) {
            Map<?, ?> info = errorCondition.getInfo();
            if (info != null && CONTAINER_ID.equals(info.get(INVALID_FIELD))) {
                remoteError = new InvalidClientIDException(message);
            } else {
                remoteError = new JMSException(message);
            }
        } else {
            remoteError = new JMSException(message);
        }
    } else {
        remoteError = new JMSException("Unknown error from remote peer");
    }
    return remoteError;
}
Also used : Symbol(org.apache.qpid.proton.amqp.Symbol) JMSSecurityException(javax.jms.JMSSecurityException) InvalidClientIDException(javax.jms.InvalidClientIDException) InvalidDestinationException(javax.jms.InvalidDestinationException) TransactionRolledBackException(javax.jms.TransactionRolledBackException) JMSException(javax.jms.JMSException) ResourceAllocationException(javax.jms.ResourceAllocationException) Map(java.util.Map) IOException(java.io.IOException) ResourceAllocationException(javax.jms.ResourceAllocationException) InvalidClientIDException(javax.jms.InvalidClientIDException) JMSException(javax.jms.JMSException) InvalidDestinationException(javax.jms.InvalidDestinationException) JMSSecurityException(javax.jms.JMSSecurityException) TransactionRolledBackException(javax.jms.TransactionRolledBackException)

Example 3 with ResourceAllocationException

use of javax.jms.ResourceAllocationException in project activemq-artemis by apache.

the class AmqpFlowControlTest method testAddressIsBlockedForOtherProdudersWhenFull.

@Test(timeout = 60000)
public void testAddressIsBlockedForOtherProdudersWhenFull() throws Exception {
    Connection connection = createConnection();
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    Destination d = session.createQueue(getQueueName());
    MessageProducer p = session.createProducer(d);
    fillAddress(getQueueName());
    Exception e = null;
    try {
        p.send(session.createBytesMessage());
    } catch (ResourceAllocationException rae) {
        e = rae;
    }
    assertTrue(e instanceof ResourceAllocationException);
    assertTrue(e.getMessage().contains("resource-limit-exceeded"));
    long addressSize = server.getPagingManager().getPageStore(new SimpleString(getQueueName())).getAddressSize();
    assertTrue(addressSize >= MAX_SIZE_BYTES_REJECT_THRESHOLD);
}
Also used : Destination(javax.jms.Destination) Connection(javax.jms.Connection) AmqpConnection(org.apache.activemq.transport.amqp.client.AmqpConnection) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageProducer(javax.jms.MessageProducer) ResourceAllocationException(javax.jms.ResourceAllocationException) IOException(java.io.IOException) ResourceAllocationException(javax.jms.ResourceAllocationException) AmqpSession(org.apache.activemq.transport.amqp.client.AmqpSession) Session(javax.jms.Session) Test(org.junit.Test)

Example 4 with ResourceAllocationException

use of javax.jms.ResourceAllocationException in project activemq-artemis by apache.

the class AMQSession method sendShouldBlockProducer.

private void sendShouldBlockProducer(final ProducerInfo producerInfo, final Message messageSend, final boolean sendProducerAck, final PagingStore store, final ActiveMQDestination dest, final AtomicInteger count, final org.apache.activemq.artemis.api.core.Message coreMsg, final SimpleString address) throws ResourceAllocationException {
    if (!store.checkMemory(() -> {
        Exception exceptionToSend = null;
        try {
            getCoreSession().send(coreMsg, false, dest.isTemporary());
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
            exceptionToSend = e;
        }
        connection.enableTtl();
        if (count == null || count.decrementAndGet() == 0) {
            if (exceptionToSend != null) {
                this.connection.getContext().setDontSendReponse(false);
                connection.sendException(exceptionToSend);
            } else {
                server.getStorageManager().afterCompleteOperations(new IOCallback() {

                    @Override
                    public void done() {
                        if (sendProducerAck) {
                            try {
                                ProducerAck ack = new ProducerAck(producerInfo.getProducerId(), messageSend.getSize());
                                connection.dispatchAsync(ack);
                            } catch (Exception e) {
                                connection.getContext().setDontSendReponse(false);
                                ActiveMQServerLogger.LOGGER.warn(e.getMessage(), e);
                                connection.sendException(e);
                            }
                        } else {
                            connection.getContext().setDontSendReponse(false);
                            try {
                                Response response = new Response();
                                response.setCorrelationId(messageSend.getCommandId());
                                connection.dispatchAsync(response);
                            } catch (Exception e) {
                                ActiveMQServerLogger.LOGGER.warn(e.getMessage(), e);
                                connection.sendException(e);
                            }
                        }
                    }

                    @Override
                    public void onError(int errorCode, String errorMessage) {
                        try {
                            final IOException e = new IOException(errorMessage);
                            ActiveMQServerLogger.LOGGER.warn(errorMessage);
                            connection.serviceException(e);
                        } catch (Exception ex) {
                            ActiveMQServerLogger.LOGGER.debug(ex);
                        }
                    }
                });
            }
        }
    })) {
        this.connection.getContext().setDontSendReponse(false);
        connection.enableTtl();
        throw new ResourceAllocationException("Queue is full " + address);
    }
}
Also used : Response(org.apache.activemq.command.Response) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) IOException(java.io.IOException) ResourceAllocationException(javax.jms.ResourceAllocationException) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) ProducerAck(org.apache.activemq.command.ProducerAck) InvalidDestinationException(javax.jms.InvalidDestinationException) ActiveMQQueueExistsException(org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException) IOException(java.io.IOException) ResourceAllocationException(javax.jms.ResourceAllocationException)

Example 5 with ResourceAllocationException

use of javax.jms.ResourceAllocationException in project activemq-artemis by apache.

the class ProducerFlowControlSendFailTest method testPublisherRecoverAfterBlockWithSyncSend.

@Test
public void testPublisherRecoverAfterBlockWithSyncSend() throws Exception {
    ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) getConnectionFactory();
    factory.setExceptionListener(null);
    factory.setUseAsyncSend(false);
    this.flowControlConnection = (ActiveMQConnection) factory.createConnection();
    this.flowControlConnection.start();
    final Session session = this.flowControlConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    final MessageProducer producer = session.createProducer(queueA);
    final AtomicBoolean keepGoing = new AtomicBoolean(true);
    final AtomicInteger exceptionCount = new AtomicInteger(0);
    Thread thread = new Thread("Filler") {

        @Override
        public void run() {
            while (keepGoing.get()) {
                try {
                    producer.send(session.createTextMessage("Test message"));
                } catch (JMSException arg0) {
                    if (arg0 instanceof ResourceAllocationException) {
                        gotResourceException.set(true);
                        exceptionCount.incrementAndGet();
                    }
                }
            }
        }
    };
    thread.start();
    waitForBlockedOrResourceLimit(new AtomicBoolean(false));
    // resourceException on second message, resumption if we
    // can receive 10
    MessageConsumer consumer = session.createConsumer(queueA);
    TextMessage msg;
    for (int idx = 0; idx < 10; ++idx) {
        msg = (TextMessage) consumer.receive(1000);
        if (msg != null) {
            msg.acknowledge();
        }
    }
    assertTrue("we were blocked at least 5 times", 5 < exceptionCount.get());
    keepGoing.set(false);
}
Also used : ActiveMQConnectionFactory(org.apache.activemq.ActiveMQConnectionFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) MessageConsumer(javax.jms.MessageConsumer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) JMSException(javax.jms.JMSException) MessageProducer(javax.jms.MessageProducer) ResourceAllocationException(javax.jms.ResourceAllocationException) TextMessage(javax.jms.TextMessage) Session(javax.jms.Session) Test(org.junit.Test)

Aggregations

ResourceAllocationException (javax.jms.ResourceAllocationException)5 IOException (java.io.IOException)3 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 InvalidDestinationException (javax.jms.InvalidDestinationException)2 JMSException (javax.jms.JMSException)2 MessageProducer (javax.jms.MessageProducer)2 Session (javax.jms.Session)2 ProducerAck (org.apache.activemq.command.ProducerAck)2 Test (org.junit.Test)2 Map (java.util.Map)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 Connection (javax.jms.Connection)1 Destination (javax.jms.Destination)1 InvalidClientIDException (javax.jms.InvalidClientIDException)1 JMSSecurityException (javax.jms.JMSSecurityException)1 MessageConsumer (javax.jms.MessageConsumer)1 TextMessage (javax.jms.TextMessage)1 TransactionRolledBackException (javax.jms.TransactionRolledBackException)1 ActiveMQConnectionFactory (org.apache.activemq.ActiveMQConnectionFactory)1