diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/QueueStatus.java b/dspace-api/src/main/java/org/dspace/app/ldn/LDNMessageQueueStatus.java similarity index 91% rename from dspace-api/src/main/java/org/dspace/app/ldn/QueueStatus.java rename to dspace-api/src/main/java/org/dspace/app/ldn/LDNMessageQueueStatus.java index 77144ce37c..ad3dd36e69 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/QueueStatus.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/LDNMessageQueueStatus.java @@ -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) diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueExtractor.java b/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueExtractor.java index c11e5922ea..7afadbf89d 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueExtractor.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueExtractor.java @@ -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) { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueTimeoutChecker.java b/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueTimeoutChecker.java index 560f6a172e..acba7fbfca 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueTimeoutChecker.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/LDNQueueTimeoutChecker.java @@ -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); diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/LDNRouter.java b/dspace-api/src/main/java/org/dspace/app/ldn/LDNRouter.java index 31d594e538..14957aa503 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/LDNRouter.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/LDNRouter.java @@ -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 ldnMessageTypeSet = new HashSet(); diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNAction.java b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNAction.java index be1cf6f22c..b0c895de99 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNAction.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNAction.java @@ -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; } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/action/ActionStatus.java b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNActionStatus.java similarity index 91% rename from dspace-api/src/main/java/org/dspace/app/ldn/action/ActionStatus.java rename to dspace-api/src/main/java/org/dspace/app/ldn/action/LDNActionStatus.java index ad0e17fd47..86f56ed9ba 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/action/ActionStatus.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNActionStatus.java @@ -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; } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNCorrectionAction.java b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNCorrectionAction.java index 29cbb791f3..5ce3804bce 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNCorrectionAction.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNCorrectionAction.java @@ -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; diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNEmailAction.java b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNEmailAction.java index eda7ce870b..3d1ad18c45 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNEmailAction.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNEmailAction.java @@ -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; } /** diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNRelationCorrectionAction.java b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNRelationCorrectionAction.java index 7bd36412c7..0c2f5dfc17 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNRelationCorrectionAction.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/action/LDNRelationCorrectionAction.java @@ -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; diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/action/SendLDNMessageAction.java b/dspace-api/src/main/java/org/dspace/app/ldn/action/SendLDNMessageAction.java index 748f0d380b..b11e95972f 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/action/SendLDNMessageAction.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/action/SendLDNMessageAction.java @@ -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; } } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/dao/LDNMessageDao.java b/dspace-api/src/main/java/org/dspace/app/ldn/dao/LDNMessageDao.java index 410c0eec2b..c3f4907cce 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/dao/LDNMessageDao.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/dao/LDNMessageDao.java @@ -25,13 +25,44 @@ import org.dspace.core.GenericDAO; */ public interface LDNMessageDao extends GenericDAO { + /** + * 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 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 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 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 findAllRelatedMessagesByItem( Context context, LDNMessageEntity msg, Item item, String... relatedTypes) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/dao/impl/LDNMessageDaoImpl.java b/dspace-api/src/main/java/org/dspace/app/ldn/dao/impl/LDNMessageDaoImpl.java index b7cc24920f..5cb09bae01 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/dao/impl/LDNMessageDaoImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/dao/impl/LDNMessageDaoImpl.java @@ -39,7 +39,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO im @Override public List findOldestMessageToProcess(Context context, int max_attempts) throws SQLException { - // looking for oldest failed-processed message CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, LDNMessageEntity.class); Root root = criteriaQuery.from(LDNMessageEntity.class); @@ -54,7 +53,6 @@ public class LDNMessageDaoImpl extends AbstractHibernateDAO 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 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 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 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 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 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 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 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 result = list(context, criteriaQuery, false, LDNMessageEntity.class, -1, -1); if (result == null || result.isEmpty()) { log.debug("No LDN messages found"); diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Actor.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Actor.java index 16b445d7b2..a81cc3f800 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Actor.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Actor.java @@ -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 { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Base.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Base.java index d7709859df..6ddaae110e 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Base.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Base.java @@ -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) diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Citation.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Citation.java index bb4afb1485..c6629f5e7b 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Citation.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Citation.java @@ -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 { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Context.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Context.java index b411c70df5..78fe373416 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Context.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Context.java @@ -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 { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Notification.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Notification.java index 2c441afebc..52bc9840f4 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Notification.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Notification.java @@ -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. + * see official coar doc */ @JsonPropertyOrder(value = { "@context", diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Object.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Object.java index ebbffdbf4d..8913af47da 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Object.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Object.java @@ -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 { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Service.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Service.java index c4f261f5e8..cdd3ba5bb5 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Service.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Service.java @@ -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 { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/model/Url.java b/dspace-api/src/main/java/org/dspace/app/ldn/model/Url.java index 4df258289b..694afed654 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/model/Url.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/model/Url.java @@ -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 { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNContextRepeater.java b/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNContextRepeater.java index 229fce26b0..a5ef0957ff 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNContextRepeater.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNContextRepeater.java @@ -50,7 +50,7 @@ public class LDNContextRepeater { /** * @param notification - * @return Iterator + * @return Iterator */ public Iterator 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()) { diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNMetadataProcessor.java b/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNMetadataProcessor.java index 5551b99f69..223c8b7a34 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNMetadataProcessor.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/processor/LDNMetadataProcessor.java @@ -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; } } diff --git a/dspace-api/src/main/java/org/dspace/app/ldn/service/impl/LDNMessageServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/ldn/service/impl/LDNMessageServiceImpl.java index f2d44237ed..4244e245e4 100644 --- a/dspace-api/src/main/java/org/dspace/app/ldn/service/impl/LDNMessageServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/ldn/service/impl/LDNMessageServiceImpl.java @@ -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); diff --git a/dspace-api/src/main/java/org/dspace/app/suggestion/SolrSuggestionStorageServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/suggestion/SolrSuggestionStorageServiceImpl.java index 9d77fc2886..e684c14db1 100644 --- a/dspace-api/src/main/java/org/dspace/app/suggestion/SolrSuggestionStorageServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/suggestion/SolrSuggestionStorageServiceImpl.java @@ -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>() { - }.getType(); - List evidences = new Gson().fromJson(evidencesJson, listType); - suggestion.getEvidences().addAll(evidences); + ObjectMapper mapper = new ObjectMapper(); + List evidences; + try { + evidences = mapper.readValue(evidencesJson, List.class); + suggestion.getEvidences().addAll(evidences); + } catch (JsonProcessingException e) { + log.error(e); + } return suggestion; } diff --git a/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifyConfigurationService.java b/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifyConfigurationService.java index 368f51745a..de44e811e1 100644 --- a/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifyConfigurationService.java +++ b/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifyConfigurationService.java @@ -21,13 +21,13 @@ public class COARNotifyConfigurationService { * Mapping the submission step process identifier with the configuration * (see configuration at coar-notify.xml) */ - private Map> patterns; + private Map> patterns; - public Map> getPatterns() { + public Map> getPatterns() { return patterns; } - public void setPatterns(Map> patterns) { + public void setPatterns(Map> patterns) { this.patterns = patterns; } diff --git a/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifySubmissionConfiguration.java b/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifySubmissionConfiguration.java index f68ce32162..6be026ff9c 100644 --- a/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifySubmissionConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/coarnotify/COARNotifySubmissionConfiguration.java @@ -26,13 +26,13 @@ public class COARNotifySubmissionConfiguration { * the map values of configured bean of COARNotifyConfigurationService * in coar-notify.xml */ - private List patterns; + private List patterns; public COARNotifySubmissionConfiguration() { } - public COARNotifySubmissionConfiguration(String id, List patterns) { + public COARNotifySubmissionConfiguration(String id, List 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 getPatterns() { + public List 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 patterns) { + public void setPatterns(final List patterns) { this.patterns = patterns; } } diff --git a/dspace-api/src/main/java/org/dspace/coarnotify/LDNPattern.java b/dspace-api/src/main/java/org/dspace/coarnotify/COARPattern.java similarity index 88% rename from dspace-api/src/main/java/org/dspace/coarnotify/LDNPattern.java rename to dspace-api/src/main/java/org/dspace/coarnotify/COARPattern.java index ca65eb86ab..072bcaab02 100644 --- a/dspace-api/src/main/java/org/dspace/coarnotify/LDNPattern.java +++ b/dspace-api/src/main/java/org/dspace/coarnotify/COARPattern.java @@ -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; } diff --git a/dspace-api/src/main/java/org/dspace/coarnotify/SubmissionCOARNotifyServiceImpl.java b/dspace-api/src/main/java/org/dspace/coarnotify/SubmissionCOARNotifyServiceImpl.java index ba99735223..5e34a3e47d 100644 --- a/dspace-api/src/main/java/org/dspace/coarnotify/SubmissionCOARNotifyServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/coarnotify/SubmissionCOARNotifyServiceImpl.java @@ -29,7 +29,7 @@ public class SubmissionCOARNotifyServiceImpl implements SubmissionCOARNotifyServ @Override public COARNotifySubmissionConfiguration findOne(String id) { - List patterns = + List patterns = coarNotifyConfigurationService.getPatterns().get(id); if (patterns == null) { diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.08.02__notifyservices_table.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.08.02__notifyservices_table.sql deleted file mode 100644 index e8c9396cad..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.08.02__notifyservices_table.sql +++ /dev/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); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.08.23__LDN_Messages_table.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.08.23__LDN_Messages_table.sql deleted file mode 100644 index 1529bf4299..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.08.23__LDN_Messages_table.sql +++ /dev/null @@ -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 -); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.09.21__add_enabled_column_notifyservices_table.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.09.21__add_enabled_column_notifyservices_table.sql deleted file mode 100644 index 5e37147cdb..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.09.21__add_enabled_column_notifyservices_table.sql +++ /dev/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; \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.10.05__notifypatterns_to_trigger_table.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.10.05__notifypatterns_to_trigger_table.sql deleted file mode 100644 index 97dfcd11b4..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.10.05__notifypatterns_to_trigger_table.sql +++ /dev/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); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.10.13__add_score_column_notifyservices_table.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.10.13__add_score_column_notifyservices_table.sql deleted file mode 100644 index 2be6684f9c..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.10.13__add_score_column_notifyservices_table.sql +++ /dev/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 score column ------------------------------------------------------------------------------------ - -ALTER TABLE notifyservice ADD COLUMN score NUMERIC(6, 5); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.12.05__notifyservice_table_unique_ldn_url.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.12.05__notifyservice_table_unique_ldn_url.sql deleted file mode 100644 index 76497df4f9..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2023.12.05__notifyservice_table_unique_ldn_url.sql +++ /dev/null @@ -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); - diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.01.12__notifyservice_table_ip_range_coulmns.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.01.12__notifyservice_table_ip_range_coulmns.sql deleted file mode 100644 index 740bd525b8..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.01.12__notifyservice_table_ip_range_coulmns.sql +++ /dev/null @@ -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); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.01.13__ldn_message_table_source_ip_coulmn.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.01.13__ldn_message_table_source_ip_coulmn.sql deleted file mode 100644 index 5ddfc767de..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.01.13__ldn_message_table_source_ip_coulmn.sql +++ /dev/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/ --- - --------------------------------------------------------------------------- --- ADD source_ip columns to ldn_message table --------------------------------------------------------------------------- - -ALTER TABLE ldn_message ADD COLUMN source_ip VARCHAR(45); \ No newline at end of file diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.02.14__ldn_tables.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.02.14__ldn_tables.sql new file mode 100644 index 0000000000..f5ea59254f --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V8.0_2024.02.14__ldn_tables.sql @@ -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); diff --git a/dspace-api/src/test/java/org/dspace/app/ldn/action/SendLDNMessageActionIT.java b/dspace-api/src/test/java/org/dspace/app/ldn/action/SendLDNMessageActionIT.java index e206c6ae68..3623a5bc06 100644 --- a/dspace-api/src/test/java/org/dspace/app/ldn/action/SendLDNMessageActionIT.java +++ b/dspace-api/src/test/java/org/dspace/app/ldn/action/SendLDNMessageActionIT.java @@ -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; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionCOARNotifyRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionCOARNotifyRest.java index 0f414b3724..ac03e90a2e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionCOARNotifyRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SubmissionCOARNotifyRest.java @@ -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 { private String id; - private List patterns; + private List patterns; public String getId() { return id; @@ -37,11 +37,11 @@ public class SubmissionCOARNotifyRest extends BaseObjectRest { this.id = id; } - public List getPatterns() { + public List getPatterns() { return patterns; } - public void setPatterns(final List patterns) { + public void setPatterns(final List patterns) { this.patterns = patterns; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/COARNotifySubmissionService.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/COARNotifySubmissionService.java index b560d5c916..0731b76e89 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/COARNotifySubmissionService.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/COARNotifySubmissionService.java @@ -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 patterns = coarNotifyConfigurationService.getPatterns().get(config); + List 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)); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/COARNotifyValidation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/COARNotifyValidation.java index 7f2d07b302..3e2e98d596 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/COARNotifyValidation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/COARNotifyValidation.java @@ -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 patterns = coarNotifyConfigurationService.getPatterns().getOrDefault(config.getId(), List.of()) .stream() - .map(LDNPattern::getPattern) + .map(COARPattern::getPattern) .collect(Collectors.toList()); patterns.forEach(pattern -> { diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LDNInboxControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LDNInboxControllerIT.java index 30f27004ab..99d5b188d0 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/LDNInboxControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/LDNInboxControllerIT.java @@ -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); + message = message.replaceAll("<>", 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 { diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCOARNotifyRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCOARNotifyRestRepositoryIT.java index e00d1099d3..1c50fc1b16 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCOARNotifyRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionCOARNotifyRestRepositoryIT.java @@ -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))) ))); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionCOARNotifyMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionCOARNotifyMatcher.java index d425283821..b4c42b9014 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionCOARNotifyMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionCOARNotifyMatcher.java @@ -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 matchCOARNotifyEntry(String id, List patterns) { + public static Matcher matchCOARNotifyEntry(String id, List 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)))); } diff --git a/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ldn_origin_inbox_unregistered.json b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ldn_origin_inbox_unregistered.json new file mode 100644 index 0000000000..30c5cc5590 --- /dev/null +++ b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ldn_origin_inbox_unregistered.json @@ -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": "<>", + "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": "<>", + "id_oai": "oai:www.openstarts.units.it:<>", + "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" + ] + } \ No newline at end of file diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 086a2c3ab2..589577cedc 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -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 diff --git a/dspace/config/modules/coar-notify-ldn.cfg b/dspace/config/modules/coar-notify-ldn.cfg index 11f9abdc8c..d8ff1a794a 100644 --- a/dspace/config/modules/coar-notify-ldn.cfg +++ b/dspace/config/modules/coar-notify-ldn.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} diff --git a/dspace/config/modules/ldn.cfg b/dspace/config/modules/ldn.cfg deleted file mode 100644 index 35507f447d..0000000000 --- a/dspace/config/modules/ldn.cfg +++ /dev/null @@ -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} diff --git a/dspace/config/registries/coar-types.xml b/dspace/config/registries/coar-types.xml index 5d2bca34ed..39c78e8f8c 100644 --- a/dspace/config/registries/coar-types.xml +++ b/dspace/config/registries/coar-types.xml @@ -51,4 +51,11 @@ Released by + + coar + notify + endorsedBy + Endorsed by + + diff --git a/dspace/config/registries/notify-types.xml b/dspace/config/registries/notify-types.xml deleted file mode 100644 index 1c5cbdff80..0000000000 --- a/dspace/config/registries/notify-types.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Notify fields definition - - - - notify - http://dspace.org/notify - - - - notify - relation - endorsedBy - Endorsed by - - - diff --git a/dspace/config/spring/api/coar-notify.xml b/dspace/config/spring/api/coar-notify.xml index c837ffb82c..0ab8a84615 100644 --- a/dspace/config/spring/api/coar-notify.xml +++ b/dspace/config/spring/api/coar-notify.xml @@ -19,17 +19,17 @@ - + - + - + diff --git a/dspace/config/spring/api/qaevents.xml b/dspace/config/spring/api/qaevents.xml index b3128dd180..69fdd71822 100644 --- a/dspace/config/spring/api/qaevents.xml +++ b/dspace/config/spring/api/qaevents.xml @@ -79,7 +79,7 @@ - +