/* * Copyright 2015-2016 OpenCB * * 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 org.opencb.opencga.catalog.db.mongodb; import com.mongodb.BasicDBObject; import com.mongodb.DuplicateKeyException; import org.apache.commons.lang3.StringUtils; import org.bson.Document; import org.opencb.commons.datastore.core.DataStoreServerAddress; import org.opencb.commons.datastore.core.QueryResult; import org.opencb.commons.datastore.mongodb.MongoDBCollection; import org.opencb.commons.datastore.mongodb.MongoDBConfiguration; import org.opencb.commons.datastore.mongodb.MongoDataStore; import org.opencb.commons.datastore.mongodb.MongoDataStoreManager; import org.opencb.opencga.catalog.config.Admin; import org.opencb.opencga.catalog.config.Configuration; import org.opencb.opencga.catalog.db.DBAdaptorFactory; import org.opencb.opencga.catalog.db.api.PanelDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogDBException; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.models.Metadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.opencb.opencga.catalog.db.mongodb.MongoDBUtils.getMongoDBDocument; /** * Created by pfurio on 08/01/16. */ public class MongoDBAdaptorFactory implements DBAdaptorFactory { private final List<String> COLLECTIONS_LIST = Arrays.asList( "user", "study", "file", "job", "sample", "individual", "cohort", "dataset", "panel", "metadata", "audit" ); protected static final String USER_COLLECTION = "user"; protected static final String STUDY_COLLECTION = "study"; protected static final String FILE_COLLECTION = "file"; protected static final String JOB_COLLECTION = "job"; protected static final String SAMPLE_COLLECTION = "sample"; protected static final String INDIVIDUAL_COLLECTION = "individual"; protected static final String COHORT_COLLECTION = "cohort"; protected static final String DATASET_COLLECTION = "dataset"; protected static final String PANEL_COLLECTION = "panel"; protected static final String METADATA_COLLECTION = "metadata"; protected static final String AUDIT_COLLECTION = "audit"; static final String METADATA_OBJECT_ID = "METADATA"; private final MongoDataStoreManager mongoManager; private final MongoDBConfiguration configuration; private final String database; // private final DataStoreServerAddress dataStoreServerAddress; private MongoDataStore db; private MongoDBCollection metaCollection; private MongoDBCollection userCollection; private MongoDBCollection studyCollection; private MongoDBCollection fileCollection; private MongoDBCollection sampleCollection; private MongoDBCollection individualCollection; private MongoDBCollection jobCollection; private MongoDBCollection cohortCollection; private MongoDBCollection datasetCollection; private MongoDBCollection panelCollection; private MongoDBCollection auditCollection; private Map<String, MongoDBCollection> collections; private UserMongoDBAdaptor userDBAdaptor; private StudyMongoDBAdaptor studyDBAdaptor; private IndividualMongoDBAdaptor individualDBAdaptor; private SampleMongoDBAdaptor sampleDBAdaptor; private FileMongoDBAdaptor fileDBAdaptor; private JobMongoDBAdaptor jobDBAdaptor; private ProjectMongoDBAdaptor projectDBAdaptor; private CohortMongoDBAdaptor cohortDBAdaptor; private DatasetMongoDBAdaptor datasetDBAdaptor; private PanelMongoDBAdaptor panelDBAdaptor; private AuditMongoDBAdaptor auditDBAdaptor; private MetaMongoDBAdaptor metaDBAdaptor; private Logger logger; public MongoDBAdaptorFactory(List<DataStoreServerAddress> dataStoreServerAddressList, MongoDBConfiguration configuration, String database) throws CatalogDBException { // super(LoggerFactory.getLogger(CatalogMongoDBAdaptor.class)); this.mongoManager = new MongoDataStoreManager(dataStoreServerAddressList); this.configuration = configuration; this.database = database; logger = LoggerFactory.getLogger(this.getClass()); connect(); } @Override public void initializeCatalogDB(Admin admin) throws CatalogDBException { //If "metadata" document doesn't exist, create. if (!isCatalogDBReady()) { /* Check all collections are empty */ for (Map.Entry<String, MongoDBCollection> entry : collections.entrySet()) { if (entry.getValue().count().first() != 0L) { throw new CatalogDBException("Fail to initialize Catalog Database in MongoDB. Collection " + entry.getKey() + " is " + "not empty."); } } try { // DBObject metadataObject = getDbObject(new Metadata(), "Metadata"); Document metadataObject = getMongoDBDocument(new Metadata(), "Metadata"); metadataObject.put("_id", METADATA_OBJECT_ID); metadataObject.put("admin", getMongoDBDocument(admin, "Admin")); metaCollection.insert(metadataObject, null); } catch (DuplicateKeyException e) { logger.warn("Trying to replace MetadataObject. DuplicateKey"); } //Set indexes // BasicDBObject unique = new BasicDBObject("unique", true); // nativeUserCollection.createIndexes(new BasicDBObject("id", 1), unique); // nativeFileCollection.createIndexes(BasicDBObjectBuilder.start("studyId", 1).append("path", 1).get(), unique); // nativeJobCollection.createIndexes(new BasicDBObject("id", 1), unique); } else { throw new CatalogDBException("Catalog already initialized"); } } @Override public void installCatalogDB(Configuration configuration) throws CatalogException { // TODO: Check META object does not exist. Use {@link isCatalogDBReady} // TODO: Check all collections do not exists, or are empty // TODO: Catch DuplicatedKeyException while inserting META object MongoDataStore mongoDataStore = mongoManager.get(database, this.configuration); if (mongoDataStore.getCollectionNames().size() > 0) { throw new CatalogException("Database " + database + " already exists with the following collections: " + StringUtils.join(mongoDataStore.getCollectionNames()) + ".\nPlease, remove the database or choose a different one."); } COLLECTIONS_LIST.forEach(mongoDataStore::createCollection); metaDBAdaptor.createIndexes(); metaDBAdaptor.initializeMetaCollection(configuration); } @Override public void createIndexes() throws CatalogDBException { metaDBAdaptor.createIndexes(); // InputStream resourceAsStream = getClass().getResourceAsStream("/catalog-indexes.txt"); // ObjectMapper objectMapper = new ObjectMapper(); // BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resourceAsStream)); // bufferedReader.lines().filter(s -> !s.trim().isEmpty()).forEach(s -> { // try { // System.out.println(s); // HashMap hashMap = objectMapper.readValue(s, HashMap.class); // System.out.println(hashMap); // QueryResult<Document> index = getCatalogUserDBAdaptor().getUserCollection().getIndex(); // System.out.println(index); // } catch (IOException e) { // e.printStackTrace(); // } // }); // try { // bufferedReader.close(); // } catch (IOException e) { // e.printStackTrace(); // } } @Override public void deleteCatalogDB() throws CatalogDBException { mongoManager.drop(database); } @Override public boolean isCatalogDBReady() { QueryResult<Long> queryResult = metaCollection.count(new BasicDBObject("_id", METADATA_OBJECT_ID)); return queryResult.getResult().get(0) == 1; } @Override public void close() { mongoManager.close(db.getDatabaseName()); } @Override public MetaMongoDBAdaptor getCatalogMetaDBAdaptor() { return metaDBAdaptor; } @Override public UserMongoDBAdaptor getCatalogUserDBAdaptor() { return userDBAdaptor; } @Override public ProjectMongoDBAdaptor getCatalogProjectDbAdaptor() { return projectDBAdaptor; } @Override public StudyMongoDBAdaptor getCatalogStudyDBAdaptor() { return studyDBAdaptor; } @Override public SampleMongoDBAdaptor getCatalogSampleDBAdaptor() { return sampleDBAdaptor; } @Override public IndividualMongoDBAdaptor getCatalogIndividualDBAdaptor() { return individualDBAdaptor; } @Override public FileMongoDBAdaptor getCatalogFileDBAdaptor() { return fileDBAdaptor; } @Override public JobMongoDBAdaptor getCatalogJobDBAdaptor() { return jobDBAdaptor; } @Override public CohortMongoDBAdaptor getCatalogCohortDBAdaptor() { return cohortDBAdaptor; } @Override public DatasetMongoDBAdaptor getCatalogDatasetDBAdaptor() { return datasetDBAdaptor; } @Override public PanelDBAdaptor getCatalogPanelDBAdaptor() { return panelDBAdaptor; } @Override public AuditMongoDBAdaptor getCatalogAuditDbAdaptor() { return auditDBAdaptor; } private void connect() throws CatalogDBException { db = mongoManager.get(database, configuration); if (db == null) { throw new CatalogDBException("Unable to connect to MongoDB"); } metaCollection = db.getCollection(METADATA_COLLECTION); userCollection = db.getCollection(USER_COLLECTION); studyCollection = db.getCollection(STUDY_COLLECTION); fileCollection = db.getCollection(FILE_COLLECTION); sampleCollection = db.getCollection(SAMPLE_COLLECTION); individualCollection = db.getCollection(INDIVIDUAL_COLLECTION); jobCollection = db.getCollection(JOB_COLLECTION); cohortCollection = db.getCollection(COHORT_COLLECTION); datasetCollection = db.getCollection(DATASET_COLLECTION); auditCollection = db.getCollection(AUDIT_COLLECTION); panelCollection = db.getCollection(PANEL_COLLECTION); collections = new HashMap<>(); collections.put(METADATA_COLLECTION, metaCollection); collections.put(USER_COLLECTION, userCollection); collections.put(STUDY_COLLECTION, studyCollection); collections.put(FILE_COLLECTION, fileCollection); collections.put(SAMPLE_COLLECTION, sampleCollection); collections.put(INDIVIDUAL_COLLECTION, individualCollection); collections.put(JOB_COLLECTION, jobCollection); collections.put(COHORT_COLLECTION, cohortCollection); collections.put(DATASET_COLLECTION, datasetCollection); collections.put(AUDIT_COLLECTION, auditCollection); collections.put(PANEL_COLLECTION, panelCollection); fileDBAdaptor = new FileMongoDBAdaptor(fileCollection, this); individualDBAdaptor = new IndividualMongoDBAdaptor(individualCollection, this); jobDBAdaptor = new JobMongoDBAdaptor(jobCollection, this); projectDBAdaptor = new ProjectMongoDBAdaptor(userCollection, this); sampleDBAdaptor = new SampleMongoDBAdaptor(sampleCollection, this); studyDBAdaptor = new StudyMongoDBAdaptor(studyCollection, this); userDBAdaptor = new UserMongoDBAdaptor(userCollection, this); cohortDBAdaptor = new CohortMongoDBAdaptor(cohortCollection, this); datasetDBAdaptor = new DatasetMongoDBAdaptor(datasetCollection, this); panelDBAdaptor = new PanelMongoDBAdaptor(panelCollection, this); metaDBAdaptor = new MetaMongoDBAdaptor(metaCollection, this); auditDBAdaptor = new AuditMongoDBAdaptor(auditCollection); } }