private void sendMessage(final CommandMessage message, final InternalConnection connection) { ByteBufferBsonOutput bsonOutput = new ByteBufferBsonOutput(connection); try { int documentPosition = message.encodeWithMetadata(bsonOutput).getFirstDocumentPosition(); sendStartedEvent(connection, bsonOutput, message, documentPosition); connection.sendMessage(bsonOutput.getByteBuffers(), message.getId()); } finally { bsonOutput.close(); } }
@Override public T execute(final InternalConnection connection) { if (LOGGER.isDebugEnabled()) { LOGGER.debug( format( "Sending command {%s : %s} to database %s on connection [%s] to server %s", getCommandName(), command.values().iterator().next(), namespace.getDatabaseName(), connection.getDescription().getConnectionId(), connection.getDescription().getServerAddress())); } long startTimeNanos = System.nanoTime(); CommandMessage commandMessage = new CommandMessage( namespace.getFullName(), command, slaveOk, fieldNameValidator, ProtocolHelper.getMessageSettings(connection.getDescription())); ResponseBuffers responseBuffers = null; try { sendMessage(commandMessage, connection); responseBuffers = connection.receiveMessage(commandMessage.getId()); if (!ProtocolHelper.isCommandOk( new BsonBinaryReader(new ByteBufferBsonInput(responseBuffers.getBodyByteBuffer())))) { throw getCommandFailureException( getResponseDocument(responseBuffers, commandMessage, new BsonDocumentCodec()), connection.getDescription().getServerAddress()); } T retval = getResponseDocument(responseBuffers, commandMessage, commandResultDecoder); if (commandListener != null) { sendSucceededEvent( connection.getDescription(), startTimeNanos, commandMessage, getResponseDocument(responseBuffers, commandMessage, new RawBsonDocumentCodec())); } LOGGER.debug("Command execution completed"); return retval; } catch (RuntimeException e) { sendFailedEvent(connection.getDescription(), startTimeNanos, commandMessage, e); throw e; } finally { if (responseBuffers != null) { responseBuffers.close(); } } }
@Override public void executeAsync( final InternalConnection connection, final SingleResultCallback<T> callback) { long startTimeNanos = System.nanoTime(); CommandMessage message = new CommandMessage( namespace.getFullName(), command, slaveOk, fieldNameValidator, ProtocolHelper.getMessageSettings(connection.getDescription())); boolean sentStartedEvent = false; try { if (LOGGER.isDebugEnabled()) { LOGGER.debug( format( "Asynchronously sending command {%s : %s} to database %s on connection [%s] to server %s", getCommandName(), command.values().iterator().next(), namespace.getDatabaseName(), connection.getDescription().getConnectionId(), connection.getDescription().getServerAddress())); } ByteBufferBsonOutput bsonOutput = new ByteBufferBsonOutput(connection); int documentPosition = ProtocolHelper.encodeMessageWithMetadata(message, bsonOutput).getFirstDocumentPosition(); sendStartedEvent(connection, bsonOutput, message, documentPosition); sentStartedEvent = true; SingleResultCallback<ResponseBuffers> receiveCallback = new CommandResultCallback(callback, message, connection.getDescription(), startTimeNanos); connection.sendMessageAsync( bsonOutput.getByteBuffers(), message.getId(), new SendMessageCallback<T>( connection, bsonOutput, message, getCommandName(), startTimeNanos, commandListener, callback, receiveCallback)); } catch (Throwable t) { if (sentStartedEvent) { sendFailedEvent(connection.getDescription(), startTimeNanos, message, t); } callback.onResult(null, t); } }
private static <D> D getResponseDocument( final ResponseBuffers responseBuffers, final CommandMessage commandMessage, final Decoder<D> decoder) { responseBuffers.reset(); ReplyMessage<D> replyMessage = new ReplyMessage<D>(responseBuffers, decoder, commandMessage.getId()); return replyMessage.getDocuments().get(0); }
CommandResultCallback( final SingleResultCallback<T> callback, final CommandMessage message, final ConnectionDescription connectionDescription, final long startTimeNanos) { super(message.getId(), connectionDescription.getServerAddress()); this.callback = callback; this.message = message; this.connectionDescription = connectionDescription; this.startTimeNanos = startTimeNanos; }