org.apache.qpid.proton.amqp.messaging.Released Java Examples

The following examples show how to use org.apache.qpid.proton.amqp.messaging.Released. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AmqpConsumer.java    From qpid-jms with Apache License 2.0 6 votes vote down vote up
private void releasePrefetch() {
    Delivery delivery = getEndpoint().head();

    while (delivery != null) {
        Delivery current = delivery;
        delivery = delivery.next();

        if (current.getContext() instanceof JmsInboundMessageDispatch) {
            JmsInboundMessageDispatch envelope = (JmsInboundMessageDispatch) current.getContext();
            if (!envelope.isDelivered()) {
                handleDisposition(envelope, current, Released.getInstance());
            }
        } else {
            LOG.debug("{} Found incomplete delivery with no context during release processing", AmqpConsumer.this);
        }
    }
}
 
Example #2
Source File: MappingAndDelegatingCommandHandlerTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies the behaviour of the <em>mapAndDelegateIncomingCommandMessage</em> method in a scenario where
 * no command handling adapter instance is found for the command message device.
 */
@Test
public void testMapWithNoAdapterInstanceFound() {
    final String deviceId = "4711";

    // GIVEN no registered commandHandler for the deviceId
    // but a deviceId commandHandler registered for the local adapter instance
    when(commandTargetMapper.getTargetGatewayAndAdapterInstance(anyString(), anyString(), any()))
            .thenReturn(Future.succeededFuture(createTargetAdapterInstanceJson(deviceId, adapterInstanceId)));

    // WHEN mapping and delegating a command message
    final Message message = getValidCommandMessage(deviceId);
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    mappingAndDelegatingCommandHandler.mapAndDelegateIncomingCommandMessage(Constants.DEFAULT_TENANT, delivery, message);

    // THEN the disposition is RELEASED
    verify(delivery).disposition(any(Released.class), eq(true));
}
 
Example #3
Source File: MappingAndDelegatingCommandHandlerTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies the behaviour of the <em>mapAndDelegateIncomingCommandMessage</em> method in a scenario where
 * the command handler is not found.
 */
@Test
public void testMapWithCommandHandlerNotFound() {
    final String deviceId = "4711";

    // GIVEN a 'NOT_FOUND' error when looking up the adapter instance
    when(commandTargetMapper.getTargetGatewayAndAdapterInstance(anyString(), anyString(), any()))
            .thenReturn(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND)));

    // WHEN mapping and delegating a command message
    final Message message = getValidCommandMessage(deviceId);
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    mappingAndDelegatingCommandHandler.mapAndDelegateIncomingCommandMessage(Constants.DEFAULT_TENANT, delivery, message);

    // THEN the disposition is RELEASED
    verify(delivery).disposition(any(Released.class), eq(true));
}
 
Example #4
Source File: MappingAndDelegatingCommandHandlerTest.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Verifies the behaviour of the <em>mapAndDelegateIncomingCommandMessage</em> method in a scenario where
 * the command shall get handled by another adapter instance and where sending the command message to
 * the adapter instance fails.
 */
@Test
public void testMapWithCommandHandlerOnAnotherInstanceWithMessageSendingFailed() {
    final String deviceId = "4711";

    // GIVEN a deviceId commandHandler registered for another adapter instance (not the local one)
    final String otherAdapterInstance = "otherAdapterInstance";
    when(commandTargetMapper.getTargetGatewayAndAdapterInstance(anyString(), anyString(), any()))
            .thenReturn(Future.succeededFuture(createTargetAdapterInstanceJson(deviceId, otherAdapterInstance)));

    // AND an error when sending the command message to another adapter instance (no credit)
    when(sender.sendQueueFull()).thenReturn(Boolean.TRUE);

    // register local command handler - that shall not get used
    final AtomicReference<CommandContext> localHandlerCmdContextRef = new AtomicReference<>();
    adapterInstanceCommandHandler.putDeviceSpecificCommandHandler(Constants.DEFAULT_TENANT, deviceId, null, localHandlerCmdContextRef::set);

    // WHEN mapping and delegating the command message
    final Message message = getValidCommandMessage(deviceId);
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    mappingAndDelegatingCommandHandler.mapAndDelegateIncomingCommandMessage(Constants.DEFAULT_TENANT, delivery, message);

    // THEN the delivery gets RELEASED
    verify(delivery).disposition(any(Released.class), eq(true));
    assertThat(localHandlerCmdContextRef.get()).isNull();
}
 
Example #5
Source File: AmqpTransactionCoordinatorBuilder.java    From qpid-jms with Apache License 2.0 6 votes vote down vote up
@Override
protected Sender createEndpoint(JmsSessionInfo resourceInfo) {
    Coordinator coordinator = new Coordinator();
    coordinator.setCapabilities(TxnCapability.LOCAL_TXN);

    Symbol[] outcomes = new Symbol[]{ Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL, Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL };

    Source source = new Source();
    source.setOutcomes(outcomes);

    String coordinatorName = "qpid-jms:coordinator:" + resourceInfo.getId().toString();

    Sender sender = getParent().getSession().getEndpoint().sender(coordinatorName);
    sender.setSource(source);
    sender.setTarget(coordinator);
    sender.setSenderSettleMode(SenderSettleMode.UNSETTLED);
    sender.setReceiverSettleMode(ReceiverSettleMode.FIRST);

    return sender;
}
 
Example #6
Source File: GenericMessageSenderImpl.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Sends an AMQP 1.0 message to the peer this client is configured for
 * and waits for the outcome of the transfer.
 *
 * @param message The message to send.
 * @return A future indicating the outcome of transferring the message.
 *         <p>
 *         The future will succeed with the updated delivery from the peer if
 *         the message has been settled with the <em>accepted</em> outcome.
 *         <p>
 *         The future will be failed with a {@link ServerErrorException} if the
 *         message could not be sent, e.g. due to a lack of credit. It will be
 *         failed with a {@link ClientErrorException} if the message has not
 *         been accepted by the peer.
 * @throws NullPointerException if the message is {@code null}.
 */
@Override
public Future<ProtonDelivery> sendAndWaitForOutcome(final Message message) {
    return connection.executeOnContext(result -> {
        if (sender.isOpen() && sender.getCredit() > 0) {
            sender.send(message, updatedDelivery -> {
                if (updatedDelivery.getRemoteState() instanceof Accepted) {
                    result.complete(updatedDelivery);
                } else if (updatedDelivery.getRemoteState() instanceof Released) {
                    result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE));
                } else {
                    result.fail(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
                }
            });
        } else {
            result.fail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE));
        }
    });
}
 
Example #7
Source File: AbstractSender.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Creates a log entry in the given span with information about the message delivery outcome given in the delivery
 * parameter. Sets the {@link Tags#HTTP_STATUS} as well.
 * <p>
 * Also corresponding log output is created.
 *
 * @param currentSpan The current span to log to.
 * @param message The message.
 * @param delivery The updated delivery.
 * @throws NullPointerException if any of the parameters is {@code null}.
 */
protected final void logUpdatedDeliveryState(final Span currentSpan, final Message message, final ProtonDelivery delivery) {
    Objects.requireNonNull(currentSpan);
    final String messageId = message.getMessageId() != null ? message.getMessageId().toString() : "";
    final String messageAddress = getMessageAddress(message);
    final DeliveryState remoteState = delivery.getRemoteState();
    if (Accepted.class.isInstance(remoteState)) {
        log.trace("message [ID: {}, address: {}] accepted by peer", messageId, messageAddress);
        currentSpan.log("message accepted by peer");
        Tags.HTTP_STATUS.set(currentSpan, HttpURLConnection.HTTP_ACCEPTED);
    } else {
        final Map<String, Object> events = new HashMap<>();
        if (Rejected.class.isInstance(remoteState)) {
            final Rejected rejected = (Rejected) delivery.getRemoteState();
            Tags.HTTP_STATUS.set(currentSpan, HttpURLConnection.HTTP_BAD_REQUEST);
            if (rejected.getError() == null) {
                logMessageSendingError("message [ID: {}, address: {}] rejected by peer", messageId, messageAddress);
                events.put(Fields.MESSAGE, "message rejected by peer");
            } else {
                logMessageSendingError("message [ID: {}, address: {}] rejected by peer: {}, {}", messageId,
                        messageAddress, rejected.getError().getCondition(), rejected.getError().getDescription());
                events.put(Fields.MESSAGE, String.format("message rejected by peer: %s, %s",
                        rejected.getError().getCondition(), rejected.getError().getDescription()));
            }
        } else if (Released.class.isInstance(remoteState)) {
            logMessageSendingError("message [ID: {}, address: {}] not accepted by peer, remote state: {}",
                    messageId, messageAddress, remoteState.getClass().getSimpleName());
            Tags.HTTP_STATUS.set(currentSpan, HttpURLConnection.HTTP_UNAVAILABLE);
            events.put(Fields.MESSAGE, "message not accepted by peer, remote state: " + remoteState);
        } else if (Modified.class.isInstance(remoteState)) {
            final Modified modified = (Modified) delivery.getRemoteState();
            logMessageSendingError("message [ID: {}, address: {}] not accepted by peer, remote state: {}",
                    messageId, messageAddress, modified);
            Tags.HTTP_STATUS.set(currentSpan, modified.getUndeliverableHere() ? HttpURLConnection.HTTP_NOT_FOUND
                    : HttpURLConnection.HTTP_UNAVAILABLE);
            events.put(Fields.MESSAGE, "message not accepted by peer, remote state: " + remoteState);
        }
        TracingHelper.logError(currentSpan, events);
    }
}
 
Example #8
Source File: SessionIntegrationTest.java    From qpid-jms with Apache License 2.0 5 votes vote down vote up
@Test(timeout = 20000)
public void testCreateProducerLinkSupportedSourceOutcomes() throws Exception {
    try (TestAmqpPeer testPeer = new TestAmqpPeer();) {
        Connection connection = testFixture.establishConnecton(testPeer);
        testPeer.expectBegin();

        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        String queueName = "myQueue";

        SourceMatcher sourceMatcher = new SourceMatcher();
        sourceMatcher.withOutcomes(arrayContaining(Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL, Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL));
        //TODO: what default outcome for producers?
        //Accepted normally, Rejected for transaction controller?
        //sourceMatcher.withDefaultOutcome(outcomeMatcher);

        TargetMatcher targetMatcher = new TargetMatcher();
        targetMatcher.withAddress(equalTo(queueName));

        testPeer.expectSenderAttach(sourceMatcher, targetMatcher, false, false);
        testPeer.expectClose();

        Queue queue = session.createQueue(queueName);
        session.createProducer(queue);

        connection.close();

        testPeer.waitForAllHandlersToComplete(1000);
    }
}
 
Example #9
Source File: AmqpConsumer.java    From qpid-jms with Apache License 2.0 5 votes vote down vote up
@Override
public void processDeliveryUpdates(AmqpProvider provider, Delivery delivery) throws ProviderException {
    if(delivery.getDefaultDeliveryState() == null){
        delivery.setDefaultDeliveryState(Released.getInstance());
    }

    if (delivery.isReadable() && !delivery.isPartial()) {
        LOG.trace("{} has incoming Message(s).", this);
        try {
            if (processDelivery(delivery)) {
                // We processed a message, signal completion
                // of a message pull request if there is one.
                if (pullRequest != null) {
                    pullRequest.onSuccess();
                    pullRequest = null;
                }
            }
        } catch (Exception e) {
            throw ProviderExceptionSupport.createNonFatalOrPassthrough(e);
        }
    }

    if (getEndpoint().current() == null) {
        // We have exhausted the locally queued messages on this link.
        // Check if we tried to stop and have now run out of credit.
        if (getEndpoint().getRemoteCredit() <= 0) {
            if (stopRequest != null) {
                stopRequest.onSuccess();
                stopRequest = null;
            }
        }
    }

    super.processDeliveryUpdates(provider, delivery);
}
 
Example #10
Source File: AmqpProducerBuilder.java    From qpid-jms with Apache License 2.0 5 votes vote down vote up
@Override
protected Sender createEndpoint(JmsProducerInfo resourceInfo) {
    JmsDestination destination = resourceInfo.getDestination();
    AmqpConnection connection = getParent().getConnection();

    String targetAddress = AmqpDestinationHelper.getDestinationAddress(destination, connection);

    Symbol[] outcomes = new Symbol[]{ Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL, Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL };
    String sourceAddress = resourceInfo.getId().toString();
    Source source = new Source();
    source.setAddress(sourceAddress);
    source.setOutcomes(outcomes);
    // TODO: default outcome. Accepted normally, Rejected for transaction controller?

    Target target = new Target();
    target.setAddress(targetAddress);
    Symbol typeCapability =  AmqpDestinationHelper.toTypeCapability(destination);
    if (typeCapability != null) {
        target.setCapabilities(typeCapability);
    }

    String senderName = "qpid-jms:sender:" + sourceAddress + ":" + targetAddress;

    Sender sender = getParent().getEndpoint().sender(senderName);
    sender.setSource(source);
    sender.setTarget(target);
    if (resourceInfo.isPresettle()) {
        sender.setSenderSettleMode(SenderSettleMode.SETTLED);
    } else {
        sender.setSenderSettleMode(SenderSettleMode.UNSETTLED);
    }
    sender.setReceiverSettleMode(ReceiverSettleMode.FIRST);

    if (!connection.getProperties().isDelayedDeliverySupported()) {
        validateDelayedDeliveryLinkCapability = true;
        sender.setDesiredCapabilities(new Symbol[] { AmqpSupport.DELAYED_DELIVERY });
    }

    return sender;
}
 
Example #11
Source File: ProtonSessionImpl.java    From vertx-proton with Apache License 2.0 5 votes vote down vote up
@Override
public ProtonSender createSender(String address, ProtonLinkOptions senderOptions) {
  Sender sender = session.sender(getOrCreateLinkName(senderOptions));

  Symbol[] outcomes = new Symbol[] { Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL,
      Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL };
  Source source = new Source();
  source.setOutcomes(outcomes);

  Target target = new Target();
  target.setAddress(address);
  if(senderOptions.isDynamic()) {
    target.setDynamic(true);
  }

  sender.setSource(source);
  sender.setTarget(target);

  ProtonSenderImpl s = new ProtonSenderImpl(sender);
  if (address == null) {
    s.setAnonymousSender(true);
  }

  s.openHandler((result) -> {
    LOG.trace("Sender open completed");
  });
  s.closeHandler((result) -> {
    if (result.succeeded()) {
      LOG.trace("Sender closed");
    } else {
      LOG.warn("Sender closed with error", result.cause());
    }
  });

  // Default to at-least-once
  s.setQoS(ProtonQoS.AT_LEAST_ONCE);

  return s;
}
 
Example #12
Source File: ProtonSessionImpl.java    From vertx-proton with Apache License 2.0 5 votes vote down vote up
@Override
public ProtonReceiver createReceiver(String address, ProtonLinkOptions receiverOptions) {
  Receiver receiver = session.receiver(getOrCreateLinkName(receiverOptions));

  Symbol[] outcomes = new Symbol[] { Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL,
      Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL };

  Source source = new Source();
  source.setAddress(address);
  source.setOutcomes(outcomes);
  source.setDefaultOutcome(Released.getInstance());
  if(receiverOptions.isDynamic()) {
    source.setDynamic(true);
  }

  Target target = new Target();

  receiver.setSource(source);
  receiver.setTarget(target);

  ProtonReceiverImpl r = new ProtonReceiverImpl(receiver);
  r.openHandler((result) -> {
    LOG.trace("Receiver open completed");
  });
  r.closeHandler((result) -> {
    if (result.succeeded()) {
      LOG.trace("Receiver closed");
    } else {
      LOG.warn("Receiver closed with error", result.cause());
    }
  });

  // Default to at-least-once
  r.setQoS(ProtonQoS.AT_LEAST_ONCE);

  return r;
}
 
Example #13
Source File: AmqpReceiver.java    From activemq-artemis with Apache License 2.0 5 votes vote down vote up
protected void configureSource(Source source) {
   Map<Symbol, DescribedType> filters = new HashMap<>();
   Symbol[] outcomes = new Symbol[] {Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL, Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL};

   if (getSubscriptionName() != null && !getSubscriptionName().isEmpty()) {
      source.setExpiryPolicy(TerminusExpiryPolicy.NEVER);
      source.setDurable(TerminusDurability.UNSETTLED_STATE);
      source.setDistributionMode(COPY);
   } else {
      source.setDurable(TerminusDurability.NONE);
      source.setExpiryPolicy(TerminusExpiryPolicy.LINK_DETACH);
   }

   source.setOutcomes(outcomes);

   Modified modified = new Modified();
   modified.setDeliveryFailed(true);
   modified.setUndeliverableHere(false);

   source.setDefaultOutcome(modified);

   if (isNoLocal()) {
      filters.put(NO_LOCAL_NAME, AmqpNoLocalFilter.NO_LOCAL);
   }

   if (getSelector() != null && !getSelector().trim().equals("")) {
      filters.put(JMS_SELECTOR_NAME, new AmqpJmsSelectorFilter(getSelector()));
   }

   if (!filters.isEmpty()) {
      source.setFilter(filters);
   }
}
 
Example #14
Source File: AmqpReceiver.java    From activemq-artemis with Apache License 2.0 5 votes vote down vote up
/**
 * Release a message that was dispatched under the given Delivery instance.
 *
 * @param delivery
 *        the Delivery instance to release.
 * @throws IOException
 *         if an error occurs while sending the release.
 */
public void release(final Delivery delivery) throws IOException {
   checkClosed();

   if (delivery == null) {
      throw new IllegalArgumentException("Delivery to release cannot be null");
   }

   final ClientFuture request = new ClientFuture();
   session.getScheduler().execute(new Runnable() {

      @Override
      public void run() {
         checkClosed();
         try {
            if (!delivery.isSettled()) {
               delivery.disposition(Released.getInstance());
               delivery.settle();
               session.pumpToProtonTransport(request);
            }
            request.onSuccess();
         } catch (Exception e) {
            request.onFailure(e);
         }
      }
   });

   request.sync();
}
 
Example #15
Source File: FastPathDispositionType.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
private byte deduceEncodingCode(Disposition value, int elementCount) {
    if (value.getState() == null) {
        return EncodingCodes.LIST8;
    } else if (value.getState() == Accepted.getInstance() || value.getState() == Released.getInstance()) {
        return EncodingCodes.LIST8;
    } else {
        return EncodingCodes.LIST32;
    }
}
 
Example #16
Source File: VertxBasedAmqpProtocolAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the adapter closes the link for sending commands to a device when no
 * delivery update is received after a certain amount of time.
 */
@SuppressWarnings("unchecked")
@Test
public void testLinkForSendingCommandsCloseAfterTimeout() {
    // GIVEN an AMQP adapter
    final VertxBasedAmqpProtocolAdapter adapter = givenAnAmqpAdapter();
    // to which a device is connected
    final ProtonSender deviceLink = mock(ProtonSender.class);
    when(deviceLink.getQoS()).thenReturn(ProtonQoS.AT_LEAST_ONCE);
    // that has subscribed to commands
    final TenantObject tenantObject = givenAConfiguredTenant(TEST_TENANT_ID, true);

    // WHEN an application sends a one-way command to the device
    final ProtonDelivery commandDelivery = mock(ProtonDelivery.class);
    final String commandAddress = String.format("%s/%s/%s", getCommandEndpoint(), TEST_TENANT_ID, TEST_DEVICE);
    final Buffer payload = Buffer.buffer("payload");
    final Message message = getFakeMessage(commandAddress, payload, "commandToExecute");
    final Command command = Command.from(message, TEST_TENANT_ID, TEST_DEVICE);
    final CommandContext context = CommandContext.from(command, commandDelivery, mock(Span.class));
    final ProtocolAdapterCommandConsumer commandConsumer = mock(ProtocolAdapterCommandConsumer.class);
    when(commandConsumer.close(any())).thenReturn(Future.succeededFuture());

    // AND no delivery update is received from the device after sometime
    doAnswer(invocation -> {
        final Handler<Long> task =  invocation.getArgument(1);
        task.handle(1L);
        return 1L;
    }).when(vertx).setTimer(anyLong(), any(Handler.class));

    adapter.onCommandReceived(tenantObject, deviceLink, context);
    // THEN the adapter notifies the application by sending back a RELEASED disposition
    verify(commandDelivery).disposition(any(Released.class), eq(true));
}
 
Example #17
Source File: VertxBasedAmqpProtocolAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the adapter signals a released one-way command
 * back to the sender of the command.
 */
@Test
public void testOneWayCommandUnsettled() {

    final DeliveryState remoteState = mock(DeliveryState.class);
    final ProtonDelivery unsuccessfulDelivery = mock(ProtonDelivery.class);
    when(unsuccessfulDelivery.remotelySettled()).thenReturn(false);
    when(unsuccessfulDelivery.getRemoteState()).thenReturn(remoteState);
    testOneWayCommandOutcome(unsuccessfulDelivery, Released.class, ProcessingOutcome.UNDELIVERABLE);
}
 
Example #18
Source File: VertxBasedAmqpProtocolAdapterTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Verifies that the adapter signals a released one-way command
 * back to the sender of the command.
 */
@Test
public void testOneWayCommandReleased() {

    final DeliveryState remoteState = new Released();
    final ProtonDelivery unsuccessfulDelivery = mock(ProtonDelivery.class);
    when(unsuccessfulDelivery.remotelySettled()).thenReturn(true);
    when(unsuccessfulDelivery.getRemoteState()).thenReturn(remoteState);
    testOneWayCommandOutcome(unsuccessfulDelivery, Released.class, ProcessingOutcome.UNDELIVERABLE);
}
 
Example #19
Source File: AdapterInstanceCommandHandlerTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
@Test
void testHandleCommandMessageWithNoHandlerFound() {
    final Message msg = mock(Message.class);
    final String deviceId = "4711";
    when(msg.getAddress()).thenReturn(String.format("%s/%s/%s",
            CommandConstants.COMMAND_ENDPOINT, Constants.DEFAULT_TENANT, deviceId));
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    adapterInstanceCommandHandler.handleCommandMessage(msg, delivery);

    final ArgumentCaptor<DeliveryState> deliveryStateCaptor = ArgumentCaptor.forClass(DeliveryState.class);
    verify(delivery).disposition(deliveryStateCaptor.capture(), anyBoolean());
    assertThat(deliveryStateCaptor.getValue()).isNotNull();
    assertThat(deliveryStateCaptor.getValue()).isInstanceOf(Released.class);
}
 
Example #20
Source File: CommandContext.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Settles the command message with the given {@code DeliveryState} outcome.
 * <p>
 * This method also finishes the OpenTracing span returned by
 * {@link #getCurrentSpan()}.
 *
 * @param deliveryState The deliveryState to set in the disposition frame.
 * @throws NullPointerException if deliveryState is {@code null}.
 */
public void disposition(final DeliveryState deliveryState) {

    Objects.requireNonNull(deliveryState);
    delivery.disposition(deliveryState, true);
    if (Accepted.class.isInstance(deliveryState)) {
        LOG.trace("accepted command message [{}]", getCommand());
        currentSpan.log("accepted command for device");

    } else if (Released.class.isInstance(deliveryState)) {
        LOG.debug("released command message [{}]", getCommand());
        TracingHelper.logError(currentSpan, "released command for device");

    } else if (Modified.class.isInstance(deliveryState)) {
        final Modified modified = (Modified) deliveryState;
        LOG.debug("modified command message [{}]", getCommand());
        TracingHelper.logError(currentSpan, "modified command for device"
                + (Boolean.TRUE.equals(modified.getDeliveryFailed()) ? "; delivery failed" : "")
                + (Boolean.TRUE.equals(modified.getUndeliverableHere()) ? "; undeliverable here" : ""));

    } else if (Rejected.class.isInstance(deliveryState)) {
        final ErrorCondition errorCondition = ((Rejected) deliveryState).getError();
        LOG.debug("rejected command message [error: {}, command: {}]", errorCondition, getCommand());
        TracingHelper.logError(currentSpan, "rejected command for device"
                + ((errorCondition != null && errorCondition.getDescription() != null) ? "; error: " + errorCondition.getDescription() : ""));
    } else {
        LOG.warn("unexpected delivery state [{}] when settling command message [{}]", deliveryState, getCommand());
        TracingHelper.logError(currentSpan, "unexpected delivery state: " + deliveryState);
    }
    currentSpan.finish();
}
 
Example #21
Source File: TransportImplTest.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
/**
 * Verify that no Disposition frame is emitted by the Transport should a Delivery
 * have disposition applied after the Close frame was sent.
 */
@Test
public void testDispositionAfterCloseSent()
{
    MockTransportImpl transport = new MockTransportImpl();
    Connection connection = Proton.connection();
    transport.bind(connection);

    connection.open();

    Session session = connection.session();
    session.open();

    String linkName = "myReceiver";
    Receiver receiver = session.receiver(linkName);
    receiver.flow(5);
    receiver.open();

    pumpMockTransport(transport);

    assertEquals("Unexpected frames written: " + getFrameTypesWritten(transport), 4, transport.writes.size());

    assertTrue("Unexpected frame type", transport.writes.get(0) instanceof Open);
    assertTrue("Unexpected frame type", transport.writes.get(1) instanceof Begin);
    assertTrue("Unexpected frame type", transport.writes.get(2) instanceof Attach);
    assertTrue("Unexpected frame type", transport.writes.get(3) instanceof Flow);

    Delivery delivery = receiver.current();
    assertNull("Should not yet have a delivery", delivery);

    // Send the necessary responses to open/begin/attach as well as a transfer
    transport.handleFrame(new TransportFrame(0, new Open(), null));

    Begin begin = new Begin();
    begin.setRemoteChannel(UnsignedShort.valueOf((short) 0));
    begin.setNextOutgoingId(UnsignedInteger.ONE);
    begin.setIncomingWindow(UnsignedInteger.valueOf(1024));
    begin.setOutgoingWindow(UnsignedInteger.valueOf(1024));
    transport.handleFrame(new TransportFrame(0, begin, null));

    Attach attach = new Attach();
    attach.setHandle(UnsignedInteger.ZERO);
    attach.setRole(Role.SENDER);
    attach.setName(linkName);
    attach.setInitialDeliveryCount(UnsignedInteger.ZERO);
    transport.handleFrame(new TransportFrame(0, attach, null));

    String deliveryTag = "tag1";
    String messageContent = "content1";
    handleTransfer(transport, 1, deliveryTag, messageContent);

    assertEquals("Unexpected frames written: " + getFrameTypesWritten(transport), 4, transport.writes.size());

    delivery = verifyDelivery(receiver, deliveryTag, messageContent);
    assertNotNull("Should now have a delivery", delivery);

    // Cause the Close frame to be sent
    connection.close();
    pumpMockTransport(transport);

    assertEquals("Unexpected frames written: " + getFrameTypesWritten(transport), 5, transport.writes.size());
    assertTrue("Unexpected frame type", transport.writes.get(4) instanceof Close);

    delivery.disposition(Released.getInstance());
    delivery.settle();

    pumpMockTransport(transport);

    assertEquals("Unexpected frames written: " + getFrameTypesWritten(transport), 5, transport.writes.size());
}
 
Example #22
Source File: ReleasedType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public Class<Released> getTypeClass()
{
    return Released.class;
}
 
Example #23
Source File: ReleasedType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
public Released newInstance(Object described)
{
    return Released.getInstance();
}
 
Example #24
Source File: ProtonPublisherImpl.java    From vertx-proton with Apache License 2.0 4 votes vote down vote up
@Override
public void subscribe(Subscriber<? super Delivery> subscriber) {
  LOG.trace("Subscribe called");
  Objects.requireNonNull(subscriber, "A subscriber must be supplied");

  if(subscribed.getAndSet(true)) {
    throw new IllegalStateException("Only a single susbcriber supported, and subscribe already called.");
  }

  subscription = new AmqpSubscription(subscriber);

  connCtx.runOnContext(x-> {
    conn.addEndHandler(v -> {
      if(emitOnConnectionEnd) {
        subscription.indicateError(new Exception("Connection closed: " + conn.getContainer()));
      }
    });

    receiver.closeHandler(res-> {
      subscription.indicateError(new Exception("Link closed unexpectedly"));
      receiver.close();
    });

    receiver.detachHandler(res-> {
      subscription.indicateError(new Exception("Link detached unexpectedly"));
      receiver.detach();
    });

    receiver.openHandler(res -> {
      subscription.indicateSubscribed();
    });

    receiver.handler((delivery, message) -> {
      Delivery envelope = new DeliveryImpl(message, delivery, connCtx);
      if(!subscription.onNextWrapper(envelope)){
        delivery.disposition(Released.getInstance(), true);
      }
    });

    receiver.open();
  });
}
 
Example #25
Source File: ReleasedType.java    From qpid-proton-j with Apache License 2.0 4 votes vote down vote up
@Override
protected List wrap(Released val)
{
    return Collections.EMPTY_LIST;
}
 
Example #26
Source File: AmqpConsumerBuilder.java    From qpid-jms with Apache License 2.0 4 votes vote down vote up
private void configureSource(Source source) {
    Map<Symbol, DescribedType> filters = new HashMap<Symbol, DescribedType>();
    Symbol[] outcomes = new Symbol[]{ Accepted.DESCRIPTOR_SYMBOL, Rejected.DESCRIPTOR_SYMBOL,
                                      Released.DESCRIPTOR_SYMBOL, Modified.DESCRIPTOR_SYMBOL };

    if (resourceInfo.isDurable()) {
        source.setExpiryPolicy(TerminusExpiryPolicy.NEVER);
        source.setDurable(TerminusDurability.UNSETTLED_STATE);
        source.setDistributionMode(COPY);
    } else {
        source.setDurable(TerminusDurability.NONE);
        source.setExpiryPolicy(TerminusExpiryPolicy.LINK_DETACH);
    }

    if (resourceInfo.isBrowser()) {
        source.setDistributionMode(COPY);
    }

    // Capabilities
    LinkedList<Symbol> capabilities = new LinkedList<>();

    Symbol typeCapability =  AmqpDestinationHelper.toTypeCapability(resourceInfo.getDestination());
    if (typeCapability != null){
        capabilities.add(typeCapability);
    }

    if (resourceInfo.isShared()) {
        capabilities.add(AmqpSupport.SHARED);

        if(!resourceInfo.isExplicitClientID()) {
            capabilities.add(AmqpSupport.GLOBAL);
        }
    }

    if (!capabilities.isEmpty()) {
        Symbol[] capArray = capabilities.toArray(new Symbol[capabilities.size()]);
        source.setCapabilities(capArray);
    }

    //Outcomes
    source.setOutcomes(outcomes);
    source.setDefaultOutcome(MODIFIED_FAILED);

    // Filters
    if (resourceInfo.isNoLocal()) {
        filters.put(JMS_NO_LOCAL_SYMBOL, AmqpJmsNoLocalType.NO_LOCAL);
    }

    if (resourceInfo.getSelector() != null && !resourceInfo.getSelector().trim().equals("")) {
        filters.put(JMS_SELECTOR_SYMBOL, new AmqpJmsSelectorType(resourceInfo.getSelector()));
    }

    if (!filters.isEmpty()) {
        source.setFilter(filters);
    }
}
 
Example #27
Source File: AmqpConsumer.java    From qpid-jms with Apache License 2.0 4 votes vote down vote up
/**
 * Called to acknowledge all messages that have been marked as delivered but
 * have not yet been marked consumed.  Usually this is called as part of an
 * client acknowledge session operation.
 *
 * Only messages that have already been acknowledged as delivered by the JMS
 * framework will be in the delivered Map.  This means that the link credit
 * would already have been given for these so we just need to settle them.
 *
 * @param ackType the type of acknowledgement to perform
 */
public void acknowledge(ACK_TYPE ackType) {
    LOG.trace("Session Acknowledge for consumer {} with ack type {}", getResourceInfo().getId(), ackType);
    Delivery delivery = getEndpoint().head();
    while (delivery != null) {
        Delivery current = delivery;
        delivery = delivery.next();

        if (!(current.getContext() instanceof JmsInboundMessageDispatch)) {
            LOG.debug("{} Found incomplete delivery with no context during session acknowledge processing", AmqpConsumer.this);
            continue;
        }

        JmsInboundMessageDispatch envelope = (JmsInboundMessageDispatch) current.getContext();
        if(ackType == ACK_TYPE.SESSION_SHUTDOWN && (envelope.isDelivered() || envelope.isRecovered())) {
            handleDisposition(envelope, current, MODIFIED_FAILED);
        } else if (envelope.isDelivered()) {
            final DeliveryState disposition;

            switch (ackType) {
                case ACCEPTED:
                    disposition = Accepted.getInstance();
                    break;
                case RELEASED:
                    disposition = Released.getInstance();
                    break;
                case REJECTED:
                    disposition = REJECTED;
                    break;
                case MODIFIED_FAILED:
                    disposition = MODIFIED_FAILED;
                    break;
                case MODIFIED_FAILED_UNDELIVERABLE:
                    disposition = MODIFIED_FAILED_UNDELIVERABLE;
                    break;
                default:
                    throw new IllegalArgumentException("Invalid acknowledgement type specified: " + ackType);
            }

            handleDisposition(envelope, current, disposition);
        }
    }

    tryCompleteDeferredClose();
}
 
Example #28
Source File: ProtonHelper.java    From vertx-proton with Apache License 2.0 2 votes vote down vote up
/**
 * Release the given delivery by applying Released disposition state, and optionally settling.
 *
 * @param delivery
 *          the delivery to update
 * @param settle
 *          whether to settle
 * @return the delivery
 */
public static ProtonDelivery released(ProtonDelivery delivery, boolean settle) {
  delivery.disposition(Released.getInstance(), settle);
  return delivery;
}