mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 18:14:26 +00:00
coar-notify-7 follow-ups on the community advices
This commit is contained in:
@@ -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)
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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>();
|
||||
|
@@ -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;
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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",
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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 {
|
||||
|
||||
|
@@ -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()) {
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
@@ -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) {
|
||||
|
@@ -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);
|
@@ -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
|
||||
);
|
@@ -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;
|
@@ -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);
|
@@ -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);
|
@@ -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);
|
||||
|
@@ -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);
|
@@ -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);
|
@@ -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);
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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 -> {
|
||||
|
@@ -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 {
|
||||
|
@@ -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)))
|
||||
)));
|
||||
}
|
||||
|
||||
|
@@ -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))));
|
||||
}
|
||||
|
@@ -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"
|
||||
]
|
||||
}
|
@@ -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
|
||||
|
@@ -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}
|
||||
|
@@ -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}
|
@@ -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>
|
||||
|
@@ -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>
|
@@ -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>
|
||||
|
@@ -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">
|
||||
|
Reference in New Issue
Block a user