use of org.apache.qpid.server.model.NamedAddressSpace in project qpid-broker-j by apache.
the class SendingLinkEndpoint method detach.
@Override
protected void detach(Error error, final boolean close) {
if (_consumerTarget != null) {
_consumerTarget.close();
}
Source source = getSource();
TerminusExpiryPolicy expiryPolicy = source.getExpiryPolicy();
NamedAddressSpace addressSpace = getSession().getConnection().getAddressSpace();
List<Symbol> sourceCapabilities = source.getCapabilities() == null ? Collections.emptyList() : Arrays.asList(source.getCapabilities());
if (close || TerminusExpiryPolicy.LINK_DETACH.equals(expiryPolicy) || ((expiryPolicy == null || TerminusExpiryPolicy.SESSION_END.equals(expiryPolicy)) && getSession().isClosing()) || (TerminusExpiryPolicy.CONNECTION_CLOSE.equals(expiryPolicy) && getSession().getConnection().isClosing())) {
Error closingError = null;
if (getDestination() instanceof ExchangeSendingDestination && addressSpace instanceof QueueManagingVirtualHost) {
cleanUpUnsettledDeliveries();
try {
((QueueManagingVirtualHost) addressSpace).removeSubscriptionQueue(((ExchangeSendingDestination) getDestination()).getQueue().getName());
TerminusDurability sourceDurability = source.getDurable();
if (sourceDurability != null && !TerminusDurability.NONE.equals(sourceDurability) && sourceCapabilities.contains(Session_1_0.SHARED_CAPABILITY) && sourceCapabilities.contains(ExchangeSendingDestination.TOPIC_CAPABILITY)) {
Pattern containerIdPattern = sourceCapabilities.contains(Session_1_0.GLOBAL_CAPABILITY) ? ANY_CONTAINER_ID : Pattern.compile("^" + Pattern.quote(getSession().getConnection().getRemoteContainerId()) + "$");
Pattern linkNamePattern = Pattern.compile("^" + Pattern.quote(getLinkName()) + "\\|?\\d*$");
final Collection<LinkModel> links = addressSpace.findSendingLinks(containerIdPattern, linkNamePattern);
for (LinkModel link : links) {
if (link instanceof Link_1_0) {
((Link_1_0) link).linkClosed();
}
}
}
} catch (AccessControlException e) {
LOGGER.error("Error unregistering subscription", e);
closingError = new Error(AmqpError.NOT_ALLOWED, "Error unregistering subscription");
} catch (IllegalStateException e) {
String message;
if (sourceCapabilities.contains(Session_1_0.SHARED_CAPABILITY) && sourceCapabilities.contains(ExchangeSendingDestination.TOPIC_CAPABILITY)) {
String subscriptionName = getLinkName();
int separator = subscriptionName.indexOf("|");
if (separator > 0) {
subscriptionName = subscriptionName.substring(0, separator);
}
message = "There are active consumers on the shared subscription '" + subscriptionName + "'";
} else {
message = e.getMessage();
}
closingError = new Error(AmqpError.RESOURCE_LOCKED, message);
} catch (NotFoundException e) {
closingError = new Error(AmqpError.NOT_FOUND, e.getMessage());
}
}
if (error == null) {
error = closingError;
} else {
LOGGER.warn("Unexpected error on detaching endpoint {}: {}", getLinkName(), error);
}
} else if (addressSpace instanceof QueueManagingVirtualHost && ((QueueManagingVirtualHost) addressSpace).isDiscardGlobalSharedSubscriptionLinksOnDetach() && sourceCapabilities.contains(Session_1_0.SHARED_CAPABILITY) && sourceCapabilities.contains(Session_1_0.GLOBAL_CAPABILITY) && sourceCapabilities.contains(ExchangeSendingDestination.TOPIC_CAPABILITY)) {
// However, we keep one link (ending with "|global") to perform a null-source lookup upon un-subscription.
if (!getLinkName().endsWith("|global")) {
getLink().linkClosed();
} else {
Pattern linkNamePattern = Pattern.compile("^" + Pattern.quote(getLinkName()) + "$");
final Collection<LinkModel> links = addressSpace.findSendingLinks(ANY_CONTAINER_ID, linkNamePattern);
if (links.size() > 1) {
getLink().linkClosed();
}
}
}
super.detach(error, close);
}
use of org.apache.qpid.server.model.NamedAddressSpace in project qpid-broker-j by apache.
the class ServerConnection method closed.
public void closed() {
try {
performDeleteTasks();
if (state == OPEN) {
exception(new ConnectionException("connection aborted"));
}
LOGGER.debug("connection closed: {}", this);
synchronized (lock) {
List<ServerSession> values = new ArrayList<ServerSession>(channels.values());
for (ServerSession ssn : values) {
ssn.closed();
}
try {
sender.close();
} catch (Exception e) {
// ignore.
}
sender = null;
setState(CLOSED);
}
} finally {
NamedAddressSpace addressSpace = getAddressSpace();
if (addressSpace != null) {
addressSpace.deregisterConnection(_amqpConnection);
}
}
}
use of org.apache.qpid.server.model.NamedAddressSpace 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.model.NamedAddressSpace in project qpid-broker-j by apache.
the class ServerSessionDelegate method queueDeclare.
@Override
public void queueDeclare(ServerSession session, final QueueDeclare method) {
final NamedAddressSpace addressSpace = getAddressSpace(session);
String queueName = method.getQueue();
Queue<?> queue;
// TODO: do we need to check that the queue already exists with exactly the same "configuration"?
final boolean exclusive = method.getExclusive();
final boolean autoDelete = method.getAutoDelete();
if (method.getPassive()) {
queue = getQueue(addressSpace, queueName);
if (queue == null) {
String description = "Queue: " + queueName + " not found on VirtualHost(" + addressSpace + ").";
ExecutionErrorCode errorCode = ExecutionErrorCode.NOT_FOUND;
exception(session, method, errorCode, description);
} else if (exclusive) {
if (queue.getExclusive() == ExclusivityPolicy.NONE) {
String description = "Cannot passively declare queue ('" + queueName + "')" + " as exclusive as queue with same name is" + " already declared as non-exclusive";
ExecutionErrorCode errorCode = ExecutionErrorCode.RESOURCE_LOCKED;
exception(session, method, errorCode, description);
} else if (!verifySessionAccess(session, queue)) {
String description = "Cannot passively declare queue('" + queueName + "')," + " as exclusive queue with same name " + "declared on another session";
ExecutionErrorCode errorCode = ExecutionErrorCode.RESOURCE_LOCKED;
exception(session, method, errorCode, description);
}
}
} else {
try {
final Map<String, Object> arguments = QueueArgumentsConverter.convertWireArgsToModel(queueName, method.getArguments());
final String alternateExchangeName = method.getAlternateExchange();
if (method.hasAlternateExchange() && !nameNullOrEmpty(alternateExchangeName)) {
validateAlternateExchangeIsNotQueue(addressSpace, alternateExchangeName);
arguments.put(Queue.ALTERNATE_BINDING, Collections.singletonMap(AlternateBinding.DESTINATION, alternateExchangeName));
}
arguments.put(Queue.NAME, queueName);
if (!arguments.containsKey(Queue.LIFETIME_POLICY)) {
LifetimePolicy lifetime;
if (autoDelete) {
lifetime = exclusive ? LifetimePolicy.DELETE_ON_SESSION_END : LifetimePolicy.DELETE_ON_NO_OUTBOUND_LINKS;
} else {
lifetime = LifetimePolicy.PERMANENT;
}
arguments.put(Queue.LIFETIME_POLICY, lifetime);
}
if (!arguments.containsKey(Queue.EXCLUSIVE)) {
ExclusivityPolicy exclusivityPolicy = exclusive ? ExclusivityPolicy.SESSION : ExclusivityPolicy.NONE;
arguments.put(Queue.EXCLUSIVE, exclusivityPolicy);
}
arguments.put(Queue.DURABLE, method.getDurable());
queue = addressSpace.createMessageSource(Queue.class, arguments);
} catch (AbstractConfiguredObject.DuplicateNameException qe) {
queue = (Queue<?>) qe.getExisting();
if (!verifySessionAccess(session, queue)) {
String description = "Cannot declare queue('" + queueName + "')," + " as exclusive queue with same name " + "declared on another session";
ExecutionErrorCode errorCode = ExecutionErrorCode.RESOURCE_LOCKED;
exception(session, method, errorCode, description);
}
} catch (AccessControlException e) {
exception(session, method, ExecutionErrorCode.UNAUTHORIZED_ACCESS, e.getMessage());
} catch (UnknownAlternateBindingException e) {
exception(session, method, ExecutionErrorCode.NOT_FOUND, String.format("Unknown alternate exchange '%s'", e.getAlternateBindingName()));
} catch (IllegalArgumentException | IllegalConfigurationException e) {
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, e.getMessage());
}
}
}
use of org.apache.qpid.server.model.NamedAddressSpace in project qpid-broker-j by apache.
the class ServerSessionDelegate method exchangeBound.
@Override
public void exchangeBound(ServerSession session, ExchangeBound method) {
ExchangeBoundResult result = new ExchangeBoundResult();
NamedAddressSpace addressSpace = getAddressSpace(session);
Exchange<?> exchange;
MessageSource source;
Queue<?> queue;
boolean isDefaultExchange;
if (!nameNullOrEmpty(method.getExchange())) {
isDefaultExchange = false;
exchange = getExchange(addressSpace, method.getExchange());
if (exchange == null) {
result.setExchangeNotFound(true);
}
} else {
isDefaultExchange = true;
exchange = null;
}
if (isDefaultExchange) {
// fake the existence of the "default" exchange for 0-10
if (method.hasQueue()) {
queue = getQueue(session, method.getQueue());
if (queue == null) {
result.setQueueNotFound(true);
} else {
if (method.hasBindingKey()) {
if (!method.getBindingKey().equals(method.getQueue())) {
result.setKeyNotMatched(true);
}
}
}
} else if (method.hasBindingKey()) {
if (getQueue(session, method.getBindingKey()) == null) {
result.setKeyNotMatched(true);
}
}
if (method.hasArguments() && !method.getArguments().isEmpty()) {
result.setArgsNotMatched(true);
}
} else if (method.hasQueue()) {
source = getMessageSource(session, method.getQueue());
if (source == null) {
result.setQueueNotFound(true);
}
if (source == null || source instanceof Queue) {
queue = (Queue<?>) source;
if (exchange != null && queue != null) {
boolean queueMatched = exchange.isBound(queue);
result.setQueueNotMatched(!queueMatched);
if (method.hasBindingKey()) {
if (queueMatched) {
final boolean keyMatched = exchange.isBound(method.getBindingKey(), queue);
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments(), queue));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments(), queue));
}
}
} else {
boolean keyMatched = exchange.isBound(method.getBindingKey());
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments()));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
}
} else if (method.hasArguments()) {
if (queueMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getArguments(), queue));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
} else if (exchange != null && method.hasBindingKey()) {
final boolean keyMatched = exchange.isBound(method.getBindingKey());
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments()));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
}
}
} else if (exchange != null && method.hasBindingKey()) {
final boolean keyMatched = exchange.isBound(method.getBindingKey());
result.setKeyNotMatched(!keyMatched);
if (method.hasArguments()) {
if (keyMatched) {
result.setArgsNotMatched(!exchange.isBound(method.getBindingKey(), method.getArguments()));
} else {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
}
} else if (exchange != null && method.hasArguments()) {
result.setArgsNotMatched(!exchange.isBound(method.getArguments()));
}
session.executionResult((int) method.getId(), result);
}
Aggregations