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

io.mongock.driver.mongodb.reactive.repository.MongoReactiveChangeEntryRepository Maven / Gradle / Ivy

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


import com.mongodb.client.model.Filters;
import com.mongodb.client.model.ReplaceOptions;
import com.mongodb.client.result.UpdateResult;
import com.mongodb.reactivestreams.client.ClientSession;
import com.mongodb.reactivestreams.client.MongoCollection;
import io.mongock.api.exception.MongockException;
import io.mongock.driver.api.entry.ChangeEntry;
import io.mongock.driver.api.entry.ChangeState;
import io.mongock.driver.api.entry.ChangeType;
import io.mongock.driver.core.entry.ChangeEntryRepositoryWithEntity;
import io.mongock.utils.DateUtils;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static io.mongock.driver.api.entry.ChangeEntry.KEY_ERROR_TRACE;
import static io.mongock.driver.api.entry.ChangeEntry.KEY_EXECUTION_HOST_NAME;

public class MongoReactiveChangeEntryRepository extends MongoReactiveRepositoryBase implements ChangeEntryRepositoryWithEntity {

  private final static Logger logger = LoggerFactory.getLogger(MongoReactiveChangeEntryRepository.class);


  protected static String KEY_EXECUTION_ID;
  protected static String KEY_CHANGE_ID;
  protected static String KEY_STATE;
  protected static String KEY_TYPE;
  protected static String KEY_AUTHOR;
  protected static String KEY_TIMESTAMP;
  protected static String KEY_CHANGELOG_CLASS;
  protected static String KEY_CHANGESET_METHOD;
  protected static String KEY_EXECUTION_MILLIS;
  protected static String KEY_EXECUTION_HOSTNAME;
  protected static String KEY_METADATA;
  protected static String KEY_SYSTEM_CHANGE;

  private ClientSession clientSession;

  static {
    try {
      Field field = ChangeEntry.class.getDeclaredField("executionId");
      field.setAccessible(true);
      KEY_EXECUTION_ID = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("changeId");
      field.setAccessible(true);
      KEY_CHANGE_ID = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("state");
      field.setAccessible(true);
      KEY_STATE = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("type");
      field.setAccessible(true);
      KEY_TYPE = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("author");
      field.setAccessible(true);
      KEY_AUTHOR = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("timestamp");
      field.setAccessible(true);
      KEY_TIMESTAMP = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("changeLogClass");
      field.setAccessible(true);
      KEY_CHANGELOG_CLASS = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("changeSetMethod");
      field.setAccessible(true);
      KEY_CHANGESET_METHOD = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("metadata");
      field.setAccessible(true);
      KEY_METADATA = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("executionMillis");
      field.setAccessible(true);
      KEY_EXECUTION_MILLIS = field.getAnnotation(io.mongock.utils.field.Field.class).value();

      field = ChangeEntry.class.getDeclaredField("executionHostname");
      field.setAccessible(true);
      KEY_EXECUTION_HOSTNAME = field.getAnnotation(io.mongock.utils.field.Field.class).value();
      
      field = ChangeEntry.class.getDeclaredField("systemChange");
      field.setAccessible(true);
      KEY_SYSTEM_CHANGE = field.getAnnotation(io.mongock.utils.field.Field.class).value();
    } catch (NoSuchFieldException e) {
      throw new MongockException(e);
    }
  }

  public MongoReactiveChangeEntryRepository(MongoCollection collection) {
    this(collection, ReadWriteConfiguration.getDefault());
  }

  public MongoReactiveChangeEntryRepository(MongoCollection collection, ReadWriteConfiguration readWriteConfiguration) {
    super(collection, new String[]{KEY_EXECUTION_ID, KEY_AUTHOR, KEY_CHANGE_ID}, readWriteConfiguration);
  }

  @Override
  public List getEntriesLog() {
    return collection.find()
        .stream()
        .map(entry -> new ChangeEntry(
            entry.getString(KEY_EXECUTION_ID),
            entry.getString(KEY_CHANGE_ID),
            entry.getString(KEY_AUTHOR),
            DateUtils.toDate(entry.get(KEY_TIMESTAMP)),
            entry.containsKey(KEY_STATE) ? ChangeState.valueOf(entry.getString(KEY_STATE)) : null,
            entry.containsKey(KEY_TYPE) ? ChangeType.valueOf(entry.getString(KEY_TYPE)) : null,
            entry.getString(KEY_CHANGELOG_CLASS),
            entry.getString(KEY_CHANGESET_METHOD),
            entry.containsKey(KEY_EXECUTION_MILLIS) && entry.get(KEY_EXECUTION_MILLIS) != null
                    ? ((Number) entry.get(KEY_EXECUTION_MILLIS)).longValue() : -1L,
            entry.getString(KEY_EXECUTION_HOSTNAME),
            entry.get(KEY_METADATA),
            entry.getBoolean(KEY_SYSTEM_CHANGE)))
        .collect(Collectors.toList());
  }

  @Override
  public void saveOrUpdate(ChangeEntry changeEntry) throws MongockException {
    Bson filter = Filters.and(
        Filters.eq(KEY_EXECUTION_ID, changeEntry.getExecutionId()),
        Filters.eq(KEY_CHANGE_ID, changeEntry.getChangeId()),
        Filters.eq(KEY_AUTHOR, changeEntry.getAuthor())
    );

    Document entryDocument = toEntity(changeEntry);
    UpdateResult result = getClientSession()
        .map(clientSession -> collection.replaceOne(clientSession, filter, entryDocument, new ReplaceOptions().upsert(true)))
        .orElseGet(() -> collection.replaceOne(filter, entryDocument, new ReplaceOptions().upsert(true)));
    logger.debug("SaveOrUpdate[{}] with result" +
        "\n[upsertId:{}, matches: {}, modifies: {}, acknowledged: {}]", changeEntry, result.getUpsertedId(), result.getMatchedCount(), result.getModifiedCount(), result.wasAcknowledged());
  }


  public void setClientSession(ClientSession clientSession) {
    this.clientSession = clientSession;
  }

  public void clearClientSession() {
    setClientSession(null);
  }

  private Optional getClientSession() {
    return Optional.ofNullable(clientSession);
  }
  
  @Override
  public void ensureField(Field field) {
    // Nothing to do in MongoDB
  }

  @Override
  public Document toEntity(ChangeEntry domain) {
    return new Document()
        .append(KEY_EXECUTION_ID, domain.getExecutionId())
        .append(KEY_CHANGE_ID, domain.getChangeId())
        .append(KEY_AUTHOR, domain.getAuthor())
        .append(KEY_TIMESTAMP, domain.getTimestamp())
        .append(KEY_STATE, domain.getState().toString())
        .append(KEY_TYPE, domain.getType().toString())
        .append(KEY_CHANGELOG_CLASS, domain.getChangeLogClass())
        .append(KEY_CHANGESET_METHOD, domain.getChangeSetMethod())
        .append(KEY_METADATA, domain.getMetadata())
        .append(KEY_EXECUTION_MILLIS, domain.getExecutionMillis())
        .append(KEY_EXECUTION_HOST_NAME, domain.getExecutionHostname())
        .append(KEY_ERROR_TRACE, domain.getErrorTrace().orElse(null))
        .append(KEY_SYSTEM_CHANGE, domain.isSystemChange());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy