This commit is contained in:
Francesco Mangiacrapa 2024-06-20 16:04:03 +02:00
parent 3d9b5ae9d1
commit 10e7eca4ca
8 changed files with 230 additions and 93 deletions

View File

@ -64,6 +64,12 @@
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.data-catalogue</groupId>
<artifactId>gcat-client</artifactId>
<version>[2.0.0,3.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>

View File

@ -4,8 +4,10 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.bson.Document;
import org.gcube.application.cms.cataloguebinding.config.CatalogueBindingPluginConfigModel;
import org.gcube.application.cms.cataloguebinding.config.SubscribeEventsConfig;
import org.gcube.application.cms.cataloguebinding.doaction.BindingAction;
import org.gcube.application.cms.cataloguebinding.util.SerializationUtil;
@ -165,7 +167,7 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
String context = UserUtils.getCurrent().getContext();
if (getCatalogueBindingMapPerContext() == null) {
log.info("Initializing in " + context);
catalogueBindingMap.put(context, new LinkedHashMap<String, EventsSubscribed>());
catalogueBindingMap.put(context, new LinkedHashMap<String, CatalogueBindingPluginConfigModel>());
}
report.setStatus(Report.Status.OK);
report.putMessage("Initialized " + DESCRIPTOR.getId() + " in the " + context);
@ -177,39 +179,39 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
return report;
}
// Map<Scope<Map<UDC_ID, EventsSubscribed>>
protected Map<String, Map<String, EventsSubscribed>> catalogueBindingMap = null;
// Map<Scope<Map<UDC_ID, CatalogueBindingPluginConfigModel>>
protected Map<String, Map<String, CatalogueBindingPluginConfigModel>> catalogueBindingMap = null;
/**
* Gets the catalogue binding map per context.
*
* @return the catalogue binding map per context
*/
protected Map<String, EventsSubscribed> getCatalogueBindingMapPerContext() {
protected Map<String, CatalogueBindingPluginConfigModel> getCatalogueBindingMapPerContext() {
String context = UserUtils.getCurrent().getContext();
log.debug("Getting {} from cache map for context {}", CatalogueBindingPlugin.PLUGIN_ID, context);
if (catalogueBindingMap == null) {
catalogueBindingMap = new LinkedHashMap<String, Map<String, EventsSubscribed>>();
catalogueBindingMap = new LinkedHashMap<String, Map<String, CatalogueBindingPluginConfigModel>>();
}
// Map<UDC_ID, EventsSubscribed>
Map<String, EventsSubscribed> map = catalogueBindingMap.get(context);
return map == null ? new LinkedHashMap<String, EventsSubscribed>() : map;
// Map<UDC_ID, EventSubscribed>
Map<String, CatalogueBindingPluginConfigModel> map = catalogueBindingMap.get(context);
return map == null ? new LinkedHashMap<String, CatalogueBindingPluginConfigModel>() : map;
}
/**
* Read events subscribed from configuration in the UCD.
*
* @param useCaseDescriptor the use case descriptor
* @return the events subscribed
* @return the catalogue binding plugin config model
* @throws Exception the exception
*/
public EventsSubscribed readEventsSubscribedFromConfigurationInTheUCD(UseCaseDescriptor useCaseDescriptor)
throws Exception {
public CatalogueBindingPluginConfigModel readEventsSubscribedFromConfigurationInTheUCD(
UseCaseDescriptor useCaseDescriptor) throws Exception {
log.debug("Reading subscribed events from UCD");
EventsSubscribed eventsSubscrInTheUCD = new EventsSubscribed();
CatalogueBindingPluginConfigModel cbpcm = null;
if (useCaseDescriptor == null)
throw new Exception("Error reading UCD null found");
@ -218,43 +220,53 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
String context = UserUtils.getCurrent().getContext();
final Map<String, EventsSubscribed> mapCatalogBindingPerContext = getCatalogueBindingMapPerContext();
final Map<String, CatalogueBindingPluginConfigModel> mapCatalogBindingPerContext = getCatalogueBindingMapPerContext();
eventsSubscrInTheUCD = mapCatalogBindingPerContext.get(useCaseDescriptor.getId());
cbpcm = mapCatalogBindingPerContext.get(useCaseDescriptor.getId());
List<Event> listEventsSubscribedPerUCD = new ArrayList<EventManager.Event>();
if (eventsSubscrInTheUCD == null || listEventsSubscribedPerUCD.isEmpty()) {
if (cbpcm == null) {
cbpcm = new CatalogueBindingPluginConfigModel();
List<EventSubscribed> eventsSubscrInTheUCD = new ArrayList<EventSubscribed>();
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 = SerializationUtil.convert(fsConfigObj, SubscribeEventsConfig.class);
SubscribeEventsConfig fsConfig = SerializationUtil.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());
EventSubscribed eventSub = new EventSubscribed();
Event event = SerializationUtil.convert(theEventSubsribed, Event.class);
log.debug("Added event {} to list ", event);
listEventsSubscribedPerUCD.add(event);
log.debug("Added event {} ", event);
eventSub.setEvent(event);
if (fsConfig.getWhen() != null)
eventSub.setWhen(fsConfig.getWhen());
eventsSubscrInTheUCD.add(eventSub);
}
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_path(freemarkerTPath);
eventsSubscrInTheUCD.setFreemarker_template_host(freemakerTHost);
cbpcm.setContext(context);
cbpcm.setFreemarker_template_host(freemakerTHost);
cbpcm.setFreemarker_template_path(freemarkerTPath);
cbpcm.setListEventSubscribed(eventsSubscrInTheUCD);
// updating the cache
mapCatalogBindingPerContext.put(useCaseDescriptor.getId(), eventsSubscrInTheUCD);
mapCatalogBindingPerContext.put(useCaseDescriptor.getId(), cbpcm);
catalogueBindingMap.put(context, mapCatalogBindingPerContext);
log.info("Events subscribed read from config {} ", eventsSubscrInTheUCD);
@ -269,7 +281,7 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
log.error("Exception, Unable to read configuration ", t);
}
return eventsSubscrInTheUCD;
return cbpcm;
}
/**
@ -281,10 +293,10 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
public boolean checkIfSubscribedEvent(ItemObserved<Project> observerd) {
log.info("Checking if {} is an subscribed event", observerd.getEvent());
try {
EventsSubscribed eventsSub = readEventsSubscribedFromConfigurationInTheUCD(
CatalogueBindingPluginConfigModel cbpcm = readEventsSubscribedFromConfigurationInTheUCD(
observerd.getUseCaseDescriptor());
List<Event> listEvents = eventsSub.getListEventSubscribed();
List<EventSubscribed> listEvents = cbpcm.getListEventSubscribed();
log.info("List events is {}", listEvents);
if (listEvents == null) {
@ -292,10 +304,11 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
return false;
}
if (listEvents.contains(observerd.getEvent())) {
if (listEvents.stream().filter(e -> e.getEvent().equals(observerd.getEvent())).count() > 0) {
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;
@ -333,12 +346,22 @@ public class CatalogueBindingPlugin extends AbstractPlugin implements EventListe
if (isSubscribedEvent) {
// Map (UCD_ID, Notification)
final Map<String, EventsSubscribed> mapCatalogBindingPerContext = getCatalogueBindingMapPerContext();
EventsSubscribed eventsSubscribed = mapCatalogBindingPerContext.get(itemObserved.getUCD_Id());
// Map (UCD_ID, CatalogueBindingPluginConfigModel)
Map<String, CatalogueBindingPluginConfigModel> mapCatalogBindingPerContext = getCatalogueBindingMapPerContext();
new BindingAction().doAction(itemObserved, eventsSubscribed);
// CatalogueBindingPluginConfigModel per UCD
CatalogueBindingPluginConfigModel cbm = mapCatalogBindingPerContext.get(itemObserved.getUCD_Id());
List<EventSubscribed> list = cbm.getListEventSubscribed().stream()
.filter(e -> e.getEvent().equals(itemObserved.getEvent())).collect(Collectors.toList());
if (list.size() > 0) {
// expected one configuration for event type
EventSubscribed eventSubscribed = list.get(0);
BindingAction ba = new BindingAction(itemObserved, eventSubscribed, cbm.getFreemarker_template_host(),
cbm.getFreemarker_template_path());
ba.doAction();
}
}
}

View File

@ -2,16 +2,13 @@ package org.gcube.application.cms.cataloguebinding;
import java.util.List;
import org.gcube.application.cms.cataloguebinding.config.BindingWhen;
import org.gcube.application.cms.plugins.events.EventManager.Event;
import lombok.Data;
@Data
public class EventsSubscribed {
String context;
List<Event> listEventSubscribed;
String freemarker_template_path;
String freemarker_template_host;
public class EventSubscribed {
Event event;
List<BindingWhen> when;
}

View File

@ -0,0 +1,19 @@
package org.gcube.application.cms.cataloguebinding.config;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
/**
* Instantiates a new notification when.
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class BindingWhen {
List<String> target_phase;
String last_invoked_step;
}

View File

@ -0,0 +1,19 @@
package org.gcube.application.cms.cataloguebinding.config;
import java.util.List;
import org.gcube.application.cms.cataloguebinding.EventSubscribed;
import lombok.Data;
@Data
public class CatalogueBindingPluginConfigModel {
String context; //the scope
List<EventSubscribed> listEventSubscribed;
String freemarker_template_path;
String freemarker_template_host;
}

View File

@ -1,5 +1,9 @@
package org.gcube.application.cms.cataloguebinding.config;
import java.util.List;
import org.gcube.com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -7,4 +11,6 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class SubscribeEventsConfig {
private String event;
@JsonProperty("when")
private List<BindingWhen> when;
}

View File

@ -2,12 +2,20 @@ package org.gcube.application.cms.cataloguebinding.doaction;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import org.gcube.application.cms.cataloguebinding.EventsSubscribed;
import org.gcube.application.cms.cataloguebinding.EventSubscribed;
import org.gcube.application.cms.cataloguebinding.config.BindingWhen;
import org.gcube.application.cms.cataloguebinding.freemarker.FreemarkerConfig;
import org.gcube.application.cms.cataloguebinding.freemarker.MappingToCatalogue;
import org.gcube.application.cms.plugins.events.ItemObserved;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.gcat.client.GCatClientDiscovery;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.spi.json.JsonOrgJsonProvider;
import freemarker.core.ParseException;
import freemarker.template.MalformedTemplateNameException;
@ -19,15 +27,105 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class BindingAction {
public void doAction(ItemObserved<Project> itemObserved, EventsSubscribed eventsSubscribed) {
private static final String TARGET_PHASE_DRAFT = "DRAFT";
private static final String TARGET_PHASE_PUBLISHED = "Published";
private ItemObserved<Project> itemObserved;
private EventSubscribed eventSubscribed;
private String templateHost;
private String templatePath;
public BindingAction(ItemObserved<Project> itemObserved, EventSubscribed eventSubscribed, String templateHost,
String templatePath) {
this.itemObserved = itemObserved;
this.eventSubscribed = eventSubscribed;
this.templateHost = templateHost;
this.templatePath = templatePath;
}
public void doAction() {
log.info("Do action called on: {}", itemObserved.getEvent());
switch (eventSubscribed.getEvent()) {
case PROJECT_CREATED:
log.info("Going to create item on the catalogue");
break;
case PROJECT_DELETED:
log.info("Going to delete item on the catalogue");
break;
case PROJECT_UPDATED:
log.info("Going to update the item on the catalogue");
break;
case LIFECYCLE_STEP_PERFORMED:
List<BindingWhen> listBindingWhen = eventSubscribed.getWhen();
if (listBindingWhen == null || listBindingWhen.size() == 0) {
log.warn("No binding found, so returning!!");
return;
}
for (BindingWhen bindingWhen : listBindingWhen) {
log.info("Checking configuration matching on: {}", bindingWhen);
if (bindingWhen.getTarget_phase() == null || bindingWhen.getTarget_phase().size() == 0) {
log.warn("No binding on target_phase, so returning!!");
continue;
}
if (bindingWhen.getLast_invoked_step() == null || bindingWhen.getLast_invoked_step().length() == 0) {
log.warn("No binding on last invoked step, so returning!!");
continue;
}
// Reading 'phase' and 'lastInvokedStep' properties from itemObserved
LifecycleInformation lInfo = itemObserved.getProject().getLifecycleInformation();
String itemPhase = lInfo.getPhase();
String lastInvokedStep = lInfo.getLastInvokedStep();
log.info("ItemObserved phase is: {}, lastInvokedStep is: {}", itemPhase, lastInvokedStep);
// If there is matching between the plugin configuration and item observed on
// phase' and 'lastInvokedStep' fields
if (bindingWhen.getTarget_phase().contains(itemPhase)
&& bindingWhen.getLast_invoked_step().equalsIgnoreCase(lastInvokedStep)) {
log.info(
"The item observerd has phase '{}' and lastInvokedStep '{}' like the plugin configuration model",
itemPhase, lastInvokedStep);
if (itemPhase.equalsIgnoreCase(TARGET_PHASE_PUBLISHED)) {
log.info("Going to create item on the catalogue");
// Create or Update the item on the catalogue
String catelogueItem = toCatalogueItem();
} else if (itemPhase.equalsIgnoreCase(TARGET_PHASE_DRAFT)) {
// Delete the item on the catalogue
String projectID = itemObserved.getProjectId();
log.info("Going to delete item with id {} on the catalogue", projectID);
}
} else {
log.info(
"Skipping the operation!! No mathing {} status with plugin configuration model [bindingWhen phase '{}', lastInvokedStep '{}']",
ItemObserved.class.getSimpleName(), itemPhase, lastInvokedStep);
}
}
break;
default:
break;
}
}
public String toCatalogueItem() {
String toCatalogueJSON = null;
try {
FreemarkerConfig fmc = new FreemarkerConfig(eventsSubscribed.getFreemarker_template_host());
Template fmTemplate = fmc.getTemplate(eventsSubscribed.getFreemarker_template_path());
String toCatalogueJSON = MappingToCatalogue.apply(fmTemplate, itemObserved.getProject(), itemObserved.getUseCaseDescriptor(), itemObserved.getContext().getId());
FreemarkerConfig fmc = new FreemarkerConfig(templateHost);
Template fmTemplate = fmc.getTemplate(templatePath);
toCatalogueJSON = MappingToCatalogue.apply(fmTemplate, itemObserved.getProject(),
itemObserved.getUseCaseDescriptor(), itemObserved.getContext().getId());
} catch (MalformedURLException e) {
log.error("Error: ", e);
} catch (TemplateException e) {
@ -42,23 +140,7 @@ public class BindingAction {
log.error("Error: ", e);
}
switch (itemObserved.getEvent()) {
case PROJECT_CREATED:
break;
case PROJECT_DELETED:
break;
case PROJECT_UPDATED:
break;
case LIFECYCLE_STEP_PERFORMED:
break;
default:
break;
}
return toCatalogueJSON;
}
}

View File

@ -1,20 +1,16 @@
package junit;
import org.bson.Document;
import org.gcube.application.cms.cataloguebinding.CatalogueBindingPlugin;
import org.gcube.application.cms.cataloguebinding.EventsSubscribed;
import org.gcube.application.cms.cataloguebinding.util.SerializationUtil;
import org.gcube.application.cms.cataloguebinding.config.CatalogueBindingPluginConfigModel;
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;
@ -69,10 +65,10 @@ public class CatalogueBindingPluginTest extends BasicPluginTest {
e1.printStackTrace();
}
EventsSubscribed events;
try {
events = plugin.readEventsSubscribedFromConfigurationInTheUCD(descriptor);
System.out.println("Events: " + events);
CatalogueBindingPluginConfigModel pluginBindingModel = plugin
.readEventsSubscribedFromConfigurationInTheUCD(descriptor);
System.out.println("CatalogueBindingPluginConfigModel: " + pluginBindingModel);
} catch (Exception e) {
e.printStackTrace();
}
@ -82,34 +78,23 @@ public class CatalogueBindingPluginTest extends BasicPluginTest {
/**
* Check notifications SUBMIT_FOR_REVIEW to USERS
*/
@Test
//@Test
public void checkNotify() {
org.junit.Assume.assumeTrue(GCubeTest.isTestInfrastructureEnabled());
CatalogueBindingPlugin plugin = (CatalogueBindingPlugin) plugins.get(CatalogueBindingPlugin.DESCRIPTOR.getId());
UseCaseDescriptor descriptor = TestProfiles.profiles.get(profileID);
CatalogueBindingPluginConfigModel pluginBindingModel;
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);
pluginBindingModel = plugin.readEventsSubscribedFromConfigurationInTheUCD(descriptor);
System.out.println("Events: " + pluginBindingModel);
} catch (Exception e) {
e.printStackTrace();
}
ItemObserved<Project> item;
try {
EventManager.Event event = Event.PROJECT_CREATED;
EventManager.Event event = Event.LIFECYCLE_STEP_PERFORMED;
item = mockItemObserverd(event);
// Setting creator
@ -120,8 +105,8 @@ public class CatalogueBindingPluginTest extends BasicPluginTest {
LifecycleInformation lifecycleInfo = item.getProject().getLifecycleInformation();
// Test Stage (Pending Approval, "SUBMIT-FOR-REVIEW")
lifecycleInfo.setPhase("Pending Approval");
lifecycleInfo.setLastInvokedStep("SUBMIT-FOR-REVIEW");
lifecycleInfo.setPhase("Published");
lifecycleInfo.setLastInvokedStep("APPROVE-SUBMITTED");
System.out.println("By notifying event " + event + " project " + item.getProjectId());
EventManager.getInstance().notify(event, item);