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

com.lordofthejars.nosqlunit.mongodb.DefaultInsertionStrategy Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.lordofthejars.nosqlunit.mongodb;

import com.lordofthejars.nosqlunit.core.IOUtils;
import com.mongodb.*;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.IndexOptions;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class DefaultInsertionStrategy implements MongoInsertionStrategy {

    private static final String SHARD_KEY_PATTERN = "shard-key-pattern";
    private static final String INDEXES = "indexes";
    private static final String INDEX = "index";
    private static final String INDEX_OPTIONS = "options";
    private static final String DATA = "data";
    private static final String DATABASE_COLLECTION_SEPARATOR = ".";

    @Override
    public void insert(MongoDbConnectionCallback connection, InputStream dataset) throws IOException {
        String jsonData = loadContentFromInputStream(dataset);
        Document parsedData = parseData(jsonData);

        insertParsedData(parsedData, connection.db(), connection.mongoClient());
    }

    private String loadContentFromInputStream(InputStream inputStreamContent) throws IOException {
        return IOUtils.readFullStream(inputStreamContent);
    }

    private Document parseData(String jsonData) throws IOException {
        Document parsedData = Document.parse(jsonData);
        return parsedData;
    }

    private void insertParsedData(Document parsedData, MongoDatabase mongoDb, MongoClient mongoClient) {
        Set collectionaNames = parsedData.keySet();

        for (String collectionName : collectionaNames) {

            final Object document = parsedData.get(collectionName, Object.class);
            if (!isDataDirectly(document)) {
                Document doc = (Document) document;
                if (isShardedCollection(doc)) {
                    insertShardKeyPattern(mongoDb, mongoClient, collectionName, doc);
                }
                if (isIndexes(doc)) {
                    insertIndexes(mongoDb, collectionName, doc);
                }
            }

            insertCollection(parsedData, mongoDb, collectionName);

        }
    }

    private void insertCollection(Document parsedData, MongoDatabase mongoDb, String collectionName) {
        List data;
        if (isDataDirectly(parsedData.get(collectionName))) { // Insert
            data = parsedData.get(collectionName, List.class);
        } else {
            Document collection = parsedData.get(collectionName, Document.class);
            data = collection.get(DATA, List.class);
        }

        insertData(data, mongoDb, collectionName);
    }

    private void insertIndexes(MongoDatabase mongoDb, String collectionName, Document collection) {
        MongoCollection indexedCollection = mongoDb.getCollection(collectionName);
        List indexes = collection.get(INDEXES, List.class);

        for (Document index : indexes) {

            Document indexKeys = index.get(INDEX, Document.class);

            if (index.containsKey(INDEX_OPTIONS)) {
                Document indexOptions = index.get(INDEX_OPTIONS, Document.class);
                indexedCollection.createIndex(indexKeys, toIndexOptions(indexOptions));
            } else {
                indexedCollection.createIndex(indexKeys);
            }
        }

    }

    private IndexOptions toIndexOptions(Document indexOptions) {
        IndexOptions mongoDbIndexOptions = new IndexOptions();

        if (indexOptions.containsKey("background")) {
            mongoDbIndexOptions.background(indexOptions.getBoolean("background"));
        }

        if (indexOptions.containsKey("unique")) {
            mongoDbIndexOptions.unique(indexOptions.getBoolean("unique"));
        }

        if (indexOptions.containsKey("name")) {
            mongoDbIndexOptions.name(indexOptions.getString("name"));
        }

        if (indexOptions.containsKey("sparse")) {
            mongoDbIndexOptions.sparse(indexOptions.getBoolean("sparse"));
        }

        if (indexOptions.containsKey("expireAfterSeconds")) {
            mongoDbIndexOptions.expireAfter(indexOptions.getLong("expireAfterSeconds"), TimeUnit.SECONDS);
        }

        if (indexOptions.containsKey("version")) {
            mongoDbIndexOptions.version(indexOptions.getInteger("version"));
        }

        if (indexOptions.containsKey("weights")) {
            mongoDbIndexOptions.weights(indexOptions.get("weights", Bson.class));
        }

        if (indexOptions.containsKey("defaultLanguage")) {
            mongoDbIndexOptions.defaultLanguage(indexOptions.getString("defaultLanguage"));
        }

        if (indexOptions.containsKey("languageOverride")) {
            mongoDbIndexOptions.languageOverride(indexOptions.getString("languageOverride"));
        }

        if (indexOptions.containsKey("textVersion")) {
            mongoDbIndexOptions.textVersion(indexOptions.getInteger("textVersion"));
        }

        if (indexOptions.containsKey("sphereVersion")) {
            mongoDbIndexOptions.sphereVersion(indexOptions.getInteger("sphereVersion"));
        }

        if (indexOptions.containsKey("bits")) {
            mongoDbIndexOptions.bits(indexOptions.getInteger("bits"));
        }

        if (indexOptions.containsKey("min")) {
            mongoDbIndexOptions.min(indexOptions.getDouble("min"));
        }

        if (indexOptions.containsKey("max")) {
            mongoDbIndexOptions.max(indexOptions.getDouble("max"));
        }

        if (indexOptions.containsKey("bucketSize")) {
            mongoDbIndexOptions.bucketSize(indexOptions.getDouble("bucketSize"));
        }

        if (indexOptions.containsKey("storageEngine")) {
            mongoDbIndexOptions.storageEngine(indexOptions.get("storageEngine", Bson.class));
        }

        if (indexOptions.containsKey("partialFilterExpression")) {
            mongoDbIndexOptions.partialFilterExpression(indexOptions.get("partialFilterExpression", Bson.class));
        }

        return mongoDbIndexOptions;

    }

    private void insertShardKeyPattern(MongoDatabase mongoDb, MongoClient mongoClient, String collectionName, Document collection) {
        String databaseName = mongoDb.getName();
        String collectionWithDatabase = databaseName + DATABASE_COLLECTION_SEPARATOR + collectionName;

        Document shardKeys = shardKeys(collection);
        MongoDbCommands.shardCollection(mongoClient, collectionWithDatabase, shardKeys);
    }

    private Document shardKeys(Document collection) {
        List shards = collection.get(SHARD_KEY_PATTERN, List.class);
        Document document = new Document();

        for (Object dbObject : shards) {
            document.append(dbObject.toString(), 1);
        }
        return document;
    }

    private void insertData(List dataObjects, MongoDatabase mongoDb, String collectionName) {

        MongoCollection dbCollection = mongoDb.getCollection(collectionName);

        for (Document dataObject : dataObjects) {
            dbCollection.insertOne(dataObject);
        }
    }

    private boolean isDataDirectly(Object object) {
        return List.class.isAssignableFrom(object.getClass());
    }

    private boolean isIndexes(Document document) {
        return document.containsKey(INDEXES);
    }

    private boolean isShardedCollection(Document document) {
        return document.containsKey(SHARD_KEY_PATTERN);
    }
}