com.stratio.connector.mongodb.core.engine.MongoMetadataEngine.java Source code

Java tutorial

Introduction

Here is the source code for com.stratio.connector.mongodb.core.engine.MongoMetadataEngine.java

Source

/*
 * Licensed to STRATIO (C) under one or more contributor license agreements.
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.  The STRATIO (C) licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.stratio.connector.mongodb.core.engine;

import com.mongodb.*;
import com.stratio.connector.commons.connection.Connection;
import com.stratio.connector.commons.engine.CommonsMetadataEngine;
import com.stratio.connector.commons.metadata.CatalogMetadataBuilder;
import com.stratio.connector.commons.metadata.TableMetadataBuilder;
import com.stratio.connector.mongodb.core.configuration.ConfigurationOptions;
import com.stratio.connector.mongodb.core.connection.MongoConnectionHandler;
import com.stratio.connector.mongodb.core.engine.metadata.*;
import com.stratio.connector.mongodb.core.exceptions.MongoValidationException;
import com.stratio.crossdata.common.data.AlterOptions;
import com.stratio.crossdata.common.data.CatalogName;
import com.stratio.crossdata.common.data.ClusterName;
import com.stratio.crossdata.common.data.TableName;
import com.stratio.crossdata.common.exceptions.ConnectorException;
import com.stratio.crossdata.common.exceptions.ExecutionException;
import com.stratio.crossdata.common.exceptions.UnsupportedException;
import com.stratio.crossdata.common.metadata.*;
import com.stratio.crossdata.common.statements.structures.Selector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * The Class MongoMetadataEngine.
 *
 */
public class MongoMetadataEngine extends CommonsMetadataEngine<MongoClient> {

    /**
     * The Log.
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private static MongoMetadataEngine instance = null;

    /**
     * Instantiates a new mongo metadata engine.
     *
     * @param connectionHandler
     *            the connection handler
     */

    private MongoMetadataEngine(MongoConnectionHandler connectionHandler) {
        super(connectionHandler);
    }

    public static MongoMetadataEngine getInstance(MongoConnectionHandler connectionHandler) {
        if (instance == null) {
            instance = new MongoMetadataEngine(connectionHandler);
        }
        return instance;
    }

    /**
     * Create a database in MongoDB.
     *
     * @param catalogMetadata
     *            the catalogMetadata
     * @param connection
     *            the connection which contains the native connector
     * @throws UnsupportedException
     *             if the specified operation is not supported
     */
    @Override
    protected void createCatalog(CatalogMetadata catalogMetadata, Connection<MongoClient> connection)
            throws UnsupportedException {
        final String msg = "Create catalog is not supported";
        logger.error(msg);
        throw new UnsupportedException(msg);
    }

    /**
     * Create a collection in MongoDB.
     *
     * @param tableMetadata
     *            the tableMetadata
     * @param connection
     *            the connection which contains the native connector
     * @throws ExecutionException
     *             if an error exist when running the database command or the specified operation is not supported
     */
    @Override
    protected void createTable(TableMetadata tableMetadata, Connection<MongoClient> connection)
            throws ExecutionException {

        if (tableMetadata == null) {
            throw new MongoValidationException("the table metadata is required");
        }

        if (tableMetadata.getName() == null) {
            throw new MongoValidationException("the table name is required");
        }

        if (ShardUtils.isCollectionSharded(SelectorOptionsUtils.processOptions(tableMetadata.getOptions()))) {
            ShardUtils.shardCollection((MongoClient) connection.getNativeConnection(), tableMetadata);
        }
    }

    /**
     * Drop a database in MongoDB.
     *
     * @param name
     *            the database name
     * @param connection
     *            the connection which contains the native connector
     * @throws ExecutionException
     *             if an error exist when running the database command
     */
    @Override
    protected void dropCatalog(CatalogName name, Connection<MongoClient> connection) throws ExecutionException {
        try {
            connection.getNativeConnection().dropDatabase(name.getName());
        } catch (MongoException e) {
            logger.error("Error dropping the catalog: " + e.getMessage());
            throw new ExecutionException(e.getMessage(), e);
        }
    }

    /**
     * Drop a collection in MongoDB.
     *
     * @param name
     *            the collection name
     * @param connection
     *            the connection
     * @throws ExecutionException
     *             if an error exist when running the database command
     */
    @Override
    protected void dropTable(TableName name, Connection<MongoClient> connection) throws ExecutionException {

        DB db = connection.getNativeConnection().getDB(name.getCatalogName().getName());
        try {
            db.getCollection(name.getName()).drop();
        } catch (MongoException e) {
            logger.error("Error dropping the collection: " + e.getMessage());
            throw new ExecutionException(e.getMessage(), e);
        }
    }

    /**
     * Create an index.
     *
     * @param indexMetadata
     *            the index metadata
     * @param connection
     *            the connection
     * @throws ExecutionException
     *             if an error exist when running the database command or the specified operation is not supported
     */
    @Override
    protected void createIndex(IndexMetadata indexMetadata, Connection<MongoClient> connection)
            throws ExecutionException {

        DB db = connection.getNativeConnection()
                .getDB(indexMetadata.getName().getTableName().getCatalogName().getName());

        DBObject indexDBObject = IndexUtils.getIndexDBObject(indexMetadata);
        DBObject indexOptionsDBObject = IndexUtils.getCustomOptions(indexMetadata);

        try {
            db.getCollection(indexMetadata.getName().getTableName().getName()).createIndex(indexDBObject,
                    indexOptionsDBObject);
        } catch (MongoException e) {
            logger.error("Error creating the index: " + e.getMessage());
            throw new ExecutionException(e.getMessage(), e);
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Index created: " + indexDBObject.toString() + " with options: " + indexOptionsDBObject);
        }
    }

    /**
     * Drop an index.
     *
     * @param indexMetadata
     *            the index metadata
     * @param connection
     *            the connection
     * @throws ExecutionException
     *             if an error exist when running the database command or the specified operation is not supported
     */
    @Override
    protected void dropIndex(IndexMetadata indexMetadata, Connection<MongoClient> connection)
            throws ExecutionException {
        DB db = connection.getNativeConnection()
                .getDB(indexMetadata.getName().getTableName().getCatalogName().getName());

        String indexName = null;
        if (indexMetadata.getName() != null) {
            indexName = indexMetadata.getName().getName();
        }

        if (indexName != null) {
            try {
                db.getCollection(indexMetadata.getName().getTableName().getName()).dropIndex(indexName);
            } catch (MongoException e) {
                logger.error("Error dropping the index: " + e.getMessage());
                throw new ExecutionException(e.getMessage(), e);
            }
        } else {
            IndexUtils.dropIndexWithDefaultName(indexMetadata, db);
        }

    }

    @Override
    protected void alterTable(TableName tableName, AlterOptions alterOptions, Connection<MongoClient> connection)
            throws ExecutionException {

        DB db = connection.getNativeConnection().getDB(tableName.getCatalogName().getName());
        DBCollection collection = db.getCollection(tableName.getName());

        switch (alterOptions.getOption()) {
        case ADD_COLUMN:
            break;
        case ALTER_COLUMN:
            throw new MongoValidationException("Alter options is not supported");
        case DROP_COLUMN:
            String name = alterOptions.getColumnMetadata().getName().getName();
            collection.updateMulti(new BasicDBObject(), AlterOptionsUtils.buildDropColumnDBObject(name));
            break;
        case ALTER_OPTIONS:
        default:
            throw new MongoValidationException("Alter options is not supported");
        }

    }

    @Override
    protected void alterCatalog(CatalogName catalogName, Map<Selector, Selector> options,
            Connection<MongoClient> connection) throws UnsupportedException, ExecutionException {
        final String msg = "Alter catalog is not supported";
        logger.error(msg);
        throw new UnsupportedException(msg);

    }

    @Override
    protected List<CatalogMetadata> provideMetadata(ClusterName clusterName, Connection<MongoClient> connection)
            throws ConnectorException {
        List<String> databaseNames = connection.getNativeConnection().getDatabaseNames();
        List<CatalogMetadata> catalogMetadataList = new ArrayList<>();
        for (String databaseName : databaseNames) {
            CatalogName dbName = new CatalogName(databaseName);
            catalogMetadataList.add(provideCatalogMetadata(dbName, clusterName, connection));
        }
        return catalogMetadataList;
    }

    @Override
    protected CatalogMetadata provideCatalogMetadata(CatalogName catalogName, ClusterName clusterName,
            Connection<MongoClient> connection) throws ConnectorException {
        DB db = connection.getNativeConnection().getDB(catalogName.getName());
        Set<String> collectionNames = db.getCollectionNames();
        CatalogMetadataBuilder catalogMetadataBuilder = new CatalogMetadataBuilder(catalogName.getName());
        for (String collectionName : collectionNames) {
            TableName tableName = new TableName(catalogName.getName(), collectionName);
            catalogMetadataBuilder.withTables(provideTableMetadata(tableName, clusterName, connection));
        }
        return catalogMetadataBuilder.build();
    }

    @Override
    protected TableMetadata provideTableMetadata(TableName tableName, ClusterName clusterName,
            Connection<MongoClient> connection) throws ConnectorException {

        DB db = connection.getNativeConnection().getDB(tableName.getCatalogName().getName());
        DBCollection collection = db.getCollection(tableName.getName());

        TableMetadataBuilder tableMetadataBuilder = new TableMetadataBuilder(tableName.getCatalogName().getName(),
                tableName.getName(), clusterName.getName());
        String sampleNumber = (connection.getSessionObject(String.class, "sample_probability") != null)
                ? connection.getSessionObject(String.class, "sample_probability")
                : ConfigurationOptions.SAMPLE_PROBABILITY.getDefaultValue()[0];
        // Add columns
        for (Map.Entry<String, String> entry : DiscoverMetadataUtils
                .discoverFieldsWithType(collection, sampleNumber).entrySet()) {
            if (entry.getValue() == null) {
                tableMetadataBuilder.addColumn(entry.getKey(), new ColumnType(DataType.TEXT));
                continue;
            }

            if (entry.getValue().equals("string")) {
                tableMetadataBuilder.addColumn(entry.getKey(), new ColumnType(DataType.TEXT));
            } else if (entry.getValue().equals("boolean")) {
                tableMetadataBuilder.addColumn(entry.getKey(), new ColumnType(DataType.BOOLEAN));
            } else if (entry.getValue().equals("number")) {
                tableMetadataBuilder.addColumn(entry.getKey(), new ColumnType(DataType.INT));
            } else {
                tableMetadataBuilder.addColumn(entry.getKey(), null);
            }
        }
        // Add indexes and column with indexes
        for (IndexMetadata indexMetadata : DiscoverMetadataUtils.discoverIndexes(collection)) {
            tableMetadataBuilder.withColumns(new ArrayList<ColumnMetadata>(indexMetadata.getColumns().values()));
            tableMetadataBuilder.addIndex(indexMetadata);
        }
        // Add pkey
        tableMetadataBuilder.withPartitionKey("_id");
        return tableMetadataBuilder.build();

    }

}