mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-14 05:23:14 +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;
|
||||
|
Reference in New Issue
Block a user