coar-notify-7 follow-ups on the community advices

This commit is contained in:
frabacche
2024-02-14 17:54:08 +01:00
parent d81408b2d3
commit d7350437f2
52 changed files with 387 additions and 341 deletions

View File

@@ -7,7 +7,7 @@
*/
package org.dspace.app.ldn;
public enum QueueStatus {
public enum LDNMessageQueueStatus {
/**
* Resulting processing status of an LDN Message (aka queue management)

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.app.ldn;
import java.io.IOException;
import java.sql.SQLException;
import org.apache.logging.log4j.Logger;
@@ -32,7 +31,17 @@ public class LDNQueueExtractor {
private LDNQueueExtractor() {
}
public static int extractMessageFromQueue() throws IOException, SQLException {
/**
* invokes
* @see org.dspace.app.ldn.service.impl.LDNMessageServiceImpl#extractAndProcessMessageFromQueue(Context)
* to process the oldest ldn messages from the queue. An LdnMessage is processed when is routed to a
* @see org.dspace.app.ldn.processor.LDNProcessor
* Also a +1 is added to the ldnMessage entity
* @see org.dspace.app.ldn.LDNMessageEntity#getQueueAttempts()
* @return the number of processed ldnMessages.
* @throws SQLException
*/
public static int extractMessageFromQueue() throws SQLException {
Context context = new Context(Context.Mode.READ_WRITE);
int processed_messages = ldnMessageService.extractAndProcessMessageFromQueue(context);
if (processed_messages >= 0) {

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.app.ldn;
import java.io.IOException;
import java.sql.SQLException;
import org.apache.logging.log4j.Logger;
@@ -32,7 +31,16 @@ public class LDNQueueTimeoutChecker {
private LDNQueueTimeoutChecker() {
}
public static int checkQueueMessageTimeout() throws IOException, SQLException {
/**
* invokes
* @see org.dspace.app.ldn.service.impl.LDNMessageServiceImpl#checkQueueMessageTimeout(Context)
* to refresh the queue status of timed-out and in progressing status ldn messages:
* according to their attempts put them back in queue or set their status as failed if maxAttempts
* reached.
* @return the number of managed ldnMessages.
* @throws SQLException
*/
public static int checkQueueMessageTimeout() throws SQLException {
Context context = new Context(Context.Mode.READ_WRITE);
int fixed_messages = 0;
fixed_messages = ldnMessageService.checkQueueMessageTimeout(context);

View File

@@ -32,11 +32,11 @@ public class LDNRouter {
*/
public LDNProcessor route(LDNMessageEntity ldnMessage) {
if (ldnMessage == null) {
log.warn("an null LDNMessage is received for routing!");
log.warn("A null LDNMessage was received and could not be routed.");
return null;
}
if (StringUtils.isEmpty(ldnMessage.getType())) {
log.warn("LDNMessage " + ldnMessage + " has no type!");
log.warn("LDNMessage " + ldnMessage + " was received. It has no type, so it couldn't be routed.");
return null;
}
Set<String> ldnMessageTypeSet = new HashSet<String>();

View File

@@ -26,6 +26,6 @@ public interface LDNAction {
* @return ActionStatus the resulting status of the action
* @throws Exception general exception that can be thrown while executing action
*/
public ActionStatus execute(Context context, Notification notification, Item item) throws Exception;
public LDNActionStatus execute(Context context, Notification notification, Item item) throws Exception;
}

View File

@@ -10,6 +10,6 @@ package org.dspace.app.ldn.action;
/**
* Resulting status of an execution of an action.
*/
public enum ActionStatus {
public enum LDNActionStatus {
CONTINUE, ABORT;
}

View File

@@ -11,7 +11,7 @@ import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Date;
import com.github.jsonldjava.utils.JsonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.NotifyServiceEntity;
@@ -51,8 +51,8 @@ public class LDNCorrectionAction implements LDNAction {
private HandleService handleService;
@Override
public ActionStatus execute(Context context, Notification notification, Item item) throws Exception {
ActionStatus result = ActionStatus.ABORT;
public LDNActionStatus execute(Context context, Notification notification, Item item) throws Exception {
LDNActionStatus result = LDNActionStatus.ABORT;
String itemName = itemService.getName(item);
QAEvent qaEvent = null;
if (notification.getObject() != null) {
@@ -69,15 +69,14 @@ public class LDNCorrectionAction implements LDNAction {
}
BigDecimal score = getScore(context, notification);
double doubleScoreValue = score != null ? score.doubleValue() : 0d;
/* String fullHandleUrl = configurationService.getProperty("dspace.ui.url") + "/handle/"
+ handleService.findHandle(context, item); */
ObjectMapper mapper = new ObjectMapper();
qaEvent = new QAEvent(QAEvent.COAR_NOTIFY_SOURCE,
handleService.findHandle(context, item), item.getID().toString(), itemName,
this.getQaEventTopic(), doubleScoreValue,
JsonUtils.toString(message)
, new Date());
mapper.writeValueAsString(message),
new Date());
qaEventService.store(context, qaEvent);
result = ActionStatus.CONTINUE;
result = LDNActionStatus.CONTINUE;
}
return result;

View File

@@ -70,7 +70,7 @@ public class LDNEmailAction implements LDNAction {
* @throws Exception
*/
@Override
public ActionStatus execute(Context context, Notification notification, Item item) throws Exception {
public LDNActionStatus execute(Context context, Notification notification, Item item) throws Exception {
try {
Locale supportedLocale = I18nUtil.getEPersonLocale(context.getCurrentUser());
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, actionSendEmailTextFile));
@@ -96,7 +96,7 @@ public class LDNEmailAction implements LDNAction {
log.error("An Error Occurred while sending a notification email", e);
}
return ActionStatus.CONTINUE;
return LDNActionStatus.CONTINUE;
}
/**

View File

@@ -11,7 +11,7 @@ import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Date;
import com.github.jsonldjava.utils.JsonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.NotifyServiceEntity;
@@ -51,14 +51,12 @@ public class LDNRelationCorrectionAction implements LDNAction {
private HandleService handleService;
@Override
public ActionStatus execute(Context context, Notification notification, Item item) throws Exception {
ActionStatus result = ActionStatus.ABORT;
public LDNActionStatus execute(Context context, Notification notification, Item item) throws Exception {
LDNActionStatus result = LDNActionStatus.ABORT;
String itemName = itemService.getName(item);
QAEvent qaEvent = null;
if (notification.getObject() != null) {
NotifyMessageDTO message = new NotifyMessageDTO();
/*relationFormat.replace("[0]", notification.getObject().getAsRelationship());
hrefValue = hrefValue.replace("[1]", notification.getObject().getAsSubject());*/
message.setHref(notification.getObject().getAsSubject());
message.setRelationship(notification.getObject().getAsRelationship());
if (notification.getOrigin() != null) {
@@ -67,13 +65,14 @@ public class LDNRelationCorrectionAction implements LDNAction {
}
BigDecimal score = getScore(context, notification);
double doubleScoreValue = score != null ? score.doubleValue() : 0d;
ObjectMapper mapper = new ObjectMapper();
qaEvent = new QAEvent(QAEvent.COAR_NOTIFY_SOURCE,
handleService.findHandle(context, item), item.getID().toString(), itemName,
this.getQaEventTopic(), doubleScoreValue,
JsonUtils.toString(message)
, new Date());
mapper.writeValueAsString(message),
new Date());
qaEventService.store(context, qaEvent);
result = ActionStatus.CONTINUE;
result = LDNActionStatus.CONTINUE;
}
return result;

View File

@@ -9,7 +9,7 @@ package org.dspace.app.ldn.action;
import java.net.URI;
import com.google.gson.Gson;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.Header;
import org.apache.http.HttpException;
import org.apache.http.HttpHeaders;
@@ -46,31 +46,31 @@ public class SendLDNMessageAction implements LDNAction {
}
@Override
public ActionStatus execute(Context context, Notification notification, Item item) throws Exception {
public LDNActionStatus execute(Context context, Notification notification, Item item) throws Exception {
//TODO authorization with Bearer token should be supported.
String url = notification.getTarget().getInbox();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application, ld+json");
Gson gson = new Gson();
httpPost.setEntity(new StringEntity(gson.toJson(notification), "UTF-8"));
ObjectMapper mapper = new ObjectMapper();
httpPost.setEntity(new StringEntity(mapper.writeValueAsString(notification), "UTF-8"));
try {
//Server-side request forgery Critical check gitHub failure is a false positive,
//because the LDN Service URL is configured by the user from DSpace
//frontend configuration at /admin/ldn/services
// NOTE: Github believes there is a "Potential server-side request forgery due to a user-provided value"
// This is a false positive because the LDN Service URL is configured by the user from DSpace.
// See the frontend configuration at [dspace.ui.url]/admin/ldn/services
CloseableHttpResponse response = client.execute(httpPost);
if (isSuccessful(response.getStatusLine().getStatusCode())) {
return ActionStatus.CONTINUE;
return LDNActionStatus.CONTINUE;
} else if (isRedirect(response.getStatusLine().getStatusCode())) {
return handleRedirect(response, httpPost);
} else {
return ActionStatus.ABORT;
return LDNActionStatus.ABORT;
}
} catch (Exception e) {
log.error(e);
return ActionStatus.ABORT;
return LDNActionStatus.ABORT;
}
}
@@ -84,7 +84,7 @@ public class SendLDNMessageAction implements LDNAction {
statusCode == HttpStatus.SC_MOVED_TEMPORARILY;
}
private ActionStatus handleRedirect(CloseableHttpResponse oldresponse,
private LDNActionStatus handleRedirect(CloseableHttpResponse oldresponse,
HttpPost request) throws HttpException {
Header[] urls = oldresponse.getHeaders(HttpHeaders.LOCATION);
@@ -97,12 +97,12 @@ public class SendLDNMessageAction implements LDNAction {
request.setURI(new URI(url));
CloseableHttpResponse response = client.execute(request);
if (isSuccessful(response.getStatusLine().getStatusCode())) {
return ActionStatus.CONTINUE;
return LDNActionStatus.CONTINUE;
}
} catch (Exception e) {
log.error("Error following redirect:", e);
}
return ActionStatus.ABORT;
return LDNActionStatus.ABORT;
}
}

View File

@@ -25,13 +25,44 @@ import org.dspace.core.GenericDAO;
*/
public interface LDNMessageDao extends GenericDAO<LDNMessageEntity> {
/**
* load the oldest ldn messages considering their {@link org.dspace.app.ldn.LDNMessageEntity#queueLastStartTime}
* @param context
* @param max_attempts consider ldn_message entity with queue_attempts <= max_attempts
* @return ldn message entities to be routed
* @throws SQLException
*/
public List<LDNMessageEntity> findOldestMessageToProcess(Context context, int max_attempts) throws SQLException;
/**
* find ldn message entties in processing status and already timed out.
* @param context
* @param max_attempts consider ldn_message entity with queue_attempts <= max_attempts
* @return ldn message entities
* @throws SQLException
*/
public List<LDNMessageEntity> findProcessingTimedoutMessages(Context context, int max_attempts) throws SQLException;
/**
* find all ldn messages related to an item
* @param context
* @param item item related to the returned ldn messages
* @param activities involves only this specific group of activities
* @return all ldn messages related to the given item
* @throws SQLException
*/
public List<LDNMessageEntity> findAllMessagesByItem(
Context context, Item item, String... activities) throws SQLException;
/**
* find all ldn messages related to an item and to a specific ldn message
* @param context
* @param msg the referring ldn message
* @param item the referring repository item
* @param relatedTypes filter for @see org.dspace.app.ldn.LDNMessageEntity#activityStreamType
* @return all related ldn messages
* @throws SQLException
*/
public List<LDNMessageEntity> findAllRelatedMessagesByItem(
Context context, LDNMessageEntity msg, Item item, String... relatedTypes) throws SQLException;
}

View File

@@ -39,7 +39,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO<LDNMessageEntity> im
@Override
public List<LDNMessageEntity> findOldestMessageToProcess(Context context, int max_attempts) throws SQLException {
// looking for oldest failed-processed message
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
CriteriaQuery<LDNMessageEntity> criteriaQuery = getCriteriaQuery(criteriaBuilder, LDNMessageEntity.class);
Root<LDNMessageEntity> root = criteriaQuery.from(LDNMessageEntity.class);
@@ -54,7 +53,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO<LDNMessageEntity> im
orderList.add(criteriaBuilder.desc(root.get(LDNMessageEntity_.queueAttempts)));
orderList.add(criteriaBuilder.asc(root.get(LDNMessageEntity_.queueLastStartTime)));
criteriaQuery.orderBy(orderList);
// setHint("org.hibernate.cacheable", Boolean.FALSE);
List<LDNMessageEntity> result = list(context, criteriaQuery, false, LDNMessageEntity.class, -1, -1);
if (result == null || result.isEmpty()) {
log.debug("No LDN messages found to be processed");
@@ -79,7 +77,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO<LDNMessageEntity> im
orderList.add(criteriaBuilder.desc(root.get(LDNMessageEntity_.queueAttempts)));
orderList.add(criteriaBuilder.asc(root.get(LDNMessageEntity_.queueLastStartTime)));
criteriaQuery.orderBy(orderList);
// setHint("org.hibernate.cacheable", Boolean.FALSE);
List<LDNMessageEntity> result = list(context, criteriaQuery, false, LDNMessageEntity.class, -1, -1);
if (result == null || result.isEmpty()) {
log.debug("No LDN messages found to be processed");
@@ -98,8 +95,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO<LDNMessageEntity> im
Predicate relatedtypePredicate = null;
andPredicates.add(
criteriaBuilder.equal(root.get(LDNMessageEntity_.queueStatus), LDNMessageEntity.QUEUE_STATUS_PROCESSED));
/*andPredicates.add(
criteriaBuilder.equal(root.get(LDNMessageEntity_.object), item));*/
andPredicates.add(
criteriaBuilder.isNull(root.get(LDNMessageEntity_.target)));
andPredicates.add(
@@ -113,7 +108,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO<LDNMessageEntity> im
orderList.add(criteriaBuilder.asc(root.get(LDNMessageEntity_.queueLastStartTime)));
orderList.add(criteriaBuilder.desc(root.get(LDNMessageEntity_.queueAttempts)));
criteriaQuery.orderBy(orderList);
// setHint("org.hibernate.cacheable", Boolean.FALSE);
List<LDNMessageEntity> result = list(context, criteriaQuery, false, LDNMessageEntity.class, -1, -1);
if (result == null || result.isEmpty()) {
log.debug("No LDN messages ACK found to be processed");
@@ -145,7 +139,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO<LDNMessageEntity> im
orderList.add(criteriaBuilder.asc(root.get(LDNMessageEntity_.queueLastStartTime)));
orderList.add(criteriaBuilder.desc(root.get(LDNMessageEntity_.queueAttempts)));
criteriaQuery.orderBy(orderList);
// setHint("org.hibernate.cacheable", Boolean.FALSE);
List<LDNMessageEntity> result = list(context, criteriaQuery, false, LDNMessageEntity.class, -1, -1);
if (result == null || result.isEmpty()) {
log.debug("No LDN messages found");

View File

@@ -10,7 +10,7 @@ package org.dspace.app.ldn.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
public class Actor extends Base {

View File

@@ -17,7 +17,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
@JsonInclude(Include.NON_EMPTY)
@JsonIgnoreProperties(ignoreUnknown = true)

View File

@@ -9,8 +9,9 @@ package org.dspace.app.ldn.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
public class Citation extends Base {

View File

@@ -11,8 +11,9 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
public class Context extends Citation {

View File

@@ -11,7 +11,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
/**
*
* the json object from witch @see org.dspace.app.ldn.LDNMessageEntity are created.
* <a href="https://notify.coar-repositories.org/patterns/">see official coar doc</a>
*/
@JsonPropertyOrder(value = {
"@context",

View File

@@ -10,7 +10,7 @@ package org.dspace.app.ldn.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
public class Object extends Citation {

View File

@@ -10,7 +10,7 @@ package org.dspace.app.ldn.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
public class Service extends Base {

View File

@@ -10,7 +10,7 @@ package org.dspace.app.ldn.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
*
* used to map @see org.dspace.app.ldn.model.Notification
*/
public class Url extends Base {

View File

@@ -50,7 +50,7 @@ public class LDNContextRepeater {
/**
* @param notification
* @return Iterator<Notification>
* @return Iterator<Notification>
*/
public Iterator<Notification> iterator(Notification notification) {
return new NotificationIterator(notification, repeatOver);
@@ -79,7 +79,7 @@ public class LDNContextRepeater {
JsonNode notificationNode = objectMapper.valueToTree(notification);
log.info("Notification {}", notificationNode);
log.debug("Notification {}", notificationNode);
JsonNode topContextNode = notificationNode.get(CONTEXT);
if (topContextNode.isNull()) {

View File

@@ -19,8 +19,8 @@ import org.apache.http.HttpStatus;
import org.apache.http.client.HttpResponseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.app.ldn.action.ActionStatus;
import org.dspace.app.ldn.action.LDNAction;
import org.dspace.app.ldn.action.LDNActionStatus;
import org.dspace.app.ldn.model.Notification;
import org.dspace.app.ldn.utility.LDNUtils;
import org.dspace.content.DSpaceObject;
@@ -79,8 +79,8 @@ public class LDNMetadataProcessor implements LDNProcessor {
*
* @throws Exception failed execute the action
*/
private ActionStatus runActions(Context context, Notification notification, Item item) throws Exception {
ActionStatus operation = ActionStatus.CONTINUE;
private LDNActionStatus runActions(Context context, Notification notification, Item item) throws Exception {
LDNActionStatus operation = LDNActionStatus.CONTINUE;
for (LDNAction action : actions) {
log.info("Running action {} for notification {} {}",
action.getClass().getSimpleName(),
@@ -88,7 +88,7 @@ public class LDNMetadataProcessor implements LDNProcessor {
notification.getType());
operation = action.execute(context, notification, item);
if (operation == ActionStatus.ABORT) {
if (operation == LDNActionStatus.ABORT) {
break;
}
}

View File

@@ -19,7 +19,6 @@ import java.util.UUID;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonSyntaxException;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
@@ -120,18 +119,16 @@ public class LDNMessageServiceImpl implements LDNMessageService {
ldnMessage.setCoarNotifyType(notificationTypeArrayList.get(1));
}
ldnMessage.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_QUEUED);
//CST-12126 if source is untrusted, set the queue_status of the
//ldnMsgEntity to UNTRUSTED
if (ldnMessage.getOrigin() == null && !"Offer".equalsIgnoreCase(ldnMessage.getActivityStreamType())) {
ldnMessage.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_UNTRUSTED);
} else {
if (!isValidIp(ldnMessage)) {
ldnMessage.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_UNTRUSTED_IP);
}
}
ldnMessage.setQueueTimeout(new Date());
ldnMessage.setSourceIp(sourceIp);
if (!isValidIp(ldnMessage)) {
ldnMessage.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_UNTRUSTED_IP);
}
update(context, ldnMessage);
return ldnMessage;
}
@@ -177,8 +174,6 @@ public class LDNMessageServiceImpl implements LDNMessageService {
@Override
public void update(Context context, LDNMessageEntity ldnMessage) throws SQLException {
//CST-12126 then LDNMessageService.update() when the origin is set != null,
//move the queue_status from UNTRUSTED to QUEUED
if (ldnMessage.getOrigin() != null &&
LDNMessageEntity.QUEUE_STATUS_UNTRUSTED.compareTo(ldnMessage.getQueueStatus()) == 0) {
ldnMessage.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_QUEUED);
@@ -261,9 +256,6 @@ public class LDNMessageServiceImpl implements LDNMessageService {
processor.process(context, notification);
msg.setQueueStatus(LDNMessageEntity.QUEUE_STATUS_PROCESSED);
result = 1;
} catch (JsonSyntaxException jse) {
result = -1;
log.error("Unable to read JSON notification from LdnMessage " + msg, jse);
} catch (Exception e) {
result = -1;
log.error(e);

View File

@@ -10,7 +10,6 @@ package org.dspace.app.suggestion;
import static org.apache.commons.collections.CollectionUtils.isEmpty;
import java.io.IOException;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -19,9 +18,11 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.SortClause;
@@ -41,6 +42,7 @@ import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.util.UUIDUtils;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Service to deal with the local suggestion solr core used by the
* SolrSuggestionProvider(s)
@@ -50,6 +52,8 @@ import org.springframework.beans.factory.annotation.Autowired;
*/
public class SolrSuggestionStorageServiceImpl implements SolrSuggestionStorageService {
private static final Logger log = LogManager.getLogger(SolrSuggestionStorageServiceImpl.class);
protected SolrClient solrSuggestionClient;
@Autowired
@@ -73,7 +77,7 @@ public class SolrSuggestionStorageServiceImpl implements SolrSuggestionStorageSe
public void addSuggestion(Suggestion suggestion, boolean force, boolean commit)
throws SolrServerException, IOException {
if (force || !exist(suggestion)) {
Gson gson = new Gson();
ObjectMapper mapper = new ObjectMapper();
SolrInputDocument document = new SolrInputDocument();
document.addField(SOURCE, suggestion.getSource());
String suggestionFullID = suggestion.getID();
@@ -89,7 +93,7 @@ public class SolrSuggestionStorageServiceImpl implements SolrSuggestionStorageSe
document.addField(EXTERNAL_URI, suggestion.getExternalSourceUri());
document.addField(SCORE, suggestion.getScore());
document.addField(PROCESSED, false);
document.addField(EVIDENCES, gson.toJson(suggestion.getEvidences()));
document.addField(EVIDENCES, mapper.writeValueAsString(suggestion.getEvidences()));
getSolr().add(document);
if (commit) {
getSolr().commit();
@@ -326,10 +330,14 @@ public class SolrSuggestionStorageServiceImpl implements SolrSuggestionStorageSe
}
}
String evidencesJson = (String) solrDoc.getFieldValue(EVIDENCES);
Type listType = new TypeToken<ArrayList<SuggestionEvidence>>() {
}.getType();
List<SuggestionEvidence> evidences = new Gson().fromJson(evidencesJson, listType);
suggestion.getEvidences().addAll(evidences);
ObjectMapper mapper = new ObjectMapper();
List<SuggestionEvidence> evidences;
try {
evidences = mapper.readValue(evidencesJson, List.class);
suggestion.getEvidences().addAll(evidences);
} catch (JsonProcessingException e) {
log.error(e);
}
return suggestion;
}

View File

@@ -21,13 +21,13 @@ public class COARNotifyConfigurationService {
* Mapping the submission step process identifier with the configuration
* (see configuration at coar-notify.xml)
*/
private Map<String, List<LDNPattern>> patterns;
private Map<String, List<COARPattern>> patterns;
public Map<String, List<LDNPattern>> getPatterns() {
public Map<String, List<COARPattern>> getPatterns() {
return patterns;
}
public void setPatterns(Map<String, List<LDNPattern>> patterns) {
public void setPatterns(Map<String, List<COARPattern>> patterns) {
this.patterns = patterns;
}

View File

@@ -26,13 +26,13 @@ public class COARNotifySubmissionConfiguration {
* the map values of configured bean of COARNotifyConfigurationService
* in coar-notify.xml
*/
private List<LDNPattern> patterns;
private List<COARPattern> patterns;
public COARNotifySubmissionConfiguration() {
}
public COARNotifySubmissionConfiguration(String id, List<LDNPattern> patterns) {
public COARNotifySubmissionConfiguration(String id, List<COARPattern> patterns) {
super();
this.id = id;
this.patterns = patterns;
@@ -51,7 +51,7 @@ public class COARNotifySubmissionConfiguration {
*
* @return the list of configured COAR Notify Patterns
*/
public List<LDNPattern> getPatterns() {
public List<COARPattern> getPatterns() {
return patterns;
}
@@ -59,7 +59,7 @@ public class COARNotifySubmissionConfiguration {
* Sets the list of configured COAR Notify Patterns
* @param patterns
*/
public void setPatterns(final List<LDNPattern> patterns) {
public void setPatterns(final List<COARPattern> patterns) {
this.patterns = patterns;
}
}

View File

@@ -12,16 +12,16 @@ package org.dspace.coarnotify;
*
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
*/
public class LDNPattern {
public class COARPattern {
private String pattern;
private boolean multipleRequest;
public LDNPattern() {
public COARPattern() {
}
public LDNPattern(String pattern, boolean multipleRequest) {
public COARPattern(String pattern, boolean multipleRequest) {
this.pattern = pattern;
this.multipleRequest = multipleRequest;
}

View File

@@ -29,7 +29,7 @@ public class SubmissionCOARNotifyServiceImpl implements SubmissionCOARNotifyServ
@Override
public COARNotifySubmissionConfiguration findOne(String id) {
List<LDNPattern> patterns =
List<COARPattern> patterns =
coarNotifyConfigurationService.getPatterns().get(id);
if (patterns == null) {

View File

@@ -1,38 +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/
--
-----------------------------------------------------------------------------------
-- CREATE notifyservice table
-----------------------------------------------------------------------------------
CREATE SEQUENCE if NOT EXISTS notifyservice_id_seq;
CREATE TABLE notifyservice (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
description TEXT,
url VARCHAR(255),
ldn_url VARCHAR(255)
);
-----------------------------------------------------------------------------------
-- CREATE notifyservice_inbound_pattern_id_seq table
-----------------------------------------------------------------------------------
CREATE SEQUENCE if NOT EXISTS notifyservice_inbound_pattern_id_seq;
CREATE TABLE notifyservice_inbound_pattern (
id INTEGER PRIMARY KEY,
service_id INTEGER REFERENCES notifyservice(id) ON DELETE CASCADE,
pattern VARCHAR(255),
constraint_name VARCHAR(255),
automatic BOOLEAN
);
CREATE INDEX notifyservice_inbound_idx ON notifyservice_inbound_pattern (service_id);

View File

@@ -1,34 +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/
--
-------------------------------------------------------------------------------
-- Table to store LDN messages
-------------------------------------------------------------------------------
CREATE TABLE ldn_message
(
id VARCHAR(255) PRIMARY KEY,
object uuid,
message TEXT,
type VARCHAR(255),
origin INTEGER,
target INTEGER,
inReplyTo VARCHAR(255),
context uuid,
activity_stream_type VARCHAR(255),
coar_notify_type VARCHAR(255),
queue_status INTEGER DEFAULT NULL,
queue_attempts INTEGER DEFAULT 0,
queue_last_start_time TIMESTAMP,
queue_timeout TIMESTAMP,
FOREIGN KEY (object) REFERENCES dspaceobject (uuid) ON DELETE SET NULL,
FOREIGN KEY (context) REFERENCES dspaceobject (uuid) ON DELETE SET NULL,
FOREIGN KEY (origin) REFERENCES notifyservice (id) ON DELETE SET NULL,
FOREIGN KEY (target) REFERENCES notifyservice (id) ON DELETE SET NULL,
FOREIGN KEY (inReplyTo) REFERENCES ldn_message (id) ON DELETE SET NULL
);

View File

@@ -1,13 +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/
--
-----------------------------------------------------------------------------------
-- edit notifyservice table add enabled column
-----------------------------------------------------------------------------------
ALTER TABLE notifyservice ADD COLUMN enabled BOOLEAN NOT NULL;

View File

@@ -1,24 +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/
--
-------------------------------------------------------------------------------
-- Table to store notify patterns that will be triggered
-------------------------------------------------------------------------------
CREATE SEQUENCE if NOT EXISTS notifypatterns_to_trigger_id_seq;
CREATE TABLE notifypatterns_to_trigger
(
id INTEGER PRIMARY KEY,
item_id UUID REFERENCES Item(uuid) ON DELETE CASCADE,
service_id INTEGER REFERENCES notifyservice(id) ON DELETE CASCADE,
pattern VARCHAR(255)
);
CREATE INDEX notifypatterns_to_trigger_item_idx ON notifypatterns_to_trigger (item_id);
CREATE INDEX notifypatterns_to_trigger_service_idx ON notifypatterns_to_trigger (service_id);

View File

@@ -1,13 +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/
--
-----------------------------------------------------------------------------------
-- edit notifyservice table add score column
-----------------------------------------------------------------------------------
ALTER TABLE notifyservice ADD COLUMN score NUMERIC(6, 5);

View File

@@ -1,14 +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/
--
-----------------------------------------------------------------------------------
-- ADD CONSTRAINT on notifyservice table: ldn_url as unique
-----------------------------------------------------------------------------------
ALTER TABLE notifyservice ADD CONSTRAINT ldn_url_unique UNIQUE (ldn_url);

View File

@@ -1,15 +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/
--
--------------------------------------------------------------------------
-- ADD IP Range columns to notifyservice table
--------------------------------------------------------------------------
ALTER TABLE notifyservice ADD COLUMN lower_ip VARCHAR(45);
ALTER TABLE notifyservice ADD COLUMN upper_ip VARCHAR(45);

View File

@@ -1,13 +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/
--
--------------------------------------------------------------------------
-- ADD source_ip columns to ldn_message table
--------------------------------------------------------------------------
ALTER TABLE ldn_message ADD COLUMN source_ip VARCHAR(45);

View File

@@ -0,0 +1,90 @@
--
-- 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/
--
-----------------------------------------------------------------------------------
-- CREATE notifyservice table
-----------------------------------------------------------------------------------
CREATE SEQUENCE if NOT EXISTS notifyservice_id_seq;
CREATE TABLE notifyservice (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
description TEXT,
url VARCHAR(255),
ldn_url VARCHAR(255),
enabled BOOLEAN NOT NULL,
score NUMERIC(6, 5),
lower_ip VARCHAR(45),
upper_ip VARCHAR(45),
CONSTRAINT ldn_url_unique UNIQUE (ldn_url)
);
-----------------------------------------------------------------------------------
-- CREATE notifyservice_inbound_pattern_id_seq table
-----------------------------------------------------------------------------------
CREATE SEQUENCE if NOT EXISTS notifyservice_inbound_pattern_id_seq;
CREATE TABLE notifyservice_inbound_pattern (
id INTEGER PRIMARY KEY,
service_id INTEGER REFERENCES notifyservice(id) ON DELETE CASCADE,
pattern VARCHAR(255),
constraint_name VARCHAR(255),
automatic BOOLEAN
);
CREATE INDEX notifyservice_inbound_idx ON notifyservice_inbound_pattern (service_id);
-------------------------------------------------------------------------------
-- Table to store LDN messages
-------------------------------------------------------------------------------
CREATE TABLE ldn_message
(
id VARCHAR(255) PRIMARY KEY,
object uuid,
message TEXT,
type VARCHAR(255),
origin INTEGER,
target INTEGER,
inReplyTo VARCHAR(255),
context uuid,
activity_stream_type VARCHAR(255),
coar_notify_type VARCHAR(255),
queue_status INTEGER DEFAULT NULL,
queue_attempts INTEGER DEFAULT 0,
queue_last_start_time TIMESTAMP,
queue_timeout TIMESTAMP,
source_ip VARCHAR(45),
FOREIGN KEY (object) REFERENCES dspaceobject (uuid) ON DELETE SET NULL,
FOREIGN KEY (context) REFERENCES dspaceobject (uuid) ON DELETE SET NULL,
FOREIGN KEY (origin) REFERENCES notifyservice (id) ON DELETE SET NULL,
FOREIGN KEY (target) REFERENCES notifyservice (id) ON DELETE SET NULL,
FOREIGN KEY (inReplyTo) REFERENCES ldn_message (id) ON DELETE SET NULL
);
-------------------------------------------------------------------------------
-- Table to store notify patterns that will be triggered
-------------------------------------------------------------------------------
CREATE SEQUENCE if NOT EXISTS notifypatterns_to_trigger_id_seq;
CREATE TABLE notifypatterns_to_trigger
(
id INTEGER PRIMARY KEY,
item_id UUID REFERENCES Item(uuid) ON DELETE CASCADE,
service_id INTEGER REFERENCES notifyservice(id) ON DELETE CASCADE,
pattern VARCHAR(255)
);
CREATE INDEX notifypatterns_to_trigger_item_idx ON notifypatterns_to_trigger (item_id);
CREATE INDEX notifypatterns_to_trigger_service_idx ON notifypatterns_to_trigger (service_id);

View File

@@ -7,8 +7,8 @@
*/
package org.dspace.app.ldn.action;
import static org.dspace.app.ldn.action.ActionStatus.ABORT;
import static org.dspace.app.ldn.action.ActionStatus.CONTINUE;
import static org.dspace.app.ldn.action.LDNActionStatus.ABORT;
import static org.dspace.app.ldn.action.LDNActionStatus.CONTINUE;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;

View File

@@ -13,7 +13,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.dspace.app.rest.RestResourceController;
import org.dspace.coarnotify.COARNotifySubmissionConfiguration;
import org.dspace.coarnotify.LDNPattern;
import org.dspace.coarnotify.COARPattern;
/**
* This class is the REST representation of the COARNotifySubmissionConfiguration model object
@@ -27,7 +27,7 @@ public class SubmissionCOARNotifyRest extends BaseObjectRest<String> {
private String id;
private List<LDNPattern> patterns;
private List<COARPattern> patterns;
public String getId() {
return id;
@@ -37,11 +37,11 @@ public class SubmissionCOARNotifyRest extends BaseObjectRest<String> {
this.id = id;
}
public List<LDNPattern> getPatterns() {
public List<COARPattern> getPatterns() {
return patterns;
}
public void setPatterns(final List<LDNPattern> patterns) {
public void setPatterns(final List<COARPattern> patterns) {
this.patterns = patterns;
}

View File

@@ -25,7 +25,7 @@ import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.step.DataCOARNotify;
import org.dspace.authorize.AuthorizeException;
import org.dspace.coarnotify.COARNotifyConfigurationService;
import org.dspace.coarnotify.LDNPattern;
import org.dspace.coarnotify.COARPattern;
import org.dspace.content.InProgressSubmission;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
@@ -90,6 +90,11 @@ public class COARNotifySubmissionService {
}
}
/**
* extract pattern from path. see COARNotifyConfigurationService bean
* @param path
* @return the extracted pattern
*/
public String extractPattern(String path) {
Pattern pattern = Pattern.compile("/([^/]+)/([^/]+)/([^/]+)");
Matcher matcher = pattern.matcher(path);
@@ -107,13 +112,13 @@ public class COARNotifySubmissionService {
}
private boolean isContainPattern(String config, String pattern) {
List<LDNPattern> patterns = coarNotifyConfigurationService.getPatterns().get(config);
List<COARPattern> patterns = coarNotifyConfigurationService.getPatterns().get(config);
if (CollectionUtils.isEmpty(patterns)) {
return false;
}
return patterns.stream()
.map(LDNPattern::getPattern)
.map(COARPattern::getPattern)
.anyMatch(v ->
v.equals(pattern));
}

View File

@@ -23,7 +23,7 @@ import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.util.DCInputsReaderException;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.coarnotify.COARNotifyConfigurationService;
import org.dspace.coarnotify.LDNPattern;
import org.dspace.coarnotify.COARPattern;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.content.logic.LogicalStatement;
@@ -54,7 +54,7 @@ public class COARNotifyValidation extends AbstractValidation {
List<String> patterns =
coarNotifyConfigurationService.getPatterns().getOrDefault(config.getId(), List.of())
.stream()
.map(LDNPattern::getPattern)
.map(COARPattern::getPattern)
.collect(Collectors.toList());
patterns.forEach(pattern -> {

View File

@@ -313,6 +313,46 @@ public class LDNInboxControllerIT extends AbstractControllerIntegrationTest {
assertEquals(ldnMessage.getQueueStatus(), LDNMessageEntity.QUEUE_STATUS_UNTRUSTED_IP);
}
@Test
public void ldnInboxAnnounceEndorsementInvalidInboxTest() 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();
NotifyServiceEntity notifyServiceEntity =
NotifyServiceBuilder.createNotifyServiceBuilder(context)
.withName("service name")
.withDescription("service description")
.withUrl("service url")
.withLdnUrl("https://overlay-journal.com/inbox/")
.withLowerIp("127.0.0.2")
.withUpperIp("127.0.0.5")
.build();
context.restoreAuthSystemState();
InputStream announceEndorsementStream = getClass().getResourceAsStream("ldn_origin_inbox_unregistered.json");
String announceEndorsement = IOUtils.toString(announceEndorsementStream, Charset.defaultCharset());
announceEndorsementStream.close();
String message = announceEndorsement.replaceAll("<<object>>", object);
message = message.replaceAll("<<object_handle>>", 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());
int processed = ldnMessageService.extractAndProcessMessageFromQueue(context);
assertEquals(processed, 0);
LDNMessageEntity ldnMessage = ldnMessageService.find(context, notification.getId());
checkStoredLDNMessage(notification, ldnMessage, object);
assertEquals(ldnMessage.getQueueStatus(), LDNMessageEntity.QUEUE_STATUS_UNTRUSTED);
}
@Override
@After
public void destroy() throws Exception {

View File

@@ -17,7 +17,7 @@ import java.util.List;
import org.dspace.app.rest.matcher.SubmissionCOARNotifyMatcher;
import org.dspace.app.rest.repository.SubmissionCoarNotifyRestRepository;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.coarnotify.LDNPattern;
import org.dspace.coarnotify.COARPattern;
import org.hamcrest.Matchers;
import org.junit.Test;
@@ -43,9 +43,9 @@ public class SubmissionCOARNotifyRestRepositoryIT extends AbstractControllerInte
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissioncoarnotifyconfigs", Matchers.containsInAnyOrder(
SubmissionCOARNotifyMatcher.matchCOARNotifyEntry("coarnotify", List.of(
new LDNPattern("request-review", true),
new LDNPattern("request-endorsement", true),
new LDNPattern("request-ingest", false)))
new COARPattern("request-review", true),
new COARPattern("request-endorsement", true),
new COARPattern("request-ingest", false)))
)));
}
@@ -72,9 +72,9 @@ public class SubmissionCOARNotifyRestRepositoryIT extends AbstractControllerInte
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$", Matchers.is(
SubmissionCOARNotifyMatcher.matchCOARNotifyEntry("coarnotify", List.of(
new LDNPattern("request-review", true),
new LDNPattern("request-endorsement", true),
new LDNPattern("request-ingest", false)))
new COARPattern("request-review", true),
new COARPattern("request-endorsement", true),
new COARPattern("request-ingest", false)))
)));
}

View File

@@ -14,7 +14,7 @@ import static org.hamcrest.Matchers.is;
import java.util.List;
import org.dspace.coarnotify.LDNPattern;
import org.dspace.coarnotify.COARPattern;
import org.hamcrest.Matcher;
/**
@@ -28,16 +28,16 @@ public class SubmissionCOARNotifyMatcher {
private SubmissionCOARNotifyMatcher() {
}
public static Matcher<? super Object> matchCOARNotifyEntry(String id, List<LDNPattern> patterns) {
public static Matcher<? super Object> matchCOARNotifyEntry(String id, List<COARPattern> patterns) {
return allOf(
hasJsonPath("$.id", is(id)),
hasJsonPath(
"$.patterns", contains(
patterns.stream()
.map(ldnPattern ->
.map(coarPattern ->
allOf(
hasJsonPath("pattern", is(ldnPattern.getPattern())),
hasJsonPath("multipleRequest", is(ldnPattern.isMultipleRequest()))
hasJsonPath("pattern", is(coarPattern.getPattern())),
hasJsonPath("multipleRequest", is(coarPattern.isMultipleRequest()))
))
.toArray(Matcher[]::new))));
}

View File

@@ -0,0 +1,49 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://purl.org/coar/notify"
],
"actor": {
"id": "https://overlay-journal.com",
"name": "Overlay Journal",
"type": ["Service"]
},
"context": {
"id": "<<object>>",
"ietf:cite-as": "https://doi.org/10.5555/12345680",
"type": ["sorg:AboutPage"],
"url": {
"id": "https://research-organisation.org/repository/preprint/201203/421/content.pdf",
"mediaType": "application/pdf",
"type": [
"Article",
"sorg:ScholarlyArticle"
]
}
},
"id": "urn:uuid:94ecae35-dcfd-4182-8550-22c7164fe23f",
"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/",
"type": [
"Page",
"sorg:WebPage"
]
},
"origin": {
"id": "https://overlay-journal.com/system",
"inbox": "https://letsfake.it/inbox/",
"type": ["Service"]
},
"target": {
"id": "https://research-organisation.org/repository",
"inbox": "https://research-organisation.org/inbox/",
"type": ["Service"]
},
"type": [
"Announce",
"coar-notify:EndorsementAction"
]
}

View File

@@ -938,8 +938,6 @@ registry.metadata.load = dspace-types.xml
registry.metadata.load = iiif-types.xml
registry.metadata.load = datacite-types.xml
registry.metadata.load = coar-types.xml
registry.metadata.load = notify-types.xml
#---------------------------------------------------------------#
#-----------------UI-Related CONFIGURATIONS---------------------#
@@ -1662,7 +1660,6 @@ include = ${module_dir}/rdf.cfg
include = ${module_dir}/rest.cfg
include = ${module_dir}/iiif.cfg
include = ${module_dir}/signposting.cfg
include = ${module_dir}/ldn.cfg
include = ${module_dir}/solr-statistics.cfg
include = ${module_dir}/solrauthority.cfg
include = ${module_dir}/researcher-profile.cfg

View File

@@ -10,3 +10,37 @@ coar-notify.enabled = true
# For debugging purposes only, skip the check on the IP range.
#coar-notify.ip-range.enabled = false
#### LDN CONFIGURATION ####
# To enable the LDN service, set to true.
ldn.enabled = true
#LDN message inbox endpoint
ldn.notify.inbox = ${dspace.server.url}/ldn/inbox
# List the external services IDs for review/endorsement
# These IDs needs to be configured in the input-form.xml as well
# These IDs must contain only the hostname and the resource path
# Do not include any protocol
# Each IDs must match with the ID returned by the external service
# in the JSON-LD Actor field
service.service-id.ldn =
# LDN Queue extractor elaborates LDN Message entities of the queue
ldn.queue.extractor.cron = 0 0/5 * * * ?
# LDN Queue timeout checks LDN Message Entities relation with the queue
ldn.queue.timeout.checker.cron = 0 0 */1 * * ?
# LDN Queue extractor elaborates LDN Message entities with max_attempts < than ldn.processor.max.attempts
ldn.processor.max.attempts = 5
# LDN Queue extractor sets LDN Message Entity queue_timeout property every time it tryies a new elaboration
# 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)
ldn.processor.queue.msg.timeout = 60
# EMAIL CONFIGURATION
ldn.notification.email = ${mail.admin}

View File

@@ -1,33 +0,0 @@
#### LDN CONFIGURATION ####
# To enable the LDN service, set to true.
ldn.enabled = true
#LDN message inbox endpoint
ldn.notify.inbox = ${dspace.server.url}/ldn/inbox
# List the external services IDs for review/endorsement
# These IDs needs to be configured in the input-form.xml as well
# These IDs must contain only the hostname and the resource path
# Do not include any protocol
# Each IDs must match with the ID returned by the external service
# in the JSON-LD Actor field
service.service-id.ldn =
# LDN Queue extractor elaborates LDN Message entities of the queue
ldn.queue.extractor.cron = 0 0/5 * * * ?
# LDN Queue timeout checks LDN Message Entities relation with the queue
ldn.queue.timeout.checker.cron = 0 0 */1 * * ?
# LDN Queue extractor elaborates LDN Message entities with max_attempts < than ldn.processor.max.attempts
ldn.processor.max.attempts = 5
# LDN Queue extractor sets LDN Message Entity queue_timeout property every time it tryies a new elaboration
# 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)
ldn.processor.queue.msg.timeout = 60
# EMAIL CONFIGURATION
ldn.notification.email = ${mail.admin}

View File

@@ -51,4 +51,11 @@
<scope_note>Released by</scope_note>
</dc-type>
<dc-type>
<schema>coar</schema>
<element>notify</element>
<qualifier>endorsedBy</qualifier>
<scope_note>Endorsed by</scope_note>
</dc-type>
</dspace-dc-types>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dspace-dc-types SYSTEM "dspace-dc-types.dtd">
<dspace-dc-types>
<dspace-header>
<title>Notify fields definition</title>
</dspace-header>
<dc-schema>
<name>notify</name>
<namespace>http://dspace.org/notify</namespace>
</dc-schema>
<dc-type>
<schema>notify</schema>
<element>relation</element>
<qualifier>endorsedBy</qualifier>
<scope_note>Endorsed by</scope_note>
</dc-type>
</dspace-dc-types>

View File

@@ -19,17 +19,17 @@
</property>
</bean>
<bean id="requestReview" class="org.dspace.coarnotify.LDNPattern">
<bean id="requestReview" class="org.dspace.coarnotify.COARPattern">
<property name="pattern" value="request-review"/>
<property name="multipleRequest" value="true"/>
</bean>
<bean id="requestEndorsement" class="org.dspace.coarnotify.LDNPattern">
<bean id="requestEndorsement" class="org.dspace.coarnotify.COARPattern">
<property name="pattern" value="request-endorsement"/>
<property name="multipleRequest" value="true"/>
</bean>
<bean id="requestIngest" class="org.dspace.coarnotify.LDNPattern">
<bean id="requestIngest" class="org.dspace.coarnotify.COARPattern">
<property name="pattern" value="request-ingest"/>
<property name="multipleRequest" value="false"/>
</bean>

View File

@@ -79,7 +79,7 @@
</bean>
<bean id="AddEndorsedMetadataAction" class="org.dspace.qaevent.action.QANotifySimpleMetadataAction">
<property name="metadata" value="notify.relation.endorsedBy"/>
<property name="metadata" value="coar.notify.endorsedBy"/>
</bean>
<!-- Add a new identifier to the given item, using the defined types mapping -->
<bean id="PIDMetadataAction" class="org.dspace.qaevent.action.QAOpenaireMetadataMapAction">