use of org.apache.qpid.server.protocol.v1_0.type.transport.Error 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.protocol.v1_0.type.transport.Error in project qpid-broker-j by apache.
the class AMQPConnection_1_0Impl method receiveBegin.
@Override
public void receiveBegin(final int receivingChannelId, final Begin begin) {
assertState(ConnectionState.OPENED);
if (begin.getRemoteChannel() != null) {
closeConnection(ConnectionError.FRAMING_ERROR, "BEGIN received on channel " + receivingChannelId + " with given remote-channel " + begin.getRemoteChannel() + ". Since the broker does not spontaneously start channels, this must be an error.");
} else // Peer requesting session creation
{
if (_receivingSessions[receivingChannelId] == null) {
int sendingChannelId = getFirstFreeChannel();
if (sendingChannelId == -1) {
closeConnection(ConnectionError.FRAMING_ERROR, "BEGIN received on channel " + receivingChannelId + ". There are no free channels for the broker to respond on.");
} else {
Session_1_0 session = new Session_1_0(this, begin, sendingChannelId, receivingChannelId, getContextValue(Long.class, AMQPConnection_1_0.CONNECTION_SESSION_CREDIT_WINDOW_SIZE));
session.create();
_receivingSessions[receivingChannelId] = session;
_sendingSessions[sendingChannelId] = session;
Begin beginToSend = new Begin();
beginToSend.setRemoteChannel(UnsignedShort.valueOf(receivingChannelId));
beginToSend.setNextOutgoingId(session.getNextOutgoingId());
beginToSend.setOutgoingWindow(session.getOutgoingWindow());
beginToSend.setIncomingWindow(session.getIncomingWindow());
sendFrame(sendingChannelId, beginToSend);
synchronized (_blockingLock) {
_sessions.add(session);
if (_blocking) {
session.block();
}
}
}
} else {
closeConnection(ConnectionError.FRAMING_ERROR, "BEGIN received on channel " + receivingChannelId + " which is already in use.");
}
}
}
use of org.apache.qpid.server.protocol.v1_0.type.transport.Error 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.protocol.v1_0.type.transport.Error 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.protocol.v1_0.type.transport.Error in project qpid-broker-j by apache.
the class AbstractLinkEndpoint method handleOversizedUnsettledMapIfNecessary.
private Attach handleOversizedUnsettledMapIfNecessary(final Attach attachToSend) {
final AMQPDescribedTypeRegistry describedTypeRegistry = getSession().getConnection().getDescribedTypeRegistry();
final ValueWriter<Attach> valueWriter = describedTypeRegistry.getValueWriter(attachToSend);
if (valueWriter.getEncodedSize() + 8 > getSession().getConnection().getMaxFrameSize()) {
_localIncompleteUnsettled = true;
attachToSend.setIncompleteUnsettled(true);
final int targetSize = getSession().getConnection().getMaxFrameSize();
int lowIndex = 0;
Map<Binary, DeliveryState> localUnsettledMap = attachToSend.getUnsettled();
if (localUnsettledMap == null) {
localUnsettledMap = Collections.emptyMap();
}
int highIndex = localUnsettledMap.size();
int currentIndex = (highIndex - lowIndex) / 2;
int oldIndex;
HashMap<Binary, DeliveryState> unsettledMap = null;
int totalSize;
do {
HashMap<Binary, DeliveryState> partialUnsettledMap = new HashMap<>(currentIndex);
final Iterator<Map.Entry<Binary, DeliveryState>> iterator = localUnsettledMap.entrySet().iterator();
for (int i = 0; i < currentIndex; ++i) {
final Map.Entry<Binary, DeliveryState> entry = iterator.next();
partialUnsettledMap.put(entry.getKey(), entry.getValue());
}
attachToSend.setUnsettled(partialUnsettledMap);
totalSize = describedTypeRegistry.getValueWriter(attachToSend).getEncodedSize() + FRAME_HEADER_SIZE;
if (totalSize > targetSize) {
highIndex = currentIndex;
} else if (totalSize < targetSize) {
lowIndex = currentIndex;
unsettledMap = partialUnsettledMap;
} else {
lowIndex = highIndex = currentIndex;
unsettledMap = partialUnsettledMap;
}
oldIndex = currentIndex;
currentIndex = lowIndex + (highIndex - lowIndex) / 2;
} while (oldIndex != currentIndex);
if (unsettledMap == null || unsettledMap.isEmpty()) {
final End endWithError = new End();
endWithError.setError(new Error(AmqpError.FRAME_SIZE_TOO_SMALL, "Cannot fit a single unsettled delivery into Attach frame."));
getSession().end(endWithError);
}
attachToSend.setUnsettled(unsettledMap);
} else {
_localIncompleteUnsettled = false;
}
return attachToSend;
}
Aggregations