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
## [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).

View File

@ -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).

View File

@ -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);

View File

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

View File

@ -20,30 +20,24 @@ public class BindingAction {
public void doAction(ItemObserved<Project> 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:

View File

@ -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() {

View File

@ -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<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.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<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)
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();
}

View File

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