use of org.apache.qpid.server.protocol.v1_0.type.messaging.Modified in project qpid-broker-j by apache.
the class SendingLinkEndpoint method attachReceived.
@Override
public void attachReceived(final Attach attach) throws AmqpErrorException {
super.attachReceived(attach);
Target target = (Target) attach.getTarget();
Source source = getSource();
if (source == null) {
source = new Source();
Source attachSource = (Source) attach.getSource();
final Modified defaultOutcome = new Modified();
defaultOutcome.setDeliveryFailed(true);
source.setDefaultOutcome(defaultOutcome);
source.setOutcomes(Accepted.ACCEPTED_SYMBOL, Released.RELEASED_SYMBOL, Rejected.REJECTED_SYMBOL);
source.setAddress(attachSource.getAddress());
source.setDynamic(attachSource.getDynamic());
if (Boolean.TRUE.equals(attachSource.getDynamic()) && attachSource.getDynamicNodeProperties() != null) {
Map<Symbol, Object> dynamicNodeProperties = new HashMap<>();
if (attachSource.getDynamicNodeProperties().containsKey(Session_1_0.LIFETIME_POLICY)) {
dynamicNodeProperties.put(Session_1_0.LIFETIME_POLICY, attachSource.getDynamicNodeProperties().get(Session_1_0.LIFETIME_POLICY));
}
source.setDynamicNodeProperties(dynamicNodeProperties);
}
source.setDurable(TerminusDurability.min(attachSource.getDurable(), getLink().getHighestSupportedTerminusDurability()));
source.setExpiryPolicy(attachSource.getExpiryPolicy());
source.setDistributionMode(attachSource.getDistributionMode());
source.setFilter(attachSource.getFilter());
source.setCapabilities(attachSource.getCapabilities());
final SendingDestination destination = getSession().getSendingDestination(getLink(), source);
source.setCapabilities(destination.getCapabilities());
getLink().setSource(source);
prepareConsumerOptionsAndFilters(destination);
}
getLink().setTarget(target);
final MessageInstanceConsumer oldConsumer = getConsumer();
createConsumerTarget();
_resumeAcceptedTransfers.clear();
_resumeFullTransfers.clear();
final NamedAddressSpace addressSpace = getSession().getConnection().getAddressSpace();
// TODO: QPID-7845 : Resuming links is unsupported at the moment. Thus, cleaning up unsettled deliveries unconditionally.
cleanUpUnsettledDeliveries();
getSession().addDeleteTask(_cleanUpUnsettledDeliveryTask);
Map<Binary, OutgoingDelivery> unsettledCopy = new HashMap<>(_unsettled);
Map<Binary, DeliveryState> remoteUnsettled = attach.getUnsettled() == null ? Collections.emptyMap() : new HashMap<>(attach.getUnsettled());
final boolean isUnsettledComplete = !Boolean.TRUE.equals(attach.getIncompleteUnsettled());
for (Map.Entry<Binary, OutgoingDelivery> entry : unsettledCopy.entrySet()) {
Binary deliveryTag = entry.getKey();
final MessageInstance queueEntry = entry.getValue().getMessageInstance();
if (!remoteUnsettled.containsKey(deliveryTag) && isUnsettledComplete) {
queueEntry.setRedelivered();
queueEntry.release(oldConsumer);
_unsettled.remove(deliveryTag);
} else if (remoteUnsettled.get(deliveryTag) instanceof Outcome) {
Outcome outcome = (Outcome) remoteUnsettled.get(deliveryTag);
if (outcome instanceof Accepted) {
if (oldConsumer.acquires()) {
AutoCommitTransaction txn = new AutoCommitTransaction(addressSpace.getMessageStore());
if (queueEntry.acquire() || queueEntry.isAcquired()) {
txn.dequeue(Collections.singleton(queueEntry), new ServerTransaction.Action() {
@Override
public void postCommit() {
queueEntry.delete();
}
@Override
public void onRollback() {
}
});
}
}
} else if (outcome instanceof Released) {
if (oldConsumer.acquires()) {
AutoCommitTransaction txn = new AutoCommitTransaction(addressSpace.getMessageStore());
txn.dequeue(Collections.singleton(queueEntry), new ServerTransaction.Action() {
@Override
public void postCommit() {
queueEntry.release(oldConsumer);
}
@Override
public void onRollback() {
}
});
}
}
// TODO: QPID-7845: Handle rejected and modified outcome
remoteUnsettled.remove(deliveryTag);
_resumeAcceptedTransfers.add(deliveryTag);
} else {
_resumeFullTransfers.add(queueEntry);
// TODO:QPID-7845: exists in receivers map, but not yet got an outcome ... should resend with resume = true
}
}
getConsumerTarget().updateNotifyWorkDesired();
}
use of org.apache.qpid.server.protocol.v1_0.type.messaging.Modified in project qpid-broker-j by apache.
the class SendingLinkEndpoint method cleanUpUnsettledDeliveries.
private void cleanUpUnsettledDeliveries() {
getSession().removeDeleteTask(_cleanUpUnsettledDeliveryTask);
Modified state = new Modified();
state.setDeliveryFailed(true);
for (OutgoingDelivery delivery : _unsettled.values()) {
UnsettledAction action = delivery.getAction();
if (action != null) {
action.process(state, Boolean.TRUE);
delivery.setAction(null);
}
}
_unsettled.clear();
}
use of org.apache.qpid.server.protocol.v1_0.type.messaging.Modified in project qpid-broker-j by apache.
the class OutcomeTest method modifiedOutcomeWithUndeliverableHere.
@Test
@SpecificationTest(section = "3.4.5", description = "If the undeliverable-here is set, then any messages released" + " MUST NOT be redelivered to the modifying link endpoint.")
public void modifiedOutcomeWithUndeliverableHere() throws Exception {
getBrokerAdmin().putMessageOnQueue(BrokerAdmin.TEST_QUEUE_NAME, "message1");
getBrokerAdmin().putMessageOnQueue(BrokerAdmin.TEST_QUEUE_NAME, "message2");
try (FrameTransport transport = new FrameTransport(_brokerAddress).connect()) {
final Interaction interaction = transport.newInteraction().negotiateProtocol().consumeResponse().open().consumeResponse(Open.class).begin().consumeResponse(Begin.class).attachRole(Role.RECEIVER).attachSourceAddress(BrokerAdmin.TEST_QUEUE_NAME).attach().consumeResponse(Attach.class).flowIncomingWindow(UnsignedInteger.ONE).flowLinkCredit(UnsignedInteger.ONE).flowHandleFromLinkHandle().flow().receiveDelivery().decodeLatestDelivery();
Object firstDeliveryPayload = interaction.getDecodedLatestDelivery();
assertThat(firstDeliveryPayload, is(equalTo("message1")));
Modified modifiedOutcome = new Modified();
modifiedOutcome.setUndeliverableHere(Boolean.TRUE);
interaction.dispositionSettled(true).dispositionRole(Role.RECEIVER).dispositionFirstFromLatestDelivery().dispositionState(modifiedOutcome).disposition().flowIncomingWindow(UnsignedInteger.valueOf(2)).flowLinkCredit(UnsignedInteger.valueOf(2)).flowNextIncomingIdFromLatestDelivery().flow().receiveDelivery().decodeLatestDelivery();
Object secondDeliveryPayload = interaction.getDecodedLatestDelivery();
assertThat(secondDeliveryPayload, is(equalTo("message2")));
// verify that no unexpected performative is received by closing
interaction.doCloseConnection();
}
}
Aggregations