Search in sources :

Example 1 with SessionContext

use of com.mongodb.internal.session.SessionContext in project mongo-java-driver by mongodb.

the class MixedBulkWriteOperation method executeAsync.

public void executeAsync(final AsyncWriteBinding binding, final SingleResultCallback<BulkWriteResult> callback) {
    // see the comment in `execute(WriteBinding)` explaining the manual tracking of attempts
    RetryState retryState = new RetryState();
    BulkWriteTracker.attachNew(retryState, retryWrites);
    binding.retain();
    AsyncCallbackSupplier<BulkWriteResult> retryingBulkWrite = this.<BulkWriteResult>decorateWriteWithRetries(retryState, funcCallback -> {
        logRetryExecute(retryState);
        withAsyncSourceAndConnection(binding::getWriteConnectionSource, true, funcCallback, (source, connection, releasingCallback) -> {
            ConnectionDescription connectionDescription = connection.getDescription();
            int maxWireVersion = connectionDescription.getMaxWireVersion();
            // attach `maxWireVersion` ASAP because it is used to check whether we can retry
            retryState.attach(AttachmentKeys.maxWireVersion(), maxWireVersion, true);
            BulkWriteTracker bulkWriteTracker = retryState.attachment(AttachmentKeys.bulkWriteTracker()).orElseThrow(Assertions::fail);
            SessionContext sessionContext = binding.getSessionContext();
            WriteConcern writeConcern = getAppliedWriteConcern(sessionContext);
            if (!retryState.isFirstAttempt() && !isRetryableWrite(retryWrites, writeConcern, source.getServerDescription(), connectionDescription, sessionContext)) {
                Throwable prospectiveFailedResult = retryState.exception().orElse(null);
                if (retryState.breakAndCompleteIfRetryAnd(() -> !(prospectiveFailedResult instanceof MongoWriteConcernWithResponseException), releasingCallback)) {
                    return;
                }
                bulkWriteTracker.batch().ifPresent(bulkWriteBatch -> {
                    assertTrue(prospectiveFailedResult instanceof MongoWriteConcernWithResponseException);
                    bulkWriteBatch.addResult((BsonDocument) ((MongoWriteConcernWithResponseException) prospectiveFailedResult).getResponse());
                    BulkWriteTracker.attachNext(retryState, bulkWriteBatch);
                });
            }
            if (validateWriteRequestsAndCompleteIfInvalid(connectionDescription, bypassDocumentValidation, writeRequests, writeConcern, releasingCallback)) {
                return;
            }
            if (writeConcern.isAcknowledged() || serverIsAtLeastVersionThreeDotSix(connectionDescription)) {
                try {
                    if (!bulkWriteTracker.batch().isPresent()) {
                        BulkWriteTracker.attachNew(retryState, BulkWriteBatch.createBulkWriteBatch(namespace, source.getServerDescription(), connectionDescription, ordered, writeConcern, bypassDocumentValidation, retryWrites, writeRequests, sessionContext));
                    }
                } catch (Throwable t) {
                    releasingCallback.onResult(null, t);
                    return;
                }
                logRetryExecute(retryState);
                executeBulkWriteBatchAsync(retryState, binding, connection, maxWireVersion, releasingCallback);
            } else {
                retryState.markAsLastAttempt();
                executeLegacyBatchesAsync(binding, connection, releasingCallback);
            }
        });
    }).whenComplete(binding::release);
    retryingBulkWrite.get(exceptionTransformingCallback(errorHandlingCallback(callback, LOGGER)));
}
Also used : LoopState(com.mongodb.internal.async.function.LoopState) WriteRequest(com.mongodb.internal.bulk.WriteRequest) CommandOperationHelper.addRetryableWriteErrorLabel(com.mongodb.internal.operation.CommandOperationHelper.addRetryableWriteErrorLabel) MongoBulkWriteException(com.mongodb.MongoBulkWriteException) MongoWriteConcernWithResponseException(com.mongodb.internal.connection.MongoWriteConcernWithResponseException) ProtocolHelper(com.mongodb.internal.connection.ProtocolHelper) ConnectionDescription(com.mongodb.connection.ConnectionDescription) BsonArray(org.bson.BsonArray) OperationHelper.validateWriteRequests(com.mongodb.internal.operation.OperationHelper.validateWriteRequests) OperationHelper.withSourceAndConnection(com.mongodb.internal.operation.OperationHelper.withSourceAndConnection) MongoException(com.mongodb.MongoException) AsyncCallbackSupplier(com.mongodb.internal.async.function.AsyncCallbackSupplier) Set(java.util.Set) Collectors(java.util.stream.Collectors) AsyncCallbackRunnable(com.mongodb.internal.async.function.AsyncCallbackRunnable) ServerVersionHelper.serverIsAtLeastVersionThreeDotSix(com.mongodb.internal.operation.ServerVersionHelper.serverIsAtLeastVersionThreeDotSix) SingleResultCallback(com.mongodb.internal.async.SingleResultCallback) REPLACE(com.mongodb.internal.bulk.WriteRequest.Type.REPLACE) RetryState(com.mongodb.internal.async.function.RetryState) List(java.util.List) Assertions.notNull(com.mongodb.assertions.Assertions.notNull) Optional(java.util.Optional) RetryingSyncSupplier(com.mongodb.internal.async.function.RetryingSyncSupplier) InsertRequest(com.mongodb.internal.bulk.InsertRequest) RetryingAsyncCallbackSupplier(com.mongodb.internal.async.function.RetryingAsyncCallbackSupplier) CommandOperationHelper.logRetryExecute(com.mongodb.internal.operation.CommandOperationHelper.logRetryExecute) CommandOperationHelper.exceptionTransformingCallback(com.mongodb.internal.operation.CommandOperationHelper.exceptionTransformingCallback) ErrorHandlingResultCallback.errorHandlingCallback(com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback) BsonString(org.bson.BsonString) Supplier(java.util.function.Supplier) BsonDocument(org.bson.BsonDocument) LOGGER(com.mongodb.internal.operation.OperationHelper.LOGGER) Connection(com.mongodb.internal.connection.Connection) NoOpFieldNameValidator(com.mongodb.internal.validator.NoOpFieldNameValidator) WriteBinding(com.mongodb.internal.binding.WriteBinding) Assertions(com.mongodb.assertions.Assertions) WriteConcernResult(com.mongodb.WriteConcernResult) AsyncCallbackLoop(com.mongodb.internal.async.function.AsyncCallbackLoop) AsyncWriteBinding(com.mongodb.internal.binding.AsyncWriteBinding) DeleteRequest(com.mongodb.internal.bulk.DeleteRequest) SessionContext(com.mongodb.internal.session.SessionContext) FieldNameValidator(org.bson.FieldNameValidator) OperationHelper.validateWriteRequestsAndCompleteIfInvalid(com.mongodb.internal.operation.OperationHelper.validateWriteRequestsAndCompleteIfInvalid) INSERT(com.mongodb.internal.bulk.WriteRequest.Type.INSERT) MongoNamespace(com.mongodb.MongoNamespace) UpdateRequest(com.mongodb.internal.bulk.UpdateRequest) OperationHelper.isRetryableWrite(com.mongodb.internal.operation.OperationHelper.isRetryableWrite) CommandOperationHelper.transformWriteException(com.mongodb.internal.operation.CommandOperationHelper.transformWriteException) Assertions.isTrueArgument(com.mongodb.assertions.Assertions.isTrueArgument) Assertions.assertTrue(com.mongodb.assertions.Assertions.assertTrue) OperationHelper.withAsyncSourceAndConnection(com.mongodb.internal.operation.OperationHelper.withAsyncSourceAndConnection) BulkWriteResult(com.mongodb.bulk.BulkWriteResult) Nullable(com.mongodb.lang.Nullable) WriteConcern(com.mongodb.WriteConcern) UPDATE(com.mongodb.internal.bulk.WriteRequest.Type.UPDATE) AsyncConnection(com.mongodb.internal.connection.AsyncConnection) AttachmentKeys(com.mongodb.internal.operation.retry.AttachmentKeys) ConnectionDescription(com.mongodb.connection.ConnectionDescription) MongoWriteConcernWithResponseException(com.mongodb.internal.connection.MongoWriteConcernWithResponseException) BsonDocument(org.bson.BsonDocument) WriteConcern(com.mongodb.WriteConcern) SessionContext(com.mongodb.internal.session.SessionContext) BulkWriteResult(com.mongodb.bulk.BulkWriteResult) RetryState(com.mongodb.internal.async.function.RetryState)

Example 2 with SessionContext

use of com.mongodb.internal.session.SessionContext in project mongo-java-driver by mongodb.

the class CryptConnection method commandAsync.

@Override
public <T> void commandAsync(final String database, final BsonDocument command, final FieldNameValidator commandFieldNameValidator, final ReadPreference readPreference, final Decoder<T> commandResultDecoder, final SessionContext sessionContext, final ServerApi serverApi, final RequestContext requestContext, final boolean responseExpected, @Nullable final SplittablePayload payload, @Nullable final FieldNameValidator payloadFieldNameValidator, final SingleResultCallback<T> callback) {
    if (serverIsLessThanVersionFourDotTwo(wrapped.getDescription())) {
        callback.onResult(null, new MongoClientException("Auto-encryption requires a minimum MongoDB version of 4.2"));
        return;
    }
    try {
        BasicOutputBuffer bsonOutput = new BasicOutputBuffer();
        BsonBinaryWriter bsonBinaryWriter = new BsonBinaryWriter(new BsonWriterSettings(), new BsonBinaryWriterSettings(getDescription().getMaxDocumentSize()), bsonOutput, getFieldNameValidator(payload, commandFieldNameValidator, payloadFieldNameValidator));
        BsonWriter writer = payload == null ? bsonBinaryWriter : new SplittablePayloadBsonWriter(bsonBinaryWriter, bsonOutput, createSplittablePayloadMessageSettings(), payload, MAX_SPLITTABLE_DOCUMENT_SIZE);
        getEncoder(command).encode(writer, command, EncoderContext.builder().build());
        crypt.encrypt(database, new RawBsonDocument(bsonOutput.getInternalBuffer(), 0, bsonOutput.getSize())).flatMap((Function<RawBsonDocument, Mono<RawBsonDocument>>) encryptedCommand -> Mono.create(sink -> wrapped.commandAsync(database, encryptedCommand, commandFieldNameValidator, readPreference, new RawBsonDocumentCodec(), sessionContext, serverApi, requestContext, responseExpected, null, null, sinkToCallback(sink)))).flatMap(crypt::decrypt).map(decryptedResponse -> commandResultDecoder.decode(new BsonBinaryReader(decryptedResponse.getByteBuffer().asNIO()), DecoderContext.builder().build())).subscribe(decryptedResult -> callback.onResult(decryptedResult, null), e -> callback.onResult(null, e));
    } catch (Throwable t) {
        callback.onResult(null, t);
    }
}
Also used : ReadPreference(com.mongodb.ReadPreference) InsertRequest(com.mongodb.internal.bulk.InsertRequest) MongoClientException(com.mongodb.MongoClientException) ServerApi(com.mongodb.ServerApi) HashMap(java.util.HashMap) CodecRegistry(org.bson.codecs.configuration.CodecRegistry) SplittablePayloadBsonWriter(com.mongodb.internal.connection.SplittablePayloadBsonWriter) BsonBinaryWriter(org.bson.BsonBinaryWriter) Function(java.util.function.Function) BsonDocument(org.bson.BsonDocument) ConnectionDescription(com.mongodb.connection.ConnectionDescription) Connection(com.mongodb.internal.connection.Connection) Map(java.util.Map) WriteConcernResult(com.mongodb.WriteConcernResult) DeleteRequest(com.mongodb.internal.bulk.DeleteRequest) SessionContext(com.mongodb.internal.session.SessionContext) MappedFieldNameValidator(com.mongodb.internal.validator.MappedFieldNameValidator) FieldNameValidator(org.bson.FieldNameValidator) BsonBinaryWriterSettings(org.bson.BsonBinaryWriterSettings) DecoderContext(org.bson.codecs.DecoderContext) RawBsonDocumentCodec(org.bson.codecs.RawBsonDocumentCodec) EncoderContext(org.bson.codecs.EncoderContext) QueryResult(com.mongodb.internal.connection.QueryResult) MongoNamespace(com.mongodb.MongoNamespace) MessageSettings(com.mongodb.internal.connection.MessageSettings) UpdateRequest(com.mongodb.internal.bulk.UpdateRequest) RawBsonDocument(org.bson.RawBsonDocument) CodecRegistries.fromProviders(org.bson.codecs.configuration.CodecRegistries.fromProviders) BasicOutputBuffer(org.bson.io.BasicOutputBuffer) Mono(reactor.core.publisher.Mono) RequestContext(com.mongodb.RequestContext) BsonValueCodecProvider(org.bson.codecs.BsonValueCodecProvider) ServerVersionHelper.serverIsLessThanVersionFourDotTwo(com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionFourDotTwo) SplittablePayload(com.mongodb.internal.connection.SplittablePayload) SingleResultCallback(com.mongodb.internal.async.SingleResultCallback) Decoder(org.bson.codecs.Decoder) List(java.util.List) BsonBinaryReader(org.bson.BsonBinaryReader) Codec(org.bson.codecs.Codec) BsonWriter(org.bson.BsonWriter) MongoOperationPublisher.sinkToCallback(com.mongodb.reactivestreams.client.internal.MongoOperationPublisher.sinkToCallback) Nullable(com.mongodb.lang.Nullable) AsyncConnection(com.mongodb.internal.connection.AsyncConnection) BsonWriterSettings(org.bson.BsonWriterSettings) MongoClientException(com.mongodb.MongoClientException) RawBsonDocumentCodec(org.bson.codecs.RawBsonDocumentCodec) BsonBinaryReader(org.bson.BsonBinaryReader) SplittablePayloadBsonWriter(com.mongodb.internal.connection.SplittablePayloadBsonWriter) BsonWriter(org.bson.BsonWriter) RawBsonDocument(org.bson.RawBsonDocument) Function(java.util.function.Function) SplittablePayloadBsonWriter(com.mongodb.internal.connection.SplittablePayloadBsonWriter) BsonBinaryWriter(org.bson.BsonBinaryWriter) BsonBinaryWriterSettings(org.bson.BsonBinaryWriterSettings) BsonWriterSettings(org.bson.BsonWriterSettings) BasicOutputBuffer(org.bson.io.BasicOutputBuffer)

Example 3 with SessionContext

use of com.mongodb.internal.session.SessionContext in project mongo-java-driver by mongodb.

the class MixedBulkWriteOperation method execute.

/**
 * Executes a bulk write operation.
 *
 * @param binding the WriteBinding        for the operation
 * @return the bulk write result.
 * @throws MongoBulkWriteException if a failure to complete the bulk write is detected based on the server response
 */
@Override
public BulkWriteResult execute(final WriteBinding binding) {
    /* We cannot use the tracking of attempts built in the `RetryState` class because conceptually we have to maintain multiple attempt
         * counters while executing a single bulk write operation:
         * - a counter that limits attempts to select server and checkout a connection before we created a batch;
         * - a counter per each batch that limits attempts to execute the specific batch.
         * Fortunately, these counters do not exist concurrently with each other. While maintaining the counters manually,
         * we must adhere to the contract of `RetryingSyncSupplier`. When the retry timeout is implemented, there will be no counters,
         * and the code related to the attempt tracking in `BulkWriteTracker` will be removed. */
    RetryState retryState = new RetryState();
    BulkWriteTracker.attachNew(retryState, retryWrites);
    Supplier<BulkWriteResult> retryingBulkWrite = decorateWriteWithRetries(retryState, () -> {
        logRetryExecute(retryState);
        return withSourceAndConnection(binding::getWriteConnectionSource, true, (source, connection) -> {
            ConnectionDescription connectionDescription = connection.getDescription();
            int maxWireVersion = connectionDescription.getMaxWireVersion();
            // attach `maxWireVersion` ASAP because it is used to check whether we can retry
            retryState.attach(AttachmentKeys.maxWireVersion(), maxWireVersion, true);
            BulkWriteTracker bulkWriteTracker = retryState.attachment(AttachmentKeys.bulkWriteTracker()).orElseThrow(Assertions::fail);
            SessionContext sessionContext = binding.getSessionContext();
            WriteConcern writeConcern = getAppliedWriteConcern(sessionContext);
            if (!retryState.isFirstAttempt() && !isRetryableWrite(retryWrites, writeConcern, source.getServerDescription(), connectionDescription, sessionContext)) {
                RuntimeException prospectiveFailedResult = (RuntimeException) retryState.exception().orElse(null);
                retryState.breakAndThrowIfRetryAnd(() -> !(prospectiveFailedResult instanceof MongoWriteConcernWithResponseException));
                bulkWriteTracker.batch().ifPresent(bulkWriteBatch -> {
                    assertTrue(prospectiveFailedResult instanceof MongoWriteConcernWithResponseException);
                    bulkWriteBatch.addResult((BsonDocument) ((MongoWriteConcernWithResponseException) prospectiveFailedResult).getResponse());
                    BulkWriteTracker.attachNext(retryState, bulkWriteBatch);
                });
            }
            validateWriteRequests(connectionDescription, bypassDocumentValidation, writeRequests, writeConcern);
            if (writeConcern.isAcknowledged() || serverIsAtLeastVersionThreeDotSix(connectionDescription)) {
                if (!bulkWriteTracker.batch().isPresent()) {
                    BulkWriteTracker.attachNew(retryState, BulkWriteBatch.createBulkWriteBatch(namespace, source.getServerDescription(), connectionDescription, ordered, writeConcern, bypassDocumentValidation, retryWrites, writeRequests, sessionContext));
                }
                logRetryExecute(retryState);
                return executeBulkWriteBatch(retryState, binding, connection, maxWireVersion);
            } else {
                retryState.markAsLastAttempt();
                return executeLegacyBatches(binding, connection);
            }
        });
    });
    try {
        return retryingBulkWrite.get();
    } catch (MongoException e) {
        throw transformWriteException(e);
    }
}
Also used : MongoException(com.mongodb.MongoException) Assertions(com.mongodb.assertions.Assertions) BulkWriteResult(com.mongodb.bulk.BulkWriteResult) ConnectionDescription(com.mongodb.connection.ConnectionDescription) MongoWriteConcernWithResponseException(com.mongodb.internal.connection.MongoWriteConcernWithResponseException) WriteConcern(com.mongodb.WriteConcern) SessionContext(com.mongodb.internal.session.SessionContext) RetryState(com.mongodb.internal.async.function.RetryState)

Aggregations

ConnectionDescription (com.mongodb.connection.ConnectionDescription)3 MongoException (com.mongodb.MongoException)2 MongoNamespace (com.mongodb.MongoNamespace)2 WriteConcern (com.mongodb.WriteConcern)2 WriteConcernResult (com.mongodb.WriteConcernResult)2 Assertions (com.mongodb.assertions.Assertions)2 BulkWriteResult (com.mongodb.bulk.BulkWriteResult)2 SingleResultCallback (com.mongodb.internal.async.SingleResultCallback)2 RetryState (com.mongodb.internal.async.function.RetryState)2 DeleteRequest (com.mongodb.internal.bulk.DeleteRequest)2 InsertRequest (com.mongodb.internal.bulk.InsertRequest)2 UpdateRequest (com.mongodb.internal.bulk.UpdateRequest)2 AsyncConnection (com.mongodb.internal.connection.AsyncConnection)2 Connection (com.mongodb.internal.connection.Connection)2 MongoWriteConcernWithResponseException (com.mongodb.internal.connection.MongoWriteConcernWithResponseException)2 SessionContext (com.mongodb.internal.session.SessionContext)2 MongoBulkWriteException (com.mongodb.MongoBulkWriteException)1 MongoClientException (com.mongodb.MongoClientException)1 ReadPreference (com.mongodb.ReadPreference)1 RequestContext (com.mongodb.RequestContext)1