created prototype of the plugin and configured it

This commit is contained in:
Francesco Mangiacrapa 2024-01-17 17:32:34 +01:00
parent 413f6516d9
commit b5126cb189
9 changed files with 448 additions and 18 deletions

View File

@ -1,6 +1,6 @@
# Changelog for org.gcube.application.cms.catalogue-binding-plugin
## [v0.0.1-SNAPSHOT] - 2023-12-21
## [v1.0.0-SNAPSHOT] - 2023-12-21
- First release

View File

@ -1,7 +1,8 @@
gCube CMS Suite : Catalogue Binding Plugin
--------------------------------------------------
This library is expected to contain the "Catalogue Binding Plugin" for binding from the products registered in the Geoportal system to the D4Science Catalogue system.
This component is expected to contain the "Catalogue Binding Plugin" for binding from
the products registered in the Geoportal system to the D4Science Catalogue system.
## Built with
* [gCube SmartGears] (https://gcube.wiki.gcube-system.org/gcube/SmartGears) - The gCube SmartGears framework
@ -13,6 +14,31 @@ This library is expected to contain the "Catalogue Binding Plugin" for binding f
## Documentation
[gCube CMS Suite](../) parent module containing references, documentation, guides ad utilities.
This plugin requires an handler defined in the UCD so defined:
{
"_id": "Catalogue-Binding-Plugin",
"_type": "EventListener",
"_configuration": {
"subscribeEvents": [
{
"event": "{EVENT_NAME_1}"
},
{
"event": "{EVENT_NAME_2}"
}
]
}
}
The supported events are:
"PROJECT_CREATED"
"PROJECT_UPDATED"
"PROJECT_DELETED"
"LIFECYCLE_STEP_PERFORMED"
## Change log
See [CHANGELOG.md](CHANGELOG.md).

View File

@ -10,7 +10,7 @@
</parent>
<artifactId>catalogue-binding-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<name>Catalogue Binding Plugin</name>
@ -49,6 +49,12 @@
<groupId>org.gcube.application.cms</groupId>
<artifactId>cms-plugin-framework</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>
<artifactId>default-lc-managers</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.application.cms</groupId>

View File

@ -0,0 +1,242 @@
package org.gcube.application.cms.plugins.cataloguebinding;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.bson.Document;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.cms.plugins.InitializablePlugin;
import org.gcube.application.cms.plugins.events.EventListener;
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.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.MaterializationException;
import org.gcube.application.cms.plugins.implementations.AbstractPlugin;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report.Status;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.useCaseDescriptor.UseCaseDescriptor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* The Class CatalogueBindingAbstractPlugin.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Jan 17, 2024
*/
@Slf4j
public abstract class CatalogueBindingAbstractPlugin extends AbstractPlugin implements InitializablePlugin {
public static final String SUBSCRIBE_EVENTS_CONFIG = "subscribeEvents";
public static final String PLUGIN_ID = "Catalogue-Binding-Plugin";
public static final String PLUGIN_TYPE = "EventListener";
/**
* Instantiates a new materialization config.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Jan 17, 2024
*/
/**
* Instantiates a new subscribe events config.
*/
@Data
public static class SubscribeEventsConfig {
private String event;
}
protected Map<String, EventsSubscribed> catalogueBindingMap = null;
/**
* Gets the catalogue binding map per context.
*
* @return the catalogue binding map per context
*/
protected EventsSubscribed getCatalogueBindingMapPerContext() {
String context = UserUtils.getCurrent().getContext();
log.debug("Getting {} from cache map for context {}", CatalogueBindingAbstractPlugin.PLUGIN_ID, context);
if (catalogueBindingMap == null)
catalogueBindingMap = new LinkedHashMap<String, EventsSubscribed>();
return catalogueBindingMap.get(context);
}
/**
* Inits the.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
@Override
public InitializationReport init() throws InitializationException {
// Creating all listeners
EventListener<ItemObserved<Project>> listenerCreated = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerCreated fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerUpdated = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerUpdated fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerDeleted = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerDeleted fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
EventListener<ItemObserved<Project>> listenerLCStepPerformed = new EventListener<ItemObserved<Project>>() {
@Override
public void updated(ItemObserved<Project> observerd) {
log.info("listenerLCStepPerformed fired on item: {} " + observerd);
boolean subscribed = checkIfSubscribedEvent(observerd);
if (subscribed) {
doAction(observerd);
}
}
};
// Subscribing all events
EventManager eventMngInst = EventManager.getInstance();
eventMngInst.subscribe(Event.PROJECT_CREATED, listenerCreated);
eventMngInst.subscribe(Event.PROJECT_UPDATED, listenerUpdated);
eventMngInst.subscribe(Event.PROJECT_DELETED, listenerDeleted);
eventMngInst.subscribe(Event.LIFECYCLE_STEP_PERFORMED, listenerLCStepPerformed);
return new InitializationReport(Status.OK, PLUGIN_ID + " init performed");
}
/**
* Read events subscribed from configuration in the UCD.
*
* @param useCaseDescriptor the use case descriptor
* @return the events subscribed
* @throws Exception the exception
*/
public EventsSubscribed readEventsSubscribedFromConfigurationInTheUCD(UseCaseDescriptor useCaseDescriptor)
throws Exception {
log.debug("Reading subscribed events from UCD");
EventsSubscribed eventsSubscrInTheUCD = new EventsSubscribed();
if (useCaseDescriptor == null)
throw new Exception("Error reading UCD null found");
try {
String context = UserUtils.getCurrent().getContext();
eventsSubscrInTheUCD = getCatalogueBindingMapPerContext();
List<Event> listEventsSubscribedPerUCD = new ArrayList<EventManager.Event>();
if (eventsSubscrInTheUCD == null || listEventsSubscribedPerUCD.isEmpty()) {
Document profileConfiguration = getConfigurationFromProfile(useCaseDescriptor).getConfiguration();
log.debug("UseCaseDescriptor Configuration is {} ", profileConfiguration);
// JSONPathWrapper schemaNavigator = new
// JSONPathWrapper(useCaseDescriptor.getSchema().toJson());
for (Object fsConfigObj : profileConfiguration.get(SUBSCRIBE_EVENTS_CONFIG, List.class)) {
log.debug("Managing {} ", fsConfigObj);
SubscribeEventsConfig fsConfig = Serialization.convert(fsConfigObj, SubscribeEventsConfig.class);
log.debug("Converted config {}", fsConfig);
String theEventSubsribed = fsConfig.getEvent();
if (theEventSubsribed == null || theEventSubsribed.isEmpty())
throw new MaterializationException(
"Invalid Field Definition path in configuration [NO MATCH] : " + fsConfig.getEvent());
Event event = Serialization.convert(theEventSubsribed, Event.class);
log.debug("Added event {} to list ", event);
listEventsSubscribedPerUCD.add(event);
}
eventsSubscrInTheUCD = new EventsSubscribed();
eventsSubscrInTheUCD.setContext(context);
eventsSubscrInTheUCD.setListEventSubscribed(listEventsSubscribedPerUCD);
catalogueBindingMap.put(context, eventsSubscrInTheUCD);
log.info("Events subscribed read from config {} ", eventsSubscrInTheUCD);
}
} catch (Exception e) {
log.error("Unable to read configuration ", e);
} catch (Throwable t) {
log.error("Exception, Unable to read configuration ", t);
}
return eventsSubscrInTheUCD;
}
/**
* Check if subscribed event.
*
* @param observerd the observerd
* @return true, if successful
*/
public boolean checkIfSubscribedEvent(ItemObserved<Project> observerd) {
log.info("Checking if {} is an subscribed event", observerd.getEvent());
try {
EventsSubscribed eventsSub = readEventsSubscribedFromConfigurationInTheUCD(
observerd.getUseCaseDescriptor());
List<Event> listEvents = eventsSub.getListEventSubscribed();
log.info("List events is {}", listEvents);
if (listEvents.contains(observerd.getEvent())) {
log.info("the event {} is subscribed from config ", observerd.getEvent());
return true;
}
log.info("the event {} is not subscribed from config ", observerd.getEvent());
return false;
} catch (Exception e) {
log.error("Exception, Error on checking subscribed events", e);
return false;
}
}
public abstract void doAction(ItemObserved<Project> observerd);
}

View File

@ -1,38 +1,88 @@
package org.gcube.application.cms.plugins.cataloguebinding;
import org.gcube.application.cms.plugins.InitializablePlugin;
import org.gcube.application.cms.implementations.utils.UserUtils;
import org.gcube.application.cms.plugins.cataloguebinding.doaction.BindingAction;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.cms.plugins.faults.InitializationException;
import org.gcube.application.cms.plugins.faults.ShutDownException;
import org.gcube.application.cms.plugins.reports.InitializationReport;
import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor;
public class CatalogueBindingPlugin implements InitializablePlugin {
import com.vdurmont.semver4j.Semver;
static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(
CatalogueBindingPlugin.class.getSimpleName(),
"Manage the binding from geoportal to catalogue");
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
/**
* The Class CatalogueBindingPlugin.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Jan 17, 2024
*/
@Slf4j
public class CatalogueBindingPlugin extends CatalogueBindingAbstractPlugin {
public static final PluginDescriptor DESCRIPTOR = new PluginDescriptor(CatalogueBindingAbstractPlugin.PLUGIN_ID,
CatalogueBindingAbstractPlugin.PLUGIN_TYPE);
static {
DESCRIPTOR.setVersion(new Semver("1.0.0"));
DESCRIPTOR.setDescription("Manage the data binding from geoportal to catalogue");
}
/**
* Gets the descriptor.
*
* @return the descriptor
*/
@Override
public PluginDescriptor getDescriptor() {
return DESCRIPTOR;
}
/**
* Inits the in context.
*
* @return the initialization report
* @throws InitializationException the initialization exception
*/
@Override
@Synchronized
public InitializationReport initInContext() throws InitializationException {
// TODO Auto-generated method stub
return null;
}
@Override
public InitializationReport init() throws InitializationException {
// TODO Auto-generated method stub
return null;
InitializationReport report = new InitializationReport();
try {
String context = UserUtils.getCurrent().getContext();
if (getCatalogueBindingMapPerContext() == null) {
log.info("Initializing in " + context);
catalogueBindingMap.put(context, new EventsSubscribed());
}
report.setStatus(Report.Status.OK);
report.putMessage("Initialized " + DESCRIPTOR.getId() + " in the " + context);
} catch (Exception e) {
throw new InitializationException("Unable to initialize " + DESCRIPTOR.getId(), e);
}
return report;
}
/**
* Shutdown.
*
* @throws ShutDownException the shut down exception
*/
@Override
public void shutdown() throws ShutDownException {
// TODO Auto-generated method stub
}
@Override
public void doAction(ItemObserved<Project> observerd) {
new BindingAction().doAction(observerd);
}
}

View File

@ -0,0 +1,13 @@
package org.gcube.application.cms.plugins.cataloguebinding;
import java.util.List;
import org.gcube.application.cms.plugins.events.EventManager.Event;
import lombok.Data;
@Data
public class EventsSubscribed {
String context;
List<Event> listEventSubscribed;
}

View File

@ -0,0 +1,32 @@
package org.gcube.application.cms.plugins.cataloguebinding.doaction;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.geoportal.common.model.document.Project;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class BindingAction {
public void doAction(ItemObserved<Project> itemObserved) {
log.info("Do action: {}", itemObserved.getEvent());
switch (itemObserved.getEvent()) {
case PROJECT_CREATED:
break;
case PROJECT_DELETED:
break;
case PROJECT_UPDATED:
break;
case LIFECYCLE_STEP_PERFORMED:
break;
default:
break;
}
}
}

View File

@ -0,0 +1,60 @@
import org.gcube.application.cms.plugins.cataloguebinding.CatalogueBindingPlugin;
import org.gcube.application.cms.plugins.cataloguebinding.EventsSubscribed;
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.useCaseDescriptor.UseCaseDescriptor;
import org.gcube.application.geoportal.common.utils.tests.GCubeTest;
import org.junit.Test;
public class CatalogueBindingPluginTest extends BasicPluginTest {
//@Test
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();
}
System.out.println("Plugin check: " + plugin);
}
//@Test
public void checkPluginConfig() {
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();
}
}
}

View File

@ -0,0 +1 @@
/tokens.properties