use of org.apache.qpid.server.message.MessageDestination in project qpid-broker-j by apache.
the class Session_1_0 method createDynamicDestination.
private MessageDestination createDynamicDestination(final Link_1_0<?, ?> link, Map properties, final Symbol[] capabilities) throws AmqpErrorException {
final Set<Symbol> capabilitySet = capabilities == null ? Collections.emptySet() : Sets.newHashSet(capabilities);
boolean isTopic = capabilitySet.contains(Symbol.valueOf("temporary-topic")) || capabilitySet.contains(Symbol.valueOf("topic"));
final String destName = (isTopic ? "TempTopic" : "TempQueue") + UUID.randomUUID().toString();
try {
Map<String, Object> attributes = convertDynamicNodePropertiesToAttributes(link, properties, destName);
Class<? extends MessageDestination> clazz = isTopic ? Exchange.class : MessageDestination.class;
if (isTopic) {
attributes.put(Exchange.TYPE, ExchangeDefaults.FANOUT_EXCHANGE_CLASS);
}
return Subject.doAs(getSubjectWithAddedSystemRights(), (PrivilegedAction<MessageDestination>) () -> getAddressSpace().createMessageDestination(clazz, attributes));
} catch (AccessControlException e) {
throw new AmqpErrorException(AmqpError.UNAUTHORIZED_ACCESS, e.getMessage());
} catch (AbstractConfiguredObject.DuplicateNameException e) {
LOGGER.error("A temporary destination was created with a name which collided with an existing destination name '{}'", destName);
throw new ConnectionScopedRuntimeException(e);
}
}
use of org.apache.qpid.server.message.MessageDestination in project qpid-broker-j by apache.
the class ServerSessionDelegate method messageTransfer.
@Override
public void messageTransfer(ServerSession ssn, final MessageTransfer xfr) {
try {
if (ssn.blockingTimeoutExceeded()) {
getEventLogger(ssn).message(ChannelMessages.FLOW_CONTROL_IGNORED());
ssn.close(ErrorCodes.MESSAGE_TOO_LARGE, "Session flow control was requested, but not enforced by sender");
} else if (xfr.getBodySize() > ssn.getConnection().getMaxMessageSize()) {
exception(ssn, xfr, ExecutionErrorCode.RESOURCE_LIMIT_EXCEEDED, "Message size of " + xfr.getBodySize() + " greater than allowed maximum of " + ssn.getConnection().getMaxMessageSize());
} else {
final MessageDestination destination = getDestinationForMessage(ssn, xfr);
final DeliveryProperties delvProps = xfr.getHeader() == null ? null : xfr.getHeader().getDeliveryProperties();
if (delvProps != null && delvProps.hasTtl() && !delvProps.hasExpiration()) {
delvProps.setExpiration(System.currentTimeMillis() + delvProps.getTtl());
}
final MessageMetaData_0_10 messageMetaData = new MessageMetaData_0_10(xfr);
final NamedAddressSpace virtualHost = getAddressSpace(ssn);
try {
ssn.getAMQPConnection().checkAuthorizedMessagePrincipal(getMessageUserId(xfr));
ssn.authorisePublish(destination, messageMetaData.getRoutingKey(), messageMetaData.isImmediate(), ssn.getAMQPConnection().getLastReadTime());
} catch (AccessControlException e) {
ExecutionErrorCode errorCode = ExecutionErrorCode.UNAUTHORIZED_ACCESS;
exception(ssn, xfr, errorCode, e.getMessage());
return;
}
final MessageStore store = virtualHost.getMessageStore();
final StoredMessage<MessageMetaData_0_10> storeMessage = createStoreMessage(xfr, messageMetaData, store);
final MessageTransferMessage message = new MessageTransferMessage(storeMessage, ssn.getReference());
MessageReference<MessageTransferMessage> reference = message.newReference();
try {
final InstanceProperties instanceProperties = new InstanceProperties() {
@Override
public Object getProperty(final Property prop) {
switch(prop) {
case EXPIRATION:
return message.getExpiration();
case IMMEDIATE:
return message.isImmediate();
case MANDATORY:
return (delvProps == null || !delvProps.getDiscardUnroutable()) && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT;
case PERSISTENT:
return message.isPersistent();
case REDELIVERED:
return delvProps.getRedelivered();
}
return null;
}
};
RoutingResult<MessageTransferMessage> routingResult = ssn.enqueue(message, instanceProperties, destination);
boolean explictlyRejected = routingResult.containsReject(RejectType.LIMIT_EXCEEDED);
if (!routingResult.hasRoutes() || explictlyRejected) {
boolean closeWhenNoRoute = ssn.getAMQPConnection().getPort().getCloseWhenNoRoute();
boolean discardUnroutable = delvProps != null && delvProps.getDiscardUnroutable();
if (!discardUnroutable && xfr.getAcceptMode() == MessageAcceptMode.EXPLICIT) {
RangeSet rejects = RangeSetFactory.createRangeSet();
rejects.add(xfr.getId());
MessageReject reject = new MessageReject(rejects, MessageRejectCode.UNROUTABLE, "Unroutable");
ssn.invoke(reject);
} else if (!discardUnroutable && closeWhenNoRoute && explictlyRejected) {
ExecutionErrorCode code = ExecutionErrorCode.RESOURCE_LIMIT_EXCEEDED;
String errorMessage = String.format("No route for message with destination '%s' and routing key '%s' : %s", xfr.getDestination(), message.getInitialRoutingAddress(), routingResult.getRejectReason());
ExecutionException ex = new ExecutionException();
ex.setErrorCode(code);
ex.setDescription(errorMessage);
ssn.invoke(ex);
ssn.close(ErrorCodes.RESOURCE_ERROR, errorMessage);
return;
} else {
getEventLogger(ssn).message(ExchangeMessages.DISCARDMSG(destination.getName(), messageMetaData.getRoutingKey()));
}
}
// TODO: we currently do not send MessageAccept when AcceptMode is EXPLICIT
if (ssn.isTransactional()) {
ssn.processed(xfr);
} else {
ssn.recordFuture(Futures.immediateFuture(null), new CommandProcessedAction(ssn, xfr));
}
} catch (VirtualHostUnavailableException e) {
getServerConnection(ssn).sendConnectionCloseAsync(ConnectionCloseCode.CONNECTION_FORCED, e.getMessage());
} finally {
reference.release();
}
}
} finally {
xfr.dispose();
}
}
use of org.apache.qpid.server.message.MessageDestination in project qpid-broker-j by apache.
the class AbstractQueue method validateOrCreateAlternateBinding.
private void validateOrCreateAlternateBinding(final Queue<?> queue, final boolean mayCreate) {
Object value = queue.getAttribute(ALTERNATE_BINDING);
if (value instanceof AlternateBinding) {
AlternateBinding alternateBinding = (AlternateBinding) value;
String destinationName = alternateBinding.getDestination();
MessageDestination messageDestination = _virtualHost.getAttainedMessageDestination(destinationName, mayCreate);
if (messageDestination == null) {
throw new UnknownAlternateBindingException(destinationName);
} else if (messageDestination == this) {
throw new IllegalConfigurationException(String.format("Cannot create alternate binding for '%s' : Alternate binding destination cannot refer to self.", getName()));
} else if (isDurable() && !messageDestination.isDurable()) {
throw new IllegalConfigurationException(String.format("Cannot create alternate binding for '%s' : Alternate binding destination '%s' is not durable.", getName(), destinationName));
}
}
}
use of org.apache.qpid.server.message.MessageDestination in project qpid-broker-j by apache.
the class QueueEntryImpl method routeToAlternate.
@Override
public int routeToAlternate(final Action<? super MessageInstance> action, ServerTransaction txn) {
if (!isAcquired()) {
throw new IllegalStateException("Illegal queue entry state. " + this + " is not acquired.");
}
final Queue<?> currentQueue = getQueue();
MessageDestination alternateBindingDestination = currentQueue.getAlternateBindingDestination();
boolean autocommit = txn == null;
if (autocommit) {
txn = new LocalTransaction(getQueue().getVirtualHost().getMessageStore());
}
RoutingResult result;
if (alternateBindingDestination != null) {
result = alternateBindingDestination.route(getMessage(), getMessage().getInitialRoutingAddress(), getInstanceProperties());
} else {
result = new RoutingResult<>(getMessage());
}
txn.dequeue(getEnqueueRecord(), new ServerTransaction.Action() {
@Override
public void postCommit() {
delete();
}
@Override
public void onRollback() {
}
});
int enqueues = result.send(txn, null);
if (autocommit) {
txn.commit();
}
return enqueues;
}
use of org.apache.qpid.server.message.MessageDestination in project qpid-broker-j by apache.
the class AbstractExchange method validateOrCreateAlternateBinding.
private void validateOrCreateAlternateBinding(final Exchange<?> exchange, final boolean mayCreate) {
Object value = exchange.getAttribute(ALTERNATE_BINDING);
if (value instanceof AlternateBinding) {
AlternateBinding alternateBinding = (AlternateBinding) value;
String destinationName = alternateBinding.getDestination();
MessageDestination messageDestination = _virtualHost.getAttainedMessageDestination(destinationName, mayCreate);
if (messageDestination == null) {
throw new UnknownAlternateBindingException(destinationName);
} else if (messageDestination == this) {
throw new IllegalConfigurationException(String.format("Cannot create alternate binding for '%s' : Alternate binding destination cannot refer to self.", getName()));
} else if (isDurable() && !messageDestination.isDurable()) {
throw new IllegalConfigurationException(String.format("Cannot create alternate binding for '%s' : Alternate binding destination '%s' is not durable.", getName(), destinationName));
}
}
}
Aggregations