org.axway.grapes.server.db.mongo.MongodbHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.axway.grapes.server.db.mongo.MongodbHandler.java

Source

package org.axway.grapes.server.db.mongo;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import com.sun.jersey.api.NotFoundException;
import org.axway.grapes.server.config.DataBaseConfig;
import org.axway.grapes.server.core.options.FiltersHolder;
import org.axway.grapes.server.db.DataUtils;
import org.axway.grapes.server.db.RepositoryHandler;
import org.axway.grapes.server.db.datamodel.*;
import org.axway.grapes.server.db.datamodel.DbCredential.AvailableRoles;
import org.jongo.Jongo;
import org.jongo.MongoCollection;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Mongodb Handler
 *
 * <p>Repository Handler designed for mongodb<p/>
 *
 * @author jdcoffre
 */
public class MongodbHandler implements RepositoryHandler {
    // cache for credentials
    private LoadingCache<String, DbCredential> credentialCache;
    // DB connection
    private final DB db;

    public MongodbHandler(final DataBaseConfig config) throws UnknownHostException {
        final ServerAddress address = new ServerAddress(config.getHost(), config.getPort());
        final MongoClient mongo = new MongoClient(address);
        db = mongo.getDB(config.getDatastore());

        if (config.getUser() != null && config.getPwd() != null) {
            db.authenticate(config.getUser(), config.getPwd());
        }

        // Init credentials' cache
        credentialCache = CacheBuilder.newBuilder().maximumSize(1000)
                .build(new CacheLoader<String, DbCredential>() {
                    public DbCredential load(String user) {
                        return getCredential(user);
                    }
                });
    }

    /**
    * Initialize a connection with the database using Jongo.
    * 
    * <p>WARNING: The database connection is closed only when Datastore instance is garbage collected!!!!</p>
    * 
    * @return Jongo instance
    */
    private Jongo getJongoDataStore() {
        return new Jongo(db);
    }

    @Override
    public void store(final DbCredential credential) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection dbCredentials = datastore.getCollection(DbCollections.DB_CREDENTIALS);

        final DbCredential dbCredential = getCredential(credential.getUser());

        if (dbCredential == null) {
            dbCredentials.save(credential);
        } else {
            dbCredentials.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, dbCredential.getUser()))
                    .with(credential);
        }

        credentialCache.invalidate(credential.getUser());
    }

    @Override
    public void addUserRole(final String user, final AvailableRoles role) {
        final DbCredential credential = getCredential(user);

        if (credential == null) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }

        final Jongo datastore = getJongoDataStore();
        final MongoCollection credentials = datastore.getCollection(DbCollections.DB_CREDENTIALS);

        if (!credential.getRoles().contains(role)) {
            credential.addRole(role);
            credentials.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, user))
                    .with("{ $set: { \"" + DbCredential.ROLES_FIELD + "\": #}} ", credential.getRoles());
        }

        credentialCache.invalidate(credential.getUser());

    }

    @Override
    public void removeUserRole(final String user, final AvailableRoles role) {
        final DbCredential credential = getCredential(user);

        if (credential == null) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }

        final Jongo datastore = getJongoDataStore();
        final MongoCollection credentials = datastore.getCollection(DbCollections.DB_CREDENTIALS);

        if (credential.getRoles().contains(role)) {
            credential.removeRole(role);
            credentials.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, user))
                    .with("{ $set: { \"" + DbCredential.ROLES_FIELD + "\": #}} ", credential.getRoles());
        }
        credentialCache.invalidate(credential.getUser());
    }

    @Override
    public DbCredential getCredential(final String user) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_CREDENTIALS)
                .findOne(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, user)).as(DbCredential.class);
    }

    @Override
    public void store(final DbLicense license) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection dbLicenses = datastore.getCollection(DbCollections.DB_LICENSES);
        final DbLicense dbLicense = getLicense(license.getName());

        if (dbLicense == null) {
            dbLicenses.save(license);
        } else {
            dbLicenses.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, dbLicense.getName()))
                    .with(license);
        }

    }

    @Override
    public List<String> getLicenseNames(final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        final Iterable<DbLicense> dbLicenses = datastore.getCollection(DbCollections.DB_LICENSES).find()
                .as(DbLicense.class);

        final List<String> licenseNames = new ArrayList<String>();
        for (DbLicense dbLicense : dbLicenses) {
            if (filters.shouldBeInReport(dbLicense)) {
                licenseNames.add(dbLicense.getName());
            }
        }

        return licenseNames;
    }

    @Override
    public List<DbLicense> getAllLicenses() {
        final Jongo datastore = getJongoDataStore();
        final Iterator<DbLicense> licenses = datastore.getCollection(DbCollections.DB_LICENSES).find()
                .as(DbLicense.class).iterator();

        return Lists.newArrayList(licenses);
    }

    @Override
    public DbLicense getLicense(final String name) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_LICENSES)
                .findOne(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, name)).as(DbLicense.class);
    }

    @Override
    public void deleteLicense(final String name) {
        final DbLicense license = getLicense(name);

        if (license == null) {
            throw new NotFoundException("The license does not exist: " + name);
        } else {
            final Jongo datastore = getJongoDataStore();
            datastore.getCollection(DbCollections.DB_LICENSES)
                    .remove(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, name));
        }
    }

    @Override
    public List<DbArtifact> getArtifacts(final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        final List<DbArtifact> artifacts = new ArrayList<DbArtifact>();

        final Iterable<DbArtifact> dbArtifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS)
                .find(JongoUtils.generateQuery(filters.getArtifactFieldsFilters())).as(DbArtifact.class);

        for (DbArtifact dbArtifact : dbArtifacts) {
            artifacts.add(dbArtifact);
        }
        return artifacts;
    }

    @Override
    public void addLicenseToArtifact(final DbArtifact artifact, final String licenseId) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection artifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS);
        artifact.addLicense(licenseId);
        artifacts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, artifact.getGavc()))
                .with("{ $set: { \"" + DbArtifact.LICENCES_DB_FIELD + "\": #}} ", artifact.getLicenses());

    }

    @Override
    public void removeLicenseFromArtifact(final DbArtifact artifact, final String licenseId) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection artifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS);

        if (artifact.getLicenses().contains(licenseId)) {
            artifact.removeLicense(licenseId);
            artifacts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, artifact.getGavc()))
                    .with("{ $set: { \"" + DbArtifact.LICENCES_DB_FIELD + "\": #}} ", artifact.getLicenses());
        }

    }

    @Override
    public void approveLicense(final DbLicense license, final Boolean approved) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection licenses = datastore.getCollection(DbCollections.DB_LICENSES);

        licenses.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, license.getName()))
                .with("{ $set: { \"" + DbLicense.APPROVED_DB_FIELD + "\": #}} ", approved);
    }

    @Override
    public void store(final DbArtifact artifact) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection dbArtifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS);
        final DbArtifact dbArtifact = getArtifact(artifact.getGavc());

        if (dbArtifact == null) {
            dbArtifacts.save(artifact);
        } else {

            // Important: merge existing license and new ones :
            //    * because an existing license could have been manually enforce by a user
            //    * because all Grapes clients are not to send license information
            for (String license : dbArtifact.getLicenses()) {
                artifact.addLicense(license);
            }

            dbArtifacts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, dbArtifact.getGavc()))
                    .with(artifact);
        }
    }

    @Override
    public List<String> getGavcs(final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_ARTIFACTS).distinct(DbCollections.DEFAULT_ID)
                .query(JongoUtils.generateQuery(filters.getArtifactFieldsFilters())).as(String.class);
    }

    @Override
    public List<String> getGroupIds(final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_ARTIFACTS).distinct(DbArtifact.GROUPID_DB_FIELD)
                .as(String.class);
    }

    @Override
    public List<String> getArtifactVersions(final DbArtifact artifact) {
        final Jongo datastore = getJongoDataStore();
        final Map<String, Object> params = new HashMap<String, Object>();
        params.put(DbArtifact.GROUPID_DB_FIELD, artifact.getGroupId());
        params.put(DbArtifact.ARTIFACTID_DB_FIELD, artifact.getArtifactId());
        params.put(DbArtifact.CLASSIFIER_DB_FIELD, artifact.getClassifier());
        params.put(DbArtifact.EXTENSION_DB_FIELD, artifact.getExtension());

        return datastore.getCollection(DbCollections.DB_ARTIFACTS).distinct(DbArtifact.VERSION_DB_FIELD)
                .query(JongoUtils.generateQuery(params)).as(String.class);
    }

    @Override
    public DbArtifact getArtifact(final String gavc) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_ARTIFACTS)
                .findOne(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, gavc)).as(DbArtifact.class);
    }

    @Override
    public void deleteArtifact(final String gavc) {
        final DbArtifact artifact = getArtifact(gavc);

        if (artifact == null) {
            throw new NotFoundException("The artifact does not exist: " + gavc);
        } else {
            final Jongo datastore = getJongoDataStore();
            datastore.getCollection(DbCollections.DB_ARTIFACTS)
                    .remove(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, gavc));
        }
    }

    @Override
    public void updateDoNotUse(final DbArtifact artifact, final Boolean doNotUse) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection artifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS);

        artifacts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, artifact.getGavc()))
                .with("{ $set: { \"" + DbArtifact.DO_NOT_USE + "\": #}} ", doNotUse);
    }

    @Override
    public void updateDownloadUrl(final DbArtifact artifact, final String downLoadUrl) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection artifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS);

        artifacts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, artifact.getGavc()))
                .with("{ $set: { \"" + DbArtifact.DOWNLOAD_URL_DB_FIELD + "\": #}} ", downLoadUrl);
    }

    @Override
    public void updateProvider(final DbArtifact artifact, final String provider) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection artifacts = datastore.getCollection(DbCollections.DB_ARTIFACTS);

        artifacts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, artifact.getGavc()))
                .with("{ $set: { \"" + DbArtifact.PROVIDER + "\": #}} ", provider);
    }

    @Override
    public List<DbModule> getAncestors(final DbArtifact artifact, final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        final Map<String, Object> queryParams = filters.getModuleFieldsFilters();
        queryParams.put(DbModule.USE_DB_FIELD, artifact.getGavc());

        final Iterable<DbModule> results = datastore.getCollection(DbCollections.DB_MODULES)
                .find(JongoUtils.generateQuery(queryParams)).as(DbModule.class);

        final List<DbModule> ancestors = new ArrayList<DbModule>();
        for (DbModule ancestor : results) {
            ancestors.add(ancestor);
        }

        return ancestors;
    }

    @Override
    public void store(final DbModule module) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection dbModules = datastore.getCollection(DbCollections.DB_MODULES);
        final DbModule dbModule = getModule(module.getId());

        // has to be done due to mongo limitation: https://jira.mongodb.org/browse/SERVER-267
        module.updateHasAndUse();

        if (dbModule == null) {
            dbModules.save(module);
        } else {
            // let's keep the old build info and override with new values if any
            final Map<String, String> consolidatedBuildInfo = dbModule.getBuildInfo();
            consolidatedBuildInfo.putAll(module.getBuildInfo());
            module.setBuildInfo(consolidatedBuildInfo);

            dbModules.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, dbModule.getId())).with(module);
        }

    }

    @Override
    public List<String> getModuleNames(final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_MODULES).distinct(DbModule.NAME_DB_FIELD)
                .query(JongoUtils.generateQuery(filters.getModuleFieldsFilters())).as(String.class);
    }

    @Override
    public List<String> getModuleVersions(final String name, final FiltersHolder filters) {
        final Map<String, Object> params = filters.getModuleFieldsFilters();
        params.put(DbModule.NAME_DB_FIELD, name);

        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_MODULES).distinct(DbModule.VERSION_DB_FIELD)
                .query(JongoUtils.generateQuery(params)).as(String.class);
    }

    @Override
    public DbModule getModule(final String moduleId) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_MODULES)
                .findOne(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, moduleId)).as(DbModule.class);
    }

    @Override
    public List<DbModule> getModules(final FiltersHolder filters) {
        final Jongo datastore = getJongoDataStore();
        final List<DbModule> modules = new ArrayList<DbModule>();

        final Iterable<DbModule> dbModules = datastore.getCollection(DbCollections.DB_MODULES)
                .find(JongoUtils.generateQuery(filters.getModuleFieldsFilters())).as(DbModule.class);

        for (DbModule dbModule : dbModules) {
            modules.add(dbModule);
        }
        return modules;
    }

    @Override
    public void deleteModule(final String moduleId) {
        final DbModule module = getModule(moduleId);

        if (module == null) {
            throw new NotFoundException("The module does not exist: " + moduleId);
        } else {
            final Jongo datastore = getJongoDataStore();
            datastore.getCollection(DbCollections.DB_MODULES)
                    .remove(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, moduleId));
        }
    }

    @Override
    public void promoteModule(final DbModule module) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection modules = datastore.getCollection(DbCollections.DB_MODULES);

        modules.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, module.getId()))
                .with("{ $set: { \"" + DbModule.PROMOTION_DB_FIELD + "\": #}} ", Boolean.TRUE);
    }

    @Override
    public DbModule getRootModuleOf(final String gavc) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_MODULES)
                .findOne(JongoUtils.generateQuery(DbModule.HAS_DB_FIELD, gavc)).as(DbModule.class);
    }

    @Override
    public DbModule getModuleOf(final String gavc) {
        final DbModule module = getRootModuleOf(gavc);

        // It may be a submodule...
        if (module != null && !module.getArtifacts().contains(gavc)) {
            for (DbModule submodule : DataUtils.getAllSubmodules(module)) {
                if (submodule.getArtifacts().contains(gavc)) {
                    return submodule;
                }
            }
        }

        return module;
    }

    @Override
    public List<String> getOrganizationNames() {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_ORGANIZATION).distinct(DbCollections.DEFAULT_ID)
                .as(String.class);
    }

    @Override
    public DbOrganization getOrganization(String name) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_ORGANIZATION)
                .findOne(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, name)).as(DbOrganization.class);
    }

    @Override
    public void deleteOrganization(String organizationId) {
        final Jongo datastore = getJongoDataStore();
        datastore.getCollection(DbCollections.DB_ORGANIZATION)
                .remove(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, organizationId));
    }

    @Override
    public void store(DbOrganization organization) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection dbOrganizations = datastore.getCollection(DbCollections.DB_ORGANIZATION);

        if (getOrganization(organization.getName()) == null) {
            dbOrganizations.save(organization);
        } else {
            dbOrganizations.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, organization.getName()))
                    .with(organization);
        }
    }

    @Override
    public void addModulesOrganization(final String corporateGidPrefix, final DbOrganization organization) {
        final Jongo datastore = getJongoDataStore();

        datastore.getCollection(DbCollections.DB_MODULES)
                .update("{ " + DbModule.HAS_DB_FIELD + " :#}", Pattern.compile(corporateGidPrefix + "*")).multi()
                .with("{$set: " + JongoUtils.generateQuery(DbModule.ORGANIZATION_DB_FIELD, organization.getName())
                        + "}");
    }

    @Override
    public void removeModulesOrganization(final String corporateGidPrefix, final DbOrganization organization) {
        final Jongo datastore = getJongoDataStore();

        datastore.getCollection(DbCollections.DB_MODULES)
                .update("{ $and: [" + "{ " + DbModule.HAS_DB_FIELD + " :#} ,"
                        + JongoUtils.generateQuery(DbModule.ORGANIZATION_DB_FIELD, organization.getName()) + "]}",
                        Pattern.compile(corporateGidPrefix + "*"))
                .multi().with("{$set: { " + DbModule.ORGANIZATION_DB_FIELD + " : \"\"}}");
    }

    @Override
    public void removeModulesOrganization(final DbOrganization organization) {
        final Jongo datastore = getJongoDataStore();
        datastore.getCollection(DbCollections.DB_MODULES)
                .update(JongoUtils.generateQuery(DbModule.ORGANIZATION_DB_FIELD, organization.getName()))
                .with("{$set: { " + DbModule.ORGANIZATION_DB_FIELD + " : \"\"}}");
    }

    @Override
    public List<DbOrganization> getAllOrganizations() {
        final Jongo datastore = getJongoDataStore();
        final Iterable<DbOrganization> organizations = datastore.getCollection(DbCollections.DB_ORGANIZATION).find()
                .as(DbOrganization.class);

        return Lists.newArrayList(organizations);
    }

    @Override
    public void store(final DbProduct dbProduct) {
        final Jongo datastore = getJongoDataStore();
        final MongoCollection dbProducts = datastore.getCollection(DbCollections.DB_PRODUCT);

        if (getOrganization(dbProduct.getName()) == null) {
            dbProducts.save(dbProduct);
        } else {
            dbProducts.update(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, dbProduct.getName()))
                    .with(dbProduct);
        }
    }

    @Override
    public DbProduct getProduct(final String name) {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_PRODUCT)
                .findOne(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, name)).as(DbProduct.class);
    }

    @Override
    public List<String> getProductNames() {
        final Jongo datastore = getJongoDataStore();
        return datastore.getCollection(DbCollections.DB_PRODUCT).distinct(DbCollections.DEFAULT_ID)
                .as(String.class);
    }

    @Override
    public void deleteProduct(String name) {
        final Jongo datastore = getJongoDataStore();
        datastore.getCollection(DbCollections.DB_PRODUCT)
                .remove(JongoUtils.generateQuery(DbCollections.DEFAULT_ID, name));
    }
}