diff --git a/catalogue-binding-plugin/pom.xml b/catalogue-binding-plugin/pom.xml index c4b2a2d..0f9ba61 100644 --- a/catalogue-binding-plugin/pom.xml +++ b/catalogue-binding-plugin/pom.xml @@ -64,6 +64,12 @@ [1.0.0,2.0.0-SNAPSHOT) + + org.gcube.data-catalogue + gcat-client + [2.0.0,3.0.0-SNAPSHOT) + + org.freemarker freemarker 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 aac23ea..8d6694c 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 @@ -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()); + catalogueBindingMap.put(context, new LinkedHashMap()); } 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> - protected Map> catalogueBindingMap = null; + // Map> + protected Map> catalogueBindingMap = null; /** * Gets the catalogue binding map per context. * * @return the catalogue binding map per context */ - protected Map getCatalogueBindingMapPerContext() { + protected Map getCatalogueBindingMapPerContext() { String context = UserUtils.getCurrent().getContext(); log.debug("Getting {} from cache map for context {}", CatalogueBindingPlugin.PLUGIN_ID, context); if (catalogueBindingMap == null) { - catalogueBindingMap = new LinkedHashMap>(); + catalogueBindingMap = new LinkedHashMap>(); } - // Map - Map map = catalogueBindingMap.get(context); - return map == null ? new LinkedHashMap() : map; + // Map + Map map = catalogueBindingMap.get(context); + return map == null ? new LinkedHashMap() : 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 mapCatalogBindingPerContext = getCatalogueBindingMapPerContext(); + final Map mapCatalogBindingPerContext = getCatalogueBindingMapPerContext(); - eventsSubscrInTheUCD = mapCatalogBindingPerContext.get(useCaseDescriptor.getId()); + cbpcm = mapCatalogBindingPerContext.get(useCaseDescriptor.getId()); - List listEventsSubscribedPerUCD = new ArrayList(); - if (eventsSubscrInTheUCD == null || listEventsSubscribedPerUCD.isEmpty()) { + if (cbpcm == null) { + + cbpcm = new CatalogueBindingPluginConfigModel(); + + List eventsSubscrInTheUCD = new ArrayList(); 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 observerd) { log.info("Checking if {} is an subscribed event", observerd.getEvent()); try { - EventsSubscribed eventsSub = readEventsSubscribedFromConfigurationInTheUCD( + CatalogueBindingPluginConfigModel cbpcm = readEventsSubscribedFromConfigurationInTheUCD( observerd.getUseCaseDescriptor()); - List listEvents = eventsSub.getListEventSubscribed(); + List 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 mapCatalogBindingPerContext = getCatalogueBindingMapPerContext(); - - EventsSubscribed eventsSubscribed = mapCatalogBindingPerContext.get(itemObserved.getUCD_Id()); + // Map (UCD_ID, CatalogueBindingPluginConfigModel) + Map mapCatalogBindingPerContext = getCatalogueBindingMapPerContext(); - new BindingAction().doAction(itemObserved, eventsSubscribed); + // CatalogueBindingPluginConfigModel per UCD + CatalogueBindingPluginConfigModel cbm = mapCatalogBindingPerContext.get(itemObserved.getUCD_Id()); + + List 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(); + } } } diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventSubscribed.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventSubscribed.java index 21fc4a2..dbae3ac 100644 --- a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventSubscribed.java +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/EventSubscribed.java @@ -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 listEventSubscribed; - - String freemarker_template_path; - String freemarker_template_host; - +public class EventSubscribed { + Event event; + List when; } diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/BindingWhen.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/BindingWhen.java new file mode 100644 index 0000000..769da56 --- /dev/null +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/BindingWhen.java @@ -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 target_phase; + String last_invoked_step; + +} diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/CatalogueBindingPluginConfigModel.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/CatalogueBindingPluginConfigModel.java new file mode 100644 index 0000000..96f369d --- /dev/null +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/CatalogueBindingPluginConfigModel.java @@ -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 listEventSubscribed; + + String freemarker_template_path; + String freemarker_template_host; + +} diff --git a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/SubscribeEventsConfig.java b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/SubscribeEventsConfig.java index bfc0041..b6e80a4 100644 --- a/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/SubscribeEventsConfig.java +++ b/catalogue-binding-plugin/src/main/java/org/gcube/application/cms/cataloguebinding/config/SubscribeEventsConfig.java @@ -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 when; } 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 dbfd4ed..dc838f4 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 @@ -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 itemObserved, EventsSubscribed eventsSubscribed) { + private static final String TARGET_PHASE_DRAFT = "DRAFT"; + private static final String TARGET_PHASE_PUBLISHED = "Published"; + private ItemObserved itemObserved; + private EventSubscribed eventSubscribed; + private String templateHost; + private String templatePath; + + public BindingAction(ItemObserved 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 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; } } diff --git a/catalogue-binding-plugin/src/test/java/junit/CatalogueBindingPluginTest.java b/catalogue-binding-plugin/src/test/java/junit/CatalogueBindingPluginTest.java index c046c10..0bb9d37 100644 --- a/catalogue-binding-plugin/src/test/java/junit/CatalogueBindingPluginTest.java +++ b/catalogue-binding-plugin/src/test/java/junit/CatalogueBindingPluginTest.java @@ -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 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);