package org.gcube.application.geoportal.service.engine.providers.ucd; import lombok.extern.slf4j.Slf4j; import org.gcube.application.cms.caches.AbstractScopedMap; import org.gcube.application.cms.implementations.ImplementationProvider; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.utils.ContextUtils; import org.gcube.application.geoportal.service.engine.mongo.UCDManagerI; import org.gcube.application.geoportal.service.engine.mongo.UCDMongoManager; import org.gcube.application.geoportal.service.model.internal.faults.RegistrationException; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; @Slf4j public class UCDManager extends AbstractScopedMap implements UCDManagerI { public UCDManager() { super("UCD MANAGER"); } @Override public Iterable query(QueryRequest queryRequest) throws ConfigurationException { return getMongoManager().query(queryRequest); } @Override public void deleteById(String id, boolean force) throws RegistrationException, ConfigurationException { log.warn("Trying to delete {} [force : {}]",id,force); // NB Check for existing ID UseCaseDescriptor found = getById(id); if(found!=null) { // TODO validate DELETE REQUEST // TODO STORE UCD // forceUpdateCache(); throw new WebApplicationException("TO IMPLEMENT ", Response.Status.INTERNAL_SERVER_ERROR); } else throw new WebApplicationException("No Matching UCD with ID "+id, Response.Status.NOT_FOUND); } @Override public UseCaseDescriptor put(UseCaseDescriptor desc) throws ConfigurationException, RegistrationException { log.debug("Update {} ",desc.getId()); // NB Check for existing ID UseCaseDescriptor found = getById(desc.getId()); if(found!=null) { // TODO validate UPDATE // TODO STORE UCD // forceUpdateCache(); throw new WebApplicationException("TO IMPLEMENT ", Response.Status.INTERNAL_SERVER_ERROR); } else throw new WebApplicationException("No Matching UCD with ID "+desc.getId(), Response.Status.NOT_FOUND); } @Override public UseCaseDescriptor getById(String id) throws ConfigurationException, RegistrationException { // GET from mongo cache UCDMongoManager mongo=getMongoManager(); UseCaseDescriptor toReturn=mongo.getById(id); log.debug("UCD ID : {} from mongo is {} ",id,toReturn); if(toReturn == null) { // IF void try from ProfileEngine toReturn =getLiveMap().get(id); if(toReturn != null ){ log.debug("Force update of live map {} from live map ",id); toReturn = mongo.put(toReturn); } } return toReturn; } private ProfileMap getLiveMap() throws ConfigurationException { return ImplementationProvider.get().getEngineByManagedClass(ProfileMap.class); }; private UCDMongoManager getMongoManager() throws ConfigurationException { return new UCDMongoManager(); } @Override protected UCDManagerI retrieveObject(String context) throws ConfigurationException { forceUpdateCache(); return this; } ConcurrentHashMap cleanedCaches= new ConcurrentHashMap<>(); private void forceUpdateCache() throws ConfigurationException { log.info("UPDATING PROFILE CACHE.."); final UCDMongoManager manager = getMongoManager(); manager.deleteAll(); final AtomicLong counter= new AtomicLong(0l); ProfileMap liveMap=getLiveMap(); log.debug("LiveMap size is {} ",liveMap.size()); for (Map.Entry entry : liveMap.entrySet()) { UseCaseDescriptor useCaseDescriptor = entry.getValue(); try { log.debug("Updateing cache with {} ", useCaseDescriptor.getId()); // insert/update into DB manager.put(useCaseDescriptor); } catch (RegistrationException e) { log.warn("Unable to cache UCD {}",entry.getKey(),e); } } log.info("Cached : {} UCDs in {} ",counter.get(),ContextUtils.getCurrentScope()); } }