use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class AMQChannel method receiveExchangeBound.
@Override
public void receiveExchangeBound(final AMQShortString exchangeName, final AMQShortString routingKey, final AMQShortString queueName) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("RECV[" + _channelId + "] ExchangeBound[" + " exchange: " + exchangeName + " routingKey: " + routingKey + " queue: " + queueName + " ]");
}
NamedAddressSpace virtualHost = _connection.getAddressSpace();
MethodRegistry methodRegistry = _connection.getMethodRegistry();
sync();
int replyCode;
String replyText;
if (isDefaultExchange(exchangeName)) {
if (routingKey == null) {
if (queueName == null) {
replyCode = virtualHost.hasMessageSources() ? ExchangeBoundOkBody.OK : ExchangeBoundOkBody.NO_BINDINGS;
replyText = null;
} else {
MessageSource queue = virtualHost.getAttainedMessageSource(queueName.toString());
if (queue == null) {
replyCode = ExchangeBoundOkBody.QUEUE_NOT_FOUND;
replyText = "Queue '" + queueName + "' not found";
} else {
replyCode = ExchangeBoundOkBody.OK;
replyText = null;
}
}
} else {
if (queueName == null) {
replyCode = virtualHost.getAttainedMessageDestination(routingKey.toString()) instanceof Queue ? ExchangeBoundOkBody.OK : ExchangeBoundOkBody.NO_QUEUE_BOUND_WITH_RK;
replyText = null;
} else {
MessageDestination destination = virtualHost.getAttainedMessageDestination(queueName.toString());
Queue<?> queue = destination instanceof Queue ? (Queue) destination : null;
if (queue == null) {
replyCode = ExchangeBoundOkBody.QUEUE_NOT_FOUND;
replyText = "Queue '" + queueName + "' not found";
} else {
replyCode = queueName.equals(routingKey) ? ExchangeBoundOkBody.OK : ExchangeBoundOkBody.SPECIFIC_QUEUE_NOT_BOUND_WITH_RK;
replyText = null;
}
}
}
} else {
Exchange<?> exchange = getExchange(exchangeName.toString());
if (exchange == null) {
replyCode = ExchangeBoundOkBody.EXCHANGE_NOT_FOUND;
replyText = "Exchange '" + exchangeName + "' not found";
} else if (routingKey == null) {
if (queueName == null) {
if (exchange.hasBindings()) {
replyCode = ExchangeBoundOkBody.OK;
replyText = null;
} else {
replyCode = ExchangeBoundOkBody.NO_BINDINGS;
replyText = null;
}
} else {
Queue<?> queue = getQueue(queueName.toString());
if (queue == null) {
replyCode = ExchangeBoundOkBody.QUEUE_NOT_FOUND;
replyText = "Queue '" + queueName + "' not found";
} else {
if (exchange.isBound(queue)) {
replyCode = ExchangeBoundOkBody.OK;
replyText = null;
} else {
replyCode = ExchangeBoundOkBody.QUEUE_NOT_BOUND;
replyText = "Queue '" + queueName + "' not bound to exchange '" + exchangeName + "'";
}
}
}
} else if (queueName != null) {
Queue<?> queue = getQueue(queueName.toString());
if (queue == null) {
replyCode = ExchangeBoundOkBody.QUEUE_NOT_FOUND;
replyText = "Queue '" + queueName + "' not found";
} else {
String bindingKey = routingKey == null ? null : routingKey.toString();
if (exchange.isBound(bindingKey, queue)) {
replyCode = ExchangeBoundOkBody.OK;
replyText = null;
} else {
replyCode = ExchangeBoundOkBody.SPECIFIC_QUEUE_NOT_BOUND_WITH_RK;
replyText = "Queue '" + queueName + "' not bound with routing key '" + routingKey + "' to exchange '" + exchangeName + "'";
}
}
} else {
if (exchange.isBound(routingKey == null ? "" : routingKey.toString())) {
replyCode = ExchangeBoundOkBody.OK;
replyText = null;
} else {
replyCode = ExchangeBoundOkBody.NO_QUEUE_BOUND_WITH_RK;
replyText = "No queue bound with routing key '" + routingKey + "' to exchange '" + exchangeName + "'";
}
}
}
ExchangeBoundOkBody exchangeBoundOkBody = methodRegistry.createExchangeBoundOkBody(replyCode, AMQShortString.validValueOf(replyText));
_connection.writeFrame(exchangeBoundOkBody.generateFrame(getChannelId()));
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class AMQChannel method receiveBasicGet.
@Override
public void receiveBasicGet(final AMQShortString queueName, final boolean noAck) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("RECV[" + _channelId + "] BasicGet[" + " queue: " + queueName + " noAck: " + noAck + " ]");
}
NamedAddressSpace vHost = _connection.getAddressSpace();
sync();
MessageSource queue = queueName == null ? getDefaultQueue() : vHost.getAttainedMessageSource(queueName.toString());
if (queue == null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("No queue for '" + queueName + "'");
}
if (queueName != null) {
_connection.sendConnectionClose(ErrorCodes.NOT_FOUND, "No such queue, '" + queueName + "'", _channelId);
} else {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "No queue name provided, no default queue defined.", _channelId);
}
} else {
try {
if (!performGet(queue, !noAck)) {
MethodRegistry methodRegistry = _connection.getMethodRegistry();
BasicGetEmptyBody responseBody = methodRegistry.createBasicGetEmptyBody(null);
_connection.writeFrame(responseBody.generateFrame(_channelId));
}
} catch (AccessControlException e) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, e.getMessage(), _channelId);
} catch (MessageSource.ExistingExclusiveConsumer e) {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "Queue has an exclusive consumer", _channelId);
} catch (MessageSource.ExistingConsumerPreventsExclusive e) {
_connection.sendConnectionClose(ErrorCodes.INTERNAL_ERROR, "The GET request has been evaluated as an exclusive consumer, " + "this is likely due to a programming error in the Qpid broker", _channelId);
} catch (MessageSource.ConsumerAccessRefused consumerAccessRefused) {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "Queue has an incompatible exclusivity policy", _channelId);
} catch (MessageSource.QueueDeleted queueDeleted) {
_connection.sendConnectionClose(ErrorCodes.NOT_FOUND, "Queue has been deleted", _channelId);
}
}
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class AMQChannel method receiveBasicConsume.
@Override
public void receiveBasicConsume(final AMQShortString queue, final AMQShortString consumerTag, final boolean noLocal, final boolean noAck, final boolean exclusive, final boolean nowait, final FieldTable arguments) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("RECV[" + _channelId + "] BasicConsume[" + " queue: " + queue + " consumerTag: " + consumerTag + " noLocal: " + noLocal + " noAck: " + noAck + " exclusive: " + exclusive + " nowait: " + nowait + " arguments: " + arguments + " ]");
}
AMQShortString consumerTag1 = consumerTag;
NamedAddressSpace vHost = _connection.getAddressSpace();
sync();
String queueName = AMQShortString.toString(queue);
MessageSource queue1 = queueName == null ? getDefaultQueue() : vHost.getAttainedMessageSource(queueName);
final Collection<MessageSource> sources = new HashSet<>();
if (arguments != null && arguments.get("x-multiqueue") instanceof Collection) {
for (Object object : (Collection<Object>) arguments.get("x-multiqueue")) {
String sourceName = String.valueOf(object);
sourceName = sourceName.trim();
if (sourceName.length() != 0) {
MessageSource source = vHost.getAttainedMessageSource(sourceName);
if (source == null) {
sources.clear();
break;
} else {
sources.add(source);
}
}
}
queueName = arguments.get("x-multiqueue").toString();
} else if (queue1 != null) {
sources.add(queue1);
}
if (sources.isEmpty()) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("No queue for '" + queueName + "'");
}
if (queueName != null) {
closeChannel(ErrorCodes.NOT_FOUND, "No such queue, '" + queueName + "'");
} else {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "No queue name provided, no default queue defined.", _channelId);
}
} else {
try {
consumerTag1 = consumeFromSource(consumerTag1, sources, !noAck, arguments, exclusive, noLocal);
if (!nowait) {
MethodRegistry methodRegistry = _connection.getMethodRegistry();
AMQMethodBody responseBody = methodRegistry.createBasicConsumeOkBody(consumerTag1);
_connection.writeFrame(responseBody.generateFrame(_channelId));
}
} catch (ConsumerTagInUseException cte) {
_connection.sendConnectionClose(ErrorCodes.NOT_ALLOWED, "Non-unique consumer tag, '" + consumerTag1 + "'", _channelId);
} catch (AMQInvalidArgumentException ise) {
_connection.sendConnectionClose(ErrorCodes.ARGUMENT_INVALID, ise.getMessage(), _channelId);
} catch (Queue.ExistingExclusiveConsumer e) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, "Cannot subscribe to queue '" + queue1.getName() + "' as it already has an existing exclusive consumer", _channelId);
} catch (Queue.ExistingConsumerPreventsExclusive e) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, "Cannot subscribe to queue '" + queue1.getName() + "' exclusively as it already has a consumer", _channelId);
} catch (AccessControlException e) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, "Cannot subscribe to queue '" + queue1.getName() + "' permission denied", _channelId);
} catch (MessageSource.ConsumerAccessRefused consumerAccessRefused) {
_connection.sendConnectionClose(ErrorCodes.ACCESS_REFUSED, "Cannot subscribe to queue '" + queue1.getName() + "' as it already has an incompatible exclusivity policy", _channelId);
} catch (MessageSource.QueueDeleted queueDeleted) {
_connection.sendConnectionClose(ErrorCodes.NOT_FOUND, "Cannot subscribe to queue '" + queue1.getName() + "' as it has been deleted", _channelId);
}
}
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class SendingLinkEndpoint method prepareConsumerOptionsAndFilters.
private void prepareConsumerOptionsAndFilters(final SendingDestination destination) throws AmqpErrorException {
// TODO QPID-7952: this method might modify the source. this is not good encapsulation. furthermore if it does so then it should inform the link/linkregistry about it!
_destination = destination;
final Source source = getSource();
EnumSet<ConsumerOption> options = EnumSet.noneOf(ConsumerOption.class);
boolean noLocal = false;
JMSSelectorFilter messageFilter = null;
if (destination instanceof ExchangeSendingDestination) {
options.add(ConsumerOption.ACQUIRES);
options.add(ConsumerOption.SEES_REQUEUES);
} else if (destination instanceof StandardSendingDestination) {
MessageSource messageSource = _destination.getMessageSource();
if (messageSource instanceof Queue && ((Queue<?>) messageSource).getAvailableAttributes().contains("topic")) {
source.setDistributionMode(StdDistMode.COPY);
}
Map<Symbol, Filter> filters = source.getFilter();
Map<Symbol, Filter> actualFilters = new HashMap<>();
if (filters != null) {
for (Map.Entry<Symbol, Filter> entry : filters.entrySet()) {
if (entry.getValue() instanceof NoLocalFilter) {
actualFilters.put(entry.getKey(), entry.getValue());
noLocal = true;
} else if (messageFilter == null && entry.getValue() instanceof org.apache.qpid.server.protocol.v1_0.type.messaging.JMSSelectorFilter) {
org.apache.qpid.server.protocol.v1_0.type.messaging.JMSSelectorFilter selectorFilter = (org.apache.qpid.server.protocol.v1_0.type.messaging.JMSSelectorFilter) entry.getValue();
try {
messageFilter = new JMSSelectorFilter(selectorFilter.getValue());
actualFilters.put(entry.getKey(), entry.getValue());
} catch (ParseException | SelectorParsingException | TokenMgrError e) {
Error error = new Error();
error.setCondition(AmqpError.INVALID_FIELD);
error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue());
error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter")));
throw new AmqpErrorException(error);
}
}
}
}
source.setFilter(actualFilters.isEmpty() ? null : actualFilters);
if (source.getDistributionMode() != StdDistMode.COPY) {
options.add(ConsumerOption.ACQUIRES);
options.add(ConsumerOption.SEES_REQUEUES);
}
} else {
throw new ConnectionScopedRuntimeException("Unknown destination type");
}
if (noLocal) {
options.add(ConsumerOption.NO_LOCAL);
}
FilterManager filters = null;
if (messageFilter != null) {
filters = new FilterManager();
filters.add(messageFilter.getName(), messageFilter);
}
_consumerOptions = options;
_consumerFilters = filters;
}
use of org.apache.qpid.server.message.MessageSource in project qpid-broker-j by apache.
the class ServerSessionDelegate method messageSubscribe.
@Override
public void messageSubscribe(ServerSession session, MessageSubscribe method) {
/*
TODO - work around broken Python tests
Correct code should read like
if not hasAcceptMode() exception ILLEGAL_ARGUMENT "Accept-mode not supplied"
else if not method.hasAcquireMode() exception ExecutionErrorCode.ILLEGAL_ARGUMENT, "Acquire-mode not supplied"
*/
if (!method.hasAcceptMode()) {
method.setAcceptMode(MessageAcceptMode.EXPLICIT);
}
if (!method.hasAcquireMode()) {
method.setAcquireMode(MessageAcquireMode.PRE_ACQUIRED);
}
if (!method.hasQueue()) {
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "queue not supplied");
} else {
String destination = method.getDestination();
if (destination == null) {
exception(session, method, ExecutionErrorCode.INVALID_ARGUMENT, "Subscriber must provide a destination. The protocol specification marking the destination argument as optional is considered a mistake.");
} else if (session.getSubscription(destination) != null) {
exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Subscription already exists with destination '" + destination + "'");
} else {
String queueName = method.getQueue();
NamedAddressSpace addressSpace = getAddressSpace(session);
final Collection<MessageSource> sources = new HashSet<>();
final MessageSource queue = addressSpace.getAttainedMessageSource(queueName);
if (method.getArguments() != null && method.getArguments().get("x-multiqueue") instanceof Collection) {
for (Object object : (Collection<Object>) method.getArguments().get("x-multiqueue")) {
String sourceName = String.valueOf(object);
sourceName = sourceName.trim();
if (sourceName.length() != 0) {
MessageSource source = addressSpace.getAttainedMessageSource(sourceName);
if (source == null) {
sources.clear();
break;
} else {
sources.add(source);
}
}
}
queueName = method.getArguments().get("x-multiqueue").toString();
} else if (queue != null) {
sources.add(queue);
}
if (sources.isEmpty()) {
exception(session, method, ExecutionErrorCode.NOT_FOUND, "Queue: " + queueName + " not found");
} else if (!verifySessionAccess(session, sources)) {
exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Exclusive Queue: " + queueName + " owned exclusively by another session");
} else {
ProtocolEngine protocolEngine = getServerConnection(session).getAmqpConnection();
FlowCreditManager_0_10 creditManager = new WindowCreditManager(0L, 0L);
FilterManager filterManager = null;
try {
filterManager = FilterManagerFactory.createManager(method.getArguments());
} catch (AMQInvalidArgumentException amqe) {
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Exception Creating FilterManager");
return;
}
if (method.hasArguments() && method.getArguments().containsKey(AMQPFilterTypes.REPLAY_PERIOD.toString())) {
Object value = method.getArguments().get(AMQPFilterTypes.REPLAY_PERIOD.toString());
final long period;
if (value instanceof Number) {
period = ((Number) value).longValue();
} else if (value instanceof String) {
try {
period = Long.parseLong(value.toString());
} catch (NumberFormatException e) {
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Cannot parse value " + value + " as a number for filter " + AMQPFilterTypes.REPLAY_PERIOD.toString());
return;
}
} else {
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "Cannot parse value " + value + " as a number for filter " + AMQPFilterTypes.REPLAY_PERIOD.toString());
return;
}
final long startingFrom = System.currentTimeMillis() - (1000l * period);
if (filterManager == null) {
filterManager = new FilterManager();
}
MessageFilter filter = new ArrivalTimeFilter(startingFrom, period == 0);
filterManager.add(filter.getName(), filter);
}
boolean multiQueue = sources.size() > 1;
ConsumerTarget_0_10 target = new ConsumerTarget_0_10(session, destination, method.getAcceptMode(), method.getAcquireMode(), MessageFlowMode.WINDOW, creditManager, method.getArguments(), multiQueue);
Integer priority = null;
if (method.hasArguments() && method.getArguments().containsKey("x-priority")) {
Object value = method.getArguments().get("x-priority");
if (value instanceof Number) {
priority = ((Number) value).intValue();
} else if (value instanceof String) {
try {
priority = Integer.parseInt(value.toString());
} catch (NumberFormatException e) {
}
}
}
session.register(destination, target);
try {
EnumSet<ConsumerOption> options = EnumSet.noneOf(ConsumerOption.class);
if (method.getAcquireMode() == MessageAcquireMode.PRE_ACQUIRED) {
options.add(ConsumerOption.ACQUIRES);
}
if (method.getAcquireMode() != MessageAcquireMode.NOT_ACQUIRED || method.getAcceptMode() == MessageAcceptMode.EXPLICIT) {
options.add(ConsumerOption.SEES_REQUEUES);
}
if (method.getExclusive()) {
options.add(ConsumerOption.EXCLUSIVE);
}
for (MessageSource source : sources) {
source.addConsumer(target, filterManager, MessageTransferMessage.class, destination, options, priority);
}
target.updateNotifyWorkDesired();
} catch (Queue.ExistingExclusiveConsumer existing) {
exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Queue has an exclusive consumer");
} catch (Queue.ExistingConsumerPreventsExclusive exclusive) {
exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Queue has an existing consumer - can't subscribe exclusively");
} catch (AccessControlException e) {
exception(session, method, ExecutionErrorCode.UNAUTHORIZED_ACCESS, e.getMessage());
} catch (MessageSource.ConsumerAccessRefused consumerAccessRefused) {
exception(session, method, ExecutionErrorCode.RESOURCE_LOCKED, "Queue has an incompatible exclusivity policy");
} catch (MessageSource.QueueDeleted queueDeleted) {
exception(session, method, ExecutionErrorCode.NOT_FOUND, "Queue was deleted");
}
}
}
}
}
Aggregations