package org.gcube.application.geoportal.service.engine.mongo; import com.mongodb.Block; import com.mongodb.MongoClient; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.FindOneAndReplaceOptions; import com.mongodb.client.model.FindOneAndUpdateOptions; import com.mongodb.client.model.ReturnDocument; import lombok.extern.slf4j.Slf4j; import org.bson.Document; import org.bson.types.ObjectId; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.service.engine.ImplementationProvider; import org.gcube.application.geoportal.service.model.internal.db.Mongo; import org.gcube.application.geoportal.service.model.internal.faults.ConfigurationException; import static com.mongodb.client.model.Filters.eq; import static com.mongodb.client.model.Sorts.ascending; import static com.mongodb.client.model.Sorts.descending; @Slf4j public abstract class MongoManager { protected Mongo client=null; protected static final String ID="_id"; protected static final ObjectId asId(String id) {return new ObjectId(id);} protected static final String asString(ObjectId id) {return id.toHexString();} protected static final String asString(Document d) {return d.toJson();} protected static final Document asDoc(String json) {return Document.parse(json);} public MongoManager() throws ConfigurationException { client=ImplementationProvider.get().getMongoClientProvider().getObject(); log.info("Got Mongo Client at "+client.getConnection()); log.debug("Mongo client is "+client); } // TODO check if existing DB protected abstract MongoDatabase getDatabase(); //*********** PROJECTS // NB BsonId protected ObjectId insert(Document proj, String collectionName) { MongoDatabase database=getDatabase(); MongoCollection collection = database.getCollection(collectionName); // Check if _id is present ObjectId id=proj.getObjectId(ID); if(id==null) { proj.append(ID, new ObjectId()); id=proj.getObjectId(ID); } collection.insertOne(Document.parse(proj.toJson())); return id; } public void delete(ObjectId id, String collectionName) { MongoDatabase database=getDatabase(); MongoCollection collection = database.getCollection(collectionName); collection.deleteOne(eq(ID,id)); } public Document getById(ObjectId id,String collectionName) { MongoDatabase database=getDatabase(); MongoCollection coll=database.getCollection(collectionName); return coll.find(new Document(ID,id)).first(); } public FindIterable iterate(Document filter, Document projection, String collectionName) { log.debug("Iterate over {} ",collectionName); MongoDatabase database=getDatabase(); MongoCollection coll=database.getCollection(collectionName); if(filter == null) filter=new Document(); log.debug("Applying Filter "+filter.toJson()); if(projection != null ) { log.debug("Applying projection "+projection.toJson()); return coll.find(filter).projection(projection); }else return coll.find(filter); } public FindIterable query(QueryRequest request, String collectionName){ FindIterable toReturn=iterate(request.getFilter(), request.getProjection(),collectionName); if(request.getOrdering()!=null){ if(request.getOrdering().getDirection().equals(QueryRequest.OrderedRequest.Direction.ASCENDING)) toReturn=toReturn.sort(ascending(request.getOrdering().getFields())); else toReturn=toReturn.sort(descending(request.getOrdering().getFields())); } //Paging if(request.getPaging()!=null){ QueryRequest.PagedRequest paging=request.getPaging(); toReturn=toReturn.skip(paging.getOffset()).limit(paging.getLimit()); } return toReturn; } public FindIterable iterateForClass(Document filter,String collectionName,Class clazz) { MongoDatabase database=getDatabase(); MongoCollection coll=database.getCollection(collectionName); if(filter==null) return coll.find(clazz); else return coll.find(filter,clazz); } public Document replace(Document toUpdate,String collectionName) { MongoDatabase database=getDatabase(); MongoCollection coll=database.getCollection(collectionName); return coll.findOneAndReplace( eq(ID,toUpdate.getObjectId(ID)), toUpdate,new FindOneAndReplaceOptions().returnDocument(ReturnDocument.AFTER)); } public Document update(ObjectId id, Document updateSet, String collectionName) { MongoDatabase database=getDatabase(); MongoCollection coll=database.getCollection(collectionName); return coll.findOneAndUpdate( eq(ID,id), updateSet, new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)); } //********** PROFILES }