/**
   * Determines if redelivery is enabled by checking if any of the redelivery policy settings may
   * allow redeliveries.
   *
   * @return <tt>true</tt> if redelivery is possible, <tt>false</tt> otherwise
   * @throws Exception can be thrown
   */
  private boolean determineIfRedeliveryIsEnabled() throws Exception {
    // determine if redeliver is enabled either on error handler
    if (getRedeliveryPolicy().getMaximumRedeliveries() != 0) {
      // must check for != 0 as (-1 means redeliver forever)
      return true;
    }
    if (retryWhilePolicy != null) {
      return true;
    }

    // or on the exception policies
    if (!exceptionPolicies.isEmpty()) {
      // walk them to see if any of them have a maximum redeliveries > 0 or retry until set
      for (OnExceptionDefinition def : exceptionPolicies.values()) {

        if (def.getRedeliveryPolicy() != null) {
          String ref = def.getRedeliveryPolicyRef();
          if (ref != null) {
            // lookup in registry if ref provided
            RedeliveryPolicy policy =
                CamelContextHelper.mandatoryLookup(camelContext, ref, RedeliveryPolicy.class);
            if (policy.getMaximumRedeliveries() != 0) {
              // must check for != 0 as (-1 means redeliver forever)
              return true;
            }
          } else {
            Integer max =
                CamelContextHelper.parseInteger(
                    camelContext, def.getRedeliveryPolicy().getMaximumRedeliveries());
            if (max != null && max != 0) {
              // must check for != 0 as (-1 means redeliver forever)
              return true;
            }
          }
        }

        if (def.getRetryWhilePolicy() != null || def.getRetryWhile() != null) {
          return true;
        }
      }
    }

    return false;
  }
  public void doTestDLQAfterBlock(ActiveMQDestination destination) throws Exception {
    ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) createConnectionFactory();
    RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
    // Immediately sent to the DLQ on rollback, no redelivery
    redeliveryPolicy.setMaximumRedeliveries(0);
    factory.setRedeliveryPolicy(redeliveryPolicy);

    // Separate connection for consumer so it will not be blocked by filler thread
    // sending when it blocks
    connection = (ActiveMQConnection) factory.createConnection();
    connections.add(connection);
    connection.setClientID("someId");
    connection.start();

    final Session consumerSession = connection.createSession(true, Session.SESSION_TRANSACTED);
    MessageConsumer consumer =
        destination.isQueue()
            ? consumerSession.createConsumer(destination)
            : consumerSession.createDurableSubscriber((Topic) destination, "Durable");

    connection = (ActiveMQConnection) factory.createConnection();
    connections.add(connection);
    connection.start();

    final Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
    final MessageProducer producer = session.createProducer(destination);

    final AtomicBoolean done = new AtomicBoolean(true);
    final AtomicBoolean keepGoing = new AtomicBoolean(true);
    final CountDownLatch fillerStarted = new CountDownLatch(1);

    final AtomicLong sent = new AtomicLong(0);
    Thread thread =
        new Thread("Filler") {
          int i;

          @Override
          public void run() {
            while (keepGoing.get()) {
              done.set(false);
              fillerStarted.countDown();
              try {
                producer.send(session.createTextMessage(oneKb + ++i));
                if (i % 10 == 0) {
                  session.commit();
                  sent.getAndAdd(10);
                  LOG.info("committed/sent: " + sent.get());
                }
                LOG.info("sent: " + i);
              } catch (JMSException e) {
              }
            }
          }
        };
    thread.start();

    assertTrue("filler started..", fillerStarted.await(20, TimeUnit.SECONDS));
    waitForBlocked(done);

    // consume and rollback some so message gets to DLQ
    connection = (ActiveMQConnection) factory.createConnection();
    connections.add(connection);
    connection.start();
    TextMessage msg;
    int received = 0;
    for (; received < sent.get(); ++received) {
      msg = (TextMessage) consumer.receive(4000);
      if (msg == null) {
        LOG.info("received null on count: " + received);
        break;
      }
      LOG.info("received: " + received + ", msg: " + msg.getJMSMessageID());
      if (received % 5 == 0) {
        if (received % 3 == 0) {
          // force the use of the DLQ which will use some more store
          LOG.info("rollback on : " + received);
          consumerSession.rollback();
        } else {
          LOG.info("commit on : " + received);
          consumerSession.commit();
        }
      }
    }
    LOG.info("Done:: sent: " + sent.get() + ", received: " + received);
    keepGoing.set(false);
    assertTrue("some were sent:", sent.get() > 0);
    assertEquals("received what was committed", sent.get(), received);
  }