use of org.apache.qpid.server.util.ConnectionScopedRuntimeException in project qpid-broker-j by apache.
the class AMQPConnection_1_0Impl method processProtocolHeader.
private void processProtocolHeader(final QpidByteBuffer msg) {
if (msg.remaining() >= 8) {
byte[] header = new byte[8];
msg.get(header);
final AuthenticationProvider<?> authenticationProvider = getPort().getAuthenticationProvider();
if (Arrays.equals(header, SASL_HEADER)) {
if (_saslComplete) {
throw new ConnectionScopedRuntimeException("SASL Layer header received after SASL already established");
}
try (QpidByteBuffer protocolHeader = QpidByteBuffer.wrap(SASL_HEADER)) {
getSender().send(protocolHeader);
}
SaslMechanisms mechanisms = new SaslMechanisms();
ArrayList<Symbol> mechanismsList = new ArrayList<>();
for (String name : authenticationProvider.getAvailableMechanisms(getTransport().isSecure())) {
mechanismsList.add(Symbol.valueOf(name));
}
mechanisms.setSaslServerMechanisms(mechanismsList.toArray(new Symbol[mechanismsList.size()]));
send(new SASLFrame(mechanisms), null);
_connectionState = ConnectionState.AWAIT_SASL_INIT;
_frameHandler = getFrameHandler(true);
} else if (Arrays.equals(header, AMQP_HEADER)) {
if (!_saslComplete) {
final List<String> mechanisms = authenticationProvider.getAvailableMechanisms(getTransport().isSecure());
if (mechanisms.contains(ExternalAuthenticationManagerImpl.MECHANISM_NAME) && getNetwork().getPeerPrincipal() != null) {
setUserPrincipal(new AuthenticatedPrincipal(getNetwork().getPeerPrincipal()));
} else if (mechanisms.contains(AnonymousAuthenticationManager.MECHANISM_NAME)) {
setUserPrincipal(new AuthenticatedPrincipal(((AnonymousAuthenticationManager) authenticationProvider).getAnonymousPrincipal()));
} else {
LOGGER.warn("{} : attempt to initiate AMQP connection without correctly authenticating", getLogSubject());
_connectionState = ConnectionState.CLOSED;
getNetwork().close();
}
}
try (QpidByteBuffer protocolHeader = QpidByteBuffer.wrap(AMQP_HEADER)) {
getSender().send(protocolHeader);
}
_connectionState = ConnectionState.AWAIT_OPEN;
_frameHandler = getFrameHandler(false);
} else {
LOGGER.warn("{} : unknown AMQP header {}", getLogSubject(), Functions.str(header));
_connectionState = ConnectionState.CLOSED;
getNetwork().close();
}
}
}
use of org.apache.qpid.server.util.ConnectionScopedRuntimeException in project qpid-broker-j by apache.
the class AMQPConnection_1_0Impl method closeConnection.
private void closeConnection(final Error error) {
_closeCause = error.getDescription();
Close close = new Close();
close.setError(error);
switch(_connectionState) {
case AWAIT_AMQP_OR_SASL_HEADER:
case AWAIT_SASL_INIT:
case AWAIT_SASL_RESPONSE:
case AWAIT_AMQP_HEADER:
throw new ConnectionScopedRuntimeException("Connection is closed before being fully established: " + error.getDescription());
case AWAIT_OPEN:
sendOpen(0, 0);
sendClose(close);
_connectionState = ConnectionState.CLOSED;
break;
case OPENED:
sendClose(close);
_connectionState = ConnectionState.CLOSE_SENT;
addCloseTicker();
break;
case CLOSE_RECEIVED:
sendClose(close);
_connectionState = ConnectionState.CLOSED;
addCloseTicker();
break;
case CLOSE_SENT:
case CLOSED:
// already sent our close - too late to do anything more
break;
default:
throw new ServerScopedRuntimeException("Unknown state: " + _connectionState);
}
}
use of org.apache.qpid.server.util.ConnectionScopedRuntimeException in project qpid-broker-j by apache.
the class AMQPConnection_1_0Impl method receiveClose.
@Override
public void receiveClose(final int channel, final Close close) {
switch(_connectionState) {
case AWAIT_AMQP_OR_SASL_HEADER:
case AWAIT_SASL_INIT:
case AWAIT_SASL_RESPONSE:
case AWAIT_AMQP_HEADER:
throw new ConnectionScopedRuntimeException("Received unexpected close when AMQP connection has not been established.");
case AWAIT_OPEN:
closeReceived();
closeConnection(ConnectionError.CONNECTION_FORCED, "Connection close sent before connection was opened");
break;
case OPENED:
_connectionState = ConnectionState.CLOSE_RECEIVED;
closeReceived();
if (close.getError() != null) {
final Error error = close.getError();
ErrorCondition condition = error.getCondition();
Symbol errorCondition = condition == null ? null : condition.getValue();
LOGGER.info("{} : Connection closed with error : {} - {}", getLogSubject(), errorCondition, close.getError().getDescription());
}
sendClose(new Close());
_connectionState = ConnectionState.CLOSED;
_orderlyClose.set(true);
addCloseTicker();
break;
case CLOSE_SENT:
closeReceived();
_connectionState = ConnectionState.CLOSED;
_orderlyClose.set(true);
break;
case CLOSE_RECEIVED:
case CLOSED:
break;
default:
throw new ServerScopedRuntimeException("Unknown state: " + _connectionState);
}
}
use of org.apache.qpid.server.util.ConnectionScopedRuntimeException in project qpid-broker-j by apache.
the class AMQPConnection_1_0Impl method receiveOpenInternal.
private void receiveOpenInternal(final NamedAddressSpace addressSpace) {
if (!addressSpace.isActive()) {
final Error err = new Error();
err.setCondition(AmqpError.NOT_FOUND);
populateConnectionRedirect(addressSpace, err);
closeConnection(err);
} else {
if (AuthenticatedPrincipal.getOptionalAuthenticatedPrincipalFromSubject(getSubject()) == null) {
closeConnection(AmqpError.NOT_ALLOWED, "Connection has not been authenticated");
} else {
try {
boolean registerSucceeded = addressSpace.registerConnection(this, (existingConnections, newConnection) -> {
boolean proceedWithRegistration = true;
if (newConnection instanceof AMQPConnection_1_0Impl && !newConnection.isClosing()) {
List<ListenableFuture<Void>> rescheduleFutures = new ArrayList<>();
for (AMQPConnection<?> existingConnection : StreamSupport.stream(existingConnections.spliterator(), false).filter(con -> con instanceof AMQPConnection_1_0).filter(con -> !con.isClosing()).filter(con -> con.getRemoteContainerName().equals(newConnection.getRemoteContainerName())).collect(Collectors.toList())) {
SoleConnectionEnforcementPolicy soleConnectionEnforcementPolicy = null;
if (((AMQPConnection_1_0Impl) existingConnection)._soleConnectionEnforcementPolicy != null) {
soleConnectionEnforcementPolicy = ((AMQPConnection_1_0Impl) existingConnection)._soleConnectionEnforcementPolicy;
} else if (((AMQPConnection_1_0Impl) newConnection)._soleConnectionEnforcementPolicy != null) {
soleConnectionEnforcementPolicy = ((AMQPConnection_1_0Impl) newConnection)._soleConnectionEnforcementPolicy;
}
if (SoleConnectionEnforcementPolicy.REFUSE_CONNECTION.equals(soleConnectionEnforcementPolicy)) {
_properties.put(Symbol.valueOf("amqp:connection-establishment-failed"), true);
Error error = new Error(AmqpError.INVALID_FIELD, String.format("Connection closed due to sole-connection-enforcement-policy '%s'", soleConnectionEnforcementPolicy.toString()));
error.setInfo(Collections.singletonMap(Symbol.valueOf("invalid-field"), Symbol.valueOf("container-id")));
newConnection.doOnIOThreadAsync(() -> ((AMQPConnection_1_0Impl) newConnection).closeConnection(error));
proceedWithRegistration = false;
break;
} else if (SoleConnectionEnforcementPolicy.CLOSE_EXISTING.equals(soleConnectionEnforcementPolicy)) {
final Error error = new Error(AmqpError.RESOURCE_LOCKED, String.format("Connection closed due to sole-connection-enforcement-policy '%s'", soleConnectionEnforcementPolicy.toString()));
error.setInfo(Collections.singletonMap(Symbol.valueOf("sole-connection-enforcement"), true));
rescheduleFutures.add(existingConnection.doOnIOThreadAsync(() -> ((AMQPConnection_1_0Impl) existingConnection).closeConnection(error)));
proceedWithRegistration = false;
}
}
if (!rescheduleFutures.isEmpty()) {
doAfter(allAsList(rescheduleFutures), () -> newConnection.doOnIOThreadAsync(() -> receiveOpenInternal(addressSpace)));
}
}
return proceedWithRegistration;
});
if (registerSucceeded) {
setAddressSpace(addressSpace);
if (!addressSpace.authoriseCreateConnection(this)) {
closeConnection(AmqpError.NOT_ALLOWED, "Connection refused");
} else {
switch(_connectionState) {
case AWAIT_OPEN:
sendOpen(_channelMax, _maxFrameSize);
_connectionState = ConnectionState.OPENED;
break;
case CLOSE_SENT:
case CLOSED:
// already sent our close - probably due to an error
break;
default:
throw new ConnectionScopedRuntimeException(String.format("Unexpected state %s during connection open.", _connectionState));
}
}
}
} catch (VirtualHostUnavailableException | AccessControlException e) {
closeConnection(AmqpError.NOT_ALLOWED, e.getMessage());
}
}
}
}
use of org.apache.qpid.server.util.ConnectionScopedRuntimeException in project qpid-broker-j by apache.
the class MessageConverter_from_1_0 method convertBodyToObject.
static Object convertBodyToObject(final Message_1_0 serverMessage) {
SectionDecoderImpl sectionDecoder = new SectionDecoderImpl(MessageConverter_v1_0_to_Internal.TYPE_REGISTRY.getSectionDecoderRegistry());
Object bodyObject = null;
List<EncodingRetainingSection<?>> sections = null;
try {
try (QpidByteBuffer allData = serverMessage.getContent()) {
sections = sectionDecoder.parseAll(allData);
}
List<EncodingRetainingSection<?>> bodySections = new ArrayList<>(sections.size());
ListIterator<EncodingRetainingSection<?>> iterator = sections.listIterator();
EncodingRetainingSection<?> previousSection = null;
while (iterator.hasNext()) {
EncodingRetainingSection<?> section = iterator.next();
if (section instanceof AmqpValueSection || section instanceof DataSection || section instanceof AmqpSequenceSection) {
if (previousSection != null && (previousSection.getClass() != section.getClass() || section instanceof AmqpValueSection)) {
throw new MessageConversionException("Message is badly formed and has multiple body section which are not all Data or not all AmqpSequence");
} else {
previousSection = section;
}
bodySections.add(section);
}
}
// In 1.0 of the spec, it is illegal to have message with no body but AMQP-127 asks to have that restriction lifted
if (!bodySections.isEmpty()) {
EncodingRetainingSection<?> firstBodySection = bodySections.get(0);
if (firstBodySection instanceof AmqpValueSection) {
bodyObject = convertValue(firstBodySection.getValue());
} else if (firstBodySection instanceof DataSection) {
int totalSize = 0;
for (EncodingRetainingSection<?> section : bodySections) {
totalSize += ((DataSection) section).getValue().getArray().length;
}
byte[] bodyData = new byte[totalSize];
ByteBuffer buf = ByteBuffer.wrap(bodyData);
for (EncodingRetainingSection<?> section : bodySections) {
buf.put(((DataSection) section).getValue().asByteBuffer());
}
bodyObject = bodyData;
} else {
ArrayList<Object> totalSequence = new ArrayList<>();
for (EncodingRetainingSection<?> section : bodySections) {
totalSequence.addAll(((AmqpSequenceSection) section).getValue());
}
bodyObject = convertValue(totalSequence);
}
}
} catch (AmqpErrorException e) {
throw new ConnectionScopedRuntimeException(e);
} finally {
if (sections != null) {
sections.forEach(EncodingRetaining::dispose);
}
}
return bodyObject;
}
Aggregations