Merged coar-notify-7 into coar-notify-7_CST-10632

This commit is contained in:
Stefano Maffei
2023-11-21 07:53:46 +00:00
43 changed files with 1027 additions and 1331 deletions

View File

@@ -1,190 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.ldn;
import static java.lang.String.format;
import static java.lang.String.join;
import static org.dspace.app.ldn.RdfMediaType.APPLICATION_JSON_LD;
import static org.dspace.app.ldn.utility.LDNUtils.processContextResolverId;
import java.net.URI;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.converter.JsonLdHttpMessageConverter;
import org.dspace.app.ldn.model.Actor;
import org.dspace.app.ldn.model.Context;
import org.dspace.app.ldn.model.Notification;
import org.dspace.app.ldn.model.Object;
import org.dspace.app.ldn.model.Service;
import org.dspace.content.Item;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataValue;
import org.dspace.handle.service.HandleService;
import org.dspace.services.ConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;
/**
* Linked Data Notification business delegate to facilitate sending
* notification.
*/
public class LDNBusinessDelegate {
private final static Logger log = LogManager.getLogger(LDNBusinessDelegate.class);
@Autowired
private ConfigurationService configurationService;
@Autowired
private HandleService handleService;
private final RestTemplate restTemplate;
/**
* Initialize rest template with appropriate message converters.
*/
public LDNBusinessDelegate() {
restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new JsonLdHttpMessageConverter());
}
/**
* Announce item release notification.
*
* @param item item released (deposited or updated)
* @throws SQLException
*/
public void announceRelease(Item item) {
String serviceIds = configurationService.getProperty("service.service-id.ldn");
for (String serviceId : serviceIds.split(",")) {
doAnnounceRelease(item, serviceId.trim());
}
}
/**
* Build and POST announce release notification to configured service LDN
* inboxes.
*
* @param item associated item
* @param serviceId service id for targer inbox
*/
public void doAnnounceRelease(Item item, String serviceId) {
log.info("Announcing release of item {}", item.getID());
String dspaceServerUrl = configurationService.getProperty("dspace.server.url");
String dspaceUIUrl = configurationService.getProperty("dspace.ui.url");
String dspaceName = configurationService.getProperty("dspace.name");
String dspaceLdnInboxUrl = configurationService.getProperty("ldn.notify.inbox");
log.info("DSpace Server URL {}", dspaceServerUrl);
log.info("DSpace UI URL {}", dspaceUIUrl);
log.info("DSpace Name {}", dspaceName);
log.info("DSpace LDN Inbox URL {}", dspaceLdnInboxUrl);
String serviceUrl = configurationService.getProperty(join(".", "service", serviceId, "url"));
String serviceInboxUrl = configurationService.getProperty(join(".", "service", serviceId, "inbox.url"));
String serviceResolverUrl = configurationService.getProperty(join(".", "service", serviceId, "resolver.url"));
log.info("Target URL {}", serviceUrl);
log.info("Target LDN Inbox URL {}", serviceInboxUrl);
Notification notification = new Notification();
notification.setId(format("urn:uuid:%s", UUID.randomUUID()));
notification.addType("Announce");
notification.addType("coar-notify:ReleaseAction");
Actor actor = new Actor();
actor.setId(dspaceUIUrl);
actor.setName(dspaceName);
actor.addType("Service");
Context context = new Context();
List<Context> isSupplementedBy = new ArrayList<>();
List<MetadataValue> metadata = item.getMetadata();
for (MetadataValue metadatum : metadata) {
MetadataField field = metadatum.getMetadataField();
log.info("Metadata field {} with value {}", field, metadatum.getValue());
if (field.getMetadataSchema().getName().equals("dc") &&
field.getElement().equals("data") &&
field.getQualifier().equals("uri")) {
String ietfCiteAs = metadatum.getValue();
String resolverId = processContextResolverId(ietfCiteAs);
String id = serviceResolverUrl != null
? format("%s%s", serviceResolverUrl, resolverId)
: ietfCiteAs;
Context supplement = new Context();
supplement.setId(id);
supplement.setIetfCiteAs(ietfCiteAs);
supplement.addType("sorg:Dataset");
isSupplementedBy.add(supplement);
}
}
context.setIsSupplementedBy(isSupplementedBy);
Object object = new Object();
String itemUrl = handleService.getCanonicalForm(item.getHandle());
log.info("Item Handle URL {}", itemUrl);
log.info("Item URL {}", itemUrl);
object.setId(itemUrl);
object.setIetfCiteAs(itemUrl);
object.setTitle(item.getName());
object.addType("sorg:ScholarlyArticle");
Service origin = new Service();
origin.setId(dspaceUIUrl);
origin.setInbox(dspaceLdnInboxUrl);
origin.addType("Service");
Service target = new Service();
target.setId(serviceUrl);
target.setInbox(serviceInboxUrl);
target.addType("Service");
notification.setActor(actor);
notification.setContext(context);
notification.setObject(object);
notification.setOrigin(origin);
notification.setTarget(target);
String serviceKey = configurationService.getProperty(join(".", "service", serviceId, "key"));
String serviceKeyHeader = configurationService.getProperty(join(".", "service", serviceId, "key.header"));
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", APPLICATION_JSON_LD.toString());
if (serviceKey != null && serviceKeyHeader != null) {
headers.add(serviceKeyHeader, serviceKey);
}
HttpEntity<Notification> request = new HttpEntity<Notification>(notification, headers);
log.info("Announcing notification {}", request);
restTemplate.postForLocation(URI.create(target.getInbox()), request);
}
}

View File

@@ -9,6 +9,7 @@ package org.dspace.app.ldn.action;
import org.dspace.app.ldn.model.Notification; import org.dspace.app.ldn.model.Notification;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Context;
/** /**
* An action that is run after a notification has been processed. * An action that is run after a notification has been processed.
@@ -19,11 +20,12 @@ public interface LDNAction {
* Execute action for provided notification and item corresponding to the * Execute action for provided notification and item corresponding to the
* notification context. * notification context.
* *
*@param context the context
* @param notification the processed notification to perform action against * @param notification the processed notification to perform action against
* @param item the item corresponding to the notification context * @param item the item corresponding to the notification context
* @return ActionStatus the resulting status of the action * @return ActionStatus the resulting status of the action
* @throws Exception general exception that can be thrown while executing action * @throws Exception general exception that can be thrown while executing action
*/ */
public ActionStatus execute(Notification notification, Item item) throws Exception; public ActionStatus execute(Context context, Notification notification, Item item) throws Exception;
} }

View File

@@ -11,6 +11,7 @@ import java.math.BigDecimal;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Date; import java.util.Date;
import com.github.jsonldjava.utils.JsonUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.NotifyServiceEntity; import org.dspace.app.ldn.NotifyServiceEntity;
@@ -20,11 +21,18 @@ import org.dspace.content.Item;
import org.dspace.content.QAEvent; import org.dspace.content.QAEvent;
import org.dspace.content.service.ItemService; import org.dspace.content.service.ItemService;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.handle.service.HandleService;
import org.dspace.qaevent.service.QAEventService; import org.dspace.qaevent.service.QAEventService;
import org.dspace.qaevent.service.dto.NotifyMessageDTO;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
import org.dspace.web.ContextUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/**
* Implementation for LDN Correction Action. It creates a QA Event according to the LDN Message received *
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class LDNCorrectionAction implements LDNAction { public class LDNCorrectionAction implements LDNAction {
private static final Logger log = LogManager.getLogger(LDNEmailAction.class); private static final Logger log = LogManager.getLogger(LDNEmailAction.class);
@@ -39,20 +47,38 @@ public class LDNCorrectionAction implements LDNAction {
private QAEventService qaEventService; private QAEventService qaEventService;
@Autowired @Autowired
private LDNMessageService ldnMessageService; private LDNMessageService ldnMessageService;
@Autowired
private HandleService handleService;
@Override @Override
public ActionStatus execute(Notification notification, Item item) throws Exception { public ActionStatus execute(Context context, Notification notification, Item item) throws Exception {
ActionStatus result; ActionStatus result = ActionStatus.ABORT;
Context context = ContextUtil.obtainCurrentRequestContext(); String itemName = itemService.getName(item);
//FIXME the original id should be just an (optional) identifier/reference of the event in QAEvent qaEvent = null;
// the external system. The target Item should be passed as a constructor argument if (notification.getObject() != null) {
QAEvent qaEvent = new QAEvent(QAEvent.COAR_NOTIFY, String citeAs = notification.getObject().getIetfCiteAs();
"oai:localhost:" + item.getHandle(), item.getID().toString(), item.getName(), if (citeAs == null || citeAs.isEmpty()) {
this.getQaEventTopic(), getScore(context, notification).doubleValue(), citeAs = notification.getObject().getId();
"{\"abstracts[0]\": \"" + notification.getObject().getIetfCiteAs() + "\"}" }
, new Date()); NotifyMessageDTO message = new NotifyMessageDTO();
qaEventService.store(context, qaEvent); message.setHref(citeAs);
result = ActionStatus.CONTINUE; message.setRelationship(notification.getObject().getAsRelationship());
if (notification.getOrigin() != null) {
message.setServiceId(notification.getOrigin().getId());
message.setServiceName(notification.getOrigin().getInbox());
}
BigDecimal score = getScore(context, notification);
double doubleScoreValue = score != null ? score.doubleValue() : 0d;
/* String fullHandleUrl = configurationService.getProperty("dspace.ui.url") + "/handle/"
+ handleService.findHandle(context, item); */
qaEvent = new QAEvent(QAEvent.COAR_NOTIFY_SOURCE,
handleService.findHandle(context, item), item.getID().toString(), itemName,
this.getQaEventTopic(), doubleScoreValue,
JsonUtils.toString(message)
, new Date());
qaEventService.store(context, qaEvent);
result = ActionStatus.CONTINUE;
}
return result; return result;
} }

View File

@@ -24,7 +24,6 @@ import org.dspace.core.Context;
import org.dspace.core.Email; import org.dspace.core.Email;
import org.dspace.core.I18nUtil; import org.dspace.core.I18nUtil;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
import org.dspace.web.ContextUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
@@ -71,9 +70,7 @@ public class LDNEmailAction implements LDNAction {
* @throws Exception * @throws Exception
*/ */
@Override @Override
public ActionStatus execute(Notification notification, Item item) throws Exception { public ActionStatus execute(Context context, Notification notification, Item item) throws Exception {
Context context = ContextUtil.obtainCurrentRequestContext();
try { try {
Locale supportedLocale = I18nUtil.getEPersonLocale(context.getCurrentUser()); Locale supportedLocale = I18nUtil.getEPersonLocale(context.getCurrentUser());
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, actionSendEmailTextFile)); Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, actionSendEmailTextFile));

View File

@@ -1,37 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.ldn.factory;
import org.dspace.app.ldn.LDNBusinessDelegate;
import org.dspace.services.factory.DSpaceServicesFactory;
/**
* Abstract business delegate factory to provide ability to get instance from
* dspace services factory.
*/
public abstract class LDNBusinessDelegateFactory {
/**
* Abstract method to return the business delegate bean.
*
* @return LDNBusinessDelegate business delegate bean
*/
public abstract LDNBusinessDelegate getLDNBusinessDelegate();
/**
* Static method to get the business delegate factory instance.
*
* @return LDNBusinessDelegateFactory business delegate factory from dspace
* services factory
*/
public static LDNBusinessDelegateFactory getInstance() {
return DSpaceServicesFactory.getInstance().getServiceManager()
.getServiceByName("ldnBusinessDelegateFactory", LDNBusinessDelegateFactory.class);
}
}

View File

@@ -1,30 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.ldn.factory;
import org.dspace.app.ldn.LDNBusinessDelegate;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Business delegate factory implementation that autowires business delegate for
* static retrieval.
*/
public class LDNBusinessDelegateFactoryImpl extends LDNBusinessDelegateFactory {
@Autowired(required = true)
private LDNBusinessDelegate ldnBusinessDelegate;
/**
* @return LDNBusinessDelegate
*/
@Override
public LDNBusinessDelegate getLDNBusinessDelegate() {
return ldnBusinessDelegate;
}
}

View File

@@ -14,6 +14,15 @@ import com.fasterxml.jackson.annotation.JsonProperty;
*/ */
public class Object extends Citation { public class Object extends Citation {
@JsonProperty("as:object")
private String asObject;
@JsonProperty("as:relationship")
private String asRelationship;
@JsonProperty("as:subject")
private String asSubject;
@JsonProperty("sorg:name") @JsonProperty("sorg:name")
private String title; private String title;
@@ -38,4 +47,28 @@ public class Object extends Citation {
this.title = title; this.title = title;
} }
public String getAsObject() {
return asObject;
}
public void setAsObject(String asObject) {
this.asObject = asObject;
}
public String getAsRelationship() {
return asRelationship;
}
public void setAsRelationship(String asRelationship) {
this.asRelationship = asRelationship;
}
public String getAsSubject() {
return asSubject;
}
public void setAsSubject(String asSubject) {
this.asSubject = asSubject;
}
} }

View File

@@ -88,7 +88,7 @@ public class LDNContextRepeater {
} }
JsonNode contextArrayNode = topContextNode.get(repeatOver); JsonNode contextArrayNode = topContextNode.get(repeatOver);
if (contextArrayNode.isNull()) { if (contextArrayNode == null || contextArrayNode.isNull()) {
log.error("Notification context {} is not defined", repeatOver); log.error("Notification context {} is not defined", repeatOver);
return; return;
} }

View File

@@ -1,48 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.ldn.processor;
/**
* Instuctions for adding metadata during notification processing.
*/
public class LDNMetadataAdd extends LDNMetadataChange {
private String qualifier;
// velocity template with notification as it contexts
private String valueTemplate;
/**
* @return String
*/
public String getQualifier() {
return qualifier;
}
/**
* @param qualifier
*/
public void setQualifier(String qualifier) {
this.qualifier = qualifier;
}
/**
* @return String
*/
public String getValueTemplate() {
return valueTemplate;
}
/**
* @param valueTemplate
*/
public void setValueTemplate(String valueTemplate) {
this.valueTemplate = valueTemplate;
}
}

View File

@@ -1,95 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.ldn.processor;
import static org.dspace.app.ldn.LDNMetadataFields.ELEMENT;
import static org.dspace.app.ldn.LDNMetadataFields.SCHEMA;
import static org.dspace.content.Item.ANY;
/**
* Base instructions for metadata change during notification processing.
*/
public abstract class LDNMetadataChange {
private String schema;
private String element;
private String language;
// velocity template with notification as its context
private String conditionTemplate;
/**
* Default coar schema, notify element, any language, and true condition to
* apply metadata change.
*/
public LDNMetadataChange() {
schema = SCHEMA;
element = ELEMENT;
language = ANY;
conditionTemplate = "true";
}
/**
* @return String
*/
public String getSchema() {
return schema;
}
/**
* @param schema
*/
public void setSchema(String schema) {
this.schema = schema;
}
/**
* @return String
*/
public String getElement() {
return element;
}
/**
* @param element
*/
public void setElement(String element) {
this.element = element;
}
/**
* @return String
*/
public String getLanguage() {
return language;
}
/**
* @param language
*/
public void setLanguage(String language) {
this.language = language;
}
/**
* @return String
*/
public String getConditionTemplate() {
return conditionTemplate;
}
/**
* @param conditionTemplate
*/
public void setConditionTemplate(String conditionTemplate) {
this.conditionTemplate = conditionTemplate;
}
}

View File

@@ -9,36 +9,24 @@ package org.dspace.app.ldn.processor;
import static java.lang.String.format; import static java.lang.String.format;
import java.io.StringWriter;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
import org.apache.velocity.runtime.resource.util.StringResourceRepository;
import org.dspace.app.ldn.action.ActionStatus; import org.dspace.app.ldn.action.ActionStatus;
import org.dspace.app.ldn.action.LDNAction; import org.dspace.app.ldn.action.LDNAction;
import org.dspace.app.ldn.model.Notification; import org.dspace.app.ldn.model.Notification;
import org.dspace.app.ldn.utility.LDNUtils; import org.dspace.app.ldn.utility.LDNUtils;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.service.ItemService; import org.dspace.content.service.ItemService;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.handle.service.HandleService; import org.dspace.handle.service.HandleService;
import org.dspace.web.ContextUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
@@ -51,10 +39,6 @@ public class LDNMetadataProcessor implements LDNProcessor {
private final static Logger log = LogManager.getLogger(LDNMetadataProcessor.class); private final static Logger log = LogManager.getLogger(LDNMetadataProcessor.class);
private final static String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private final VelocityEngine velocityEngine;
@Autowired @Autowired
private ItemService itemService; private ItemService itemService;
@@ -65,16 +49,11 @@ public class LDNMetadataProcessor implements LDNProcessor {
private List<LDNAction> actions = new ArrayList<>(); private List<LDNAction> actions = new ArrayList<>();
private List<LDNMetadataChange> changes = new ArrayList<>();
/** /**
* Initialize velocity engine for templating. * Initialize velocity engine for templating.
*/ */
private LDNMetadataProcessor() { private LDNMetadataProcessor() {
velocityEngine = new VelocityEngine();
velocityEngine.setProperty(Velocity.RESOURCE_LOADERS, "string");
velocityEngine.setProperty("resource.loader.string.class", StringResourceLoader.class.getName());
velocityEngine.init();
} }
/** /**
@@ -85,110 +64,9 @@ public class LDNMetadataProcessor implements LDNProcessor {
* @throws Exception something went wrong processing the notification * @throws Exception something went wrong processing the notification
*/ */
@Override @Override
public void process(Notification notification) throws Exception { public void process(Context context, Notification notification) throws Exception {
Iterator<Notification> iterator = repeater.iterator(notification);
while (iterator.hasNext()) {
Notification contextNotification = iterator.next();
Item item = doProcess(contextNotification);
runActions(contextNotification, item);
}
}
/**
* Perform the actual notification processing. Applies all defined metadata
* changes.
*
* @param notification current context notification
* @return Item associated item which persist notification details
* @throws Exception failed to process notification
*/
private Item doProcess(Notification notification) throws Exception {
log.info("Processing notification {} {}", notification.getId(), notification.getType());
Context context = ContextUtil.obtainCurrentRequestContext();
VelocityContext velocityContext = prepareTemplateContext(notification);
Item item = lookupItem(context, notification); Item item = lookupItem(context, notification);
runActions(context, notification, item);
List<MetadataValue> metadataValuesToRemove = new ArrayList<>();
for (LDNMetadataChange change : changes) {
String condition = renderTemplate(velocityContext, change.getConditionTemplate());
boolean proceed = Boolean.parseBoolean(condition);
if (!proceed) {
continue;
}
if (change instanceof LDNMetadataAdd) {
LDNMetadataAdd add = ((LDNMetadataAdd) change);
String value = renderTemplate(velocityContext, add.getValueTemplate());
log.info(
"Adding {}.{}.{} {} {}",
add.getSchema(),
add.getElement(),
add.getQualifier(),
add.getLanguage(),
value);
itemService.addMetadata(
context,
item,
add.getSchema(),
add.getElement(),
add.getQualifier(),
add.getLanguage(),
value);
} else if (change instanceof LDNMetadataRemove) {
LDNMetadataRemove remove = (LDNMetadataRemove) change;
for (String qualifier : remove.getQualifiers()) {
List<MetadataValue> itemMetadata = itemService.getMetadata(
item,
change.getSchema(),
change.getElement(),
qualifier,
Item.ANY);
for (MetadataValue metadatum : itemMetadata) {
boolean delete = true;
for (String valueTemplate : remove.getValueTemplates()) {
String value = renderTemplate(velocityContext, valueTemplate);
if (!metadatum.getValue().contains(value)) {
delete = false;
}
}
if (delete) {
log.info("Removing {}.{}.{} {} {}",
remove.getSchema(),
remove.getElement(),
qualifier,
remove.getLanguage(),
metadatum.getValue());
metadataValuesToRemove.add(metadatum);
}
}
}
}
}
if (!metadataValuesToRemove.isEmpty()) {
itemService.removeMetadataValues(context, item, metadataValuesToRemove);
}
context.turnOffAuthorisationSystem();
try {
itemService.update(context, item);
context.commit();
} finally {
context.restoreAuthSystemState();
}
return item;
} }
/** /**
@@ -201,7 +79,7 @@ public class LDNMetadataProcessor implements LDNProcessor {
* *
* @throws Exception failed execute the action * @throws Exception failed execute the action
*/ */
private ActionStatus runActions(Notification notification, Item item) throws Exception { private ActionStatus runActions(Context context, Notification notification, Item item) throws Exception {
ActionStatus operation = ActionStatus.CONTINUE; ActionStatus operation = ActionStatus.CONTINUE;
for (LDNAction action : actions) { for (LDNAction action : actions) {
log.info("Running action {} for notification {} {}", log.info("Running action {} for notification {} {}",
@@ -209,7 +87,7 @@ public class LDNMetadataProcessor implements LDNProcessor {
notification.getId(), notification.getId(),
notification.getType()); notification.getType());
operation = action.execute(notification, item); operation = action.execute(context, notification, item);
if (operation == ActionStatus.ABORT) { if (operation == ActionStatus.ABORT) {
break; break;
} }
@@ -246,20 +124,6 @@ public class LDNMetadataProcessor implements LDNProcessor {
this.actions = actions; this.actions = actions;
} }
/**
* @return List<LDNMetadataChange>
*/
public List<LDNMetadataChange> getChanges() {
return changes;
}
/**
* @param changes
*/
public void setChanges(List<LDNMetadataChange> changes) {
this.changes = changes;
}
/** /**
* Lookup associated item to the notification context. If UUID in URL, lookup bu * Lookup associated item to the notification context. If UUID in URL, lookup bu
* UUID, else lookup by handle. * UUID, else lookup by handle.
@@ -314,41 +178,4 @@ public class LDNMetadataProcessor implements LDNProcessor {
return item; return item;
} }
/**
* Prepare velocity template context with notification, timestamp and some
* static utilities.
*
* @param notification current context notification
* @return VelocityContext prepared velocity context
*/
private VelocityContext prepareTemplateContext(Notification notification) {
VelocityContext velocityContext = new VelocityContext();
String timestamp = new SimpleDateFormat(DATE_PATTERN).format(Calendar.getInstance().getTime());
velocityContext.put("notification", notification);
velocityContext.put("timestamp", timestamp);
velocityContext.put("LDNUtils", LDNUtils.class);
velocityContext.put("Objects", Objects.class);
velocityContext.put("StringUtils", StringUtils.class);
return velocityContext;
}
/**
* Render velocity template with provided context.
*
* @param context velocity context
* @param template template to render
* @return String results of rendering
*/
private String renderTemplate(VelocityContext context, String template) {
StringWriter writer = new StringWriter();
StringResourceRepository repository = StringResourceLoader.getRepository();
repository.putStringResource("template", template);
velocityEngine.getTemplate("template").merge(context, writer);
return writer.toString();
}
} }

View File

@@ -1,51 +0,0 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.ldn.processor;
import java.util.ArrayList;
import java.util.List;
/**
* Instuctions for removing metadata during notification processing.
*/
public class LDNMetadataRemove extends LDNMetadataChange {
private List<String> qualifiers = new ArrayList<>();
// velocity templates with notification as it contexts
private List<String> valueTemplates = new ArrayList<>();
/**
* @return List<String>
*/
public List<String> getQualifiers() {
return qualifiers;
}
/**
* @param qualifiers
*/
public void setQualifiers(List<String> qualifiers) {
this.qualifiers = qualifiers;
}
/**
* @return List<String>
*/
public List<String> getValueTemplates() {
return valueTemplates;
}
/**
* @param valueTemplates
*/
public void setValueTemplates(List<String> valueTemplates) {
this.valueTemplates = valueTemplates;
}
}

View File

@@ -8,6 +8,7 @@
package org.dspace.app.ldn.processor; package org.dspace.app.ldn.processor;
import org.dspace.app.ldn.model.Notification; import org.dspace.app.ldn.model.Notification;
import org.dspace.core.Context;
/** /**
* Processor interface to allow for custom implementations of process. * Processor interface to allow for custom implementations of process.
@@ -20,5 +21,5 @@ public interface LDNProcessor {
* @param notification received notification * @param notification received notification
* @throws Exception something went wrong processing the notification * @throws Exception something went wrong processing the notification
*/ */
public void process(Notification notification) throws Exception; public void process(Context context, Notification notification) throws Exception;
} }

View File

@@ -22,7 +22,6 @@ import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.LDNMessageEntity; import org.dspace.app.ldn.LDNMessageEntity;
import org.dspace.app.ldn.LDNQueueExtractor;
import org.dspace.app.ldn.LDNRouter; import org.dspace.app.ldn.LDNRouter;
import org.dspace.app.ldn.NotifyServiceEntity; import org.dspace.app.ldn.NotifyServiceEntity;
import org.dspace.app.ldn.dao.LDNMessageDao; import org.dspace.app.ldn.dao.LDNMessageDao;
@@ -38,6 +37,7 @@ import org.dspace.handle.service.HandleService;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
* Implementation of {@link LDNMessageService} * Implementation of {@link LDNMessageService}
* *
@@ -58,7 +58,7 @@ public class LDNMessageServiceImpl implements LDNMessageService {
@Autowired(required = true) @Autowired(required = true)
private LDNRouter ldnRouter; private LDNRouter ldnRouter;
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(LDNQueueExtractor.class); private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(LDNMessageServiceImpl.class);
protected LDNMessageServiceImpl() { protected LDNMessageServiceImpl() {
@@ -203,7 +203,7 @@ public class LDNMessageServiceImpl implements LDNMessageService {
update(context, msg); update(context, msg);
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
Notification notification = mapper.readValue(msg.getMessage(), Notification.class); Notification notification = mapper.readValue(msg.getMessage(), Notification.class);
processor.process(notification); processor.process(context, notification);
msg.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_PROCESSED); msg.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_PROCESSED);
result = 1; result = 1;
} catch (JsonSyntaxException jse) { } catch (JsonSyntaxException jse) {

View File

@@ -13,6 +13,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.Date; import java.util.Date;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.dspace.qaevent.service.dto.NotifyMessageDTO;
import org.dspace.qaevent.service.dto.OpenaireMessageDTO; import org.dspace.qaevent.service.dto.OpenaireMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO; import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.dspace.util.RawJsonDeserializer; import org.dspace.util.RawJsonDeserializer;
@@ -21,6 +22,7 @@ import org.dspace.util.RawJsonDeserializer;
* This class represent the Quality Assurance broker data as loaded in our solr * This class represent the Quality Assurance broker data as loaded in our solr
* qaevent core * qaevent core
* *
* @author Andrea Bollini (andrea.bollini at 4science.it)
*/ */
public class QAEvent { public class QAEvent {
public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
@@ -30,7 +32,7 @@ public class QAEvent {
public static final String DISCARDED = "discarded"; public static final String DISCARDED = "discarded";
public static final String OPENAIRE_SOURCE = "openaire"; public static final String OPENAIRE_SOURCE = "openaire";
public static final String COAR_NOTIFY = "coar-notify"; public static final String COAR_NOTIFY_SOURCE = "coar-notify";
private String source; private String source;
@@ -195,13 +197,18 @@ public class QAEvent {
} }
public Class<? extends QAMessageDTO> getMessageDtoClass() { public Class<? extends QAMessageDTO> getMessageDtoClass() {
Class<? extends QAMessageDTO> result = null;
switch (getSource()) { switch (getSource()) {
case OPENAIRE_SOURCE: case OPENAIRE_SOURCE:
case COAR_NOTIFY: result = OpenaireMessageDTO.class;
return OpenaireMessageDTO.class; break;
case COAR_NOTIFY_SOURCE:
result = NotifyMessageDTO.class;
break;
default: default:
throw new IllegalArgumentException("Unknown event's source: " + getSource()); throw new IllegalArgumentException("Unknown event's source: " + getSource());
} }
return result;
} }
} }

View File

@@ -0,0 +1,29 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.qaevent;
/**
* Constants for Quality Assurance configurations to be used into cfg and xml spring.
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class QANotifyPatterns {
public static final String TOPIC_ENRICH_MORE_PROJECT = "ENRICH/MORE/PROJECT";
public static final String TOPIC_ENRICH_MISSING_PROJECT = "ENRICH/MISSING/PROJECT";
public static final String TOPIC_ENRICH_MISSING_ABSTRACT = "ENRICH/MISSING/ABSTRACT";
public static final String TOPIC_ENRICH_MORE_REVIEW = "ENRICH/MORE/REVIEW";
public static final String TOPIC_ENRICH_MORE_ENDORSEMENT = "ENRICH/MORE/ENDORSEMENT";
public static final String TOPIC_ENRICH_MORE_PID = "ENRICH/MORE/PID";
public static final String TOPIC_ENRICH_MISSING_PID = "ENRICH/MISSING/PID";
/**
* Default constructor
*/
private QANotifyPatterns() { }
}

View File

@@ -0,0 +1,82 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.qaevent.action;
import java.sql.SQLException;
import java.util.Map;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.qaevent.QualityAssuranceAction;
import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Implementation of {@link QualityAssuranceAction} that add a specific metadata on the given
* item based on the child class implementation.
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public abstract class AMetadataMapAction implements QualityAssuranceAction {
public static final String DEFAULT = "default";
private Map<String, String> types;
@Autowired
private ItemService itemService;
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
public Map<String, String> getTypes() {
return types;
}
public void setTypes(Map<String, String> types) {
this.types = types;
}
public abstract String extractMetadataType(QAMessageDTO message);
public abstract String extractMetadataValue(QAMessageDTO message);
/**
* Apply the correction on one metadata field of the given item based on the
* openaire message type.
*/
@Override
public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) {
try {
String targetMetadata = types.get(extractMetadataType(message));
if (targetMetadata == null) {
targetMetadata = types.get(DEFAULT);
}
String[] metadata = splitMetadata(targetMetadata);
itemService.addMetadata(context, item, metadata[0], metadata[1], metadata[2], null,
extractMetadataValue(message));
itemService.update(context, item);
} catch (SQLException | AuthorizeException e) {
throw new RuntimeException(e);
}
}
public String[] splitMetadata(String metadata) {
String[] result = new String[3];
String[] split = metadata.split("\\.");
result[0] = split[0];
result[1] = split[1];
if (split.length == 3) {
result[2] = split[2];
}
return result;
}
}

View File

@@ -0,0 +1,65 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.qaevent.action;
import java.sql.SQLException;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.qaevent.QualityAssuranceAction;
import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Abstract class for Simple metadata action.
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public abstract class ASimpleMetadataAction implements QualityAssuranceAction {
private String metadata;
private String metadataSchema;
private String metadataElement;
private String metadataQualifier;
@Autowired
private ItemService itemService;
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
public String getMetadata() {
return metadata;
}
public void setMetadata(String metadata) {
this.metadata = metadata;
String[] split = metadata.split("\\.");
this.metadataSchema = split[0];
this.metadataElement = split[1];
if (split.length == 3) {
this.metadataQualifier = split[2];
}
}
public abstract String extractMetadataValue(QAMessageDTO message);
@Override
public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) {
try {
String metadataValue = extractMetadataValue(message);
itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null,
metadataValue);
itemService.update(context, item);
} catch (SQLException | AuthorizeException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,31 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.qaevent.action;
import org.dspace.qaevent.service.dto.NotifyMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO;
/**
* Openaire Implementation {@link AMetadataMapAction}
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class QANotifyMetadataMapAction extends AMetadataMapAction {
@Override
public String extractMetadataType(QAMessageDTO message) {
return ((NotifyMessageDTO)message).getRelationship();
}
@Override
public String extractMetadataValue(QAMessageDTO message) {
return ((NotifyMessageDTO)message).getHref();
}
}

View File

@@ -0,0 +1,26 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.qaevent.action;
import org.dspace.qaevent.QualityAssuranceAction;
import org.dspace.qaevent.service.dto.NotifyMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO;
/**
* Implementation of {@link QualityAssuranceAction} that add a simple metadata to the given
* item.
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class QANotifySimpleMetadataAction extends ASimpleMetadataAction {
public String extractMetadataValue(QAMessageDTO message) {
return ((NotifyMessageDTO) message).getHref();
}
}

View File

@@ -7,80 +7,25 @@
*/ */
package org.dspace.qaevent.action; package org.dspace.qaevent.action;
import java.sql.SQLException;
import java.util.Map;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.qaevent.QualityAssuranceAction;
import org.dspace.qaevent.service.dto.OpenaireMessageDTO; import org.dspace.qaevent.service.dto.OpenaireMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO; import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.springframework.beans.factory.annotation.Autowired;
/** /**
* Implementation of {@link QualityAssuranceAction} that add a specific metadata on the given * Openaire Implementation {@link AMetadataMapAction}
* item based on the OPENAIRE message type. *
* * @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
* @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public class QAOpenaireMetadataMapAction implements QualityAssuranceAction { public class QAOpenaireMetadataMapAction extends AMetadataMapAction {
public static final String DEFAULT = "default";
private Map<String, String> types;
@Autowired
private ItemService itemService;
public void setItemService(ItemService itemService) {
this.itemService = itemService;
}
public Map<String, String> getTypes() {
return types;
}
public void setTypes(Map<String, String> types) {
this.types = types;
}
/**
* Apply the correction on one metadata field of the given item based on the
* openaire message type.
*/
@Override @Override
public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) { public String extractMetadataType(QAMessageDTO message) {
return ((OpenaireMessageDTO)message).getType();
if (!(message instanceof OpenaireMessageDTO)) {
throw new IllegalArgumentException("Unsupported message type: " + message.getClass());
}
OpenaireMessageDTO openaireMessage = (OpenaireMessageDTO) message;
try {
String targetMetadata = types.get(openaireMessage.getType());
if (targetMetadata == null) {
targetMetadata = types.get(DEFAULT);
}
String[] metadata = splitMetadata(targetMetadata);
itemService.addMetadata(context, item, metadata[0], metadata[1], metadata[2], null,
openaireMessage.getValue());
itemService.update(context, item);
} catch (SQLException | AuthorizeException e) {
throw new RuntimeException(e);
}
} }
public String[] splitMetadata(String metadata) { @Override
String[] result = new String[3]; public String extractMetadataValue(QAMessageDTO message) {
String[] split = metadata.split("\\."); return ((OpenaireMessageDTO)message).getValue();
result[0] = split[0];
result[1] = split[1];
if (split.length == 3) {
result[2] = split[2];
}
return result;
} }
} }

View File

@@ -7,16 +7,9 @@
*/ */
package org.dspace.qaevent.action; package org.dspace.qaevent.action;
import java.sql.SQLException;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.qaevent.QualityAssuranceAction; import org.dspace.qaevent.QualityAssuranceAction;
import org.dspace.qaevent.service.dto.OpenaireMessageDTO; import org.dspace.qaevent.service.dto.OpenaireMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO; import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.springframework.beans.factory.annotation.Autowired;
/** /**
* Implementation of {@link QualityAssuranceAction} that add a simple metadata to the given * Implementation of {@link QualityAssuranceAction} that add a simple metadata to the given
@@ -25,40 +18,9 @@ import org.springframework.beans.factory.annotation.Autowired;
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public class QAOpenaireSimpleMetadataAction implements QualityAssuranceAction { public class QAOpenaireSimpleMetadataAction extends ASimpleMetadataAction {
private String metadata;
private String metadataSchema;
private String metadataElement;
private String metadataQualifier;
@Autowired
private ItemService itemService;
public void setItemService(ItemService itemService) { public String extractMetadataValue(QAMessageDTO message) {
this.itemService = itemService; return ((OpenaireMessageDTO) message).getAbstracts();
}
public String getMetadata() {
return metadata;
}
public void setMetadata(String metadata) {
this.metadata = metadata;
String[] split = metadata.split("\\.");
this.metadataSchema = split[0];
this.metadataElement = split[1];
if (split.length == 3) {
this.metadataQualifier = split[2];
}
}
@Override
public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) {
try {
itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null,
((OpenaireMessageDTO) message).getAbstracts());
itemService.update(context, item);
} catch (SQLException | AuthorizeException e) {
throw new RuntimeException(e);
}
} }
} }

View File

@@ -0,0 +1,58 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.qaevent.service.dto;
/**
* Implementation of {@link QAMessageDTO} that model message coming from COAR NOTIFY.
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class NotifyMessageDTO implements QAMessageDTO {
private String serviceName;
private String serviceId;
private String href;
private String relationship;
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
public String getRelationship() {
return relationship;
}
public void setRelationship(String relationship) {
this.relationship = relationship;
}
}

View File

@@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.databind.json.JsonMapper;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER; import org.apache.solr.client.solrj.SolrQuery.ORDER;
@@ -70,6 +71,8 @@ import org.springframework.beans.factory.annotation.Qualifier;
*/ */
public class QAEventServiceImpl implements QAEventService { public class QAEventServiceImpl implements QAEventService {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(QAEventServiceImpl.class);
@Autowired(required = true) @Autowired(required = true)
protected ConfigurationService configurationService; protected ConfigurationService configurationService;
@@ -649,7 +652,7 @@ public class QAEventServiceImpl implements QAEventService {
if (startPosition != -1) { if (startPosition != -1) {
return originalId.substring(startPosition + 1, originalId.length()); return originalId.substring(startPosition + 1, originalId.length());
} else { } else {
return null; return originalId;
} }
} }
@@ -673,8 +676,8 @@ public class QAEventServiceImpl implements QAEventService {
} }
private String[] getSupportedSources() { private String[] getSupportedSources() {
return configurationService.getArrayProperty("qaevent.sources", new String[] return configurationService.getArrayProperty("qaevent.sources",
{ QAEvent.OPENAIRE_SOURCE, QAEvent.COAR_NOTIFY }); new String[] { QAEvent.OPENAIRE_SOURCE, QAEvent.COAR_NOTIFY_SOURCE });
} }
} }

View File

@@ -8,6 +8,7 @@
package org.dspace.qaevent.script; package org.dspace.qaevent.script;
import static java.util.List.of; import static java.util.List.of;
import static org.dspace.content.QAEvent.COAR_NOTIFY_SOURCE;
import static org.dspace.content.QAEvent.OPENAIRE_SOURCE; import static org.dspace.content.QAEvent.OPENAIRE_SOURCE;
import static org.dspace.matcher.QAEventMatcher.pendingOpenaireEventWith; import static org.dspace.matcher.QAEventMatcher.pendingOpenaireEventWith;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
@@ -47,6 +48,7 @@ import org.dspace.content.Item;
import org.dspace.content.QAEvent; import org.dspace.content.QAEvent;
import org.dspace.matcher.QASourceMatcher; import org.dspace.matcher.QASourceMatcher;
import org.dspace.matcher.QATopicMatcher; import org.dspace.matcher.QATopicMatcher;
import org.dspace.qaevent.QANotifyPatterns;
import org.dspace.qaevent.QATopic; import org.dspace.qaevent.QATopic;
import org.dspace.qaevent.service.BrokerClientFactory; import org.dspace.qaevent.service.BrokerClientFactory;
import org.dspace.qaevent.service.QAEventService; import org.dspace.qaevent.service.QAEventService;
@@ -55,8 +57,10 @@ import org.dspace.services.ConfigurationService;
import org.dspace.utils.DSpace; import org.dspace.utils.DSpace;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
/** /**
* Integration tests for {@link OpenaireEventsImport}. * Integration tests for {@link OpenaireEventsImport}.
* *
@@ -171,11 +175,11 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
); );
List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20); List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20);
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PID, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1L)));
String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\","
+ "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\"," + "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\","
@@ -183,18 +187,21 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
+ "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\","
+ "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths\"}"; + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths\"}";
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MORE/PROJECT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 0, 20),
contains( contains(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99998", firstItem, pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99998", firstItem,
"Egypt, crossroad of translations and literary interweavings", projectMessage, "Egypt, crossroad of translations and literary interweavings", projectMessage,
"ENRICH/MORE/PROJECT", 1.00d))); QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 1.00d)));
String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}";
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MISSING/ABSTRACT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 0, 20),
contains( contains(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999",
abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); secondItem, "Test Publication",
abstractMessage, QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1.00d)));
verifyNoInteractions(mockBrokerClient); verifyNoInteractions(mockBrokerClient);
@@ -229,16 +236,17 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 3L)));
List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20); List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20);
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PID, 1L)));
String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}";
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MISSING/ABSTRACT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 0, 20),
contains( contains(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", item, "Test Publication", pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", item, "Test Publication",
abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); abstractMessage, QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1.00d)));
verifyNoInteractions(mockBrokerClient); verifyNoInteractions(mockBrokerClient);
@@ -269,14 +277,15 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 1L))); assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 1L)));
assertThat(qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20), assertThat(qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20),
contains(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); contains(QATopicMatcher.with(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1L)));
String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}";
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MISSING/ABSTRACT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 0, 20),
contains( contains(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/999991", secondItem, "Test Publication 2", pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/999991", secondItem, "Test Publication 2",
abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); abstractMessage, org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1.00d)));
verifyNoInteractions(mockBrokerClient); verifyNoInteractions(mockBrokerClient);
@@ -345,11 +354,11 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 6L))); assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 6L)));
List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20); List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20);
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PID, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 2L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 2L)));
String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\","
+ "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\"," + "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\","
@@ -357,22 +366,23 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
+ "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\","
+ "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths\"}"; + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths\"}";
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MORE/PROJECT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 0, 20),
contains( contains(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99998", firstItem, pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99998", firstItem,
"Egypt, crossroad of translations and literary interweavings", projectMessage, "Egypt, crossroad of translations and literary interweavings", projectMessage,
"ENRICH/MORE/PROJECT", 1.00d))); QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 1.00d)));
String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}";
List<QAEvent> eventList = qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, List<QAEvent> eventList = qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
"ENRICH/MISSING/ABSTRACT", 0, 20); QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 0, 20);
assertThat(eventList, hasItem( assertThat(eventList, hasItem(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication",
abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); abstractMessage, QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1.00d)));
assertThat(eventList, hasItem( assertThat(eventList, hasItem(
pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/999991", thirdItem, "Test Publication 2", pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/999991", thirdItem, "Test Publication 2",
abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); abstractMessage, QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1.00d)));
verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com"); verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com");
verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub1"), any()); verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub1"), any());
@@ -454,15 +464,17 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 6L))); assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 6L)));
List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20); List<QATopic> topicList = qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20);
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MORE/PID", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_PID, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT, 1L)));
assertThat(topicList, hasItem(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 2L))); assertThat(topicList, hasItem(QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 2L)));
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MORE/PROJECT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT, 0, 20),
hasSize(1)); hasSize(1));
assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE, "ENRICH/MISSING/ABSTRACT", 0, 20), assertThat(qaEventService.findEventsByTopicAndPage(context, OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 0, 20),
hasSize(2)); hasSize(2));
verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com"); verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com");
@@ -474,7 +486,12 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
} }
/**
* Improper test for ENRICH/MORE/REVIEW qa. It has the COAR_NOTIFY source
* which must be tested via LDNMessage {@link LDNInboxControllerIT}
*/
@Test @Test
@Ignore
public void testImportFromFileEventMoreReview() throws Exception { public void testImportFromFileEventMoreReview() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
@@ -488,10 +505,11 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase
String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("event-more-review.json") }; String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("event-more-review.json") };
ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl);
assertThat(qaEventService.findAllTopicsBySource(context, OPENAIRE_SOURCE, 0, 20), contains( assertThat(qaEventService.findAllTopicsBySource(context, COAR_NOTIFY_SOURCE, 0, 20), contains(
QATopicMatcher.with("ENRICH/MORE/REVIEW", 1L))); QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW, 1L)));
assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(OPENAIRE_SOURCE, 1L))); assertThat(qaEventService.findAllSources(context, 0, 20),
hasItem(QASourceMatcher.with(COAR_NOTIFY_SOURCE, 1L)));
verifyNoInteractions(mockBrokerClient); verifyNoInteractions(mockBrokerClient);
} }

View File

@@ -1,11 +0,0 @@
[
{
"originalId": "oai:www.openstarts.units.it:123456789/99999",
"title": "Test Publication",
"topic": "ENRICH/MORE/REVIEW",
"trust": 1.0,
"message": {
"abstracts[0]": "More review"
}
}
]

View File

@@ -14,7 +14,6 @@ import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.LDNMessageEntity; import org.dspace.app.ldn.LDNMessageEntity;
import org.dspace.app.ldn.LDNRouter; import org.dspace.app.ldn.LDNRouter;
import org.dspace.app.ldn.model.Notification; import org.dspace.app.ldn.model.Notification;
import org.dspace.app.ldn.processor.LDNProcessor;
import org.dspace.app.ldn.service.LDNMessageService; import org.dspace.app.ldn.service.LDNMessageService;
import org.dspace.app.rest.exception.InvalidLDNMessageException; import org.dspace.app.rest.exception.InvalidLDNMessageException;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -61,18 +60,6 @@ public class LDNInboxController {
log.info("stored ldn message {}", ldnMsgEntity); log.info("stored ldn message {}", ldnMsgEntity);
context.commit(); context.commit();
if (ldnMsgEntity.getQueueStatus() != LDNMessageEntity.QUEUE_STATUS_UNTRUSTED) {
LDNProcessor processor = router.route(ldnMsgEntity);
if (processor == null) {
log.error(String.format("No processor found for type %s", notification.getType()));
return ResponseEntity.badRequest()
.body(String.format("No processor found for type %s", notification.getType()));
} else {
processor.process(notification);
}
} else {
log.warn("LDNMessage " + ldnMsgEntity + " has been received by an untrusted source");
}
return ResponseEntity.accepted() return ResponseEntity.accepted()
.body(String.format("Successfully stored notification %s %s", .body(String.format("Successfully stored notification %s %s",
notification.getId(), notification.getType())); notification.getId(), notification.getType()));

View File

@@ -14,11 +14,13 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.databind.json.JsonMapper;
import org.dspace.app.rest.model.NotifyQAEventMessageRest;
import org.dspace.app.rest.model.OpenaireQAEventMessageRest; import org.dspace.app.rest.model.OpenaireQAEventMessageRest;
import org.dspace.app.rest.model.QAEventMessageRest; import org.dspace.app.rest.model.QAEventMessageRest;
import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.model.QAEventRest;
import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.projection.Projection;
import org.dspace.content.QAEvent; import org.dspace.content.QAEvent;
import org.dspace.qaevent.service.dto.NotifyMessageDTO;
import org.dspace.qaevent.service.dto.OpenaireMessageDTO; import org.dspace.qaevent.service.dto.OpenaireMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO; import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
@@ -73,10 +75,22 @@ public class QAEventConverter implements DSpaceConverter<QAEvent, QAEventRest> {
private QAEventMessageRest convertMessage(QAMessageDTO dto) { private QAEventMessageRest convertMessage(QAMessageDTO dto) {
if (dto instanceof OpenaireMessageDTO) { if (dto instanceof OpenaireMessageDTO) {
return convertOpenaireMessage(dto); return convertOpenaireMessage(dto);
} else if (dto instanceof NotifyMessageDTO) {
return convertNotifyMessage(dto);
} }
throw new IllegalArgumentException("Unknown message type: " + dto.getClass()); throw new IllegalArgumentException("Unknown message type: " + dto.getClass());
} }
private QAEventMessageRest convertNotifyMessage(QAMessageDTO dto) {
NotifyMessageDTO notifyDto = (NotifyMessageDTO) dto;
NotifyQAEventMessageRest message = new NotifyQAEventMessageRest();
message.setServiceName(notifyDto.getServiceName());
message.setServiceId(notifyDto.getServiceId());
message.setHref(notifyDto.getHref());
message.setRelationship(notifyDto.getRelationship());
return message;
}
private QAEventMessageRest convertOpenaireMessage(QAMessageDTO dto) { private QAEventMessageRest convertOpenaireMessage(QAMessageDTO dto) {
OpenaireMessageDTO openaireDto = (OpenaireMessageDTO) dto; OpenaireMessageDTO openaireDto = (OpenaireMessageDTO) dto;
OpenaireQAEventMessageRest message = new OpenaireQAEventMessageRest(); OpenaireQAEventMessageRest message = new OpenaireQAEventMessageRest();

View File

@@ -0,0 +1,58 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model;
/**
* Implementation of {@link QAEventMessageRest} related to COAR NOTIFY events.
*
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class NotifyQAEventMessageRest implements QAEventMessageRest {
private String serviceName;
private String serviceId;
private String href;
private String relationship;
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public String getHref() {
return href;
}
public void setHref(String href) {
this.href = href;
}
public String getRelationship() {
return relationship;
}
public void setRelationship(String relationship) {
this.relationship = relationship;
}
}

View File

@@ -7,9 +7,8 @@
*/ */
package org.dspace.app.rest; package org.dspace.app.rest;
import static org.dspace.content.QAEvent.COAR_NOTIFY; import static org.dspace.content.QAEvent.COAR_NOTIFY_SOURCE;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@@ -36,6 +35,7 @@ import org.dspace.content.Community;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.matcher.QASourceMatcher; import org.dspace.matcher.QASourceMatcher;
import org.dspace.matcher.QATopicMatcher; import org.dspace.matcher.QATopicMatcher;
import org.dspace.qaevent.QANotifyPatterns;
import org.dspace.qaevent.service.QAEventService; import org.dspace.qaevent.service.QAEventService;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
import org.dspace.utils.DSpace; import org.dspace.utils.DSpace;
@@ -43,6 +43,12 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/**
* LDN Controller test class. Simulate receiving external LDN messages
* @author Francesco Bacchelli (francesco.bacchelli at 4science.it)
*
*/
public class LDNInboxControllerIT extends AbstractControllerIntegrationTest { public class LDNInboxControllerIT extends AbstractControllerIntegrationTest {
@Autowired @Autowired
@@ -53,48 +59,27 @@ public class LDNInboxControllerIT extends AbstractControllerIntegrationTest {
private QAEventService qaEventService = new DSpace().getSingletonService(QAEventService.class); private QAEventService qaEventService = new DSpace().getSingletonService(QAEventService.class);
@Test
public void ldnInboxEndorsementActionTest() throws Exception {
context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).withName("community").build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).build();
String object = configurationService.getProperty("dspace.ui.url") + "/handle/" + item.getHandle();
context.restoreAuthSystemState();
InputStream offerEndorsementStream = getClass().getResourceAsStream("ldn_offer_endorsement_object.json");
String offerEndorsementJson = IOUtils.toString(offerEndorsementStream, Charset.defaultCharset());
offerEndorsementStream.close();
String message = offerEndorsementJson.replace("<<object>>", object);
ObjectMapper mapper = new ObjectMapper();
Notification notification = mapper.readValue(message, Notification.class);
getClient()
.perform(post("/ldn/inbox")
.contentType("application/ld+json")
.content(message))
.andExpect(status().isAccepted());
LDNMessageEntity ldnMessage = ldnMessageService.find(context, notification.getId());
checkStoredLDNMessage(notification, ldnMessage, object);
}
@Test @Test
public void ldnInboxAnnounceEndorsementTest() throws Exception { public void ldnInboxAnnounceEndorsementTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).withName("community").build(); Community community = CommunityBuilder.createCommunity(context).withName("community").build();
Collection collection = CollectionBuilder.createCollection(context, community).build(); Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).build(); Item item = ItemBuilder.createItem(context, collection).build();
String object = configurationService.getProperty("dspace.ui.url") + "/handle/" + item.getHandle(); String object = configurationService.getProperty("dspace.ui.url") + "/handle/" + item.getHandle();
NotifyServiceEntity notifyServiceEntity =
NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name")
.withDescription("service description")
.withUrl("service url")
.withLdnUrl("https://overlay-journal.com/inbox/")
.build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
InputStream announceEndorsementStream = getClass().getResourceAsStream("ldn_announce_endorsement.json"); InputStream announceEndorsementStream = getClass().getResourceAsStream("ldn_announce_endorsement.json");
String announceEndorsement = IOUtils.toString(announceEndorsementStream, Charset.defaultCharset()); String announceEndorsement = IOUtils.toString(announceEndorsementStream, Charset.defaultCharset());
announceEndorsementStream.close(); announceEndorsementStream.close();
String message = announceEndorsement.replace("<<object>>", object); String message = announceEndorsement.replaceAll("<<object>>", object);
message = message.replaceAll("<<object_handle>>", object);
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
Notification notification = mapper.readValue(message, Notification.class); Notification notification = mapper.readValue(message, Notification.class);
@@ -108,22 +93,26 @@ public class LDNInboxControllerIT extends AbstractControllerIntegrationTest {
checkStoredLDNMessage(notification, ldnMessage, object); checkStoredLDNMessage(notification, ldnMessage, object);
} }
@Test @Test
public void ldnInboxAnnounceReviewTest() throws Exception { public void ldnInboxAnnounceReviewTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
NotifyServiceEntity serviceEntity = NotifyServiceBuilder.createNotifyServiceBuilder(context) Community community = CommunityBuilder.createCommunity(context).withName("community").build();
.withName("Review Service") Collection collection = CollectionBuilder.createCollection(context, community).build();
.withLdnUrl("https://review-service.com/inbox/") Item item = ItemBuilder.createItem(context, collection).build();
.withScore(BigDecimal.valueOf(0.6d))
.build();
Community com = CommunityBuilder.createCommunity(context).withName("Test Community").build();
Collection col = CollectionBuilder.createCollection(context, com).withName("Test Collection").build();
Item item = ItemBuilder.createItem(context, col).withHandle("123456789/9999").withTitle("Test Item").build();
context.restoreAuthSystemState();
InputStream announceReviewStream = getClass().getResourceAsStream("ldn_announce_review.json"); InputStream announceReviewStream = getClass().getResourceAsStream("ldn_announce_review.json");
String message = IOUtils.toString(announceReviewStream, Charset.defaultCharset()); String object = configurationService.getProperty("dspace.ui.url") + "/handle/" + item.getHandle();
NotifyServiceEntity notifyServiceEntity = NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name")
.withDescription("service description")
.withUrl("https://review-service.com/inbox/about/")
.withLdnUrl("https://review-service.com/inbox/")
.withScore(BigDecimal.valueOf(0.6d))
.build();
String announceReview = IOUtils.toString(announceReviewStream, Charset.defaultCharset());
announceReviewStream.close(); announceReviewStream.close();
String message = announceReview.replaceAll("<<object>>", object);
message = message.replaceAll("<<object_handle>>", object);
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
Notification notification = mapper.readValue(message, Notification.class); Notification notification = mapper.readValue(message, Notification.class);
getClient() getClient()
@@ -131,10 +120,14 @@ public class LDNInboxControllerIT extends AbstractControllerIntegrationTest {
.contentType("application/ld+json") .contentType("application/ld+json")
.content(message)) .content(message))
.andExpect(status().isAccepted()); .andExpect(status().isAccepted());
assertThat(qaEventService.findAllSources(context, 0, 20), hasItem(QASourceMatcher.with(COAR_NOTIFY, 1L)));
assertThat(qaEventService.findAllTopicsBySource(context, COAR_NOTIFY, 0, 20), contains( ldnMessageService.extractAndProcessMessageFromQueue(context);
QATopicMatcher.with("ENRICH/MORE/REVIEW", 1L)));
assertThat(qaEventService.findAllSources(context, 0, 20),
hasItem(QASourceMatcher.with(COAR_NOTIFY_SOURCE, 1L)));
assertThat(qaEventService.findAllTopicsBySource(context, COAR_NOTIFY_SOURCE, 0, 20), hasItem(
QATopicMatcher.with(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW, 1L)));
} }

View File

@@ -9,8 +9,8 @@ package org.dspace.app.rest;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
import static org.dspace.app.rest.matcher.QAEventMatcher.matchQAEventEntry; import static org.dspace.content.QAEvent.COAR_NOTIFY_SOURCE;
import static org.dspace.content.QAEvent.COAR_NOTIFY; import static org.dspace.content.QAEvent.OPENAIRE_SOURCE;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
@@ -25,21 +25,26 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.dspace.app.ldn.NotifyServiceEntity;
import org.dspace.app.rest.matcher.ItemMatcher; import org.dspace.app.rest.matcher.ItemMatcher;
import org.dspace.app.rest.matcher.MetadataMatcher;
import org.dspace.app.rest.matcher.QAEventMatcher; import org.dspace.app.rest.matcher.QAEventMatcher;
import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.Operation;
import org.dspace.app.rest.model.patch.ReplaceOperation; import org.dspace.app.rest.model.patch.ReplaceOperation;
import org.dspace.app.rest.repository.QAEventRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder; import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder; import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.EntityTypeBuilder;
import org.dspace.builder.ItemBuilder; import org.dspace.builder.ItemBuilder;
import org.dspace.builder.NotifyServiceBuilder;
import org.dspace.builder.QAEventBuilder; import org.dspace.builder.QAEventBuilder;
import org.dspace.builder.RelationshipTypeBuilder; import org.dspace.builder.RelationshipTypeBuilder;
import org.dspace.content.Collection; import org.dspace.content.Collection;
@@ -47,7 +52,10 @@ import org.dspace.content.EntityType;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.QAEvent; import org.dspace.content.QAEvent;
import org.dspace.content.QAEventProcessed; import org.dspace.content.QAEventProcessed;
import org.dspace.content.service.ItemService;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.qaevent.QANotifyPatterns;
import org.dspace.qaevent.action.ASimpleMetadataAction;
import org.dspace.qaevent.dao.QAEventsDao; import org.dspace.qaevent.dao.QAEventsDao;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Test; import org.junit.Test;
@@ -64,6 +72,15 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
@Autowired @Autowired
private QAEventsDao qaEventsDao; private QAEventsDao qaEventsDao;
@Autowired
private ItemService itemService;
@Autowired
private ASimpleMetadataAction AddReviewMetadataAction;
@Autowired
private ASimpleMetadataAction AddEndorsedMetadataAction;
@Test @Test
public void findAllNotImplementedTest() throws Exception { public void findAllNotImplementedTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password); String adminToken = getAuthToken(admin.getEmail(), password);
@@ -81,17 +98,17 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build();
EPerson anotherSubmitter = EPersonBuilder.createEPerson(context).withEmail("another-submitter@example.com") EPerson anotherSubmitter = EPersonBuilder.createEPerson(context).withEmail("another-submitter@example.com")
.withPassword(password).build(); .withPassword(password).build();
context.setCurrentUser(anotherSubmitter); context.setCurrentUser(anotherSubmitter);
QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
@@ -117,10 +134,10 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event5 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") QAEvent event5 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5")
.withTopic("ENRICH/MISSING/PROJECT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT)
.withMessage( .withMessage(
"{\"projects[0].acronym\":\"PAThs\"," "{\"projects[0].acronym\":\"PAThs\","
+ "\"projects[0].code\":\"687567\"," + "\"projects[0].code\":\"687567\","
@@ -151,7 +168,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
getClient().perform(get("/api/integration/qualityassuranceevents/" + event1.getEventId())) getClient().perform(get("/api/integration/qualityassuranceevents/" + event1.getEventId()))
@@ -164,14 +181,14 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
EPerson anotherSubmitter = EPersonBuilder.createEPerson(context).withEmail("another_submitter@example.com") EPerson anotherSubmitter = EPersonBuilder.createEPerson(context).withEmail("another_submitter@example.com")
.build(); .build();
context.setCurrentUser(anotherSubmitter); context.setCurrentUser(anotherSubmitter);
QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"href\":\"https://doi.org/10.2307/2144300\"}").build(); .withMessage("{\"href\":\"https://doi.org/10.2307/2144300\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(eperson.getEmail(), password); String authToken = getAuthToken(eperson.getEmail(), password);
@@ -190,20 +207,20 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Item item = ItemBuilder.createItem(context, col1).withTitle("Tracking Papyrus and Parchment Paths") Item item = ItemBuilder.createItem(context, col1).withTitle("Tracking Papyrus and Parchment Paths")
.build(); .build();
QAEvent event1 = QAEventBuilder.createTarget(context, item) QAEvent event1 = QAEventBuilder.createTarget(context, item)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}")
.build(); .build();
QAEvent event2 = QAEventBuilder.createTarget(context, item) QAEvent event2 = QAEventBuilder.createTarget(context, item)
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"href\":\"https://doi.org/10.2307/2144301\"}").build(); .withMessage("{\"href\":\"https://doi.org/10.2307/2144301\"}").build();
EPerson anotherSubmitter = EPersonBuilder.createEPerson(context).withEmail("another-submitter@example.com") EPerson anotherSubmitter = EPersonBuilder.createEPerson(context).withEmail("another-submitter@example.com")
.withPassword(password).build(); .withPassword(password).build();
context.setCurrentUser(anotherSubmitter); context.setCurrentUser(anotherSubmitter);
// this event is related to a new item not submitted by eperson // this event is related to a new item not submitted by eperson
QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"href\":\"https://doi.org/10.2307/2144300\"}").build(); .withMessage("{\"href\":\"https://doi.org/10.2307/2144300\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
@@ -226,7 +243,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
getClient(authToken) getClient(authToken)
.perform( .perform(
get("/api/integration/qualityassuranceevents/search/findByTopic") get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID")) .param("topic", QAEvent.COAR_NOTIFY_SOURCE + ":ENRICH!MISSING!PID"))
.andExpect(status().isOk()).andExpect(jsonPath("$.page.size", is(20))) .andExpect(status().isOk()).andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(0))); .andExpect(jsonPath("$.page.totalElements", is(0)));
@@ -243,7 +260,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
getClient(authToken) getClient(authToken)
.perform( .perform(
get("/api/integration/qualityassuranceevents/search/findByTopic") get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MORE!REVIEW:" + uuid.toString())) .param("topic", QAEvent.COAR_NOTIFY_SOURCE + ":ENRICH!MORE!REVIEW:" + uuid.toString()))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1))) .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1)))
.andExpect(jsonPath("$._embedded.qualityassuranceevents", .andExpect(jsonPath("$._embedded.qualityassuranceevents",
Matchers.contains(QAEventMatcher.matchQAEventEntry(event2)))) Matchers.contains(QAEventMatcher.matchQAEventEntry(event2))))
@@ -261,7 +278,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
getClient(authToken) getClient(authToken)
.perform( .perform(
get("/api/integration/qualityassuranceevents/search/findByTopic") get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MORE!REVIEW")) .param("topic", QAEvent.COAR_NOTIFY_SOURCE + ":ENRICH!MORE!REVIEW"))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2))) .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2)))
.andExpect(jsonPath("$._embedded.qualityassuranceevents", .andExpect(jsonPath("$._embedded.qualityassuranceevents",
Matchers.containsInAnyOrder( Matchers.containsInAnyOrder(
@@ -283,7 +300,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
getClient(authToken) getClient(authToken)
.perform( .perform(
get("/api/integration/qualityassuranceevents/search/findByTopic") get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MORE!REVIEW:" + uuid.toString())) .param("topic", QAEvent.COAR_NOTIFY_SOURCE + ":ENRICH!MORE!REVIEW:" + uuid.toString()))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1))) .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1)))
.andExpect(jsonPath("$._embedded.qualityassuranceevents", .andExpect(jsonPath("$._embedded.qualityassuranceevents",
Matchers.contains(QAEventMatcher.matchQAEventEntry(event2)))) Matchers.contains(QAEventMatcher.matchQAEventEntry(event2))))
@@ -305,45 +322,45 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"pmc\",\"pids[0].value\":\"2144303\"}").build(); .withMessage("{\"pids[0].type\":\"pmc\",\"pids[0].value\":\"2144303\"}").build();
QAEvent event5 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") QAEvent event5 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build();
QAEvent event6 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event6 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withSource(COAR_NOTIFY) .withSource(OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event7 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEvent event7 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withSource(COAR_NOTIFY) .withSource(OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEvent event8 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEvent event8 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withSource(COAR_NOTIFY) .withSource(OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEvent event9 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEvent event9 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withSource(COAR_NOTIFY) .withSource(OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"pmc\",\"pids[0].value\":\"2144303\"}").build(); .withMessage("{\"pids[0].type\":\"pmc\",\"pids[0].value\":\"2144303\"}").build();
QAEvent event10 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") QAEvent event10 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5")
.withSource(COAR_NOTIFY) .withSource(OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build();
context.setCurrentUser(admin); context.setCurrentUser(admin);
// this event will be related to an item submitted by the admin // this event will be related to an item submitted by the admin
QAEvent event11 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") QAEvent event11 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5")
.withSource(COAR_NOTIFY) .withSource(OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
@@ -373,7 +390,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Matchers.allOf( Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"), Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"), Matchers.containsString("page=5"),
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.first.href", .andExpect(jsonPath("$._links.first.href",
Matchers.allOf( Matchers.allOf(
@@ -383,8 +400,8 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.prev.href").doesNotExist()) .andExpect(jsonPath("$._links.prev.href").doesNotExist())
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalPages", is(6)))
.andExpect(jsonPath("$.page.totalElements", is(5))); .andExpect(jsonPath("$.page.totalElements", is(11)));
getClient(authToken) getClient(authToken)
.perform( .perform(
@@ -412,7 +429,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Matchers.allOf( Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"), Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"), Matchers.containsString("page=5"),
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.first.href", .andExpect(jsonPath("$._links.first.href",
Matchers.allOf( Matchers.allOf(
@@ -427,30 +444,35 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Matchers.containsString("page=0"), Matchers.containsString("page=0"),
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalPages", is(6)))
.andExpect(jsonPath("$.page.totalElements", is(5))); .andExpect(jsonPath("$.page.totalElements", is(11)));
getClient(authToken) getClient(authToken)
.perform( .perform(
get("/api/integration/qualityassuranceevents/search/findByTopic") get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID") .param("topic", QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID")
.param("size", "2").param("page", "2")) .param("size", "2").param("page", "2"))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1))) .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2)))
.andExpect(jsonPath("$._embedded.qualityassuranceevents", .andExpect(jsonPath("$._embedded.qualityassuranceevents",
Matchers.containsInAnyOrder( Matchers.hasItem(
QAEventMatcher.matchQAEventEntry(event5)))) QAEventMatcher.matchQAEventEntry(event5))))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.allOf( Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"), Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"), Matchers.containsString("page=2"),
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.next.href").doesNotExist()) .andExpect(jsonPath("$._links.next.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=3"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", .andExpect(jsonPath("$._links.last.href",
Matchers.allOf( Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"), Matchers.containsString("topic=" + QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"), Matchers.containsString("page=5"),
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.first.href", .andExpect(jsonPath("$._links.first.href",
Matchers.allOf( Matchers.allOf(
@@ -465,130 +487,21 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Matchers.containsString("page=1"), Matchers.containsString("page=1"),
Matchers.containsString("size=2")))) Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalPages", is(6)))
.andExpect(jsonPath("$.page.totalElements", is(5))); .andExpect(jsonPath("$.page.totalElements", is(11)));
// check if the pagination is working properly also when a security filter is in place // check if the pagination is working properly also when a security filter is in place
authToken = getAuthToken(eperson.getEmail(), password); authToken = getAuthToken(eperson.getEmail(), password);
getClient(authToken) getClient(authToken)
.perform( .perform(
get("/api/integration/qualityassuranceevents/search/findByTopic") get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID") .param("topic", QAEvent.OPENAIRE_SOURCE + ":ENRICH!MISSING!PID")
.param("size", "2")) .param("size", "2"))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2))) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.qualityassuranceevents", .andExpect(jsonPath("$", hasNoJsonPath("$._embedded.qualityassuranceevents")))
Matchers.containsInAnyOrder(
QAEventMatcher.matchQAEventEntry(event6),
QAEventMatcher.matchQAEventEntry(event7))))
.andExpect(jsonPath("$._links.self.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.next.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=1"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.first.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=0"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.prev.href").doesNotExist())
.andExpect(jsonPath("$.page.size", is(2))) .andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalPages", is(3))) .andExpect(jsonPath("$.page.totalPages", is(0)))
.andExpect(jsonPath("$.page.totalElements", is(5))); .andExpect(jsonPath("$.page.totalElements", is(0)));
getClient(authToken)
.perform(
get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID")
.param("size", "2").param("page", "1"))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2)))
.andExpect(jsonPath("$._embedded.qualityassuranceevents",
Matchers.containsInAnyOrder(
QAEventMatcher.matchQAEventEntry(event8),
QAEventMatcher.matchQAEventEntry(event9))))
.andExpect(jsonPath("$._links.self.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=1"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.next.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.first.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=0"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.prev.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=0"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalPages", is(3)))
.andExpect(jsonPath("$.page.totalElements", is(5)));
getClient(authToken)
.perform(
get("/api/integration/qualityassuranceevents/search/findByTopic")
.param("topic", QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID")
.param("size", "2").param("page", "2"))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1)))
.andExpect(jsonPath("$._embedded.qualityassuranceevents",
Matchers.containsInAnyOrder(
QAEventMatcher.matchQAEventEntry(event10))))
.andExpect(jsonPath("$._links.self.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.next.href").doesNotExist())
.andExpect(jsonPath("$._links.last.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=2"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.first.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=0"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.prev.href",
Matchers.allOf(
Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"),
Matchers.containsString("topic=" + QAEvent.COAR_NOTIFY + ":ENRICH!MISSING!PID"),
Matchers.containsString("page=1"),
Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
.andExpect(jsonPath("$.page.totalPages", is(3)))
.andExpect(jsonPath("$.page.totalElements", is(5)));
} }
@Test @Test
@@ -597,16 +510,16 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
getClient() getClient()
@@ -622,16 +535,16 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password); String adminToken = getAuthToken(admin.getEmail(), password);
@@ -657,7 +570,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths")
.build(); .build();
QAEvent eventProjectBound = QAEventBuilder.createTarget(context, col1, "Science and Freedom with project") QAEvent eventProjectBound = QAEventBuilder.createTarget(context, col1, "Science and Freedom with project")
.withTopic("ENRICH/MISSING/PROJECT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT)
.withMessage( .withMessage(
"{\"projects[0].acronym\":\"PAThs\"," "{\"projects[0].acronym\":\"PAThs\","
+ "\"projects[0].code\":\"687567\"," + "\"projects[0].code\":\"687567\","
@@ -673,7 +586,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
QAEvent eventProjectNoBound = QAEventBuilder QAEvent eventProjectNoBound = QAEventBuilder
.createTarget(context, col1, "Science and Freedom with unrelated project") .createTarget(context, col1, "Science and Freedom with unrelated project")
.withTopic("ENRICH/MISSING/PROJECT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT)
.withMessage( .withMessage(
"{\"projects[0].acronym\":\"NEW\"," "{\"projects[0].acronym\":\"NEW\","
+ "\"projects[0].code\":\"123456\"," + "\"projects[0].code\":\"123456\","
@@ -684,24 +597,24 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
+ "\"projects[0].title\":\"A new project\"}") + "\"projects[0].title\":\"A new project\"}")
.build(); .build();
QAEvent eventMissingPID1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent eventMissingPID1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent eventMissingPID2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEvent eventMissingPID2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEvent eventMissingUnknownPID = QAEventBuilder.createTarget(context, col1, "Science and Freedom URN PID") QAEvent eventMissingUnknownPID = QAEventBuilder.createTarget(context, col1, "Science and Freedom URN PID")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage( .withMessage(
"{\"pids[0].type\":\"urn\",\"pids[0].value\":\"http://thesis2.sba.units.it/store/handle/item/12937\"}") "{\"pids[0].type\":\"urn\",\"pids[0].value\":\"http://thesis2.sba.units.it/store/handle/item/12937\"}")
.build(); .build();
QAEvent eventMorePID = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEvent eventMorePID = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144302\"}").build();
QAEvent eventAbstract = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEvent eventAbstract = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage("{\"abstracts[0]\": \"An abstract to add...\"}").build(); .withMessage("{\"abstracts[0]\": \"An abstract to add...\"}").build();
QAEvent eventAbstractToDiscard = QAEventBuilder.createTarget(context, col1, "Science and Freedom 7") QAEvent eventAbstractToDiscard = QAEventBuilder.createTarget(context, col1, "Science and Freedom 7")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage("{\"abstracts[0]\": \"Abstract to discard...\"}").build(); .withMessage("{\"abstracts[0]\": \"Abstract to discard...\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
// prepare the different patches for our decisions // prepare the different patches for our decisions
@@ -826,6 +739,91 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
.andExpect(jsonPath("$.totalEvents", is(0))); .andExpect(jsonPath("$.totalEvents", is(0)));
} }
@Test
public void recordDecisionNotifyTest() throws Exception {
context.turnOffAuthorisationSystem();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType project = EntityTypeBuilder.createEntityTypeBuilder(context, "Project").build();
RelationshipTypeBuilder.createRelationshipTypeBuilder(context, publication, project, "isProjectOfPublication",
"isPublicationOfProject", 0, null, 0,
null).withCopyToRight(true).build();
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withEntityType("Publication")
.withName("Collection 1").build();
Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection Fundings")
.withEntityType("Project").build();
Item item = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths")
.build();
NotifyServiceEntity notifyServiceEntity = NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name")
.withDescription("service description")
.withUrl("https://review-service.com/inbox/about/")
.withLdnUrl("https://review-service.com/inbox/")
.withScore(BigDecimal.valueOf(0.6d))
.build();
String href = "EC";
QAEvent eventMoreReview = QAEventBuilder.createTarget(context, col1, "Science and Freedom with project")
.withSource(COAR_NOTIFY_SOURCE)
.withTopic("ENRICH/MORE/REVIEW")
.withMessage(
"{"
+ "\"serviceName\":\"" + notifyServiceEntity.getName() + "\","
+ "\"serviceId\":\"" + notifyServiceEntity.getID() + "\","
+ "\"href\":\"" + href + "\","
+ "\"relationship\":\"H2020\""
+ "}")
.withRelatedItem(item.getID().toString())
.build();
QAEvent eventMoreEndorsement = QAEventBuilder.createTarget(context, col1, "Science and Freedom with project")
.withSource(COAR_NOTIFY_SOURCE)
.withTopic("ENRICH/MORE/ENDORSEMENT")
.withMessage(
"{"
+ "\"serviceName\":\"" + notifyServiceEntity.getName() + "\","
+ "\"serviceId\":\"" + notifyServiceEntity.getID() + "\","
+ "\"href\":\"" + href + "\","
+ "\"relationship\":\"H2020\""
+ "}")
.withRelatedItem(item.getID().toString())
.build();
context.restoreAuthSystemState();
List<Operation> acceptOp = new ArrayList<Operation>();
acceptOp.add(new ReplaceOperation("/status", QAEvent.ACCEPTED));
String patchAccept = getPatchContent(acceptOp);
String authToken = getAuthToken(admin.getEmail(), password);
eventMoreEndorsement.setStatus(QAEvent.ACCEPTED);
eventMoreReview.setStatus(QAEvent.ACCEPTED);
// MORE REVIEW
getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/" + eventMoreReview.getEventId())
.content(patchAccept)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$", QAEventMatcher.matchQAEventNotifyEntry(eventMoreReview)));
getClient(authToken).perform(get("/api/core/items/" + eventMoreReview.getTarget())
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$",
hasJsonPath("$.metadata",
MetadataMatcher.matchMetadata(AddReviewMetadataAction.getMetadata(), href))));
// MORE ENDORSEMENT
getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/"
+ eventMoreEndorsement.getEventId())
.content(patchAccept)
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$", QAEventMatcher.matchQAEventNotifyEntry(eventMoreEndorsement)));
getClient(authToken).perform(get("/api/core/items/" + eventMoreEndorsement.getTarget())
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$",
hasJsonPath("$.metadata",
MetadataMatcher.matchMetadata(AddEndorsedMetadataAction.getMetadata(), href))));
}
@Test @Test
public void setRelatedTest() throws Exception { public void setRelatedTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
@@ -834,7 +832,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection Fundings").build(); .withName("Collection Fundings").build();
QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5")
.withTopic("ENRICH/MISSING/PROJECT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT)
.withMessage( .withMessage(
"{\"projects[0].acronym\":\"PAThs\"," "{\"projects[0].acronym\":\"PAThs\","
+ "\"projects[0].code\":\"687567\"," + "\"projects[0].code\":\"687567\","
@@ -883,7 +881,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths")
.build(); .build();
QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5")
.withTopic("ENRICH/MISSING/PROJECT") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT)
.withMessage( .withMessage(
"{\"projects[0].acronym\":\"PAThs\"," "{\"projects[0].acronym\":\"PAThs\","
+ "\"projects[0].code\":\"687567\"," + "\"projects[0].code\":\"687567\","
@@ -926,7 +924,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection Fundings").build(); .withName("Collection Fundings").build();
QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths")
.build(); .build();
@@ -954,10 +952,10 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
@@ -1000,7 +998,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}")
.build(); .build();
@@ -1010,7 +1008,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId())) getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", matchQAEventEntry(event))); .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(event)));
List<QAEventProcessed> processedEvents = qaEventsDao.findAll(context); List<QAEventProcessed> processedEvents = qaEventsDao.findAll(context);
assertThat(processedEvents, empty()); assertThat(processedEvents, empty());
@@ -1042,10 +1040,12 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
QAEvent event = QAEvent event =
QAEventBuilder.createTarget(context, item) QAEventBuilder.createTarget(context, item)
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTrust(0.8) .withTrust(0.8)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}") .withMessage("{"
+ "\"href\": \"https://doi.org/10.3214/987654\","
+ "\"relationship\": \"some-rel\"}")
.build(); .build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
@@ -1069,9 +1069,9 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
QAEvent event = QAEvent event =
QAEventBuilder.createTarget(context, item) QAEventBuilder.createTarget(context, item)
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTrust(0.4) .withTrust(0.4)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}") .withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
.build(); .build();
@@ -1095,9 +1095,9 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
QAEvent event = QAEvent event =
QAEventBuilder.createTarget(context, item) QAEventBuilder.createTarget(context, item)
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTrust(0.3) .withTrust(0.3)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}") .withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
.build(); .build();
@@ -1121,9 +1121,9 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
QAEvent event = QAEvent event =
QAEventBuilder.createTarget(context, item) QAEventBuilder.createTarget(context, item)
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTrust(0.7) .withTrust(0.7)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}") .withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
.build(); .build();
@@ -1149,9 +1149,9 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
QAEvent event = QAEvent event =
QAEventBuilder.createTarget(context, item) QAEventBuilder.createTarget(context, item)
.withSource(COAR_NOTIFY) .withSource(COAR_NOTIFY_SOURCE)
.withTrust(0.8) .withTrust(0.8)
.withTopic("ENRICH/MORE/REVIEW") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW)
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}") .withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
.build(); .build();

View File

@@ -97,17 +97,16 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
matchQASourceEntry("test-source-2", 0)))) matchQASourceEntry("test-source-2", 0))))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(4))); .andExpect(jsonPath("$.page.totalElements", is(4)));
// check with our eperson submitter
authToken = getAuthToken(eperson.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancesources")) getClient(authToken).perform(get("/api/integration/qualityassurancesources"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancesources", contains( .andExpect(jsonPath("$._embedded.qualityassurancesources", contains(
matchQASourceEntry("coar-notify", 2), matchQASourceEntry("coar-notify", 3))))
matchQASourceEntry("openaire", 0),
matchQASourceEntry("test-source", 0),
matchQASourceEntry("test-source-2", 0))))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(4))); .andExpect(jsonPath("$.page.totalElements", is(1)));
} }
@Test @Test
@@ -130,16 +129,16 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/1", "Title 1");
createEvent("openaire", "TOPIC/OPENAIRE/2", "Title 2"); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/2", "Title 2");
createEvent("openaire", "TOPIC/OPENAIRE/2", "Title 3"); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/2", "Title 3");
createEvent("test-source", "TOPIC/TEST/1", "Title 4"); createEvent("test-source", "TOPIC/TEST/1", "Title 4");
createEvent("test-source", "TOPIC/TEST/1", "Title 5"); createEvent("test-source", "TOPIC/TEST/1", "Title 5");
createEvent("coar-notify", "TOPIC", "Title 7"); createEvent(QAEvent.COAR_NOTIFY_SOURCE, "TOPIC", "Title 7");
context.setCurrentUser(eperson); context.setCurrentUser(eperson);
createEvent("coar-notify", "TOPIC", "Title 8"); createEvent(QAEvent.COAR_NOTIFY_SOURCE, "TOPIC", "Title 8");
createEvent("coar-notify", "TOPIC", "Title 9"); createEvent(QAEvent.COAR_NOTIFY_SOURCE, "TOPIC", "Title 9");
context.setCurrentUser(null); context.setCurrentUser(null);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
@@ -172,8 +171,8 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
getClient(authToken).perform(get("/api/integration/qualityassurancesources/openaire")) getClient(authToken).perform(get("/api/integration/qualityassurancesources/openaire"))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
getClient(authToken).perform(get("/api/integration/qualityassurancesources/unknown-test-source")) getClient(authToken).perform(get("/api/integration/qualityassurancesources/unknown-test-source"))
.andExpect(status().isNotFound()); .andExpect(status().isForbidden());
// the eperson will see only 2 events in coar-notify as 1 is related ot an item was submitted by other // the eperson will see only 2 events in coar-notify as 1 is related to an item was submitted by other
getClient(authToken).perform(get("/api/integration/qualityassurancesources/coar-notify")) getClient(authToken).perform(get("/api/integration/qualityassurancesources/coar-notify"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
@@ -203,7 +202,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/1", "Title 1");
createEvent("test-source", "TOPIC/TEST/1", "Title 4"); createEvent("test-source", "TOPIC/TEST/1", "Title 4");
context.restoreAuthSystemState(); context.restoreAuthSystemState();
@@ -221,17 +220,17 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
Collection col = CollectionBuilder.createCollection(context, com).withName("Test collection").build(); Collection col = CollectionBuilder.createCollection(context, com).withName("Test collection").build();
Item target1 = ItemBuilder.createItem(context, col).withTitle("Test item1").build(); Item target1 = ItemBuilder.createItem(context, col).withTitle("Test item1").build();
Item target2 = ItemBuilder.createItem(context, col).withTitle("Test item2").build(); Item target2 = ItemBuilder.createItem(context, col).withTitle("Test item2").build();
createEvent("openaire", "TOPIC/OPENAIRE/1", target1); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/1", target1);
createEvent("openaire", "TOPIC/OPENAIRE/2", target1); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/2", target1);
createEvent("test-source", "TOPIC/TEST/1", target1); createEvent("test-source", "TOPIC/TEST/1", target1);
createEvent("test-source", "TOPIC/TEST/1", target2); createEvent("test-source", "TOPIC/TEST/1", target2);
context.setCurrentUser(eperson); context.setCurrentUser(eperson);
Item target3 = ItemBuilder.createItem(context, col).withTitle("Test item3").build(); Item target3 = ItemBuilder.createItem(context, col).withTitle("Test item3").build();
context.setCurrentUser(null); context.setCurrentUser(null);
createEvent("coar-notify", "TOPIC", target3); createEvent(QAEvent.COAR_NOTIFY_SOURCE, "TOPIC", target3);
createEvent("coar-notify", "TOPIC", target3); createEvent(QAEvent.COAR_NOTIFY_SOURCE, "TOPIC2", target3);
createEvent("coar-notify", "TOPIC", target2); createEvent(QAEvent.COAR_NOTIFY_SOURCE, "TOPIC", target2);
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
@@ -240,7 +239,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
target1.getID().toString())) target1.getID().toString()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancesources", .andExpect(jsonPath("$._embedded.qualityassurancesources",
contains(matchQASourceEntry("openaire:" + target1.getID().toString(), 2), contains(matchQASourceEntry(QAEvent.OPENAIRE_SOURCE + ":" + target1.getID().toString(), 2),
matchQASourceEntry("test-source:" + target1.getID().toString(), 1)))) matchQASourceEntry("test-source:" + target1.getID().toString(), 1))))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(2))); .andExpect(jsonPath("$.page.totalElements", is(2)));
@@ -251,7 +250,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancesources", .andExpect(jsonPath("$._embedded.qualityassurancesources",
contains( contains(
matchQASourceEntry("coar-notify:" + target2.getID().toString(), 1), matchQASourceEntry(QAEvent.COAR_NOTIFY_SOURCE + ":" + target2.getID().toString(), 1),
matchQASourceEntry("test-source:" + target2.getID().toString(), 1)))) matchQASourceEntry("test-source:" + target2.getID().toString(), 1))))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(2))); .andExpect(jsonPath("$.page.totalElements", is(2)));
@@ -260,7 +259,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
target3.getID().toString())) target3.getID().toString()))
.andExpect(status().isOk()).andExpect(content().contentType(contentType)) .andExpect(status().isOk()).andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancesources", .andExpect(jsonPath("$._embedded.qualityassurancesources",
contains(matchQASourceEntry("coar-notify:" + target3.getID().toString(), 2)))) contains(matchQASourceEntry("coar-notify:" + target3.getID().toString(), 2))))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.totalElements", is(1)));
@@ -277,7 +276,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
target2.getID().toString())) target2.getID().toString()))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(0))); .andExpect(jsonPath("$.page.totalElements", is(1)));
getClient(authToken) getClient(authToken)
.perform(get("/api/integration/qualityassurancesources/search/byTarget").param("target", .perform(get("/api/integration/qualityassurancesources/search/byTarget").param("target",
target3.getID().toString())) target3.getID().toString()))
@@ -296,8 +295,8 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
Collection col = CollectionBuilder.createCollection(context, com).withName("Test collection").build(); Collection col = CollectionBuilder.createCollection(context, com).withName("Test collection").build();
Item target1 = ItemBuilder.createItem(context, col).withTitle("Test item1").build(); Item target1 = ItemBuilder.createItem(context, col).withTitle("Test item1").build();
Item target2 = ItemBuilder.createItem(context, col).withTitle("Test item2").build(); Item target2 = ItemBuilder.createItem(context, col).withTitle("Test item2").build();
createEvent("openaire", "TOPIC/OPENAIRE/1", target1); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/1", target1);
createEvent("openaire", "TOPIC/OPENAIRE/2", target1); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/2", target1);
createEvent("test-source", "TOPIC/TEST/1", target1); createEvent("test-source", "TOPIC/TEST/1", target1);
createEvent("test-source", "TOPIC/TEST/1", target2); createEvent("test-source", "TOPIC/TEST/1", target2);
@@ -318,8 +317,8 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest
Collection col = CollectionBuilder.createCollection(context, com).withName("Test collection").build(); Collection col = CollectionBuilder.createCollection(context, com).withName("Test collection").build();
Item target1 = ItemBuilder.createItem(context, col).withTitle("Test item1").build(); Item target1 = ItemBuilder.createItem(context, col).withTitle("Test item1").build();
Item target2 = ItemBuilder.createItem(context, col).withTitle("Test item2").build(); Item target2 = ItemBuilder.createItem(context, col).withTitle("Test item2").build();
createEvent("openaire", "TOPIC/OPENAIRE/1", target1); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/1", target1);
createEvent("openaire", "TOPIC/OPENAIRE/2", target1); createEvent(QAEvent.OPENAIRE_SOURCE, "TOPIC/OPENAIRE/2", target1);
createEvent("test-source", "TOPIC/TEST/1", target1); createEvent("test-source", "TOPIC/TEST/1", target1);
createEvent("test-source", "TOPIC/TEST/1", target2); createEvent("test-source", "TOPIC/TEST/1", target2);

View File

@@ -25,6 +25,7 @@ import org.dspace.builder.QAEventBuilder;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.QAEvent; import org.dspace.content.QAEvent;
import org.dspace.qaevent.QANotifyPatterns;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Test; import org.junit.Test;
@@ -49,16 +50,16 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage( .withMessage(
"{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}")
.build(); .build();
@@ -78,16 +79,16 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage( .withMessage(
"{\"test\": \"Test...\"}") "{\"test\": \"Test...\"}")
.build(); .build();
@@ -101,13 +102,16 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!PID")) getClient(authToken).perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!PID"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2))); .andExpect(jsonPath("$",
QATopicMatcher.matchQATopicEntry(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID, 2)));
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!ABSTRACT")) getClient(authToken).perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!ABSTRACT"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1))); .andExpect(jsonPath("$",
QATopicMatcher.matchQATopicEntry(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1)));
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/test-source:TOPIC!TEST")) getClient(authToken).perform(get("/api/integration/qualityassurancetopics/test-source:TOPIC!TEST"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("test-source", "TOPIC/TEST", 1))); .andExpect(jsonPath("$",
QATopicMatcher.matchQATopicEntry("test-source", "TOPIC/TEST", 1)));
} }
@Test @Test
@@ -120,7 +124,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
@@ -144,7 +148,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
getClient().perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!PID")) getClient().perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!PID"))
.andExpect(status().isUnauthorized()); .andExpect(status().isUnauthorized());
@@ -160,7 +164,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(eperson.getEmail(), password); String authToken = getAuthToken(eperson.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!PID")) getClient(authToken).perform(get("/api/integration/qualityassurancetopics/openaire:ENRICH!MISSING!PID"))
@@ -179,16 +183,16 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage( .withMessage(
"{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}")
.build(); .build();
@@ -211,9 +215,10 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancetopics", .andExpect(jsonPath("$._embedded.qualityassurancetopics",
Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2), Matchers.containsInAnyOrder(
QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1), QATopicMatcher.matchQATopicEntry(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID, 2),
QATopicMatcher.matchQATopicEntry("ENRICH/MORE/PID", 1)))) QATopicMatcher.matchQATopicEntry(QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT, 1),
QATopicMatcher.matchQATopicEntry(QANotifyPatterns.TOPIC_ENRICH_MORE_PID, 1))))
.andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3))); .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3)));
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource")
.param("source", "test-source")) .param("source", "test-source"))
@@ -242,16 +247,16 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
//create collection //create collection
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") QAEventBuilder.createTarget(context, col1, "Science and Freedom 2")
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") QAEventBuilder.createTarget(context, col1, "Science and Freedom 3")
.withTopic("ENRICH/MORE/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MORE_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") QAEventBuilder.createTarget(context, col1, "Science and Freedom 4")
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage( .withMessage(
"{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}")
.build(); .build();
@@ -301,7 +306,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
getClient().perform(get("/api/integration/qualityassurancetopics/search/bySource") getClient().perform(get("/api/integration/qualityassurancetopics/search/bySource")
.param("source", "openaire")) .param("source", "openaire"))
@@ -316,7 +321,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.build(); .build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
QAEventBuilder.createTarget(context, col1, "Science and Freedom") QAEventBuilder.createTarget(context, col1, "Science and Freedom")
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(eperson.getEmail(), password); String authToken = getAuthToken(eperson.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource")
@@ -337,12 +342,12 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build(); Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build();
Item item2 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom 2").build(); Item item2 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom 2").build();
QAEventBuilder.createTarget(context, item1) QAEventBuilder.createTarget(context, item1)
.withSource("openaire") .withSource(QAEvent.OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build();
QAEventBuilder.createTarget(context, item1) QAEventBuilder.createTarget(context, item1)
.withSource("openaire") .withSource(QAEvent.OPENAIRE_SOURCE)
.withTopic("ENRICH/MISSING/ABSTRACT") .withTopic(org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT)
.withMessage( .withMessage(
"{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}")
.build(); .build();
@@ -355,24 +360,26 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.withSource("test-source") .withSource("test-source")
.build(); .build();
QAEventBuilder.createTarget(context, item2) QAEventBuilder.createTarget(context, item2)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build();
QAEventBuilder.createTarget(context, item2) QAEventBuilder.createTarget(context, item2)
.withTopic("ENRICH/MISSING/PID") .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID)
.withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144301\"}").build(); .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144301\"}").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(admin.getEmail(), password); String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget")
.param("target", item1.getID().toString()) .param("target", item1.getID().toString())
.param("source", "openaire")) .param("source", QAEvent.OPENAIRE_SOURCE))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancetopics", .andExpect(jsonPath("$._embedded.qualityassurancetopics",
Matchers.containsInAnyOrder( Matchers.containsInAnyOrder(
QATopicMatcher.matchQATopicEntry("openaire", "ENRICH/MISSING/PID", QATopicMatcher.matchQATopicEntry(QAEvent.OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MISSING_PID,
item1.getID().toString(), 1), item1.getID().toString(), 1),
QATopicMatcher.matchQATopicEntry("openaire", "ENRICH/MISSING/ABSTRACT", QATopicMatcher.matchQATopicEntry(QAEvent.OPENAIRE_SOURCE,
item1.getID().toString(), 1)))) QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT,
item1.getID().toString(), 1))))
.andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2)));
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget")
.param("target", item2.getID().toString()) .param("target", item2.getID().toString())
@@ -381,12 +388,13 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancetopics", .andExpect(jsonPath("$._embedded.qualityassurancetopics",
Matchers.containsInAnyOrder( Matchers.containsInAnyOrder(
QATopicMatcher.matchQATopicEntry("openaire", "ENRICH/MISSING/PID", QATopicMatcher.matchQATopicEntry(QAEvent.OPENAIRE_SOURCE,
QANotifyPatterns.TOPIC_ENRICH_MISSING_PID,
item2.getID().toString(), 2)))) item2.getID().toString(), 2))))
.andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1)));
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget")
.param("target", UUID.randomUUID().toString()) .param("target", UUID.randomUUID().toString())
.param("source", "openaire")) .param("source", QAEvent.OPENAIRE_SOURCE))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.qualityassurancetopics").doesNotExist()) .andExpect(jsonPath("$._embedded.qualityassurancetopics").doesNotExist())
@@ -410,10 +418,10 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build(); Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build();
QAEventBuilder.createTarget(context, item1) QAEventBuilder.createTarget(context, item1)
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
getClient().perform(get("/api/integration/qualityassurancetopics/search/byTarget") getClient().perform(get("/api/integration/qualityassurancetopics/search/byTarget")
.param("source", "openaire") .param("source", QAEvent.OPENAIRE_SOURCE)
.param("target", item1.getID().toString())) .param("target", item1.getID().toString()))
.andExpect(status().isUnauthorized()); .andExpect(status().isUnauthorized());
} }
@@ -427,7 +435,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build(); Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build();
QAEventBuilder.createTarget(context, item1) QAEventBuilder.createTarget(context, item1)
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(eperson.getEmail(), password); String authToken = getAuthToken(eperson.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget")
@@ -446,7 +454,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest {
Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build(); Item item1 = ItemBuilder.createItem(context, col1).withTitle("Science and Freedom").build();
QAEventBuilder.createTarget(context, item1) QAEventBuilder.createTarget(context, item1)
.withSource("test-source") .withSource("test-source")
.withTopic("ENRICH/MISSING/PID").build(); .withTopic(QANotifyPatterns.TOPIC_ENRICH_MISSING_PID).build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
String authToken = getAuthToken(eperson.getEmail(), password); String authToken = getAuthToken(eperson.getEmail(), password);
getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget") getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/byTarget")

View File

@@ -18,12 +18,16 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper; import com.fasterxml.jackson.databind.json.JsonMapper;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.hateoas.QAEventResource;
import org.dspace.content.QAEvent; import org.dspace.content.QAEvent;
import org.dspace.qaevent.service.dto.NotifyMessageDTO;
import org.dspace.qaevent.service.dto.OpenaireMessageDTO; import org.dspace.qaevent.service.dto.OpenaireMessageDTO;
import org.dspace.qaevent.service.dto.QAMessageDTO;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.hamcrest.core.IsAnything; import org.hamcrest.core.IsAnything;
/** /**
* Matcher related to {@link QAEventResource}. * Matcher related to {@link QAEventResource}.
* *
@@ -66,23 +70,63 @@ public class QAEventMatcher {
} }
} }
private static Matcher<? super Object> matchMessage(String topic, OpenaireMessageDTO message) {
if (StringUtils.endsWith(topic, "/ABSTRACT")) { public static Matcher<? super Object> matchQAEventNotifyEntry(QAEvent event) {
return allOf(hasJsonPath("$.abstract", is(message.getAbstracts()))); try {
} else if (StringUtils.endsWith(topic, "/PID")) { ObjectMapper jsonMapper = new JsonMapper();
return allOf( return allOf(hasJsonPath("$.id", is(event.getEventId())),
hasJsonPath("$.value", is(message.getValue())), hasJsonPath("$.originalId", is(event.getOriginalId())),
hasJsonPath("$.type", is(message.getType())), hasJsonPath("$.title", is(event.getTitle())),
hasJsonPath("$.pidHref", is(calculateOpenairePidHref(message.getType(), message.getValue())))); hasJsonPath("$.trust", is(new DecimalFormat("0.000").format(event.getTrust()))),
} else if (StringUtils.endsWith(topic, "/PROJECT")) { hasJsonPath("$.status", Matchers.equalToIgnoringCase(event.getStatus())),
return allOf( hasJsonPath("$.message",
hasJsonPath("$.openaireId", is(message.getOpenaireId())), matchMessage(event.getTopic(), jsonMapper.readValue(event.getMessage(),
hasJsonPath("$.acronym", is(message.getAcronym())), NotifyMessageDTO.class))),
hasJsonPath("$.code", is(message.getCode())), hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")),
hasJsonPath("$.funder", is(message.getFunder())), hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")),
hasJsonPath("$.fundingProgram", is(message.getFundingProgram())), hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")),
hasJsonPath("$.jurisdiction", is(message.getJurisdiction())), hasJsonPath("$.type", is("qualityassuranceevent")));
hasJsonPath("$.title", is(message.getTitle()))); } catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
private static Matcher<? super Object> matchMessage(String topic, QAMessageDTO message) {
if (message instanceof OpenaireMessageDTO) {
OpenaireMessageDTO oadto = (OpenaireMessageDTO) message;
if (StringUtils.endsWith(topic, "/ABSTRACT")) {
return allOf(hasJsonPath("$.abstract", is(oadto.getAbstracts())));
} else if (StringUtils.endsWith(topic, "/PID")) {
return allOf(
hasJsonPath("$.value", is(oadto.getValue())),
hasJsonPath("$.type", is(oadto.getType())),
hasJsonPath("$.pidHref", is(calculateOpenairePidHref(oadto.getType(), oadto.getValue()))));
} else if (StringUtils.endsWith(topic, "/PROJECT")) {
return allOf(
hasJsonPath("$.openaireId", is(oadto.getOpenaireId())),
hasJsonPath("$.acronym", is(oadto.getAcronym())),
hasJsonPath("$.code", is(oadto.getCode())),
hasJsonPath("$.funder", is(oadto.getFunder())),
hasJsonPath("$.fundingProgram", is(oadto.getFundingProgram())),
hasJsonPath("$.jurisdiction", is(oadto.getJurisdiction())),
hasJsonPath("$.title", is(oadto.getTitle())));
}
} else if (message instanceof NotifyMessageDTO) {
NotifyMessageDTO notifyDTO = (NotifyMessageDTO) message;
if (StringUtils.endsWith(topic, "/REVIEW")) {
return allOf(
hasJsonPath("$.serviceName", is(notifyDTO.getServiceName())),
hasJsonPath("$.serviceId", is(notifyDTO.getServiceId())),
hasJsonPath("$.href", is(notifyDTO.getHref())),
hasJsonPath("$.relationship", is(notifyDTO.getRelationship()))
);
} else if (StringUtils.endsWith(topic, "/ENDORSEMENT")) {
return allOf(
hasJsonPath("$.serviceName", is(notifyDTO.getServiceName())),
hasJsonPath("$.serviceId", is(notifyDTO.getServiceId())),
hasJsonPath("$.href", is(notifyDTO.getHref())),
hasJsonPath("$.relationship", is(notifyDTO.getRelationship()))
);
}
} }
return IsAnything.anything(); return IsAnything.anything();
} }

View File

@@ -9,7 +9,7 @@
"type": ["Service"] "type": ["Service"]
}, },
"context": { "context": {
"id": "https://research-organisation.org/repository/preprint/201203/421/", "id": "<<object>>",
"ietf:cite-as": "https://doi.org/10.5555/12345680", "ietf:cite-as": "https://doi.org/10.5555/12345680",
"type": ["sorg:AboutPage"], "type": ["sorg:AboutPage"],
"url": { "url": {
@@ -24,7 +24,9 @@
"id": "urn:uuid:94ecae35-dcfd-4182-8550-22c7164fe23f", "id": "urn:uuid:94ecae35-dcfd-4182-8550-22c7164fe23f",
"inReplyTo": "urn:uuid:0370c0fb-bb78-4a9b-87f5-bed307a509dd", "inReplyTo": "urn:uuid:0370c0fb-bb78-4a9b-87f5-bed307a509dd",
"object": { "object": {
"id": "<<object>>", "id": "<<object_handle>>",
"id_oai": "oai:www.openstarts.units.it:<<object_handle>>",
"id_old": "https://review-service.com/review/geo/202103/0021",
"ietf:cite-as": "https://overlay-journal.com/articles/00001/", "ietf:cite-as": "https://overlay-journal.com/articles/00001/",
"type": [ "type": [
"Page", "Page",

View File

@@ -9,8 +9,8 @@
"type": "Service" "type": "Service"
}, },
"context": { "context": {
"id": "http://localhost:4000/handle/123456789/9999", "id": "<<object>>",
"ietf:cite-as": "https://doi.org/10.5555/12345680", "ietf:cite-as": "https://doi.org/10.5555/12345680",
"type": "sorg:AboutPage", "type": "sorg:AboutPage",
"url": { "url": {
"id": "https://research-organisation.org/repository/preprint/201203/421/content.pdf", "id": "https://research-organisation.org/repository/preprint/201203/421/content.pdf",
@@ -24,7 +24,7 @@
"id": "urn:uuid:2f4ec582-109e-4952-a94a-b7d7615a8c69", "id": "urn:uuid:2f4ec582-109e-4952-a94a-b7d7615a8c69",
"inReplyTo": "urn:uuid:0370c0fb-bb78-4a9b-87f5-bed307a509dd", "inReplyTo": "urn:uuid:0370c0fb-bb78-4a9b-87f5-bed307a509dd",
"object": { "object": {
"id": "https://review-service.com/review/geo/202103/0021", "id": "<<object_handle>>",
"ietf:cite-as": "https://doi.org/10.3214/987654", "ietf:cite-as": "https://doi.org/10.3214/987654",
"type": [ "type": [
"Document", "Document",

View File

@@ -934,6 +934,7 @@ registry.metadata.load = dspace-types.xml
registry.metadata.load = iiif-types.xml registry.metadata.load = iiif-types.xml
registry.metadata.load = datacite-types.xml registry.metadata.load = datacite-types.xml
registry.metadata.load = coar-types.xml registry.metadata.load = coar-types.xml
registry.metadata.load = notify-types.xml
#---------------------------------------------------------------# #---------------------------------------------------------------#

View File

@@ -26,3 +26,8 @@ ldn.processor.max.attempts = 5
# of the message. LDN Message with a future queue_timeout is not elaborated. This property is used to calculateas: # of the message. LDN Message with a future queue_timeout is not elaborated. This property is used to calculateas:
# a new timeout, such as: new_timeout = now + ldn.processor.queue.msg.timeout (in minutes) # a new timeout, such as: new_timeout = now + ldn.processor.queue.msg.timeout (in minutes)
ldn.processor.queue.msg.timeout = 60 ldn.processor.queue.msg.timeout = 60
# EMAIL CONFIGURATION
ldn.notification.email = ${mail.admin}

View File

@@ -23,6 +23,8 @@ qaevents.openaire.import.topic = ENRICH/MORE/PROJECT
qaevents.openaire.import.topic = ENRICH/MORE/REVIEW qaevents.openaire.import.topic = ENRICH/MORE/REVIEW
# add more endorsement # add more endorsement
qaevents.openaire.import.topic = ENRICH/MORE/ENDORSEMENT qaevents.openaire.import.topic = ENRICH/MORE/ENDORSEMENT
# add more release/relationship
qaevents.openaire.import.topic = ENRICH/MORE/LINK
# The list of the supported pid href for the OPENAIRE events # The list of the supported pid href for the OPENAIRE events
qaevents.openaire.pid-href-prefix.arxiv = https://arxiv.org/abs/ qaevents.openaire.pid-href-prefix.arxiv = https://arxiv.org/abs/

View File

@@ -38,13 +38,20 @@
<element>relation</element> <element>relation</element>
<qualifier>isReviewedBy</qualifier> <qualifier>isReviewedBy</qualifier>
<scope_note>Reviewd by</scope_note> <scope_note>Reviewd by</scope_note>
</dc-type> </dc-type>
<dc-type> <dc-type>
<schema>datacite</schema> <schema>datacite</schema>
<element>relation</element> <element>relation</element>
<qualifier>isSupplementedBy</qualifier> <qualifier>isReferencedBy</qualifier>
<scope_note>Supplemented by</scope_note> <scope_note>Referenced by</scope_note>
</dc-type> </dc-type>
<dc-type>
<schema>datacite</schema>
<element>relation</element>
<qualifier>isSupplementedBy</qualifier>
<scope_note>Supplemented by</scope_note>
</dc-type>
</dspace-dc-types> </dspace-dc-types>

View File

@@ -56,9 +56,6 @@
<bean id="orcidServiceFactory" class="org.dspace.orcid.factory.OrcidServiceFactoryImpl"/> <bean id="orcidServiceFactory" class="org.dspace.orcid.factory.OrcidServiceFactoryImpl"/>
<bean id="supervisionOrderServiceFactory" class="org.dspace.supervision.factory.SupervisionOrderServiceFactoryImpl"/> <bean id="supervisionOrderServiceFactory" class="org.dspace.supervision.factory.SupervisionOrderServiceFactoryImpl"/>
<!-- LDN COAR Notify services -->
<bean id="ldnBusinessDelegateFactory" class="org.dspace.app.ldn.factory.LDNBusinessDelegateFactoryImpl"/>
<bean id="notifyServiceFactory" class="org.dspace.app.ldn.factory.NotifyServiceFactoryImpl"/> <bean id="notifyServiceFactory" class="org.dspace.app.ldn.factory.NotifyServiceFactoryImpl"/>

View File

@@ -22,7 +22,6 @@
<bean class="org.dspace.app.ldn.service.impl.NotifyServiceOutboundPatternServiceImpl"/> <bean class="org.dspace.app.ldn.service.impl.NotifyServiceOutboundPatternServiceImpl"/>
<bean class="org.dspace.app.ldn.service.impl.LDNMessageServiceImpl"/> <bean class="org.dspace.app.ldn.service.impl.LDNMessageServiceImpl"/>
<bean class="org.dspace.app.ldn.service.impl.NotifyPatternToTriggerImpl"/> <bean class="org.dspace.app.ldn.service.impl.NotifyPatternToTriggerImpl"/>
<bean class="org.dspace.app.ldn.LDNBusinessDelegate"></bean>
<bean name="ldnRouter" class="org.dspace.app.ldn.LDNRouter"> <bean name="ldnRouter" class="org.dspace.app.ldn.LDNRouter">
<property name="incomingProcessors"> <property name="incomingProcessors">
@@ -52,7 +51,7 @@
<value>coar-notify:ReviewAction</value> <value>coar-notify:ReviewAction</value>
</set> </set>
</key> </key>
<ref bean="acceptReviewAction" /> <ref bean="acceptAckAction" />
</entry> </entry>
<entry> <entry>
<key> <key>
@@ -61,13 +60,49 @@
<value>coar-notify:ReviewAction</value> <value>coar-notify:ReviewAction</value>
</set> </set>
</key> </key>
<ref bean="rejectReviewAction" /> <ref bean="rejectAckAction" />
</entry>
<entry>
<key>
<set>
<value>Accept</value>
<value>coar-notify:EndorsementAction</value>
</set>
</key>
<ref bean="acceptAckAction" />
</entry>
<entry>
<key>
<set>
<value>Reject</value>
<value>coar-notify:EndorsementAction</value>
</set>
</key>
<ref bean="rejectAckAction" />
</entry>
<entry>
<key>
<set>
<value>Accept</value>
<value>coar-notify:IngestAction</value>
</set>
</key>
<ref bean="acceptAckAction" />
</entry>
<entry>
<key>
<set>
<value>Reject</value>
<value>coar-notify:IngestAction</value>
</set>
</key>
<ref bean="rejectAckAction" />
</entry> </entry>
<entry> <entry>
<key> <key>
<set> <set>
<value>Announce</value> <value>Announce</value>
<value>coar-notify:ReleaseAction</value> <value>coar-notify:RelationshipAction</value>
</set> </set>
</key> </key>
<ref bean="announceReleaseAction" /> <ref bean="announceReleaseAction" />
@@ -108,33 +143,10 @@
</bean> </bean>
<bean name="announceReviewAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor"> <bean name="announceReviewAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor">
<property name="changes">
<list value-type="org.dspace.app.ldn.processor.LDNMetadataChange">
<bean class="org.dspace.app.ldn.processor.LDNMetadataRemove">
<property name="qualifiers">
<list value-type="java.lang.String">
<value>requestreview</value>
<value>examination</value>
<value>refused</value>
</list>
</property>
<property name="valueTemplates">
<list value-type="java.lang.String">
<value>$LDNUtils.removedProtocol($notification.origin.id)</value>
<value>$notification.inReplyTo</value>
</list>
</property>
</bean>
<bean class="org.dspace.app.ldn.processor.LDNMetadataAdd">
<property name="qualifier" value="review" />
<property name="valueTemplate" value="$timestamp||$LDNUtils.removedProtocol($notification.origin.id)||$notification.inReplyTo||$notification.object.id" />
</bean>
</list>
</property>
<property name="actions"> <property name="actions">
<list value-type="org.dspace.app.ldn.action.LDNAction"> <list value-type="org.dspace.app.ldn.action.LDNAction">
<bean class="org.dspace.app.ldn.action.LDNEmailAction"> <bean class="org.dspace.app.ldn.action.LDNEmailAction">
<property name="actionSendFilter" value="william_welling@harvard.edu" /> <property name="actionSendFilter" value="${ldn.notification.email}" />
<property name="actionSendEmailTextFile" value="coar_notify_reviewed" /> <property name="actionSendEmailTextFile" value="coar_notify_reviewed" />
</bean> </bean>
<bean class="org.dspace.app.ldn.action.LDNCorrectionAction"> <bean class="org.dspace.app.ldn.action.LDNCorrectionAction">
@@ -145,33 +157,10 @@
</bean> </bean>
<bean name="announceEndorsementAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor"> <bean name="announceEndorsementAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor">
<property name="changes">
<list value-type="org.dspace.app.ldn.processor.LDNMetadataChange">
<bean class="org.dspace.app.ldn.processor.LDNMetadataRemove">
<property name="qualifiers">
<list value-type="java.lang.String">
<value>requestendorsement</value>
<value>examination</value>
<value>refused</value>
</list>
</property>
<property name="valueTemplates">
<list value-type="java.lang.String">
<value>$LDNUtils.removedProtocol($notification.origin.id)</value>
<value>$notification.inReplyTo</value>
</list>
</property>
</bean>
<bean class="org.dspace.app.ldn.processor.LDNMetadataAdd">
<property name="qualifier" value="endorsement" />
<property name="valueTemplate" value="$timestamp||$LDNUtils.removedProtocol($notification.origin.id)||$notification.inReplyTo||$notification.object.id" />
</bean>
</list>
</property>
<property name="actions"> <property name="actions">
<list value-type="org.dspace.app.ldn.action.LDNAction"> <list value-type="org.dspace.app.ldn.action.LDNAction">
<bean class="org.dspace.app.ldn.action.LDNEmailAction"> <bean class="org.dspace.app.ldn.action.LDNEmailAction">
<property name="actionSendFilter" value="william_welling@harvard.edu" /> <property name="actionSendFilter" value="${ldn.notification.email}" />
<property name="actionSendEmailTextFile" value="coar_notify_endorsed" /> <property name="actionSendEmailTextFile" value="coar_notify_endorsed" />
</bean> </bean>
<bean class="org.dspace.app.ldn.action.LDNCorrectionAction"> <bean class="org.dspace.app.ldn.action.LDNCorrectionAction">
@@ -181,82 +170,22 @@
</property> </property>
</bean> </bean>
<bean name="acceptReviewAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor"> <bean name="acceptAckAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor">
<property name="changes">
<list value-type="org.dspace.app.ldn.processor.LDNMetadataChange">
<bean class="org.dspace.app.ldn.processor.LDNMetadataRemove">
<property name="qualifiers">
<list value-type="java.lang.String">
<value>requestreview</value>
<value>refused</value>
</list>
</property>
<property name="valueTemplates">
<list value-type="java.lang.String">
<value>$LDNUtils.removedProtocol($notification.origin.id)</value>
</list>
</property>
</bean>
<bean class="org.dspace.app.ldn.processor.LDNMetadataRemove">
<property name="conditionTemplate" value="$StringUtils.isNotEmpty($notification.inReplyTo)" />
<property name="qualifiers">
<list value-type="java.lang.String">
<value>refused</value>
</list>
</property>
<property name="valueTemplates">
<list value-type="java.lang.String">
<value>$LDNUtils.removedProtocol($notification.origin.id)</value>
<value>$notification.inReplyTo</value>
</list>
</property>
</bean>
<bean class="org.dspace.app.ldn.processor.LDNMetadataAdd">
<property name="conditionTemplate" value="$StringUtils.isNotEmpty($notification.inReplyTo)" />
<property name="qualifier" value="examination" />
<property name="valueTemplate" value="$timestamp||$LDNUtils.removedProtocol($notification.origin.id)||$notification.inReplyTo" />
</bean>
</list>
</property>
<property name="actions"> <property name="actions">
<list value-type="org.dspace.app.ldn.action.LDNAction"> <list value-type="org.dspace.app.ldn.action.LDNAction">
<bean class="org.dspace.app.ldn.action.LDNEmailAction"> <bean class="org.dspace.app.ldn.action.LDNEmailAction">
<property name="actionSendFilter" value="william_welling@harvard.edu" /> <property name="actionSendFilter" value="${ldn.notification.email}" />
<property name="actionSendEmailTextFile" value="coar_notify_accepted" /> <property name="actionSendEmailTextFile" value="coar_notify_accepted" />
</bean> </bean>
</list> </list>
</property> </property>
</bean> </bean>
<bean name="rejectReviewAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor"> <bean name="rejectAckAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor">
<property name="changes">
<list value-type="org.dspace.app.ldn.processor.LDNMetadataChange">
<bean class="org.dspace.app.ldn.processor.LDNMetadataRemove">
<property name="conditionTemplate" value="$StringUtils.isNotEmpty($notification.inReplyTo)" />
<property name="qualifiers">
<list value-type="java.lang.String">
<value>examination</value>
<value>requestreview</value>
<value>requestendorsement</value>
</list>
</property>
<property name="valueTemplates">
<list value-type="java.lang.String">
<value>$LDNUtils.removedProtocol($notification.origin.id)</value>
<value>$notification.inReplyTo</value>
</list>
</property>
</bean>
<bean class="org.dspace.app.ldn.processor.LDNMetadataAdd">
<property name="qualifier" value="refused" />
<property name="valueTemplate" value="$timestamp||$LDNUtils.removedProtocol($notification.origin.id)||$notification.inReplyTo" />
</bean>
</list>
</property>
<property name="actions"> <property name="actions">
<list value-type="org.dspace.app.ldn.action.LDNAction"> <list value-type="org.dspace.app.ldn.action.LDNAction">
<bean class="org.dspace.app.ldn.action.LDNEmailAction"> <bean class="org.dspace.app.ldn.action.LDNEmailAction">
<property name="actionSendFilter" value="william_welling@harvard.edu" /> <property name="actionSendFilter" value="${ldn.notification.email}" />
<property name="actionSendEmailTextFile" value="coar_notify_rejected" /> <property name="actionSendEmailTextFile" value="coar_notify_rejected" />
</bean> </bean>
</list> </list>
@@ -264,37 +193,14 @@
</bean> </bean>
<bean name="announceReleaseAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor"> <bean name="announceReleaseAction" class="org.dspace.app.ldn.processor.LDNMetadataProcessor">
<property name="repeater">
<bean class="org.dspace.app.ldn.processor.LDNContextRepeater">
<property name="repeatOver" value="IsSupplementTo" />
</bean>
</property>
<property name="changes">
<list value-type="org.dspace.app.ldn.processor.LDNMetadataChange">
<bean class="org.dspace.app.ldn.processor.LDNMetadataRemove">
<property name="qualifiers">
<list value-type="java.lang.String">
<value>release</value>
</list>
</property>
<property name="valueTemplates">
<list value-type="java.lang.String">
<value>$notification.object.ietfCiteAs</value>
<value>$LDNUtils.removedProtocol($notification.object.id)</value>
</list>
</property>
</bean>
<bean class="org.dspace.app.ldn.processor.LDNMetadataAdd">
<property name="qualifier" value="release" />
<property name="valueTemplate" value="$timestamp||$notification.object.ietfCiteAs||$LDNUtils.removedProtocol($notification.object.id)" />
</bean>
</list>
</property>
<property name="actions"> <property name="actions">
<list value-type="org.dspace.app.ldn.action.LDNAction"> <list value-type="org.dspace.app.ldn.action.LDNAction">
<bean class="org.dspace.app.ldn.action.LDNEmailAction"> <bean class="org.dspace.app.ldn.action.LDNEmailAction">
<property name="actionSendFilter" value="william_welling@harvard.edu" /> <property name="actionSendFilter" value="${ldn.notification.email}" />
<property name="actionSendEmailTextFile" value="coar_notify_released" /> <property name="actionSendEmailTextFile" value="coar_notify_relationship" />
</bean>
<bean class="org.dspace.app.ldn.action.LDNCorrectionAction">
<property name="qaEventTopic" value="ENRICH/MORE/LINK"/>
</bean> </bean>
</list> </list>
</property> </property>

View File

@@ -23,13 +23,27 @@
<map> <map>
<!--The key are the TOPIC, the value must be a valid implementation of the <!--The key are the TOPIC, the value must be a valid implementation of the
org.dspace.qaevent.QAEventAction interface --> org.dspace.qaevent.QAEventAction interface -->
<entry key="ENRICH/MORE/PROJECT" value-ref="ProjectLinkedEntityAction" /> <entry value-ref="ProjectLinkedEntityAction">
<entry key="ENRICH/MISSING/PROJECT" value-ref="ProjectLinkedEntityAction" /> <key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MORE_PROJECT"/></key>
<entry key="ENRICH/MISSING/ABSTRACT" value-ref="AbstractMetadataAction" /> </entry>
<entry key="ENRICH/MORE/REVIEW" value-ref="AddReviewMetadataAction" /> <entry value-ref="ProjectLinkedEntityAction">
<entry key="ENRICH/MORE/ENDORSEMENT" value-ref="AddEndorsedMetadataAction"/> <key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_PROJECT"/></key>
<entry key="ENRICH/MORE/PID" value-ref="PIDMetadataAction" /> </entry>
<entry key="ENRICH/MISSING/PID" value-ref="PIDMetadataAction" /> <entry value-ref="AbstractMetadataAction">
<key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_ABSTRACT"/></key>
</entry>
<entry value-ref="AddReviewMetadataAction">
<key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MORE_REVIEW"/></key>
</entry>
<entry value-ref="AddEndorsedMetadataAction">
<key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MORE_ENDORSEMENT"/></key>
</entry>
<entry value-ref="PIDMetadataAction">
<key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MORE_PID"/></key>
</entry>
<entry value-ref="PIDMetadataAction">
<key><util:constant static-field="org.dspace.qaevent.QANotifyPatterns.TOPIC_ENRICH_MISSING_PID"/></key>
</entry>
</map> </map>
</property> </property>
</bean> </bean>
@@ -57,10 +71,10 @@
<bean id="AbstractMetadataAction" class="org.dspace.qaevent.action.QAOpenaireSimpleMetadataAction"> <bean id="AbstractMetadataAction" class="org.dspace.qaevent.action.QAOpenaireSimpleMetadataAction">
<property name="metadata" value="dc.description.abstract" /> <property name="metadata" value="dc.description.abstract" />
</bean> </bean>
<bean id="AddReviewMetadataAction" class="org.dspace.qaevent.action.QAOpenaireSimpleMetadataAction"> <bean id="AddReviewMetadataAction" class="org.dspace.qaevent.action.QANotifySimpleMetadataAction">
<property name="metadata" value="datacite.relation.isReviewedBy" /> <property name="metadata" value="datacite.relation.isReviewedBy" />
</bean> </bean>
<bean id="AddEndorsedMetadataAction" class="org.dspace.qaevent.action.QAOpenaireSimpleMetadataAction"> <bean id="AddEndorsedMetadataAction" class="org.dspace.qaevent.action.QANotifySimpleMetadataAction">
<property name="metadata" value="notify.relation.endorsedBy"/> <property name="metadata" value="notify.relation.endorsedBy"/>
</bean> </bean>
<!-- Add a new identifier to the given item, using the defined types mapping --> <!-- Add a new identifier to the given item, using the defined types mapping -->
@@ -76,6 +90,15 @@
</property> </property>
</bean> </bean>
<bean id="RelationMetadataAction" class="org.dspace.qaevent.action.QANotifyMetadataMapAction">
<property name="types">
<map>
<entry key="default" value="datacite.relation.isReferencedBy" />
<entry key="http://purl.org/vocab/frbr/core#supplement" value="datacite.relation.isSupplementedBy" />
</map>
</property>
</bean>
<bean id="org.dspace.qaevent.service.QAEventSecurityService" class="org.dspace.qaevent.service.impl.QAEventSecurityServiceImpl"> <bean id="org.dspace.qaevent.service.QAEventSecurityService" class="org.dspace.qaevent.service.impl.QAEventSecurityServiceImpl">
<property name="defaultSecurity"> <property name="defaultSecurity">
<bean class="org.dspace.qaevent.security.AdministratorsOnlyQASecurity" /> <bean class="org.dspace.qaevent.security.AdministratorsOnlyQASecurity" />
@@ -100,7 +123,7 @@
AutomaticProcessingEvaluation implementation. Below you can find an example of configuration defining AutomaticProcessingEvaluation implementation. Below you can find an example of configuration defining
some thresholds rules for the coar-notify generated QAEvent to be approved, rejected and ignored some thresholds rules for the coar-notify generated QAEvent to be approved, rejected and ignored
--> -->
<!-- <!--
<util:map id="qaAutomaticProcessingMap"> <util:map id="qaAutomaticProcessingMap">
<entry key="coar-notify" value-ref="qaScoreEvaluation"/> <entry key="coar-notify" value-ref="qaScoreEvaluation"/>
</util:map> </util:map>
@@ -113,5 +136,5 @@
<property name="itemFilterToIgnore" ref="simple-demo_filter" /> <property name="itemFilterToIgnore" ref="simple-demo_filter" />
<property name="itemFilterToApprove" ref="simple-demo_filter" /> <property name="itemFilterToApprove" ref="simple-demo_filter" />
</bean> </bean>
--> -->
</beans> </beans>