All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mongock.driver.mongodb.reactive.driver.MongoReactiveDriverBase Maven / Gradle / Ivy

The newest version!
package io.mongock.driver.mongodb.reactive.driver;

import com.mongodb.MongoClientException;
import com.mongodb.reactivestreams.client.ClientSession;
import com.mongodb.reactivestreams.client.MongoClient;
import io.mongock.api.exception.MongockException;
import io.mongock.driver.api.driver.ChangeSetDependency;
import io.mongock.driver.api.driver.Transactional;
import io.mongock.driver.mongodb.reactive.util.SubscriberSync;
import io.mongock.driver.mongodb.reactive.util.MongoSubscriberSync;
import io.mongock.utils.annotation.NotThreadSafe;
import org.reactivestreams.Publisher;

import java.util.Optional;
import java.util.Set;

@NotThreadSafe
public abstract class MongoReactiveDriverBase extends MongoReactiveDriverGeneric {

  private final MongoClient mongoClient;
  protected ClientSession clientSession;

  protected MongoReactiveDriverBase(MongoClient mongoClient,
                                    String databaseName,
                                    long lockAcquiredForMillis,
                                    long lockQuitTryingAfterMillis,
                                    long lockTryFrequencyMillis) {
    super(mongoClient.getDatabase(databaseName), lockAcquiredForMillis, lockQuitTryingAfterMillis, lockTryFrequencyMillis);
    this.mongoClient = mongoClient;
  }

  @Override
  public void prepareForExecutionBlock() {
    try {
      SubscriberSync subscriber = new MongoSubscriberSync<>();
      mongoClient.startSession().subscribe(subscriber);
      clientSession = subscriber.getFirst();
    } catch (MongoClientException ex) {
      throw new MongockException("ERROR starting session. If Mongock is connected to a MongoDB cluster which doesn't support transactions, you must to disable transactions", ex);
    }
  }

  @Override
  public Set getDependencies() {
    Set dependencies = super.getDependencies();
    if (clientSession != null) {
      ChangeSetDependency clientSessionDependency = new ChangeSetDependency(ClientSession.class, clientSession, false);
      dependencies.remove(clientSessionDependency);
      dependencies.add(clientSessionDependency);
    }

    return dependencies;
  }

  @Override
  public void executeInTransaction(Runnable operation) {
    try {
      changeEntryRepository.setClientSession(clientSession);

      //TODO confirm this is right
      clientSession.startTransaction(txOptions);
      operation.run();
      voidSubscribe(clientSession.commitTransaction());
    } catch (Exception ex) {
      voidSubscribe(clientSession.abortTransaction());
      throw new MongockException(ex);
    } finally {
      changeEntryRepository.clearClientSession();
      clientSession.close();
    }
  }

  private MongoSubscriberSync voidSubscribe(Publisher voidPublisher) {
    SubscriberSync subscriber = new MongoSubscriberSync<>();
    voidPublisher.subscribe(subscriber);
    return subscriber.await();
  }


  @Override
  public Optional getTransactioner() {
    return Optional.ofNullable(transactionEnabled ? this : null);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy