diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java index e0dd7fc..44ab6b9 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/DefaultISProvider.java @@ -4,6 +4,7 @@ import org.gcube.application.cms.caches.Engine; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; import org.gcube.application.geoportal.common.utils.ISUtils; +import org.gcube.common.resources.gcore.GenericResource; import org.gcube.common.resources.gcore.ServiceEndpoint; import java.util.List; @@ -31,6 +32,12 @@ public class DefaultISProvider implements ISInterface, Engine { return ISUtils.encryptString(toEncrypt); } + @Override + public List getGenericResource(String secondaryType,String name) { + return ISUtils.getGenericResources(secondaryType,name); + } + + // ** ENGINE @Override diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java index b80b4a2..307dc4f 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/implementations/ISInterface.java @@ -2,6 +2,7 @@ package org.gcube.application.cms.implementations; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; +import org.gcube.common.resources.gcore.GenericResource; import org.gcube.common.resources.gcore.ServiceEndpoint; import java.util.List; @@ -12,4 +13,6 @@ public interface ISInterface { public List performGetAP(String category, String platform, String flagName, String flagValue); public String decryptString(String toDecrypt); public String encryptString(String toEncrypt); + + public List getGenericResource(String secondaryType,String name); } diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/Serialization.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/Serialization.java index 17363fe..ef7c735 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/Serialization.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/serialization/Serialization.java @@ -40,8 +40,7 @@ public class Serialization { s.addDeserializer(Semver.class,new SemverDeserializer()); s.addSerializer(Semver.class,new SemverSerializer()); - - + mapper.registerModule(s); } diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java index 4cb1fce..8acfb03 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/utils/ISUtils.java @@ -5,6 +5,7 @@ import org.gcube.application.geoportal.common.model.configuration.MongoConnectio import org.gcube.application.geoportal.common.model.rest.DatabaseConnection; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.common.encryption.encrypter.StringEncrypter; +import org.gcube.common.resources.gcore.GenericResource; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.common.resources.gcore.ServiceEndpoint.Property; @@ -53,6 +54,17 @@ public class ISUtils { } + public static List getGenericResources(String secondaryType,String name) { + SimpleQuery query = queryFor(GenericResource.class); + + query.addCondition("$resource/Profile/SecondaryType/text() eq '"+secondaryType+"'") + .addCondition("$resource/Profile/Name/text() eq '"+name+"'"); + + DiscoveryClient client = clientFor(GenericResource.class); + return client.submit(query); + } + + public static String decryptString(String toDecrypt){ try{ return StringEncrypter.getEncrypter().decrypt(toDecrypt); diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/GeoPortalService.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/GeoPortalService.java index 1573f33..95e7500 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/GeoPortalService.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/GeoPortalService.java @@ -8,6 +8,10 @@ import org.gcube.application.geoportal.common.utils.StorageUtils; import org.gcube.application.geoportal.service.engine.mongo.UCDManagerI; import org.gcube.application.geoportal.service.engine.postgis.PostgisDBManager; import org.gcube.application.geoportal.service.engine.providers.*; +import org.gcube.application.geoportal.service.engine.providers.ucd.ProfileMap; +import org.gcube.application.geoportal.service.engine.providers.ucd.LocalFolderProfileMapCache; +import org.gcube.application.geoportal.service.engine.providers.ucd.SingleISResourceUCDProvider; +import org.gcube.application.geoportal.service.engine.providers.ucd.UCDManager; import org.gcube.application.geoportal.service.model.internal.db.Mongo; import org.gcube.application.geoportal.service.rest.ConcessioniOverMongo; @@ -40,7 +44,8 @@ public class GeoPortalService extends ResourceConfig{ ImplementationProvider.get().setEngine(new MongoClientProvider(), Mongo.class); ImplementationProvider.get().setEngine(new StorageClientProvider(), StorageUtils.class); ImplementationProvider.get().setEngine(new PostgisConnectionProvider(), PostgisDBManager.class); - ImplementationProvider.get().setEngine(new ProfileMapCache(), ProfileMapCache.ProfileMap.class); +// ImplementationProvider.get().setEngine(new LocalFolderProfileMapCache(), ProfileMap.class); + ImplementationProvider.get().setEngine(new SingleISResourceUCDProvider(), ProfileMap.class); ImplementationProvider.get().setEngine(new PluginManager(), PluginManager.PluginMap.class); ImplementationProvider.get().setEngine(new StorageHubProvider(), StorageHubClient.class); ImplementationProvider.get().setEngine(new UCDManager(),UCDManagerI.class); diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java index 6a1c4bf..efa38cf 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java @@ -2,15 +2,12 @@ package org.gcube.application.geoportal.service.engine.mongo; import com.fasterxml.jackson.core.JsonProcessingException; 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 com.vdurmont.semver4j.Semver; import lombok.Getter; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections.ArrayStack; import org.apache.commons.io.IOUtils; import org.bson.Document; import org.bson.types.ObjectId; @@ -48,7 +45,7 @@ import org.gcube.application.cms.implementations.ImplementationProvider; import org.gcube.application.geoportal.service.engine.WorkspaceManager; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.service.engine.providers.PluginManager; -import org.gcube.application.geoportal.service.engine.providers.ProfileMapCache; +import org.gcube.application.geoportal.service.engine.providers.ucd.ProfileMap; import org.gcube.application.geoportal.service.model.internal.faults.*; import org.gcube.application.cms.serialization.Serialization; import org.gcube.application.geoportal.service.utils.UserUtils; @@ -59,7 +56,6 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import java.io.IOException; import java.io.InputStream; -import java.lang.invoke.SerializedLambda; import java.net.URL; import java.security.InvalidParameterException; import java.time.LocalDateTime; @@ -85,7 +81,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< // Check UseCaseDescriptor ID log.info("Loading useCaseDescriptor ID {} ",profileId); if(profileId==null) throw new InvalidParameterException("UseCaseDescriptor ID cannot be null"); - Map profiles=ImplementationProvider.get().getEngineByManagedClass(ProfileMapCache.ProfileMap.class); + Map profiles=ImplementationProvider.get().getEngineByManagedClass(ProfileMap.class); useCaseDescriptor = ImplementationProvider.get().getEngineByManagedClass(UCDManagerI.class).getById(profileId); if(useCaseDescriptor == null ) throw new WebApplicationException("UseCaseDescriptor " + profileId + " not registered", Response.Status.NOT_FOUND); diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/UCDMongoManager.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/UCDMongoManager.java index e5c5966..3f58aa1 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/UCDMongoManager.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/UCDMongoManager.java @@ -2,27 +2,19 @@ package org.gcube.application.geoportal.service.engine.mongo; import com.fasterxml.jackson.core.JsonProcessingException; 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.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; diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ProfileMapCache.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/LocalFolderProfileMapCache.java similarity index 80% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ProfileMapCache.java rename to geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/LocalFolderProfileMapCache.java index 727388e..652a970 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ProfileMapCache.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/LocalFolderProfileMapCache.java @@ -1,7 +1,6 @@ -package org.gcube.application.geoportal.service.engine.providers; +package org.gcube.application.geoportal.service.engine.providers.ucd; import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.gcube.application.cms.caches.AbstractScopedMap; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; @@ -11,23 +10,16 @@ import org.gcube.application.cms.serialization.Serialization; import java.io.IOException; import java.nio.charset.Charset; -import java.util.HashMap; @Slf4j -public class ProfileMapCache extends AbstractScopedMap { - - @AllArgsConstructor - public static class ProfileMap extends HashMap{ - } - - public ProfileMapCache() { - super("Profiles CACHE"); +public class LocalFolderProfileMapCache extends AbstractScopedMap { + public LocalFolderProfileMapCache() { + super("Local Profiles CACHE"); } @Override public void init() { - } @Override diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/ProfileMap.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/ProfileMap.java new file mode 100644 index 0000000..e9de365 --- /dev/null +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/ProfileMap.java @@ -0,0 +1,10 @@ +package org.gcube.application.geoportal.service.engine.providers.ucd; + +import lombok.AllArgsConstructor; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; + +import java.util.HashMap; + +@AllArgsConstructor +public class ProfileMap extends HashMap { +} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/SingleISResourceUCDProvider.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/SingleISResourceUCDProvider.java new file mode 100644 index 0000000..735724c --- /dev/null +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/SingleISResourceUCDProvider.java @@ -0,0 +1,147 @@ +package org.gcube.application.geoportal.service.engine.providers.ucd; + +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.gcube.application.cms.caches.AbstractScopedMap; +import org.gcube.application.cms.implementations.ISInterface; +import org.gcube.application.cms.implementations.ImplementationProvider; +import org.gcube.application.cms.serialization.Serialization; +import org.gcube.application.geoportal.common.model.rest.ConfigurationException; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; +import org.gcube.common.resources.gcore.GenericResource; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.*; +import java.io.StringReader; +import java.io.StringWriter; +import java.lang.reflect.GenericArrayType; +import java.net.URL; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Scanner; + +/** + * Retrieves available UCDs from a single Generic Resource + * - secondary Type : "CMS" + * - name : "UCDs" + * + * containing e.g. + * + * + * + * + * + * + */ +@Slf4j +public class SingleISResourceUCDProvider extends AbstractScopedMap { + + + public SingleISResourceUCDProvider() { + super("Single IS Resource UCD Provider"); + setTTL(Duration.of(2, ChronoUnit.MINUTES)); + } + + @XmlAccessorType(XmlAccessType.FIELD) + @XmlRootElement(name = "UCDs") + @Data + @EqualsAndHashCode + public static class ISBean { + + @NoArgsConstructor + @ToString + @Getter + @Setter + @AllArgsConstructor + @XmlAccessorType(XmlAccessType.FIELD) + @EqualsAndHashCode + public static class Record { + @XmlAttribute + private String label; + @XmlAttribute + private String ucdUrl; + @XmlAttribute + private String defaultForRegex; + } + + @XmlElement(name = "record") + private List records; + } + + + @Override + public void init() { + super.init(); + try{ + directInit(); + }catch(Throwable t){ + throw new RuntimeException("Unable to initialize. Can't read Use case descriptors ",t); + } + } + + static void directInit() throws JAXBException { + jaxbContext = JAXBContext.newInstance(ISBean.class); + marshaller = jaxbContext.createMarshaller(); + unmarshaller = jaxbContext.createUnmarshaller(); + } + private static JAXBContext jaxbContext=null; + private static Marshaller marshaller=null; + private static Unmarshaller unmarshaller = null; + + + static ISBean read(String xml) throws JAXBException { + log.trace("Loading from xml {}",xml); + return (ISBean) unmarshaller.unmarshal(new StringReader(xml)); + } + + + static String write(ISBean obj) throws JAXBException { + log.trace("Writing {} to xml",obj); + StringWriter writer = new StringWriter(); + marshaller.marshal(obj,writer); + writer.flush(); + return writer.toString(); + } + + @Override + protected ProfileMap retrieveObject(String key) throws ConfigurationException { + try { + log.info("Loading UCDs for context {} ",key); + ISInterface is = ImplementationProvider.get().getEngineByManagedClass(ISInterface.class); + List l = is.getGenericResource("CMS","UCDs"); + log.debug("Found {} resources ",l.size()); + + ProfileMap toReturn = new ProfileMap(); + l.forEach(g->{ + try { + log.debug("Reading from ID {} ", g.id()); + ISBean bean = read(g.profile().bodyAsString()); + log.debug("Found {} records ", bean.getRecords().size()); + int before = toReturn.size(); + bean.getRecords().forEach(record -> { + try { + log.debug("Loading UCD From {} ", record); + String json = new Scanner( + new URL("http://www.google.com").openStream(), + "UTF-8").next(); + UseCaseDescriptor ucd = Serialization.read(json, UseCaseDescriptor.class); + toReturn.put(ucd.getId(), ucd); + }catch (Throwable t){ + log.warn("Unable to read record {} from GR ID {} ",record,g.id(),t); + } + }); + log.debug("Loaded {} from {} ",toReturn.size()-before,g.id()); + }catch (Throwable t){ + log.warn("Unable to read from GR {} ",g.id(),t); + } + }); + return toReturn; + }catch(Throwable t){ + throw new ConfigurationException("Unable to load UCDs for "+key,t); + } + } +} diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/UCDManager.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/UCDManager.java similarity index 92% rename from geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/UCDManager.java rename to geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/UCDManager.java index 7a012f1..7ef69a7 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/UCDManager.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/providers/ucd/UCDManager.java @@ -1,21 +1,16 @@ -package org.gcube.application.geoportal.service.engine.providers; +package org.gcube.application.geoportal.service.engine.providers.ucd; -import com.mongodb.client.FindIterable; -import com.mongodb.client.MongoDatabase; import lombok.extern.slf4j.Slf4j; -import org.bson.Document; 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.MongoManager; 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.jws.soap.SOAPBinding; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import java.util.Map; @@ -83,8 +78,8 @@ public class UCDManager extends AbstractScopedMap implements UCDMan } - private ProfileMapCache.ProfileMap getLiveMap() throws ConfigurationException { - return ImplementationProvider.get().getEngineByManagedClass(ProfileMapCache.ProfileMap.class); + private ProfileMap getLiveMap() throws ConfigurationException { + return ImplementationProvider.get().getEngineByManagedClass(ProfileMap.class); }; diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java index 150d51e..fc5870e 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java @@ -13,8 +13,6 @@ import org.gcube.application.geoportal.service.engine.mongo.ProfiledMongoManager import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.cms.serialization.Serialization; import org.gcube.application.geoportal.service.engine.providers.ConfigurationCache; -import org.gcube.application.geoportal.service.engine.providers.UCDManager; -import org.gcube.application.geoportal.service.model.internal.faults.RegistrationException; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; diff --git a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/providers/ucd/UCDLoadingTest.java b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/providers/ucd/UCDLoadingTest.java new file mode 100644 index 0000000..95a5565 --- /dev/null +++ b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/providers/ucd/UCDLoadingTest.java @@ -0,0 +1,41 @@ +package org.gcube.application.geoportal.service.engine.providers.ucd; + +import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader; +import org.gcube.application.cms.tests.TokenSetter; +import org.gcube.application.geoportal.common.utils.tests.GCubeTest; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.xml.bind.JAXBException; +import java.util.ArrayList; +import java.util.Arrays; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assume.assumeTrue; + +public class UCDLoadingTest { + + @BeforeClass + public static void initProvider() throws JAXBException { + SingleISResourceUCDProvider.directInit(); + } + + @Test + public void testSerializaion() throws JAXBException { + SingleISResourceUCDProvider.ISBean bean = new SingleISResourceUCDProvider.ISBean(); + bean.setRecords(Arrays.asList( + new SingleISResourceUCDProvider.ISBean.Record("Human readable name","some url","[opt] regex"), + new SingleISResourceUCDProvider.ISBean.Record("Another readable name","some other url","[opt] regex"))); + String xml = SingleISResourceUCDProvider.write(bean); + System.out.println("XML is "+xml); + SingleISResourceUCDProvider.ISBean reloaded =SingleISResourceUCDProvider.read(xml); + assertEquals(bean,reloaded); + } + + @Test + public void testLoading(){ + assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + TokenSetter.set(GCubeTest.getContext()); +// SingleISResourceUCDProvider provider = + } +}