package org.gcube.application.geoportal.service.engine.mongo; import com.fasterxml.jackson.core.JsonProcessingException; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.FindOneAndReplaceOptions; import com.mongodb.client.model.ReturnDocument; import lombok.extern.slf4j.Slf4j; import org.bson.Document; import org.bson.types.ObjectId; import org.gcube.application.cms.caches.Engine; import org.gcube.application.cms.implementations.ImplementationProvider; import org.gcube.application.cms.serialization.Serialization; import org.gcube.application.geoportal.common.model.legacy.Concessione; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.common.utils.ContextUtils; import org.gcube.application.geoportal.service.engine.providers.ProfileMapCache; import org.gcube.application.geoportal.service.model.internal.faults.RegistrationException; import org.gcube.application.geoportal.service.rest.UseCaseDescriptors; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import java.util.NoSuchElementException; import java.util.concurrent.LinkedBlockingQueue; import java.util.function.Consumer; @Slf4j public class UCDMongoManager extends MongoManager implements UCDManagerI{ MongoDatabase db=null; public UCDMongoManager() throws ConfigurationException { String toUseDB=super.client.getConnection().getDatabase(); log.info("Connecting to DB {} ",toUseDB); db=client.getTheClient().getDatabase(toUseDB); } @Override public MongoDatabase getDatabase(){ return db; } @Override protected String mongoIDFieldName() { return UseCaseDescriptor.MONGO_ID; } private String getCollectionName(){ return "profiles_"+ContextUtils.getCurrentScope(); } public UseCaseDescriptor insert(UseCaseDescriptor desc) throws RegistrationException { try { if (desc.getMongoId() != null) throw new RegistrationException("UCD has already a mongo ID"); //TODO validate ObjectId id = super.insert(Serialization.asDocument(desc), mongoCollectionName()); desc.setMongoId(id); return Serialization.convert(super.getById(id, mongoCollectionName()), UseCaseDescriptor.class); }catch(JsonProcessingException e){ log.error("Unexpected serialization exception ",e); throw new WebApplicationException("Unexpected exception ",e); } } @Override public UseCaseDescriptor put(UseCaseDescriptor desc) throws RegistrationException, ConfigurationException { log.debug("PUT UCD ID {} MONGO ID ",desc.getId(),desc.getMongoId()); FindOneAndReplaceOptions opts = new FindOneAndReplaceOptions(); Document filter = new Document(UseCaseDescriptor.ID,desc.getId()); if(desc.getMongoId()!=null) // MONGO ID SHOULD MATCH IF PROVIDED filter.put(UseCaseDescriptor.MONGO_ID,desc.getMongoId()); try { UseCaseDescriptor toReturn = Serialization.convert(getDatabase().getCollection(mongoCollectionName()).findOneAndReplace( filter, Serialization.asDocument(desc), new FindOneAndReplaceOptions().returnDocument(ReturnDocument.BEFORE)), UseCaseDescriptor.class); log.trace("Matching is {} ", toReturn); // NOT FOUND if (toReturn == null) { if (desc.getMongoId() != null) { // illegal update check if (getById(desc.getId()) != null) throw new RegistrationException("Illegal attempt to write to " + desc.getId() + " with unmatching mongo ID "); } toReturn = insert(desc); } return toReturn; }catch (RegistrationException | ConfigurationException e){ throw e; }catch(Throwable e){ log.error("Unable to update ",e); throw new RegistrationException("Invalid UCD provided "+e.getMessage()); } } private String mongoCollectionName(){ return "_UCD"+ ContextUtils.getCurrentScope().replaceAll("/","_"); } @Override public Iterable query(QueryRequest queryRequest) { log.info("Searching UCD for {} ",queryRequest); LinkedBlockingQueue queue=new LinkedBlockingQueue(); query(queryRequest,getCollectionName()).forEach( (Consumer) d ->{try{ queue.put(Serialization.convert(d,UseCaseDescriptor.class)); }catch(Throwable t){log.warn("Unable to translate "+d);}}); log.info("Returned {} elements ",queue.size()); return queue; } @Override public void deleteById(String id, boolean force) throws ConfigurationException { delete(getById(id).getMongoId(),mongoCollectionName()); } @Override public UseCaseDescriptor getById(String id) throws ConfigurationException { log.info("Getting UC by ID {} ",id); QueryRequest request=new QueryRequest(); request.setFilter(new Document(UseCaseDescriptor.ID,id)); try { return this.query(request).iterator().next(); }catch (NoSuchElementException e){return null;} } }