implementing the plugin

This commit is contained in:
Francesco Mangiacrapa 2024-06-19 15:57:12 +02:00
parent 8ef0a31e31
commit ab34cc3a0c
9 changed files with 225 additions and 74 deletions

View File

@ -1,8 +1,8 @@
# Changelog for org.gcube.application.cms.catalogue-binding-plugin # 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). - This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

View File

@ -7,16 +7,18 @@ The "Catalogue Binding Plugin" implements the binding from
## Built with ## Built with
* [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework * [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework
* [OpenJDK](https://openjdk.java.net/) - The JDK used * [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 * [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 ## Documentation
[gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities. [gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities.
The "Catalogue Binding Plugin" requires a handler registered in the UCD so defined: The "Catalogue Binding Plugin" requires a handler registered in the UCD so defined:
{ ```
{
"_id": "Catalogue-Binding-Plugin", "_id": "Catalogue-Binding-Plugin",
"_type": "EventListener", "_type": "EventListener",
"_configuration": { "_configuration": {
@ -27,17 +29,24 @@ The "Catalogue Binding Plugin" requires a handler registered in the UCD so defin
{ {
"event": "{EVENT_NAME_2}" "event": "{EVENT_NAME_2}"
} }
] ],
} "freemarker_template_host": {FREEMARKER_TEMPLATE_HOST}
"freemarker_template_path": {PATH_TO_FREEMARKER_TEMPLATE_NAME.ftl},
} }
}
```
where the supported events are: where the supported events are:
```
"PROJECT_CREATED" "PROJECT_CREATED"
"PROJECT_UPDATED" "PROJECT_UPDATED"
"PROJECT_DELETED" "PROJECT_DELETED"
"LIFECYCLE_STEP_PERFORMED" "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 ## Change log
See [CHANGELOG.md](CHANGELOG.md). See [CHANGELOG.md](CHANGELOG.md).

View File

@ -47,8 +47,8 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
public static final String PLUGIN_TYPE = "EventListener"; public static final String PLUGIN_TYPE = "EventListener";
public static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(PLUGIN_ID, PLUGIN_TYPE); 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_PATH = "freemarker_template_path";
private static final String FREEMARKER_TEMPLATE_FOLDER = "link_to_freemarker_template_folder"; private static final String FREEMARKER_TEMPLATE_HOST = "freemarker_template_host";
static { static {
DESCRIPTOR.setVersion(new Semver("1.0.0")); DESCRIPTOR.setVersion(new Semver("1.0.0"));
@ -244,15 +244,14 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
listEventsSubscribedPerUCD.add(event); listEventsSubscribedPerUCD.add(event);
} }
String freemarker_template = profileConfiguration.get(FREEMARKER_TEMPLATE_NAME, String.class); String freemarkerTPath = profileConfiguration.get(FREEMARKER_TEMPLATE_PATH, String.class);
String link_to_freemarker_template_folder = profileConfiguration.get(FREEMARKER_TEMPLATE_FOLDER, String freemakerTHost = profileConfiguration.get(FREEMARKER_TEMPLATE_HOST, String.class);
String.class);
eventsSubscrInTheUCD = new EventsSubscribed(); eventsSubscrInTheUCD = new EventsSubscribed();
eventsSubscrInTheUCD.setContext(context); eventsSubscrInTheUCD.setContext(context);
eventsSubscrInTheUCD.setListEventSubscribed(listEventsSubscribedPerUCD); eventsSubscrInTheUCD.setListEventSubscribed(listEventsSubscribedPerUCD);
eventsSubscrInTheUCD.setFreemarker_template(freemarker_template); eventsSubscrInTheUCD.setFreemarker_template_path(freemarkerTPath);
eventsSubscrInTheUCD.setLink_to_freemarker_template_folder(link_to_freemarker_template_folder); eventsSubscrInTheUCD.setFreemarker_template_host(freemakerTHost);
// updating the cache // updating the cache
mapCatalogBindingPerContext.put(useCaseDescriptor.getId(), eventsSubscrInTheUCD); mapCatalogBindingPerContext.put(useCaseDescriptor.getId(), eventsSubscrInTheUCD);

View File

@ -11,7 +11,7 @@ public class EventsSubscribed {
String context; String context;
List<Event> listEventSubscribed; List<Event> listEventSubscribed;
String freemarker_template; String freemarker_template_path;
String link_to_freemarker_template_folder; String freemarker_template_host;
} }

View File

@ -22,26 +22,20 @@ public class BindingAction {
log.info("Do action called on: {}", itemObserved.getEvent()); log.info("Do action called on: {}", itemObserved.getEvent());
try { try {
FreemarkerConfig fmc = new FreemarkerConfig(eventsSubscribed.getLink_to_freemarker_template_folder()); FreemarkerConfig fmc = new FreemarkerConfig(eventsSubscribed.getFreemarker_template_host());
Template fmTemplate = fmc.getTemplate(eventsSubscribed.getFreemarker_template()); Template fmTemplate = fmc.getTemplate(eventsSubscribed.getFreemarker_template_path());
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
// TODO Auto-generated catch block log.error("Error: ", e);
e.printStackTrace();
} catch (TemplateException e) { } catch (TemplateException e) {
// TODO Auto-generated catch block log.error("Error: ", e);
e.printStackTrace();
} catch (TemplateNotFoundException e) { } catch (TemplateNotFoundException e) {
// TODO Auto-generated catch block log.error("Error: ", e);
e.printStackTrace();
} catch (MalformedTemplateNameException e) { } catch (MalformedTemplateNameException e) {
// TODO Auto-generated catch block log.error("Error: ", e);
e.printStackTrace();
} catch (ParseException e) { } catch (ParseException e) {
// TODO Auto-generated catch block log.error("Error: ", e);
e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block log.error("Error: ", e);
e.printStackTrace();
} }
switch (itemObserved.getEvent()) { switch (itemObserved.getEvent()) {

View File

@ -37,7 +37,7 @@ public class FreemarkerConfig {
} }
public Template getTemplate(String templateName) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException { public Template getTemplate(String templateName) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
return cfg.getTemplate(rtl.getURL(templateName).toString()); return cfg.getTemplate(templateName);
} }
public String getUrlPathToTemplate() { public String getUrlPathToTemplate() {

View File

@ -1,9 +1,20 @@
import org.bson.Document;
import org.gcube.application.cms.cataloguebinding.CatalogueBindingPlugin; import org.gcube.application.cms.cataloguebinding.CatalogueBindingPlugin;
import org.gcube.application.cms.cataloguebinding.EventsSubscribed; 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.plugins.faults.InitializationException;
import org.gcube.application.cms.tests.TestProfiles; import org.gcube.application.cms.tests.TestProfiles;
import org.gcube.application.cms.tests.plugins.BasicPluginTest; 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.model.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest; import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Test; import org.junit.Test;
@ -14,23 +25,23 @@ public class CatalogueBindingPluginTest extends BasicPluginTest {
public void checkPlugin() { public void checkPlugin() {
org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled()); org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled());
CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId()); CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId());
//
try { // try {
plugin.init(); // plugin.init();
} catch (InitializationException e1) { // } catch (InitializationException e1) {
e1.printStackTrace(); // e1.printStackTrace();
} // }
try { // try {
plugin.initInContext(); // plugin.initInContext();
} catch (InitializationException e1) { // } catch (InitializationException e1) {
e1.printStackTrace(); // e1.printStackTrace();
} // }
System.out.println("Plugin check: " + plugin); System.out.println("Plugin check: " + plugin);
} }
@Test //@Test
public void checkPluginConfig() { public void checkPluginConfig() {
org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled()); org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled());
CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId()); CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId());
@ -57,4 +68,102 @@ 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<Project> 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<Project> mockItemObserverd() {
UseCaseDescriptor descriptor = TestProfiles.profiles.get("profiledConcessioni");
// notifying the Event.PROJECT_CREATED;
ItemObserved<Project> item = new ItemObserved<Project>();
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;
}
} }

View File

@ -5,11 +5,13 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.bson.Document; import org.bson.Document;
import org.gcube.application.geoportal.client.utils.Serialization; import org.gcube.application.geoportal.client.utils.Serialization;
import org.gcube.application.geoportal.common.model.document.Project; 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.GeoportalClientCaller;
import org.gcube.application.geoportalcommon.geoportal.ProjectsCaller; import org.gcube.application.geoportalcommon.geoportal.ProjectsCaller;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
@ -18,6 +20,7 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -52,9 +55,13 @@ public class GeoportalToCatalogue {
Project theProject = clientProjects.getProjectByID(profileID, projectID); Project theProject = clientProjects.getProjectByID(profileID, projectID);
Document asDocument = Serialization.asDocument(theProject); Document asDocument = Serialization.asDocument(theProject);
UseCaseDescriptor ucd = GeoportalClientCaller.useCaseDescriptors().getUCDForId(profileID);
System.out.println("Source JSON:"); System.out.println("Source JSON:");
System.out.println(prettyPrintUsingGson(asDocument.toJson())); System.out.println(prettyPrintUsingGson(asDocument.toJson()));
applyMappingToCatalogue(asDocument.toJson()); applyMappingToCatalogue(theProject, ucd);
} catch (Exception e) { } catch (Exception e) {
// TODO: handle exception // TODO: handle exception
@ -62,6 +69,37 @@ public class GeoportalToCatalogue {
} }
public void publishProjectsOnCatalogue(int limit) {
List<Project> 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<Project> 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<String, Object> fmtJsonUtil(String json) public static Map<String, Object> fmtJsonUtil(String json)
throws JsonParseException, JsonMappingException, IOException { throws JsonParseException, JsonMappingException, IOException {
ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 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 // 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% // version (here 2.3.32) do you want to apply the fixes that are not 100%
@ -86,6 +129,7 @@ public class GeoportalToCatalogue {
cfg.setDirectoryForTemplateLoading( cfg.setDirectoryForTemplateLoading(
new File(System.getProperty("user.dir") + "/src/test/java/geoportal_to_catalogue")); new File(System.getProperty("user.dir") + "/src/test/java/geoportal_to_catalogue"));
// From here we will set the settings recommended for new projects. These // From here we will set the settings recommended for new projects. These
// aren't the defaults for backward compatibilty. // aren't the defaults for backward compatibilty.
@ -112,30 +156,30 @@ public class GeoportalToCatalogue {
com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder() com.jayway.jsonpath.Configuration configuration = com.jayway.jsonpath.Configuration.builder()
.jsonProvider(new JsonOrgJsonProvider()).build(); .jsonProvider(new JsonOrgJsonProvider()).build();
//GIS LINK // GIS LINK
JSONObject theGisLinkObj = JSONObjectOrdered.instance();
JSONObject theRootDocument = JSONObjectOrdered.instance(); theGisLinkObj.put("key", "Gis Link");
theRootDocument.put("key", "Gis Link"); theGisLinkObj.put("value", "https://data.dev.d4science.org/test/my_gis_link");
theRootDocument.put("value", "https://data.dev.d4science.org/test/my_gis_link");
System.out.println("gis link: " + theRootDocument);
DocumentContext theDoc = JsonPath.parse(toCatalogueJSON, configuration); 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("\n\nTo pretty print JSON:");
// System.out.println("gis link: "+theDoc.jsonString()); // System.out.println("gis link: "+theDoc.jsonString());
System.out.println(prettyPrintUsingGson(theDoc.jsonString())); System.out.println(prettyPrintUsingGson(theDoc.jsonString()));
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} catch (TemplateException e) { } catch (TemplateException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} } catch (JSONException e) {
catch (JSONException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -273,13 +273,9 @@ Starting document mapping to Catalogue
</#if> </#if>
</#if> </#if>
<#-- Adding extra field "Anno" to add it as group --> <#-- Adding extra field "Anno" to add it as group -->
<@assignExtraField key="Anno" value=dataInizioYear asObject=false></@assignExtraField> <@assignExtraField key="Anno" value=dataInizioYear asObject=false></@assignExtraField>
<#-- system:type -->
<@assignExtraField key="system:type" value="D4GNA" asObject=true></@assignExtraField>
<@buildExtrasFields the_extras=extras></@buildExtrasFields> <@buildExtrasFields the_extras=extras></@buildExtrasFields>
} }