mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merged in coar-notify-7_CST-12115 (pull request #1251)
[CST-12115] added support to decide if a correction suggestion should be automatically processed Approved-by: Andrea Bollini
This commit is contained in:
@@ -7,11 +7,15 @@
|
||||
*/
|
||||
package org.dspace.app.ldn.action;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.ldn.NotifyServiceEntity;
|
||||
import org.dspace.app.ldn.model.Notification;
|
||||
import org.dspace.app.ldn.service.LDNMessageService;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.QAEvent;
|
||||
import org.dspace.content.service.ItemService;
|
||||
@@ -33,14 +37,16 @@ public class LDNCorrectionAction implements LDNAction {
|
||||
protected ItemService itemService;
|
||||
@Autowired
|
||||
private QAEventService qaEventService;
|
||||
@Autowired
|
||||
private LDNMessageService ldnMessageService;
|
||||
|
||||
@Override
|
||||
public ActionStatus execute(Notification notification, Item item) throws Exception {
|
||||
ActionStatus result = ActionStatus.ABORT;
|
||||
ActionStatus result;
|
||||
Context context = ContextUtil.obtainCurrentRequestContext();
|
||||
QAEvent qaEvent = new QAEvent(QAEvent.COAR_NOTIFY,
|
||||
notification.getObject().getId(), item.getID().toString(), item.getName(),
|
||||
this.getQaEventTopic(), 0d,
|
||||
this.getQaEventTopic(), getScore(context, notification).doubleValue(),
|
||||
"{\"abstracts[0]\": \"" + notification.getObject().getIetfCiteAs() + "\"}"
|
||||
, new Date());
|
||||
qaEventService.store(context, qaEvent);
|
||||
@@ -49,6 +55,21 @@ public class LDNCorrectionAction implements LDNAction {
|
||||
return result;
|
||||
}
|
||||
|
||||
private BigDecimal getScore(Context context, Notification notification) throws SQLException {
|
||||
|
||||
if (notification.getOrigin() == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
NotifyServiceEntity service = ldnMessageService.findNotifyService(context, notification.getOrigin());
|
||||
|
||||
if (service == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return service.getScore();
|
||||
}
|
||||
|
||||
public String getQaEventTopic() {
|
||||
return qaEventTopic;
|
||||
}
|
||||
|
@@ -11,7 +11,9 @@ import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.app.ldn.LDNMessageEntity;
|
||||
import org.dspace.app.ldn.NotifyServiceEntity;
|
||||
import org.dspace.app.ldn.model.Notification;
|
||||
import org.dspace.app.ldn.model.Service;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
/**
|
||||
@@ -94,4 +96,14 @@ public interface LDNMessageService {
|
||||
* @param context The DSpace context
|
||||
*/
|
||||
public int extractAndProcessMessageFromQueue(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* find the related notify service entity
|
||||
*
|
||||
* @param context the context
|
||||
* @param service the service
|
||||
* @return the NotifyServiceEntity
|
||||
* @throws SQLException if something goes wrong
|
||||
*/
|
||||
public NotifyServiceEntity findNotifyService(Context context, Service service) throws SQLException;
|
||||
}
|
||||
|
@@ -148,7 +148,7 @@ public class LDNMessageServiceImpl implements LDNMessageService {
|
||||
return null;
|
||||
}
|
||||
|
||||
private NotifyServiceEntity findNotifyService(Context context, Service service) throws SQLException {
|
||||
public NotifyServiceEntity findNotifyService(Context context, Service service) throws SQLException {
|
||||
return notifyServiceDao.findByLdnUrl(context, service.getInbox());
|
||||
}
|
||||
|
||||
|
@@ -197,6 +197,7 @@ public class QAEvent {
|
||||
public Class<? extends QAMessageDTO> getMessageDtoClass() {
|
||||
switch (getSource()) {
|
||||
case OPENAIRE_SOURCE:
|
||||
case COAR_NOTIFY:
|
||||
return OpenaireMessageDTO.class;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown event's source: " + getSource());
|
||||
|
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.qaevent;
|
||||
|
||||
/**
|
||||
* Enumeration of possible actions to perform over a {@link org.dspace.content.QAEvent}
|
||||
*
|
||||
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
|
||||
*/
|
||||
public enum AutomaticProcessingAction {
|
||||
REJECT, ACCEPT, IGNORE
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.qaevent;
|
||||
|
||||
import org.dspace.content.QAEvent;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
/**
|
||||
* This interface allows the implemnetation of Automation Processing rules
|
||||
* defining which {@link AutomaticProcessingAction} should be eventually
|
||||
* performed on a specific {@link QAEvent}
|
||||
*
|
||||
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
|
||||
*/
|
||||
public interface QAEventAutomaticProcessingEvaluation {
|
||||
|
||||
/**
|
||||
* Evaluate a {@link QAEvent} to decide which, if any, {@link AutomaticProcessingAction} should be performed
|
||||
*
|
||||
* @param context the DSpace context
|
||||
* @param qaEvent the quality assurance event
|
||||
* @return an action of {@link AutomaticProcessingAction} or null if no automatic action should be performed
|
||||
*/
|
||||
AutomaticProcessingAction evaluateAutomaticProcessing(Context context, QAEvent qaEvent);
|
||||
|
||||
}
|
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.qaevent;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.QAEvent;
|
||||
import org.dspace.content.logic.LogicalStatement;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Context;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* A configurable implementation of {@link QAEventAutomaticProcessingEvaluation} allowing to define thresholds for
|
||||
* automatic acceptance, rejection or ignore of {@link QAEvent} matching a specific, optional, item filter
|
||||
* {@link LogicalStatement}. If the item filter is not defined only the score threshold will be used.
|
||||
*
|
||||
* @author Mohamed Eskander (mohamed.eskander at 4science.com)
|
||||
*/
|
||||
public class QAScoreAutomaticProcessingEvaluation implements QAEventAutomaticProcessingEvaluation {
|
||||
/**
|
||||
* The minimum score of QAEvent to be considered for automatic approval (trust must be greater or equals to that)
|
||||
*/
|
||||
private double scoreToApprove;
|
||||
|
||||
/**
|
||||
* The threshold under which QAEvent are considered for automatic ignore (trust must be less or equals to that)
|
||||
*/
|
||||
private double scoreToIgnore;
|
||||
|
||||
/**
|
||||
* The threshold under which QAEvent are considered for automatic rejection (trust must be less or equals to that)
|
||||
*/
|
||||
private double scoreToReject;
|
||||
|
||||
/**
|
||||
* The optional logical statement that must pass for item target of a QAEvent to be considered for automatic
|
||||
* approval
|
||||
*/
|
||||
private LogicalStatement itemFilterToApprove;
|
||||
|
||||
/**
|
||||
* The optional logical statement that must pass for item target of a QAEvent to be considered for automatic
|
||||
* ignore
|
||||
*/
|
||||
private LogicalStatement itemFilterToIgnore;
|
||||
|
||||
/**
|
||||
* The optional logical statement that must pass for item target of a QAEvent to be considered for automatic
|
||||
* rejection
|
||||
*/
|
||||
private LogicalStatement itemFilterToReject;
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@Override
|
||||
public AutomaticProcessingAction evaluateAutomaticProcessing(Context context, QAEvent qaEvent) {
|
||||
Item item = findItem(context, qaEvent.getTarget());
|
||||
|
||||
if (shouldReject(context, qaEvent.getTrust(), item)) {
|
||||
return AutomaticProcessingAction.REJECT;
|
||||
} else if (shouldIgnore(context, qaEvent.getTrust(), item)) {
|
||||
return AutomaticProcessingAction.IGNORE;
|
||||
} else if (shouldApprove(context, qaEvent.getTrust(), item)) {
|
||||
return AutomaticProcessingAction.ACCEPT;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Item findItem(Context context, String uuid) {
|
||||
try {
|
||||
return itemService.find(context, UUID.fromString(uuid));
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldReject(Context context, double trust, Item item) {
|
||||
return trust <= scoreToReject &&
|
||||
(itemFilterToReject == null || itemFilterToReject.getResult(context, item));
|
||||
}
|
||||
|
||||
private boolean shouldIgnore(Context context, double trust, Item item) {
|
||||
return trust <= scoreToIgnore &&
|
||||
(itemFilterToIgnore == null || itemFilterToIgnore.getResult(context, item));
|
||||
}
|
||||
|
||||
private boolean shouldApprove(Context context, double trust, Item item) {
|
||||
return trust >= scoreToApprove &&
|
||||
(itemFilterToApprove == null || itemFilterToApprove.getResult(context, item));
|
||||
}
|
||||
|
||||
public double getScoreToApprove() {
|
||||
return scoreToApprove;
|
||||
}
|
||||
|
||||
public void setScoreToApprove(double scoreToApprove) {
|
||||
this.scoreToApprove = scoreToApprove;
|
||||
}
|
||||
|
||||
public double getScoreToIgnore() {
|
||||
return scoreToIgnore;
|
||||
}
|
||||
|
||||
public void setScoreToIgnore(double scoreToIgnore) {
|
||||
this.scoreToIgnore = scoreToIgnore;
|
||||
}
|
||||
|
||||
public double getScoreToReject() {
|
||||
return scoreToReject;
|
||||
}
|
||||
|
||||
public void setScoreToReject(double scoreToReject) {
|
||||
this.scoreToReject = scoreToReject;
|
||||
}
|
||||
|
||||
public LogicalStatement getItemFilterToApprove() {
|
||||
return itemFilterToApprove;
|
||||
}
|
||||
|
||||
public void setItemFilterToApprove(LogicalStatement itemFilterToApprove) {
|
||||
this.itemFilterToApprove = itemFilterToApprove;
|
||||
}
|
||||
|
||||
public LogicalStatement getItemFilterToIgnore() {
|
||||
return itemFilterToIgnore;
|
||||
}
|
||||
|
||||
public void setItemFilterToIgnore(LogicalStatement itemFilterToIgnore) {
|
||||
this.itemFilterToIgnore = itemFilterToIgnore;
|
||||
}
|
||||
|
||||
public LogicalStatement getItemFilterToReject() {
|
||||
return itemFilterToReject;
|
||||
}
|
||||
|
||||
public void setItemFilterToReject(LogicalStatement itemFilterToReject) {
|
||||
this.itemFilterToReject = itemFilterToReject;
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -41,14 +42,18 @@ import org.dspace.content.QAEvent;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.service.HandleService;
|
||||
import org.dspace.qaevent.AutomaticProcessingAction;
|
||||
import org.dspace.qaevent.QAEventAutomaticProcessingEvaluation;
|
||||
import org.dspace.qaevent.QASource;
|
||||
import org.dspace.qaevent.QATopic;
|
||||
import org.dspace.qaevent.dao.QAEventsDao;
|
||||
import org.dspace.qaevent.dao.impl.QAEventsDaoImpl;
|
||||
import org.dspace.qaevent.service.QAEventActionService;
|
||||
import org.dspace.qaevent.service.QAEventService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
/**
|
||||
* Implementation of {@link QAEventService} that use Solr to store events. When
|
||||
@@ -73,6 +78,13 @@ public class QAEventServiceImpl implements QAEventService {
|
||||
@Autowired
|
||||
private QAEventsDaoImpl qaEventsDao;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("qaAutomaticProcessingMap")
|
||||
private Map<String, QAEventAutomaticProcessingEvaluation> qaAutomaticProcessingMap;
|
||||
|
||||
@Autowired
|
||||
private QAEventActionService qaEventActionService;
|
||||
|
||||
private ObjectMapper jsonMapper;
|
||||
|
||||
public QAEventServiceImpl() {
|
||||
@@ -321,12 +333,43 @@ public class QAEventServiceImpl implements QAEventService {
|
||||
updateRequest.process(getSolr());
|
||||
|
||||
getSolr().commit();
|
||||
|
||||
performAutomaticProcessingIfNeeded(context, dto);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void performAutomaticProcessingIfNeeded(Context context, QAEvent qaEvent) {
|
||||
QAEventAutomaticProcessingEvaluation evaluation = qaAutomaticProcessingMap.get(qaEvent.getSource());
|
||||
|
||||
if (evaluation == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutomaticProcessingAction action = evaluation.evaluateAutomaticProcessing(context, qaEvent);
|
||||
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case REJECT:
|
||||
qaEventActionService.reject(context, qaEvent);
|
||||
break;
|
||||
case IGNORE:
|
||||
qaEventActionService.discard(context, qaEvent);
|
||||
break;
|
||||
case ACCEPT:
|
||||
qaEventActionService.accept(context, qaEvent);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown automatic action requested " + action);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public QAEvent findEventByEventId(String eventId) {
|
||||
SolrQuery param = new SolrQuery(EVENT_ID + ":" + eventId);
|
||||
|
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<context:annotation-config /> <!-- allows us to use spring annotations in beans -->
|
||||
|
||||
<!-- this file contains extra beans related to the qaevent feature configured only for test purpose -->
|
||||
<util:map id="qaAutomaticProcessingMap">
|
||||
<entry key="coar-notify" value-ref="qaScoreEvaluation"/>
|
||||
</util:map>
|
||||
|
||||
<bean id="qaScoreEvaluation" class="org.dspace.qaevent.QAScoreAutomaticProcessingEvaluation">
|
||||
<property name="scoreToReject" value="0.3" />
|
||||
<property name="scoreToIgnore" value="0.5" />
|
||||
<property name="scoreToApprove" value="0.8" />
|
||||
<property name="itemFilterToReject" ref="simple-demo_filter" />
|
||||
<property name="itemFilterToIgnore" ref="simple-demo_filter" />
|
||||
<property name="itemFilterToApprove" ref="simple-demo_filter" />
|
||||
</bean>
|
||||
</beans>
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest;
|
||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
||||
import static org.dspace.app.rest.matcher.QAEventMatcher.matchQAEventEntry;
|
||||
import static org.dspace.content.QAEvent.COAR_NOTIFY;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
@@ -831,4 +832,140 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest {
|
||||
assertThat(processedEvent.getEperson().getID(), is(admin.getID()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQAEventsAndAcceptAutomaticallyByScoreAndFilterTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
|
||||
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||
Item item = ItemBuilder.createItem(context, col1).withTitle("demo").build();
|
||||
|
||||
QAEvent event =
|
||||
QAEventBuilder.createTarget(context, item)
|
||||
.withSource(COAR_NOTIFY)
|
||||
.withTrust(0.8)
|
||||
.withTopic("ENRICH/MORE/REVIEW")
|
||||
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String authToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(authToken).perform(get("/api/core/items/" + item.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.metadata['datacite.relation.isReviewedBy'][0].value",
|
||||
is("https://doi.org/10.3214/987654")));
|
||||
|
||||
getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQAEventsAndIgnoreAutomaticallyByScoreAndFilterTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
|
||||
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||
Item item = ItemBuilder.createItem(context, col1).withTitle("demo").build();
|
||||
|
||||
QAEvent event =
|
||||
QAEventBuilder.createTarget(context, item)
|
||||
.withSource(COAR_NOTIFY)
|
||||
.withTrust(0.4)
|
||||
.withTopic("ENRICH/MORE/REVIEW")
|
||||
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String authToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(authToken).perform(get("/api/core/items/" + item.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.metadata['datacite.relation.isReviewedBy']").doesNotExist());
|
||||
|
||||
getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQAEventsAndRejectAutomaticallyByScoreAndFilterTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
|
||||
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||
Item item = ItemBuilder.createItem(context, col1).withTitle("demo").build();
|
||||
|
||||
QAEvent event =
|
||||
QAEventBuilder.createTarget(context, item)
|
||||
.withSource(COAR_NOTIFY)
|
||||
.withTrust(0.3)
|
||||
.withTopic("ENRICH/MORE/REVIEW")
|
||||
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String authToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(authToken).perform(get("/api/core/items/" + item.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.metadata['datacite.relation.isReviewedBy']").doesNotExist());
|
||||
|
||||
getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQAEventsAndDoNothingScoreNotInRangTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
|
||||
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||
Item item = ItemBuilder.createItem(context, col1).withTitle("demo").build();
|
||||
|
||||
QAEvent event =
|
||||
QAEventBuilder.createTarget(context, item)
|
||||
.withSource(COAR_NOTIFY)
|
||||
.withTrust(0.7)
|
||||
.withTopic("ENRICH/MORE/REVIEW")
|
||||
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String authToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(authToken).perform(get("/api/core/items/" + item.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.metadata['datacite.relation.isReviewedBy']").doesNotExist());
|
||||
|
||||
getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId())
|
||||
.param("projection", "full"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createQAEventsAndDoNothingFilterNotCompatibleWithItemTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build();
|
||||
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||
Item item = ItemBuilder.createItem(context, col1).withTitle("item title").build();
|
||||
|
||||
QAEvent event =
|
||||
QAEventBuilder.createTarget(context, item)
|
||||
.withSource(COAR_NOTIFY)
|
||||
.withTrust(0.8)
|
||||
.withTopic("ENRICH/MORE/REVIEW")
|
||||
.withMessage("{\"abstracts[0]\": \"https://doi.org/10.3214/987654\"}")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String authToken = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(authToken).perform(get("/api/core/items/" + item.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.metadata['datacite.relation.isReviewedBy']").doesNotExist());
|
||||
|
||||
getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId())
|
||||
.param("projection", "full"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -928,6 +928,7 @@ registry.metadata.load = schema-publicationVolume-types.xml
|
||||
registry.metadata.load = openaire4-types.xml
|
||||
registry.metadata.load = dspace-types.xml
|
||||
registry.metadata.load = iiif-types.xml
|
||||
registry.metadata.load = datacite-types.xml
|
||||
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
|
@@ -2,10 +2,13 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
|
||||
http://www.springframework.org/schema/context/spring-context-2.5.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<context:annotation-config /> <!-- allows us to use spring annotations in beans -->
|
||||
|
||||
@@ -72,5 +75,25 @@
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<!--
|
||||
To configure rules to automatic process specific qaevent you must provide a qaAutomaticProcessingMap
|
||||
where the keys are the qaevent source provider name and the value is a reference to a
|
||||
AutomaticProcessingEvaluation implementation. Below you can find an example of configuration defining
|
||||
some thresholds rules for the coar-notify generated QAEvent to be approved, rejected and ignored
|
||||
-->
|
||||
<!--
|
||||
<util:map id="qaAutomaticProcessingMap">
|
||||
<entry key="coar-notify" value-ref="qaScoreEvaluation"/>
|
||||
</util:map>
|
||||
|
||||
<bean id="qaScoreEvaluation" class="org.dspace.qaevent.QAScoreAutomaticProcessingEvaluation">
|
||||
<property name="scoreToReject" value="0.3" />
|
||||
<property name="scoreToIgnore" value="0.5" />
|
||||
<property name="scoreToApprove" value="0.8" />
|
||||
<property name="itemFilterToReject" ref="simple-demo_filter" />
|
||||
<property name="itemFilterToIgnore" ref="simple-demo_filter" />
|
||||
<property name="itemFilterToApprove" ref="simple-demo_filter" />
|
||||
</bean>
|
||||
-->
|
||||
</beans>
|
||||
|
Reference in New Issue
Block a user