diff --git a/catalogue-binding-plugin/CHANGELOG.md b/catalogue-binding-plugin/CHANGELOG.md index 4bddbd4..108b113 100644 --- a/catalogue-binding-plugin/CHANGELOG.md +++ b/catalogue-binding-plugin/CHANGELOG.md @@ -1,8 +1,8 @@ # Changelog for org.gcube.application.cms.catalogue-binding-plugin -## [v1.0.0-SNAPSHOT] - 2023-12-21 +## [v1.0.0-SNAPSHOT] - 2024-06-19 -- First release +- First release, implemented the plugin [#26454] - This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/catalogue-binding-plugin/README.md b/catalogue-binding-plugin/README.md index 8286c70..47da4ee 100644 --- a/catalogue-binding-plugin/README.md +++ b/catalogue-binding-plugin/README.md @@ -7,37 +7,46 @@ The "Catalogue Binding Plugin" implements the binding from ## Built with * [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework * [OpenJDK](https://openjdk.java.net/) - The JDK used -* [JAX-RS](https://github.com/eclipse-ee4j/jaxrs-api) - Java™ API for RESTful Web Services -* [Jersey](https://jersey.github.io/) - JAX-RS runtime * [Maven](https://maven.apache.org/) - Dependency Management +**Uses** +* Apache [FreeMarker](https://freemarker.apache.org/) is licensed under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) + ## Documentation [gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities. The "Catalogue Binding Plugin" requires a handler registered in the UCD so defined: - { - "_id": "Catalogue-Binding-Plugin", - "_type": "EventListener", - "_configuration": { - "subscribeEvents": [ - { - "event": "{EVENT_NAME_1}" - }, - { - "event": "{EVENT_NAME_2}" - } - ] +``` +{ + "_id": "Catalogue-Binding-Plugin", + "_type": "EventListener", + "_configuration": { + "subscribeEvents": [ + { + "event": "{EVENT_NAME_1}" + }, + { + "event": "{EVENT_NAME_2}" } - } + ], + "freemarker_template_host": {FREEMARKER_TEMPLATE_HOST} + "freemarker_template_path": {PATH_TO_FREEMARKER_TEMPLATE_NAME.ftl}, + } +} +``` where the supported events are: +``` "PROJECT_CREATED" "PROJECT_UPDATED" "PROJECT_DELETED" "LIFECYCLE_STEP_PERFORMED" - +``` + +and `{FREEMARKER_TEMPLATE_HOST}` is the host where the FREEMARKER_TEMPLATE.ftl is located and the `{FREEMARKER_TEMPLATE_NAME.ftl}` is the (complete) path to the FREEMARKER_TEMPLATE.ftl file. +The template pointed by `{FREEMARKER_TEMPLATE_HOST}/{PATH_TO_FREEMARKER_TEMPLATE_NAME.ftl}` is applied to transform a Geoportal project to Catalogue Item object. ## Change log See [CHANGELOG.md](CHANGELOG.md). diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/CatalogueBindingPlugin.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/CatalogueBindingPlugin.java index c7455df..d49cb44 100644 --- a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/CatalogueBindingPlugin.java +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/CatalogueBindingPlugin.java @@ -47,8 +47,8 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe public static final String PLUGIN_TYPE = "EventListener"; public static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(PLUGIN_ID, PLUGIN_TYPE); - private static final String FREEMARKER_TEMPLATE_NAME = "freemarker_template"; - private static final String FREEMARKER_TEMPLATE_FOLDER = "link_to_freemarker_template_folder"; + private static final String FREEMARKER_TEMPLATE_PATH = "freemarker_template_path"; + private static final String FREEMARKER_TEMPLATE_HOST = "freemarker_template_host"; static { DESCRIPTOR.setVersion(new Semver("1.0.0")); @@ -244,15 +244,14 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe listEventsSubscribedPerUCD.add(event); } - String freemarker_template = profileConfiguration.get(FREEMARKER_TEMPLATE_NAME, String.class); - String link_to_freemarker_template_folder = profileConfiguration.get(FREEMARKER_TEMPLATE_FOLDER, - String.class); + String freemarkerTPath = profileConfiguration.get(FREEMARKER_TEMPLATE_PATH, String.class); + String freemakerTHost = profileConfiguration.get(FREEMARKER_TEMPLATE_HOST, String.class); eventsSubscrInTheUCD = new EventsSubscribed(); eventsSubscrInTheUCD.setContext(context); eventsSubscrInTheUCD.setListEventSubscribed(listEventsSubscribedPerUCD); - eventsSubscrInTheUCD.setFreemarker_template(freemarker_template); - eventsSubscrInTheUCD.setLink_to_freemarker_template_folder(link_to_freemarker_template_folder); + eventsSubscrInTheUCD.setFreemarker_template_path(freemarkerTPath); + eventsSubscrInTheUCD.setFreemarker_template_host(freemakerTHost); // updating the cache mapCatalogBindingPerContext.put(useCaseDescriptor.getId(), eventsSubscrInTheUCD); diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventsSubscribed.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventsSubscribed.java index 897e9e3..21fc4a2 100644 --- a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventsSubscribed.java +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventsSubscribed.java @@ -11,7 +11,7 @@ public class EventsSubscribed { String context; List listEventSubscribed; - String freemarker_template; - String link_to_freemarker_template_folder; + String freemarker_template_path; + String freemarker_template_host; } diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/doaction/BindingAction.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/doaction/BindingAction.java index 653cee3..90af44a 100644 --- a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/doaction/BindingAction.java +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/doaction/BindingAction.java @@ -20,30 +20,24 @@ public class BindingAction { public void doAction(ItemObserved itemObserved, EventsSubscribed eventsSubscribed) { log.info("Do action called on: {}", itemObserved.getEvent()); - + try { - FreemarkerConfig fmc = new FreemarkerConfig(eventsSubscribed.getLink_to_freemarker_template_folder()); - Template fmTemplate = fmc.getTemplate(eventsSubscribed.getFreemarker_template()); + FreemarkerConfig fmc = new FreemarkerConfig(eventsSubscribed.getFreemarker_template_host()); + Template fmTemplate = fmc.getTemplate(eventsSubscribed.getFreemarker_template_path()); } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("Error: ", e); } catch (TemplateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("Error: ", e); } catch (TemplateNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("Error: ", e); } catch (MalformedTemplateNameException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("Error: ", e); } catch (ParseException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("Error: ", e); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + log.error("Error: ", e); } - + switch (itemObserved.getEvent()) { case PROJECT_CREATED: diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/freemarker/FreemarkerConfig.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/freemarker/FreemarkerConfig.java index a4aeccb..42e2fb1 100644 --- a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/freemarker/FreemarkerConfig.java +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/freemarker/FreemarkerConfig.java @@ -37,7 +37,7 @@ public class FreemarkerConfig { } public Template getTemplate(String templateName) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { - return cfg.getTemplate(rtl.getURL(templateName).toString()); + return cfg.getTemplate(templateName); } public String getUrlPathToTemplate() { diff --git a/catalogue-binding-plugin/src/test/java/CatalogueBindingPluginTest.java b/catalogue-binding-plugin/src/test/java/CatalogueBindingPluginTest.java index e4c54c7..bed1e67 100644 --- a/catalogue-binding-plugin/src/test/java/CatalogueBindingPluginTest.java +++ b/catalogue-binding-plugin/src/test/java/CatalogueBindingPluginTest.java @@ -1,9 +1,20 @@ +import org.bson.Document; import org.gcube.application.cms.cataloguebinding.CatalogueBindingPlugin; import org.gcube.application.cms.cataloguebinding.EventsSubscribed; +import org.gcube.application.cms.implementations.utils.UserUtils; +import org.gcube.application.cms.plugins.events.EventManager; +import org.gcube.application.cms.plugins.events.EventManager.Event; +import org.gcube.application.cms.plugins.events.ItemObserved; +import org.gcube.application.cms.plugins.events.ItemObserved.OPTIONAL_FIELD; import org.gcube.application.cms.plugins.faults.InitializationException; import org.gcube.application.cms.tests.TestProfiles; import org.gcube.application.cms.tests.plugins.BasicPluginTest; +import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.document.accounting.AccountingInfo; +import org.gcube.application.geoportal.common.model.document.accounting.PublicationInfo; +import org.gcube.application.geoportal.common.model.document.accounting.User; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportal.common.utils.tests.GCubeTest; import org.junit.Test; @@ -14,23 +25,23 @@ public class CatalogueBindingPluginTest extends BasicPluginTest { public void checkPlugin() { org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled()); CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId()); - - try { - plugin.init(); - } catch (InitializationException e1) { - e1.printStackTrace(); - } - try { - plugin.initInContext(); - } catch (InitializationException e1) { - e1.printStackTrace(); - } +// +// try { +// plugin.init(); +// } catch (InitializationException e1) { +// e1.printStackTrace(); +// } +// try { +// plugin.initInContext(); +// } catch (InitializationException e1) { +// e1.printStackTrace(); +// } System.out.println("Plugin check: " + plugin); } - @Test + //@Test public void checkPluginConfig() { org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled()); CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId()); @@ -56,5 +67,103 @@ public class CatalogueBindingPluginTest extends BasicPluginTest { } } + + /** + * Check notifications SUBMIT_FOR_REVIEW to USERS + */ + @Test + public void checkNotify() { + org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled()); + CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId()); + UseCaseDescriptor descriptor = TestProfiles.profiles.get("profiledConcessioni"); + + try { + plugin.init(); + } catch (InitializationException e1) { + e1.printStackTrace(); + } + try { + plugin.initInContext(); + } catch (InitializationException e1) { + e1.printStackTrace(); + } + + EventsSubscribed events; + try { + events = plugin.readEventsSubscribedFromConfigurationInTheUCD(descriptor); + System.out.println("Events: " + events); + } catch (Exception e) { + e.printStackTrace(); + } + + ItemObserved item = mockItemObserverd(); + + //Setting creator + User creator = new User(); + creator.setUsername("francesco.mangiacrapa"); + item.getProject().getInfo().getCreationInfo().setUser(creator); + + EventManager.Event event = Event.PROJECT_CREATED; + item.setEvent(event); + + LifecycleInformation lifecycleInfo = item.getProject().getLifecycleInformation(); + + //Test Stage (Pending Approval, "SUBMIT-FOR-REVIEW") + lifecycleInfo.setPhase("Pending Approval"); + lifecycleInfo.setLastInvokedStep("SUBMIT-FOR-REVIEW"); + + System.out.println("By notifying event " + event + " project " + item.getProjectId()); + EventManager.getInstance().notify(event, item); + } + + /** + * Mock item observerd. + * + * @return the item observed + */ + private static ItemObserved mockItemObserverd() { + + UseCaseDescriptor descriptor = TestProfiles.profiles.get("profiledConcessioni"); + + // notifying the Event.PROJECT_CREATED; + ItemObserved item = new ItemObserved(); + EventManager.Event event = Event.LIFECYCLE_STEP_PERFORMED; + AccountingInfo user = UserUtils.getCurrent().asInfo(); +// System.out.println(user.getUser()); +// sysOut(user); + System.out.println("User is: " + user.getUser()); + System.out.println("Context is: " + user.getContext()); + item.setUserCaller(user.getUser()); + item.setContext(user.getContext()); + item.setEvent(event); + item.setUseCaseDescriptor(descriptor); + + // MOCK PROJECT + Project testProject = new Project(); + testProject.setId("655489965bdd5478cca320ea"); + testProject.setProfileID(descriptor.getId()); + PublicationInfo info = new PublicationInfo(descriptor.getCreationInfo(), null, null); + testProject.setInfo(info); + + Document theDocument = new Document(); + theDocument.append("name", "My Great Project"); + testProject.setTheDocument(theDocument); + + LifecycleInformation lifecycleInfo = new LifecycleInformation(); + //Pending Approval, "SUBMIT-FOR-REVIEW" +// lifecycleInfo.setPhase("Pending Approval"); +// lifecycleInfo.setLastInvokedStep("SUBMIT-FOR-REVIEW"); + + lifecycleInfo.setPhase("DRAFT"); + lifecycleInfo.setLastInvokedStep("REJECT-DRAFT"); + + testProject.setLifecycleInformation(lifecycleInfo); + item.setProject(testProject); + + + item.setOptional(OPTIONAL_FIELD.message, "Il mio grande progetto"); + + return item; + } } diff --git a/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/GeoportalToCatalogue.java b/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/GeoportalToCatalogue.java index c8c6922..a2e08ab 100644 --- a/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/GeoportalToCatalogue.java +++ b/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/GeoportalToCatalogue.java @@ -5,11 +5,13 @@ import java.io.FileWriter; import java.io.IOException; import java.io.StringWriter; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.bson.Document; import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.common.model.document.Project; +import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor; import org.gcube.application.geoportalcommon.geoportal.GeoportalClientCaller; import org.gcube.application.geoportalcommon.geoportal.ProjectsCaller; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; @@ -18,6 +20,7 @@ import org.json.JSONException; import org.json.JSONObject; import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -52,9 +55,13 @@ public class GeoportalToCatalogue { Project theProject = clientProjects.getProjectByID(profileID, projectID); Document asDocument = Serialization.asDocument(theProject); + + UseCaseDescriptor ucd = GeoportalClientCaller.useCaseDescriptors().getUCDForId(profileID); + + System.out.println("Source JSON:"); System.out.println(prettyPrintUsingGson(asDocument.toJson())); - applyMappingToCatalogue(asDocument.toJson()); + applyMappingToCatalogue(theProject, ucd); } catch (Exception e) { // TODO: handle exception @@ -62,6 +69,37 @@ public class GeoportalToCatalogue { } + public void publishProjectsOnCatalogue(int limit) { + + + List list; + try { + list = getListProejcts(); + UseCaseDescriptor ucd = GeoportalClientCaller.useCaseDescriptors().getUCDForId(profileID); + + limit = limit < list.size() ? limit : list.size(); + + for (int i = 0; i < limit; i++) { + Project theProject = list.get(i); + applyMappingToCatalogue(theProject, ucd); + } + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public List getListProejcts() throws Exception { + TestContextConfig.readContextSettings(); + + ScopeProvider.instance.set(TestContextConfig.CONTEXT); + SecurityTokenProvider.instance.set(TestContextConfig.TOKEN); + + ProjectsCaller clientProjects = GeoportalClientCaller.projects(); + return clientProjects.getListForProfileID(profileID); + } + public static Map fmtJsonUtil(String json) throws JsonParseException, JsonMappingException, IOException { ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -70,7 +108,12 @@ public class GeoportalToCatalogue { } - public static void applyMappingToCatalogue(String json) { + public static void applyMappingToCatalogue(Project theProject, UseCaseDescriptor ucd) throws JsonProcessingException { + + + Document asDocument = Serialization.asDocument(theProject); + + String json = asDocument.toJson(); // Create your Configuration instance, and specify if up to what FreeMarker // version (here 2.3.32) do you want to apply the fixes that are not 100% @@ -85,6 +128,7 @@ public class GeoportalToCatalogue { // plain directory for it, but non-file-system sources are possible too: cfg.setDirectoryForTemplateLoading( new File(System.getProperty("user.dir") + "/src/test/java/geoportal_to_catalogue")); + // From here we will set the settings recommended for new projects. These // aren't the defaults for backward compatibilty. @@ -112,30 +156,30 @@ public class GeoportalToCatalogue { com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() .jsonProvider(new JsonOrgJsonProvider()).build(); - //GIS LINK - - JSONObject theRootDocument = JSONObjectOrdered.instance(); - theRootDocument.put("key", "Gis Link"); - theRootDocument.put("value", "https://data.dev.d4science.org/test/my_gis_link"); - - System.out.println("gis link: " + theRootDocument); - + // GIS LINK + JSONObject theGisLinkObj = JSONObjectOrdered.instance(); + theGisLinkObj.put("key", "Gis Link"); + theGisLinkObj.put("value", "https://data.dev.d4science.org/test/my_gis_link"); DocumentContext theDoc = JsonPath.parse(toCatalogueJSON, configuration); - theDoc.add("$.extras", theRootDocument); + theDoc.add("$.extras", theGisLinkObj); + + // system:type + JSONObject theSystemType = JSONObjectOrdered.instance(); + theSystemType.put("key", "system:type"); + theSystemType.put("value", ucd.getName()); + theDoc.add("$.extras", theSystemType); System.out.println("\n\nTo pretty print JSON:"); // System.out.println("gis link: "+theDoc.jsonString()); System.out.println(prettyPrintUsingGson(theDoc.jsonString())); - } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (TemplateException e) { // TODO Auto-generated catch block e.printStackTrace(); - } - catch (JSONException e) { + } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } diff --git a/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/d4gna_to_catalogue_template.ftl b/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/d4gna_to_catalogue_template.ftl index 46e63cd..c413b33 100644 --- a/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/d4gna_to_catalogue_template.ftl +++ b/catalogue-binding-plugin/src/test/java/geoportal_to_catalogue/d4gna_to_catalogue_template.ftl @@ -273,13 +273,9 @@ Starting document mapping to Catalogue - <#-- Adding extra field "Anno" to add it as group --> <@assignExtraField key="Anno" value=dataInizioYear asObject=false> - -<#-- system:type --> -<@assignExtraField key="system:type" value="D4GNA" asObject=true> <@buildExtrasFields the_extras=extras> }