com.imaginea.mongodb.services.impl.SystemCollectionServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.imaginea.mongodb.services.impl.SystemCollectionServiceImpl.java

Source

/*
 * Copyright (c) 2011 Imaginea Technologies Private Ltd. Hyderabad, India
 *
 * Licensed 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.imaginea.mongodb.services.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.bson.Document;
import org.json.JSONObject;

/**
 * Defines services for performing operations like create/drop on indexes and users which are part
 * of system name space system.users & system.indexes collections inside a database present in mongo
 * to which we are connected to.
 *
 * @author Sanjay Chaluvadi
 */

import com.imaginea.mongodb.domain.MongoConnectionDetails;
import com.imaginea.mongodb.exceptions.ApplicationException;
import com.imaginea.mongodb.exceptions.DatabaseException;
import com.imaginea.mongodb.exceptions.ErrorCodes;
import com.imaginea.mongodb.services.AuthService;
import com.imaginea.mongodb.services.SystemCollectionService;
import com.imaginea.mongodb.utils.ApplicationUtils;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.client.ListIndexesIterable;
import com.mongodb.client.MongoCursor;

public class SystemCollectionServiceImpl implements SystemCollectionService {
    /**
     * Mongo Instance to communicate with mongo
     */
    private MongoClient mongoInstance;
    private static final AuthService AUTH_SERVICE = AuthServiceImpl.getInstance();

    /**
     * Creates an instance of MongoInstanceProvider which is used to get a mongo instance to perform
     * operations on collections. The instance is created based on a userMappingKey which is recieved
     * from the collection request dispatcher and is obtained from tokenId of user.
     *
     * @param connectionId A combination of username,mongoHost and mongoPort
     */
    public SystemCollectionServiceImpl(String connectionId) throws ApplicationException {
        MongoConnectionDetails mongoConnectionDetails = AUTH_SERVICE.getMongoConnectionDetails(connectionId);
        mongoInstance = mongoConnectionDetails.getMongo();
    }

    /**
     * Adds a user to the given database
     *
     * @param dbName   Name of the database
     * @param username Username of the user to be added
     * @param password Password of the usre to be added
     * @param role     optional attribute for creating the user
     * @param dbSource optional attribute for creating the dbSource
     * @return Returns the success message that should be shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String addUser(String dbName, String username, String password, String role, String dbSource)
            throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (username == null) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "Username is null");
        }
        if (username.equals("")) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "Username is empty");
        }
        if (password == null) {
            throw new DatabaseException(ErrorCodes.PASSWORD_IS_EMPTY, "Password is null");
        }
        if (password.equals("")) {
            throw new DatabaseException(ErrorCodes.PASSWORD_IS_EMPTY, "Password is empty");
        }
        try {

            List<Document> roles = new ArrayList<Document>();
            String[] roleSep = role.split(",");
            for (String eachRole : roleSep) {
                roles.add(new Document("role", eachRole).append("db", dbSource));
            }
            mongoInstance.getDatabase(dbName).runCommand(
                    new Document("createUser", username).append("pwd", password).append("roles", roles));

        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.USER_CREATION_EXCEPTION, e.getMessage());
        }
        return "User: " + username + " has been added to the DB: " + dbName;
    }

    /**
     * Modifies a user to the given database
     *
     * @param dbName        Name of the database
     * @param username      username of the user being modifies to the database
     * @param password      password of the user being modified to the database
     * @param revokedRoles  The parameter for removedRoles the user roles
     * @param grantNewRoles The parameter for removedRoles the user roles
     * @return Returns the success message that should be shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String modifyUser(String dbName, String username, String password, String revokedRoles,
            String grantNewRoles, String dbSource) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (username == null) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "Username is null");
        }
        if (username.equals("")) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "Username is empty");
        }
        if (password == null) {
            throw new DatabaseException(ErrorCodes.PASSWORD_IS_EMPTY, "Password is null");
        }
        if (password.equals("")) {
            throw new DatabaseException(ErrorCodes.PASSWORD_IS_EMPTY, "Password is empty");
        }
        try {

            if (username != null && password != null) {
                mongoInstance.getDatabase(dbName)
                        .runCommand(new Document("updateUser", username).append("pwd", password));
            }
            if (revokedRoles != null && revokedRoles.length() > 0) {
                List<Document> roles = new ArrayList<>();
                String[] remRoles = revokedRoles.split(",");
                for (String eachRole : remRoles) {
                    roles.add(new Document("role", eachRole).append("db", dbSource));
                }
                mongoInstance.getDatabase(dbName)
                        .runCommand(new Document("revokeRolesFromUser", username).append("roles", roles));
            }

            if (grantNewRoles != null && grantNewRoles.length() > 0) {
                List<Document> roles = new ArrayList<>();
                String[] newRoles = grantNewRoles.split(",");
                for (String eachRole : newRoles) {
                    roles.add(new Document("role", eachRole).append("db", dbSource));
                }
                mongoInstance.getDatabase(dbName)
                        .runCommand(new Document("grantRolesToUser", username).append("roles", roles));
            }
        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.USER_CREATION_EXCEPTION, e.getMessage());
        }
        return "User: " + username + " has been modified for the DB: " + dbName;
    }

    /**
     * Drops the user from the given mongo db based on the username
     *
     * @param dbName   Name of the database
     * @param username Username of the user to be deleted/dropped
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throwsuper type of UndefinedDatabaseException
     */
    @Override
    public String removeUser(String dbName, String username) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (username == null) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "Username is null");
        }
        if (username.equals("")) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "Username is empty");
        }
        try {
            Document commandArguments = new Document();
            commandArguments.put("dropUser", username);
            mongoInstance.getDatabase(dbName).runCommand(commandArguments);

        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.USER_DELETION_EXCEPTION, e.getMessage());
        }
        return "User: " + username + " deleted from the DB: " + dbName;
    }

    /**
     * Get all the users from the given mongo db
     *
     * @param dbName Name of the database
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public JSONObject getUsers(String dbName) throws ApplicationException {
        // TODO Auto-generated method stub

        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        try {

            Document document = new Document("usersInfo", 1);
            Document command = mongoInstance.getDatabase(dbName).runCommand(document);
            return ApplicationUtils.constructResponse(false, command);

        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.ANY_OTHER_EXCEPTION, e.getMessage());
        }

    }

    public JSONObject getUsersPrivileges(String dbName, String userName) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (userName == null) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "User name is null");
        }
        if (userName.equals("")) {
            throw new DatabaseException(ErrorCodes.USERNAME_IS_EMPTY, "User Name Empty");
        }

        try {
            Document doc = new Document();
            Document user = new Document("user", userName).append("db", dbName);
            doc.put("usersInfo", user);
            doc.put("showCredentials", true);
            doc.put("showPrivileges", true);

            //System.out.print(doc.toJson());
            Document comm = mongoInstance.getDatabase(dbName).runCommand(doc);
            return ApplicationUtils.constructResponse(false, comm);
        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.ANY_OTHER_EXCEPTION, e.getMessage());
        }

    }

    /**
     * Drops all the users from the given mongo db
     *
     * @param dbName Name of the database
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String removeAllUsers(String dbName) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        MongoCursor<Document> users = mongoInstance.getDatabase(dbName).getCollection("system.users").find()
                .iterator();
        if (users.hasNext()) {
            while (users.hasNext()) {
                try {
                    Document user = users.next();
                    mongoInstance.getDatabase(dbName).getCollection("system.users").findOneAndDelete(user);
                } catch (MongoException e) {
                    throw new ApplicationException(ErrorCodes.USER_DELETION_EXCEPTION, e.getMessage());
                }
            }
            return "All users are dropped from the DB: " + dbName;
        } else {
            return "The DB:" + dbName + "does not have any users";
        }
    }

    /**
     * Adds an index for a given colleciton in a mongo db
     *
     * @param dbName         Name of the database the index should be added
     * @param collectionName Name of the collection to which the index is to be added
     * @param keys           The keys with the which the index is created
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String addIndex(String dbName, String collectionName, Document keys) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (collectionName == null) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is null");
        }
        if (collectionName.equals("")) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is Empty");
        }
        if (keys == null) {
            throw new DatabaseException(ErrorCodes.KEYS_EMPTY, "Index Keys are null");
        }
        if (keys.equals("")) {
            throw new DatabaseException(ErrorCodes.KEYS_EMPTY, "Index keys are Empty");
        }
        try {

            mongoInstance.getDatabase(dbName).getCollection(collectionName).createIndex(keys);
        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.INDEX_ADDITION_EXCEPTION, e.getMessage());
        }
        return "Index successfully added to the collection: " + dbName + ":" + collectionName;
    }

    /**
     * Updates an index for a given collection in a mongo db
     *
     * @param dbName         Name of the database the index should be updated
     * @param collectionName Name of the collection to which the index is to be updated
     * @param keys           The keys with the which the index is updated
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String updateIndex(String dbName, String collectionName, Document keys) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (collectionName == null) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is null");
        }
        if (collectionName.equals("")) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is Empty");
        }
        if (keys == null) {
            throw new DatabaseException(ErrorCodes.KEYS_EMPTY, "Index Keys are null");
        }
        if (keys.equals("")) {
            throw new DatabaseException(ErrorCodes.KEYS_EMPTY, "Index keys are Empty");
        }
        try {
            for (String keyCurrent : keys.keySet()) {
                if (!((int) keys.get(keyCurrent) == 1 || (int) keys.get(keyCurrent) == -1)) {
                    keys.replace(keyCurrent, -1);
                }
            }

            mongoInstance.getDatabase(dbName).getCollection(collectionName).dropIndexes();
            if (!(keys.isEmpty() || keys == null)) {
                mongoInstance.getDatabase(dbName).getCollection(collectionName).createIndex(keys);
            }
        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.INDEX_UPDATION_EXCEPTION, e.getMessage());
        }
        return "Index successfully updated in the collection: " + dbName + ":" + collectionName;
    }

    /**
     * Gets indexes for a given collection in a mongo db
     *
     * @param dbName         Name of the database the indexes should be listed
     * @param collectionName Name of the collection to which the index is to be listed
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */
    @Override
    public JSONObject getIndex(String dbName, String collectionName) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (collectionName == null) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is null");
        }
        if (collectionName.equals("")) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is Empty");
        }
        try {

            ListIndexesIterable<Document> result = mongoInstance.getDatabase(dbName).getCollection(collectionName)
                    .listIndexes();
            MongoCursor<Document> iterator = result.iterator();

            List<Document> listOfIndexes = null;
            if (iterator.hasNext()) {
                listOfIndexes = new ArrayList<Document>();
                while (iterator.hasNext()) {
                    Document doc = iterator.next();
                    Document resultDoc = (Document) doc.get("key");
                    listOfIndexes.add(resultDoc);
                }
            }
            return ApplicationUtils.constructResponse(false, listOfIndexes.size(), listOfIndexes);
        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.INDEX_ADDITION_EXCEPTION, e.getMessage());
        }
    }

    /**
     * Removes all the indexes from all the collections in a given mongo db
     *
     * @param dbName Name of the database
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String removeIndexes(String dbName) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        MongoCursor<String> iterator = mongoInstance.getDatabase(dbName).listCollectionNames().iterator();
        if (iterator.hasNext()) {
            while (iterator.hasNext()) {
                String collection = iterator.next();
                try {
                    mongoInstance.getDatabase(dbName).getCollection(collection).dropIndexes();
                } catch (MongoException e) {
                    throw new ApplicationException(ErrorCodes.INDEX_REMOVE_EXCEPTION, e.getMessage());
                }
            }
        }
        return "All indexes are dropped from DB: " + dbName;
    }

    /**
     * Removes an index from the collection based on the index name
     *
     * @param dbName         Name of the database from which the index should be dropped/removed
     * @param collectionName Name of the collection from which the index should be dropped
     * @param indexName      Name of the index that should be deleted
     * @return Returns the success message that shown to the user
     * @throws DatabaseException throw super type of UndefinedDatabaseException
     */

    @Override
    public String removeIndex(String dbName, String collectionName, String indexName) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (collectionName == null) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is null");
        }
        if (collectionName.equals("")) {
            throw new DatabaseException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is Empty");
        }
        if (indexName == null) {
            throw new DatabaseException(ErrorCodes.INDEX_EMPTY, "Index name is null");
        }
        if (indexName.equals("")) {
            throw new DatabaseException(ErrorCodes.INDEX_EMPTY, "Index name is Empty");
        }
        try {
            mongoInstance.getDatabase(dbName).getCollection(collectionName).dropIndex(indexName);
        } catch (MongoException e) {
            throw new ApplicationException(ErrorCodes.INDEX_REMOVE_EXCEPTION, e.getMessage());
        }

        return "Index: " + indexName + " dropped from the collection: " + dbName + ":" + collectionName;
    }

    public String getMongoClientVersion(String dataBaseName) throws ApplicationException {
        String version = "";
        try {
            Document document = new Document();
            document.put("buildInfo", null);
            Document responseFromClient = mongoInstance.getDatabase(dataBaseName).runCommand(document);
            if (responseFromClient != null && responseFromClient.get("version") != null) {
                return responseFromClient.get("version").toString();
            }
            return version;
        } catch (MongoException exception) {
            throw new ApplicationException(ErrorCodes.JSON_EXCEPTION, exception.getMessage());
        }
    }

}