From 75d9d6747ed5853e71074397fa984f003791971c Mon Sep 17 00:00:00 2001 From: Andrea Bollini Date: Tue, 2 Feb 2021 19:24:37 +0100 Subject: [PATCH 01/38] Enrich local data via the OpenAIRE Graph --- .../java/org/dspace/app/nbevent/NBAction.java | 16 + .../app/nbevent/NBEntityMetadataAction.java | 157 ++ .../app/nbevent/NBEventActionService.java | 19 + .../app/nbevent/NBEventActionServiceImpl.java | 116 + .../NBEventsCliScriptConfiguration.java | 23 + .../NBEventsDeleteCascadeConsumer.java | 51 + .../dspace/app/nbevent/NBEventsRunnable.java | 141 ++ .../app/nbevent/NBEventsRunnableCli.java | 48 + .../nbevent/NBEventsScriptConfiguration.java | 63 + .../app/nbevent/NBMetadataMapAction.java | 64 + .../app/nbevent/NBSimpleMetadataAction.java | 55 + .../java/org/dspace/app/nbevent/NBTopic.java | 46 + .../app/nbevent/RawJsonDeserializer.java | 29 + .../dspace/app/nbevent/dao/NBEventsDao.java | 36 + .../app/nbevent/dao/impl/NBEventsDaoImpl.java | 58 + .../app/nbevent/service/NBEventService.java | 39 + .../app/nbevent/service/dto/MessageDto.java | 168 ++ .../service/impl/NBEventServiceImpl.java | 340 +++ .../main/java/org/dspace/content/NBEvent.java | 189 ++ .../org/dspace/content/NBEventProcessed.java | 82 + .../h2/V7.0_2020.10.16__nbevent_processed.sql | 16 + .../V7.0_2020.10.16__nbevent_processed.sql | 19 + .../V7.0_2020.10.16__nbevent_processed.sql | 19 + .../test/data/dspaceFolder/config/local.cfg | 4 +- .../config/spring/api/solr-services.xml | 4 + .../app/nbevent/MockNBEventService.java | 38 + .../org/dspace/builder/AbstractBuilder.java | 7 +- .../org/dspace/builder/NBEventBuilder.java | 125 ++ .../app/rest/NBEventRestController.java | 135 ++ .../app/rest/RestResourceController.java | 70 +- .../app/rest/converter/NBEventConverter.java | 74 + .../app/rest/converter/NBTopicConverter.java | 34 + .../app/rest/model/NBEventMessageRest.java | 88 + .../dspace/app/rest/model/NBEventRest.java | 115 + .../dspace/app/rest/model/NBTopicRest.java | 78 + .../rest/model/hateoas/NBEventResource.java | 21 + .../rest/model/hateoas/NBTopicResource.java | 21 + .../NBEventRelatedLinkRepository.java | 77 + .../repository/NBEventRestRepository.java | 127 ++ .../NBEventTargetLinkRepository.java | 73 + .../NBEventTopicLinkRepository.java | 61 + .../repository/NBTopicRestRepository.java | 54 + .../NBEventStatusReplaceOperation.java | 54 + .../org/dspace/app/rest/utils/RegexUtils.java | 2 +- .../app/rest/NBEventRestRepositoryIT.java | 709 ++++++ .../app/rest/NBTopicRestRepositoryIT.java | 169 ++ .../app/rest/matcher/NBEventMatcher.java | 81 + .../app/rest/matcher/NBTopicMatcher.java | 38 + dspace/config/dspace.cfg | 7 +- dspace/config/hibernate.cfg.xml | 2 + dspace/config/modules/oaire-nbevents.cfg | 14 + dspace/config/spring/api/nbevents.xml | 65 + dspace/config/spring/api/scripts.xml | 6 + dspace/config/spring/api/solr-services.xml | 3 + dspace/config/spring/rest/scripts.xml | 5 + dspace/solr/nbevent/conf/admin-extra.html | 31 + dspace/solr/nbevent/conf/elevate.xml | 36 + dspace/solr/nbevent/conf/protwords.txt | 21 + dspace/solr/nbevent/conf/schema.xml | 544 +++++ dspace/solr/nbevent/conf/scripts.conf | 24 + dspace/solr/nbevent/conf/solrconfig.xml | 1943 +++++++++++++++++ dspace/solr/nbevent/conf/spellings.txt | 2 + dspace/solr/nbevent/conf/stopwords.txt | 57 + dspace/solr/nbevent/conf/synonyms.txt | 31 + dspace/solr/nbevent/core.properties | 0 65 files changed, 6836 insertions(+), 8 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnableCli.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsScriptConfiguration.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java create mode 100644 dspace-api/src/main/java/org/dspace/content/NBEvent.java create mode 100644 dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2020.10.16__nbevent_processed.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2020.10.16__nbevent_processed.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2020.10.16__nbevent_processed.sql create mode 100644 dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java create mode 100644 dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java create mode 100644 dspace/config/modules/oaire-nbevents.cfg create mode 100644 dspace/config/spring/api/nbevents.xml create mode 100644 dspace/solr/nbevent/conf/admin-extra.html create mode 100644 dspace/solr/nbevent/conf/elevate.xml create mode 100644 dspace/solr/nbevent/conf/protwords.txt create mode 100644 dspace/solr/nbevent/conf/schema.xml create mode 100644 dspace/solr/nbevent/conf/scripts.conf create mode 100644 dspace/solr/nbevent/conf/solrconfig.xml create mode 100644 dspace/solr/nbevent/conf/spellings.txt create mode 100644 dspace/solr/nbevent/conf/stopwords.txt create mode 100644 dspace/solr/nbevent/conf/synonyms.txt create mode 100644 dspace/solr/nbevent/core.properties diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java new file mode 100644 index 0000000000..782fa53802 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java @@ -0,0 +1,16 @@ +/** + * 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.app.nbevent; + +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.content.Item; +import org.dspace.core.Context; + +public interface NBAction { + public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message); +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java new file mode 100644 index 0000000000..ad575b5281 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java @@ -0,0 +1,157 @@ +/** + * 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.app.nbevent; + +import java.sql.SQLException; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Collection; +import org.dspace.content.EntityType; +import org.dspace.content.Item; +import org.dspace.content.Relationship; +import org.dspace.content.RelationshipType; +import org.dspace.content.WorkspaceItem; +import org.dspace.content.service.EntityTypeService; +import org.dspace.content.service.InstallItemService; +import org.dspace.content.service.ItemService; +import org.dspace.content.service.RelationshipService; +import org.dspace.content.service.RelationshipTypeService; +import org.dspace.content.service.WorkspaceItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; + +public class NBEntityMetadataAction implements NBAction { + private String relation; + private String entityType; + private Map entityMetadata; + + @Autowired + private InstallItemService installItemService; + + @Autowired + private ItemService itemService; + + @Autowired + private EntityTypeService entityTypeService; + + @Autowired + private RelationshipService relationshipService; + + @Autowired + private RelationshipTypeService relationshipTypeService; + + @Autowired + private WorkspaceItemService workspaceItemService; + + public void setItemService(ItemService itemService) { + this.itemService = itemService; + } + + public String getRelation() { + return relation; + } + + public void setRelation(String relation) { + this.relation = relation; + } + + public String[] splitMetadata(String metadata) { + String[] result = new String[3]; + String[] split = metadata.split("\\."); + result[0] = split[0]; + result[1] = split[1]; + if (split.length == 3) { + result[2] = split[2]; + } + return result; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public Map getEntityMetadata() { + return entityMetadata; + } + + public void setEntityMetadata(Map entityMetadata) { + this.entityMetadata = entityMetadata; + } + + @Override + public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message) { + try { + if (relatedItem != null) { + link(context, item, relatedItem); + } else { + Collection collection = item.getOwningCollection(); + WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); + relatedItem = workspaceItem.getItem(); + if (StringUtils.isNotBlank(entityType)) { + itemService.addMetadata(context, relatedItem, "relationship", "type", null, null, entityType); + } + for (String key : entityMetadata.keySet()) { + String value = getValue(message, key); + if (StringUtils.isNotBlank(value)) { + String[] targetMetadata = splitMetadata(entityMetadata.get(key)); + itemService.addMetadata(context, relatedItem, targetMetadata[0], targetMetadata[1], + targetMetadata[2], null, value); + } + } + installItemService.installItem(context, workspaceItem); + itemService.update(context, relatedItem); + link(context, item, relatedItem); + } + } catch (SQLException | AuthorizeException e) { + throw new RuntimeException(e); + } + } + + private void link(Context context, Item item, Item relatedItem) throws SQLException, AuthorizeException { + EntityType project = entityTypeService.findByEntityType(context, entityType); + RelationshipType relType = relationshipTypeService.findByEntityType(context, project).stream() + .filter(r -> StringUtils.equals(r.getRightwardType(), relation)).findFirst() + .orElseThrow(() -> new IllegalStateException("No relationshipType named " + relation + + " was found for the entity type " + entityType + + ". A proper configuration is required to use the NBEntitiyMetadataAction." + + " If you don't manage funding in your repository please skip this topic in" + + " the oaire-nbevents.cfg")); + // Create the relationship + int leftPlace = relationshipService.findNextLeftPlaceByLeftItem(context, item); + int rightPlace = relationshipService.findNextRightPlaceByRightItem(context, relatedItem); + Relationship persistedRelationship = relationshipService.create(context, item, relatedItem, + relType, leftPlace, rightPlace); + relationshipService.update(context, persistedRelationship); + } + + private String getValue(MessageDto message, String key) { + if (StringUtils.equals(key, "acronym")) { + return message.getAcronym(); + } else if (StringUtils.equals(key, "code")) { + return message.getCode(); + } else if (StringUtils.equals(key, "funder")) { + return message.getFunder(); + } else if (StringUtils.equals(key, "fundingProgram")) { + return message.getFundingProgram(); + } else if (StringUtils.equals(key, "jurisdiction")) { + return message.getJurisdiction(); + } else if (StringUtils.equals(key, "openaireId")) { + return message.getOpenaireId(); + } else if (StringUtils.equals(key, "title")) { + return message.getTitle(); + } + return null; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java new file mode 100644 index 0000000000..0a4de9c7fb --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java @@ -0,0 +1,19 @@ +/** + * 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.app.nbevent; + +import org.dspace.content.NBEvent; +import org.dspace.core.Context; + +public interface NBEventActionService { + public void accept(Context context, NBEvent nbevent); + + public void discard(Context context, NBEvent nbevent); + + public void reject(Context context, NBEvent nbevent); +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java new file mode 100644 index 0000000000..b34ac6cd25 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java @@ -0,0 +1,116 @@ +/** + * 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.app.nbevent; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Map; +import java.util.UUID; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.logging.log4j.Logger; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.dspace.services.ConfigurationService; +import org.springframework.beans.factory.annotation.Autowired; + +public class NBEventActionServiceImpl implements NBEventActionService { + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(NBEventActionServiceImpl.class); + + private ObjectMapper jsonMapper; + + @Autowired + private NBEventService nbEventService; + + @Autowired + private ItemService itemService; + + @Autowired + private ConfigurationService configurationService; + + private Map topicsToActions; + + public void setTopicsToActions(Map topicsToActions) { + this.topicsToActions = topicsToActions; + } + + public Map getTopicsToActions() { + return topicsToActions; + } + + public NBEventActionServiceImpl() { + jsonMapper = new JsonMapper(); + jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + @Override + public void accept(Context context, NBEvent nbevent) { + Item item = null; + Item related = null; + try { + item = itemService.find(context, UUID.fromString(nbevent.getTarget())); + if (nbevent.getRelated() != null) { + related = itemService.find(context, UUID.fromString(nbevent.getRelated())); + } + topicsToActions.get(nbevent.getTopic()).applyCorrection(context, item, related, + jsonMapper.readValue(nbevent.getMessage(), MessageDto.class)); + nbEventService.deleteEventByEventId(context, nbevent.getEventId()); + makeAcknowledgement(nbevent.getEventId(), NBEvent.ACCEPTED); + } catch (SQLException | JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + @Override + public void discard(Context context, NBEvent nbevent) { + nbEventService.deleteEventByEventId(context, nbevent.getEventId()); + makeAcknowledgement(nbevent.getEventId(), NBEvent.DISCARDED); + } + + @Override + public void reject(Context context, NBEvent nbevent) { + nbEventService.deleteEventByEventId(context, nbevent.getEventId()); + makeAcknowledgement(nbevent.getEventId(), NBEvent.REJECTED); + } + + private void makeAcknowledgement(String eventId, String status) { + String[] ackwnoledgeCallbacks = configurationService.getArrayProperty("oaire-nbevents.acknowledge-url"); + if (ackwnoledgeCallbacks != null) { + for (String ackwnoledgeCallback : ackwnoledgeCallbacks) { + if (StringUtils.isNotBlank(ackwnoledgeCallback)) { + ObjectNode node = jsonMapper.createObjectNode(); + node.put("eventId", eventId); + node.put("status", status); + StringEntity requestEntity = new StringEntity(node.toString(), ContentType.APPLICATION_JSON); + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpPost postMethod = new HttpPost(ackwnoledgeCallback); + postMethod.setEntity(requestEntity); + try { + httpclient.execute(postMethod); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + } + } + } +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java new file mode 100644 index 0000000000..d6671676a0 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java @@ -0,0 +1,23 @@ +/** + * 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.app.nbevent; + +import org.apache.commons.cli.Options; + +public class NBEventsCliScriptConfiguration extends NBEventsScriptConfiguration { + + @Override + public Options getOptions() { + Options options = super.getOptions(); + options.addOption("h", "help", false, "help"); + options.getOption("h").setType(boolean.class); + super.options = options; + return options; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java new file mode 100644 index 0000000000..0eba13e90b --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java @@ -0,0 +1,51 @@ +/** + * 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.app.nbevent; + +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.core.Constants; +import org.dspace.core.Context; +import org.dspace.event.Consumer; +import org.dspace.event.Event; +import org.dspace.utils.DSpace; + +/** + * Consumer to delete nbevents once the target item is deleted + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +public class NBEventsDeleteCascadeConsumer implements Consumer { + + private NBEventService nbEventService; + + @Override + @SuppressWarnings("unchecked") + public void initialize() throws Exception { + nbEventService = new DSpace().getSingletonService(NBEventService.class); + } + + @Override + public void finish(Context context) throws Exception { + + } + + @Override + public void consume(Context context, Event event) throws Exception { + if (event.getEventType() == Event.DELETE) { + if (event.getSubjectType() == Constants.ITEM && event.getSubjectID() != null) { + nbEventService.deleteEventsByTargetId(context, event.getSubjectID()); + } + } + } + + public void end(Context context) throws Exception { + } + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java new file mode 100644 index 0000000000..fc0e7b9dae --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java @@ -0,0 +1,141 @@ +/** + * 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.app.nbevent; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.SQLException; +import java.util.List; +import java.util.UUID; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import org.apache.commons.cli.ParseException; +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.content.NBEvent; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.eperson.factory.EPersonServiceFactory; +import org.dspace.scripts.DSpaceRunnable; +import org.dspace.services.ConfigurationService; +import org.dspace.utils.DSpace; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of {@link DSpaceRunnable} to perfom a NBEvents import from file. + * + * @author Alessandro Martelli (alessandro.martelli at 4science.it) + * + */ +public class NBEventsRunnable extends DSpaceRunnable> { + + private static final Logger LOGGER = LoggerFactory.getLogger(NBEventsRunnable.class); + + protected NBEventService nbEventService; + + protected String[] topicsToImport; + + protected ConfigurationService configurationService; + + protected String fileLocation; + + protected List entries; + + protected Context context; + + @Override + @SuppressWarnings({ "rawtypes" }) + public NBEventsScriptConfiguration getScriptConfiguration() { + NBEventsScriptConfiguration configuration = new DSpace().getServiceManager() + .getServiceByName("import-nbevents", NBEventsScriptConfiguration.class); + return configuration; + } + + @Override + public void setup() throws ParseException { + DSpace dspace = new DSpace(); + + nbEventService = dspace.getSingletonService(NBEventService.class); + if (nbEventService == null) { + LOGGER.error("nbEventService is NULL. Error in spring configuration"); + throw new IllegalStateException(); + } else { + LOGGER.debug("nbEventService correctly loaded"); + } + + configurationService = dspace.getConfigurationService(); + + topicsToImport = configurationService.getArrayProperty("oaire-nbevents.import.topic"); + + fileLocation = commandLine.getOptionValue("f"); + + } + + @Override + public void internalRun() throws Exception { + + if (StringUtils.isEmpty(fileLocation)) { + LOGGER.info("No file location was entered"); + System.exit(1); + } + + context = new Context(); + + ObjectMapper jsonMapper = new JsonMapper(); + jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + try { + this.entries = jsonMapper.readValue(getNBEventsInputStream(), new TypeReference>() { + }); + } catch (IOException e) { + LOGGER.error("File is not found or not readable: " + fileLocation); + e.printStackTrace(); + System.exit(1); + } + + for (NBEvent entry : entries) { + if (!StringUtils.equalsAny(entry.getTopic(), topicsToImport)) { + LOGGER.info("Skip event for topic " + entry.getTopic() + " is not allowed in the oaire-nbevents.cfg"); + continue; + } + try { + nbEventService.store(context, entry); + } catch (RuntimeException e) { + System.out.println("Skip event for originalId " + entry.getOriginalId() + ": " + e.getMessage()); + } + } + + } + + /** + * Obtain an InputStream from the runnable instance. + * @return + * @throws Exception + */ + protected InputStream getNBEventsInputStream() throws Exception { + + this.assignCurrentUserInContext(); + + InputStream inputStream = handler.getFileStream(context, fileLocation) + .orElseThrow(() -> new IllegalArgumentException("Error reading file, the file couldn't be " + + "found for filename: " + fileLocation)); + + return inputStream; + } + + private void assignCurrentUserInContext() throws SQLException { + UUID uuid = getEpersonIdentifier(); + if (uuid != null) { + EPerson ePerson = EPersonServiceFactory.getInstance().getEPersonService().find(context, uuid); + context.setCurrentUser(ePerson); + } + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnableCli.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnableCli.java new file mode 100644 index 0000000000..2e33b6bfad --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnableCli.java @@ -0,0 +1,48 @@ +/** + * 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.app.nbevent; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.ParseException; +import org.dspace.utils.DSpace; + +public class NBEventsRunnableCli extends NBEventsRunnable { + + @Override + @SuppressWarnings({ "rawtypes" }) + public NBEventsCliScriptConfiguration getScriptConfiguration() { + NBEventsCliScriptConfiguration configuration = new DSpace().getServiceManager() + .getServiceByName("import-nbevents", NBEventsCliScriptConfiguration.class); + return configuration; + } + + @Override + public void setup() throws ParseException { + super.setup(); + + // in case of CLI we show the help prompt + if (commandLine.hasOption('h')) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("Import Notification event json file", getScriptConfiguration().getOptions()); + System.exit(0); + } + } + + /** + * Get the events input stream from a local file. + */ + @Override + protected InputStream getNBEventsInputStream() throws Exception { + return new FileInputStream(new File(fileLocation)); + } + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsScriptConfiguration.java new file mode 100644 index 0000000000..0826e5173d --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsScriptConfiguration.java @@ -0,0 +1,63 @@ +/** + * 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.app.nbevent; + +import java.io.InputStream; +import java.sql.SQLException; + +import org.apache.commons.cli.Options; +import org.dspace.authorize.service.AuthorizeService; +import org.dspace.core.Context; +import org.dspace.scripts.configuration.ScriptConfiguration; +import org.springframework.beans.factory.annotation.Autowired; + +public class NBEventsScriptConfiguration extends ScriptConfiguration { + + @Autowired + private AuthorizeService authorizeService; + + private Class dspaceRunnableClass; + + @Override + public Class getDspaceRunnableClass() { + return dspaceRunnableClass; + } + + /** + * Generic setter for the dspaceRunnableClass + * @param dspaceRunnableClass The dspaceRunnableClass to be set on this NBEventsScriptConfiguration + */ + @Override + public void setDspaceRunnableClass(Class dspaceRunnableClass) { + this.dspaceRunnableClass = dspaceRunnableClass; + } + + @Override + public boolean isAllowedToExecute(Context context) { + try { + return authorizeService.isAdmin(context); + } catch (SQLException e) { + throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e); + } + } + + @Override + public Options getOptions() { + if (options == null) { + Options options = new Options(); + + options.addOption("f", "file", true, "Import data from OpenAIRE notification broker files"); + options.getOption("f").setType(InputStream.class); + options.getOption("f").setRequired(true); + + super.options = options; + } + return options; + } + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java new file mode 100644 index 0000000000..ca198abaac --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java @@ -0,0 +1,64 @@ +/** + * 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.app.nbevent; + +import java.sql.SQLException; +import java.util.Map; + +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Item; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; + +public class NBMetadataMapAction implements NBAction { + public static final String DEFAULT = "default"; + + private Map types; + @Autowired + private ItemService itemService; + + public void setItemService(ItemService itemService) { + this.itemService = itemService; + } + + public Map getTypes() { + return types; + } + + public void setTypes(Map types) { + this.types = types; + } + + @Override + public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message) { + try { + String targetMetadata = types.get(message.getType()); + if (targetMetadata == null) { + targetMetadata = types.get(DEFAULT); + } + String[] metadata = splitMetadata(targetMetadata); + itemService.addMetadata(context, item, metadata[0], metadata[1], metadata[2], null, message.getValue()); + itemService.update(context, item); + } catch (SQLException | AuthorizeException e) { + throw new RuntimeException(e); + } + } + + public String[] splitMetadata(String metadata) { + String[] result = new String[3]; + String[] split = metadata.split("\\."); + result[0] = split[0]; + result[1] = split[1]; + if (split.length == 3) { + result[2] = split[2]; + } + return result; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java new file mode 100644 index 0000000000..33eaebcfaa --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java @@ -0,0 +1,55 @@ +/** + * 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.app.nbevent; + +import java.sql.SQLException; + +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Item; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; + +public class NBSimpleMetadataAction implements NBAction { + private String metadata; + private String metadataSchema; + private String metadataElement; + private String metadataQualifier; + @Autowired + private ItemService itemService; + + public void setItemService(ItemService itemService) { + this.itemService = itemService; + } + + public String getMetadata() { + return metadata; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + String[] split = metadata.split("\\."); + this.metadataSchema = split[0]; + this.metadataElement = split[1]; + if (split.length == 3) { + this.metadataQualifier = split[2]; + } + } + + @Override + public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message) { + try { + itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null, + message.getAbstracts()); + itemService.update(context, item); + } catch (SQLException | AuthorizeException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java new file mode 100644 index 0000000000..afa9990d3d --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java @@ -0,0 +1,46 @@ +/** + * 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.app.nbevent; + +import java.util.Date; + +/** + * This model class represent the notification broker topic concept + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +public class NBTopic { + private String key; + private long totalEvents; + private Date lastEvent; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public long getTotalEvents() { + return totalEvents; + } + + public void setTotalEvents(long totalEvents) { + this.totalEvents = totalEvents; + } + + public Date getLastEvent() { + return lastEvent; + } + + public void setLastEvent(Date lastEvent) { + this.lastEvent = lastEvent; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java b/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java new file mode 100644 index 0000000000..edc744d586 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java @@ -0,0 +1,29 @@ +/** + * 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.app.nbevent; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class RawJsonDeserializer extends JsonDeserializer { + + @Override + public String deserialize(JsonParser jp, DeserializationContext ctxt) + throws IOException, JsonProcessingException { + + ObjectMapper mapper = (ObjectMapper) jp.getCodec(); + JsonNode node = mapper.readTree(jp); + return mapper.writeValueAsString(node); + } +} \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java new file mode 100644 index 0000000000..f426ddf6ab --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java @@ -0,0 +1,36 @@ +/** + * 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.app.nbevent.dao; + +import java.sql.SQLException; +import java.util.List; + +import org.dspace.content.Item; +import org.dspace.content.NBEventProcessed; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; + +public interface NBEventsDao { + /** + * Search a page of notification broker events by notification ID. + * + * @param c + * @param eventId + * @param start + * @param size + * @return + * @throws SQLException + */ + public List searchByEventId(Context c, String eventId, Integer start, Integer size) + throws SQLException; + + public boolean isEventStored(Context c, String checksum) throws SQLException; + + boolean storeEvent(Context c, String checksum, EPerson eperson, Item item); + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java new file mode 100644 index 0000000000..49894441b2 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java @@ -0,0 +1,58 @@ +/** + * 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.app.nbevent.dao.impl; + +import java.sql.SQLException; +import java.util.Date; +import java.util.List; +import javax.persistence.Query; + +import org.dspace.app.nbevent.dao.NBEventsDao; +import org.dspace.content.Item; +import org.dspace.content.NBEventProcessed; +import org.dspace.core.AbstractHibernateDAO; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; + +public class NBEventsDaoImpl extends AbstractHibernateDAO implements NBEventsDao { + + @Override + public boolean storeEvent(Context context, String checksum, EPerson eperson, Item item) { + NBEventProcessed nbEvent = new NBEventProcessed(); + nbEvent.setEperson(eperson); + nbEvent.setEventId(checksum); + nbEvent.setItem(item); + nbEvent.setEventTimestamp(new Date()); + try { + create(context, nbEvent); + return true; + } catch (SQLException e) { + return false; + } + } + + @Override + public boolean isEventStored(Context context, String checksum) throws SQLException { + Query query = createQuery(context, + "SELECT count(eventId) FROM NBEventProcessed nbevent WHERE nbevent.eventId = :event_id "); + query.setParameter("event_id", checksum); + return count(query) != 0; + } + + @Override + public List searchByEventId(Context context, String eventId, Integer start, Integer size) + throws SQLException { + Query query = createQuery(context, + "SELECT * " + "FROM NBEventProcessed nbevent WHERE nbevent.nbevent_id = :event_id "); + query.setFirstResult(start); + query.setMaxResults(size); + query.setParameter("event_id", eventId); + return findMany(context, query); + } + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java new file mode 100644 index 0000000000..146f0d1290 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java @@ -0,0 +1,39 @@ +/** + * 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.app.nbevent.service; + +import java.util.List; +import java.util.UUID; + +import org.dspace.app.nbevent.NBTopic; +import org.dspace.content.NBEvent; +import org.dspace.core.Context; + +public interface NBEventService { + + public NBTopic findTopicByTopicId(String topicId); + + public List findAllTopics(Context context, long offset, long pageSize); + + public long countTopics(Context context); + + public List findEventsByTopicAndPage(Context context, String topic, + long offset, int pageSize, + String orderField, boolean ascending); + + public long countEventsByTopic(Context context, String topic); + + public NBEvent findEventByEventId(Context context, String id); + + public void store(Context context, NBEvent event); + + public void deleteEventByEventId(Context context, String id); + + public void deleteEventsByTargetId(Context context, UUID targetId); + +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java new file mode 100644 index 0000000000..6b72c58ee4 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java @@ -0,0 +1,168 @@ +/** + * 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.app.nbevent.service.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class MessageDto { + + @JsonProperty("pids[0].value") + private String value; + + @JsonProperty("pids[0].type") + private String type; + + @JsonProperty("instances[0].hostedby") + private String instanceHostedBy; + + @JsonProperty("instances[0].instancetype") + private String instanceInstanceType; + + @JsonProperty("instances[0].license") + private String instanceLicense; + + @JsonProperty("instances[0].url") + private String instanceUrl; + + @JsonProperty("abstracts[0]") + private String abstracts; + + @JsonProperty("projects[0].acronym") + private String acronym; + + @JsonProperty("projects[0].code") + private String code; + + @JsonProperty("projects[0].funder") + private String funder; + + @JsonProperty("projects[0].fundingProgram") + private String fundingProgram; + + @JsonProperty("projects[0].jurisdiction") + private String jurisdiction; + + @JsonProperty("projects[0].openaireId") + private String openaireId; + + @JsonProperty("projects[0].title") + private String title; + + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getInstanceHostedBy() { + return instanceHostedBy; + } + + public void setInstanceHostedBy(String instanceHostedBy) { + this.instanceHostedBy = instanceHostedBy; + } + + public String getInstanceInstanceType() { + return instanceInstanceType; + } + + public void setInstanceInstanceType(String instanceInstanceType) { + this.instanceInstanceType = instanceInstanceType; + } + + public String getInstanceLicense() { + return instanceLicense; + } + + public void setInstanceLicense(String instanceLicense) { + this.instanceLicense = instanceLicense; + } + + public String getInstanceUrl() { + return instanceUrl; + } + + public void setInstanceUrl(String instanceUrl) { + this.instanceUrl = instanceUrl; + } + + public String getAbstracts() { + return abstracts; + } + + public void setAbstracts(String abstracts) { + this.abstracts = abstracts; + } + + public String getAcronym() { + return acronym; + } + + public void setAcronym(String acronym) { + this.acronym = acronym; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getFunder() { + return funder; + } + + public void setFunder(String funder) { + this.funder = funder; + } + + public String getFundingProgram() { + return fundingProgram; + } + + public void setFundingProgram(String fundingProgram) { + this.fundingProgram = fundingProgram; + } + + public String getJurisdiction() { + return jurisdiction; + } + + public void setJurisdiction(String jurisdiction) { + this.jurisdiction = jurisdiction; + } + + public String getOpenaireId() { + return openaireId; + } + + public void setOpenaireId(String openaireId) { + this.openaireId = openaireId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java new file mode 100644 index 0000000000..8901079425 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java @@ -0,0 +1,340 @@ +/** + * 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.app.nbevent.service.impl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import org.apache.log4j.Logger; +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrQuery.ORDER; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.client.solrj.request.UpdateRequest; +import org.apache.solr.client.solrj.response.FacetField; +import org.apache.solr.client.solrj.response.FacetField.Count; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.SolrInputDocument; +import org.dspace.app.nbevent.NBTopic; +import org.dspace.app.nbevent.dao.impl.NBEventsDaoImpl; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.dspace.handle.service.HandleService; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; +import org.springframework.beans.factory.annotation.Autowired; + +public class NBEventServiceImpl implements NBEventService { + + private static final Logger log = Logger.getLogger(NBEventServiceImpl.class); + + @Autowired(required = true) + protected ConfigurationService configurationService; + + @Autowired(required = true) + protected ItemService itemService; + + @Autowired + private HandleService handleService; + + @Autowired + private NBEventsDaoImpl nbEventsDao; + + private ObjectMapper jsonMapper; + + public NBEventServiceImpl() { + jsonMapper = new JsonMapper(); + jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + /** + * Non-Static CommonsHttpSolrServer for processing indexing events. + */ + protected SolrClient solr = null; + + public static final String ORIGINAL_ID = "original_id"; + public static final String TITLE = "title"; + public static final String TOPIC = "topic"; + public static final String TRUST = "trust"; + public static final String MESSAGE = "message"; + public static final String EVENT_ID = "event_id"; + public static final String RESOURCE_UUID = "resource_uuid"; + public static final String LAST_UPDATE = "last_update"; + public static final String RELATED_UUID = "related_uuid"; + + protected SolrClient getSolr() { + if (solr == null) { + String solrService = DSpaceServicesFactory.getInstance().getConfigurationService() + .getProperty("oaire-nbevents.solr.server", "http://localhost:8983/solr/nbevent"); + return new HttpSolrClient.Builder(solrService).build(); + } + return solr; + } + + @Override + public long countTopics(Context context) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setRows(0); + solrQuery.setQuery("*:*"); + solrQuery.setFacet(true); + // we would like to get eventually topic that has no longer active nb events + solrQuery.setFacetMinCount(0); + solrQuery.addFacetField(TOPIC); + QueryResponse response; + try { + response = getSolr().query(solrQuery); + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + return response.getFacetField(TOPIC).getValueCount(); + } + + @Override + public void deleteEventByEventId(Context context, String id) { + try { + getSolr().deleteById(id); + getSolr().commit(); + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void deleteEventsByTargetId(Context context, UUID targetId) { + try { + getSolr().deleteByQuery(RESOURCE_UUID + ":" + targetId.toString()); + getSolr().commit(); + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public NBTopic findTopicByTopicId(String topicId) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setRows(0); + solrQuery.setQuery(TOPIC + ":" + topicId.replaceAll("!", "/")); + solrQuery.setFacet(true); + // we would like to get eventually topic that has no longer active nb events + solrQuery.setFacetMinCount(0); + solrQuery.addFacetField(TOPIC); + QueryResponse response; + try { + response = getSolr().query(solrQuery); + FacetField facetField = response.getFacetField(TOPIC); + for (Count c : facetField.getValues()) { + if (c.getName().equals(topicId.replace("!", "/"))) { + NBTopic topic = new NBTopic(); + topic.setKey(c.getName()); +// topic.setName(OpenstarSupportedTopic.sorlToRest(c.getName())); + topic.setTotalEvents(c.getCount()); + topic.setLastEvent(new Date()); + return topic; + } + } + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + return null; + } + + /** + * Method to get all topics and the number of entries for each topic + * + * @param context DSpace context + * @param offset number of results to skip + * @param count number of result to fetch + * @return list of topics with number of events + * @throws IOException + * @throws SolrServerException + * @throws InvalidEnumeratedDataValueException + * + */ + @Override + public List findAllTopics(Context context, long offset, long count) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setRows(0); + solrQuery.setQuery("*:*"); + solrQuery.setFacet(true); + // we would like to get eventually topic that has no longer active nb events + solrQuery.setFacetMinCount(0); + solrQuery.setFacetLimit((int) (offset + count)); + solrQuery.addFacetField(TOPIC); + QueryResponse response; + List nbTopics = null; + try { + response = getSolr().query(solrQuery); + FacetField facetField = response.getFacetField(TOPIC); + nbTopics = new ArrayList<>(); + int idx = 0; + for (Count c : facetField.getValues()) { + if (idx < offset) { + idx++; + continue; + } + NBTopic topic = new NBTopic(); + topic.setKey(c.getName()); + // topic.setName(c.getName().replaceAll("/", "!")); + topic.setTotalEvents(c.getCount()); + topic.setLastEvent(new Date()); + nbTopics.add(topic); + idx++; + } + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + return nbTopics; + } + + @Override + public void store(Context context, NBEvent dto) { + UpdateRequest updateRequest = new UpdateRequest(); + String topic = dto.getTopic(); + if (topic != null) { + String checksum = dto.getEventId(); + try { + if (!nbEventsDao.isEventStored(context, checksum)) { + SolrInputDocument doc = new SolrInputDocument(); + doc.addField(EVENT_ID, checksum); + doc.addField(ORIGINAL_ID, dto.getOriginalId()); + doc.addField(TITLE, dto.getTitle()); + doc.addField(TOPIC, topic); + doc.addField(TRUST, dto.getTrust()); + doc.addField(MESSAGE, dto.getMessage()); + doc.addField(LAST_UPDATE, new Date()); + final String resourceUUID = getResourceUUID(context, dto.getOriginalId()); + if (resourceUUID == null) { + log.warn("Skipped event " + checksum + " related to the oai record " + dto.getOriginalId() + + " as the record was not found"); + return; + } + doc.addField(RESOURCE_UUID, resourceUUID); + doc.addField(RELATED_UUID, dto.getRelated()); + updateRequest.add(doc); + updateRequest.process(getSolr()); + getSolr().commit(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + @Override + public NBEvent findEventByEventId(Context context, String eventId) { + SolrQuery param = new SolrQuery(EVENT_ID + ":" + eventId); + QueryResponse response; + try { + response = getSolr().query(param); + if (response != null) { + SolrDocumentList list = response.getResults(); + if (list != null && list.size() == 1) { + SolrDocument doc = list.get(0); + return getNBEventFromSOLR(doc); + } + } + } catch (SolrServerException | IOException e) { + throw new RuntimeException("Exception querying Solr", e); + } + return null; + } + + private NBEvent getNBEventFromSOLR(SolrDocument doc) { + NBEvent item = new NBEvent(); + item.setEventId((String) doc.get(EVENT_ID)); + item.setLastUpdate((Date) doc.get(LAST_UPDATE)); + item.setMessage((String) doc.get(MESSAGE)); + item.setOriginalId((String) doc.get(ORIGINAL_ID)); + item.setTarget((String) doc.get(RESOURCE_UUID)); + item.setTitle((String) doc.get(TITLE)); + item.setTopic((String) doc.get(TOPIC)); + item.setTrust((double) doc.get(TRUST)); + item.setRelated((String) doc.get(RELATED_UUID)); + return item; + } + + @Override + public List findEventsByTopicAndPage(Context context, String topic, + long offset, int pageSize, + String orderField, boolean ascending) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setStart(((Long) offset).intValue()); + solrQuery.setRows(pageSize); + solrQuery.setSort(orderField, ascending ? ORDER.asc : ORDER.desc); + solrQuery.setQuery(TOPIC + ":" + topic.replaceAll("!", "/")); + QueryResponse response; + try { + response = getSolr().query(solrQuery); + if (response != null) { + SolrDocumentList list = response.getResults(); + List responseItem = new ArrayList<>(); + for (SolrDocument doc : list) { + NBEvent item = getNBEventFromSOLR(doc); + responseItem.add(item); + } + return responseItem; + } + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + return null; + } + + @Override + public long countEventsByTopic(Context context, String topic) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setRows(0); + solrQuery.setQuery(TOPIC + ":" + topic.replace("!", "/")); + QueryResponse response = null; + try { + response = getSolr().query(solrQuery); + return response.getResults().getNumFound(); + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + } + + private String getResourceUUID(Context context, String originalId) throws Exception { + String id = getHandleFromOriginalId(originalId); + if (id != null) { + Item item = (Item) handleService.resolveToObject(context, id); + if (item != null) { + final String itemUuid = item.getID().toString(); + context.uncacheEntity(item); + return itemUuid; + } else { + return null; + } + } else { + throw new RuntimeException("Malformed originalId " + originalId); + } + } + + // oai:www.openstarts.units.it:10077/21486 + private String getHandleFromOriginalId(String originalId) { + Integer startPosition = originalId.lastIndexOf(':'); + if (startPosition != -1) { + return originalId.substring(startPosition + 1, originalId.length()); + } else { + return null; + } + } + +} diff --git a/dspace-api/src/main/java/org/dspace/content/NBEvent.java b/dspace-api/src/main/java/org/dspace/content/NBEvent.java new file mode 100644 index 0000000000..c920016917 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/NBEvent.java @@ -0,0 +1,189 @@ +/** + * 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.content; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Date; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.apache.solr.client.solrj.beans.Field; +import org.dspace.app.nbevent.RawJsonDeserializer; + +/** + * This class represent the notification broker data as loaded in our solr + * nbevent core + * + */ +public class NBEvent { + public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', + 'f' }; + public static final String ACCEPTED = "accepted"; + public static final String REJECTED = "rejected"; + public static final String DISCARDED = "discarded"; + @Field("event_id") + private String eventId; + + @Field("original_id") + private String originalId; + + @Field("resource_uuid") + private String target; + + @Field("related_uuid") + private String related; + + @Field("title") + private String title; + + @Field("topic") + private String topic; + + @Field("trust") + private double trust; + + @Field("message") + @JsonDeserialize(using = RawJsonDeserializer.class) + private String message; + + @Field("last_update") + private Date lastUpdate; + + private String status = "PENDING"; + + public NBEvent() { + } + + public NBEvent(String originalId, String target, String title, String topic, double trust, String message, + Date lastUpdate) { + super(); + this.originalId = originalId; + this.target = target; + this.title = title; + this.topic = topic; + this.trust = trust; + this.message = message; + this.lastUpdate = lastUpdate; + try { + computedEventId(); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + throw new IllegalStateException(e); + } + + } + + public String getOriginalId() { + return originalId; + } + + public void setOriginalId(String originalId) { + this.originalId = originalId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public double getTrust() { + return trust; + } + + public void setTrust(double trust) { + this.trust = trust; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getEventId() { + if (eventId == null) { + try { + computedEventId(); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Date getLastUpdate() { + return lastUpdate; + } + + public void setLastUpdate(Date lastUpdate) { + this.lastUpdate = lastUpdate; + } + + public void setRelated(String related) { + this.related = related; + } + + public String getRelated() { + return related; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } + + /* + * DTO constructed via Jackson use empty constructor. In this case, the eventId + * must be compute on the get method + */ + private void computedEventId() throws NoSuchAlgorithmException, UnsupportedEncodingException { + MessageDigest digester = MessageDigest.getInstance("MD5"); + String dataToString = "originalId=" + originalId + ", title=" + title + ", topic=" + topic + ", trust=" + trust + + ", message=" + message; + digester.update(dataToString.getBytes("UTF-8")); + byte[] signature = digester.digest(); + char[] arr = new char[signature.length << 1]; + for (int i = 0; i < signature.length; i++) { + int b = signature[i]; + int idx = i << 1; + arr[idx] = HEX_DIGITS[(b >> 4) & 0xf]; + arr[idx + 1] = HEX_DIGITS[b & 0xf]; + } + eventId = new String(arr); + + } + +} diff --git a/dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java b/dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java new file mode 100644 index 0000000000..62f8222e24 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java @@ -0,0 +1,82 @@ +/** + * 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.content; + +import java.io.Serializable; +import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.dspace.eperson.EPerson; + +/** + * This class represent the stored information about processed notification + * broker events + * + */ +@Entity +@Table(name = "nbevent_processed") +public class NBEventProcessed implements Serializable { + + private static final long serialVersionUID = 3427340199132007814L; + + @Id + @Column(name = "nbevent_id") + private String eventId; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "nbevent_timestamp") + private Date eventTimestamp; + + @JoinColumn(name = "eperson_uuid") + @OneToOne + private EPerson eperson; + + @JoinColumn(name = "item_uuid") + @OneToOne + private Item item; + + public String getEventId() { + return eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public Date getEventTimestamp() { + return eventTimestamp; + } + + public void setEventTimestamp(Date eventTimestamp) { + this.eventTimestamp = eventTimestamp; + } + + public EPerson getEperson() { + return eperson; + } + + public void setEperson(EPerson eperson) { + this.eperson = eperson; + } + + public Item getItem() { + return item; + } + + public void setItem(Item item) { + this.item = item; + } + +} diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2020.10.16__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2020.10.16__nbevent_processed.sql new file mode 100644 index 0000000000..b64c52248b --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2020.10.16__nbevent_processed.sql @@ -0,0 +1,16 @@ +-- +-- 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 TABLE nbevent_processed ( + nbevent_id VARCHAR(255) NOT NULL, + nbevent_timestamp TIMESTAMP NULL, + eperson_uuid UUID NULL REFERENCES eperson(uuid), + item_uuid uuid NOT NULL REFERENCES item(uuid) +); + +CREATE INDEX item_uuid_idx ON nbevent_processed(item_uuid); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2020.10.16__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2020.10.16__nbevent_processed.sql new file mode 100644 index 0000000000..5cf9a0484f --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2020.10.16__nbevent_processed.sql @@ -0,0 +1,19 @@ +-- +-- 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 TABLE nbevent_processed ( + nbevent_id VARCHAR(255) NOT NULL, + nbevent_timestamp TIMESTAMP NULL, + eperson_uuid UUID NULL, + item_uuid UUID NULL, + CONSTRAINT nbevent_pk PRIMARY KEY (nbevent_id), + CONSTRAINT eperson_uuid_fkey FOREIGN KEY (eperson_uuid) REFERENCES eperson (uuid), + CONSTRAINT item_uuid_fkey FOREIGN KEY (item_uuid) REFERENCES item (uuid) +); + +CREATE INDEX item_uuid_idx ON nbevent_processed(item_uuid); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2020.10.16__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2020.10.16__nbevent_processed.sql new file mode 100644 index 0000000000..5cf9a0484f --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2020.10.16__nbevent_processed.sql @@ -0,0 +1,19 @@ +-- +-- 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 TABLE nbevent_processed ( + nbevent_id VARCHAR(255) NOT NULL, + nbevent_timestamp TIMESTAMP NULL, + eperson_uuid UUID NULL, + item_uuid UUID NULL, + CONSTRAINT nbevent_pk PRIMARY KEY (nbevent_id), + CONSTRAINT eperson_uuid_fkey FOREIGN KEY (eperson_uuid) REFERENCES eperson (uuid), + CONSTRAINT item_uuid_fkey FOREIGN KEY (item_uuid) REFERENCES item (uuid) +); + +CREATE INDEX item_uuid_idx ON nbevent_processed(item_uuid); diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 3c19a68e9f..258d53ee2f 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -84,14 +84,14 @@ loglevel.dspace = INFO # IIIF TEST SETTINGS # ######################## iiif.enabled = true -event.dispatcher.default.consumers = versioning, discovery, eperson, iiif +event.dispatcher.default.consumers = versioning, discovery, eperson, iiif, nbeventsdelete ########################################### # CUSTOM UNIT / INTEGRATION TEST SETTINGS # ########################################### # custom dispatcher to be used by dspace-api IT that doesn't need SOLR event.dispatcher.exclude-discovery.class = org.dspace.event.BasicDispatcher -event.dispatcher.exclude-discovery.consumers = versioning, eperson +event.dispatcher.exclude-discovery.consumers = versioning, eperson, nbeventsdelete # Configure authority control for Unit Testing (in DSpaceControlledVocabularyTest) # (This overrides default, commented out settings in dspace.cfg) diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml index 5f86c73598..ffffa7f44d 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml @@ -47,5 +47,9 @@ + + + diff --git a/dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java b/dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java new file mode 100644 index 0000000000..12058fbf73 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java @@ -0,0 +1,38 @@ +/** + * 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.app.nbevent; + +import org.dspace.app.nbevent.service.impl.NBEventServiceImpl; +import org.dspace.solr.MockSolrServer; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Service; + +/** + * Mock SOLR service for the nbevents Core. + */ +@Service +public class MockNBEventService extends NBEventServiceImpl implements InitializingBean, DisposableBean { + private MockSolrServer mockSolrServer; + + @Override + public void afterPropertiesSet() throws Exception { + mockSolrServer = new MockSolrServer("nbevent"); + solr = mockSolrServer.getSolrServer(); + } + + /** Clear all records from the search core. */ + public void reset() { + mockSolrServer.reset(); + } + + @Override + public void destroy() throws Exception { + mockSolrServer.destroy(); + } +} \ No newline at end of file diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java index 06deacaca4..2734a11628 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java @@ -13,6 +13,7 @@ import java.util.List; import org.apache.commons.collections4.CollectionUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.requestitem.factory.RequestItemServiceFactory; import org.dspace.app.requestitem.service.RequestItemService; import org.dspace.authorize.AuthorizeException; @@ -45,6 +46,7 @@ import org.dspace.eperson.service.RegistrationDataService; import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.service.ProcessService; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.utils.DSpace; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; @@ -95,6 +97,7 @@ public abstract class AbstractBuilder { static ProcessService processService; static RequestItemService requestItemService; static VersioningService versioningService; + static NBEventService nbEventService; protected Context context; @@ -151,6 +154,8 @@ public abstract class AbstractBuilder { inProgressUserService = XmlWorkflowServiceFactory.getInstance().getInProgressUserService(); poolTaskService = XmlWorkflowServiceFactory.getInstance().getPoolTaskService(); workflowItemRoleService = XmlWorkflowServiceFactory.getInstance().getWorkflowItemRoleService(); + + nbEventService = new DSpace().getSingletonService(NBEventService.class); } @@ -183,7 +188,7 @@ public abstract class AbstractBuilder { processService = null; requestItemService = null; versioningService = null; - + nbEventService = null; } public static void cleanupObjects() throws Exception { diff --git a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java new file mode 100644 index 0000000000..9101d3bf5e --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java @@ -0,0 +1,125 @@ +/** + * 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.builder; + +import java.util.Date; + +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.core.Context; + +/** + * Builder to construct Notification Broker Event objects + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + */ +public class NBEventBuilder extends AbstractBuilder { + + private Item item; + private NBEvent target; + + private String title; + private String topic; + private String message; + private String relatedItem; + private double trust = 0.5; + private Date lastUpdate = new Date(); + + protected NBEventBuilder(Context context) { + super(context); + } + + public static NBEventBuilder createTarget(final Context context, final Collection col, final String name) { + NBEventBuilder builder = new NBEventBuilder(context); + return builder.create(context, col, name); + } + + public static NBEventBuilder createTarget(final Context context, final Item item) { + NBEventBuilder builder = new NBEventBuilder(context); + return builder.create(context, item); + } + + private NBEventBuilder create(final Context context, final Collection col, final String name) { + this.context = context; + + try { + ItemBuilder itemBuilder = ItemBuilder.createItem(context, col).withTitle(name); + item = itemBuilder.build(); + this.title = name; + context.dispatchEvents(); + indexingService.commit(); + } catch (Exception e) { + return handleException(e); + } + return this; + } + + private NBEventBuilder create(final Context context, final Item item) { + this.context = context; + this.item = item; + return this; + } + + public NBEventBuilder withTopic(final String topic) { + this.topic = topic; + return this; + } + public NBEventBuilder withTitle(final String title) { + this.title = title; + return this; + } + public NBEventBuilder withMessage(final String message) { + this.message = message; + return this; + } + public NBEventBuilder withTrust(final double trust) { + this.trust = trust; + return this; + } + public NBEventBuilder withLastUpdate(final Date lastUpdate) { + this.lastUpdate = lastUpdate; + return this; + } + + public NBEventBuilder withRelatedItem(String relatedItem) { + this.relatedItem = relatedItem; + return this; + } + + @Override + public NBEvent build() { + target = new NBEvent("oai:www.dspace.org:" + item.getHandle(), item.getID().toString(), title, topic, trust, + message, lastUpdate); + target.setRelated(relatedItem); + try { + nbEventService.store(context, target); + } catch (Exception e) { + e.printStackTrace(); + } + return target; + } + + @Override + public void cleanup() throws Exception { + nbEventService.deleteEventByEventId(context, target.getEventId()); + } + + @Override + protected NBEventService getService() { + return nbEventService; + } + + @Override + public void delete(Context c, NBEvent dso) throws Exception { + nbEventService.deleteEventByEventId(context, target.getEventId()); + +// nbEventService.deleteTarget(dso); + } +} \ No newline at end of file diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java new file mode 100644 index 0000000000..2411f4743d --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java @@ -0,0 +1,135 @@ +/** + * 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.app.rest; + +import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.converter.ConverterService; +import org.dspace.app.rest.exception.UnprocessableEntityException; +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.model.hateoas.ItemResource; +import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.app.rest.utils.Utils; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.rest.webmvc.ControllerUtils; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.hateoas.RepresentationModel; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * This RestController will take care to manipulate the related item eventually associated with a nb event + * "/api/integration/nbevents/{nbeventid}/related" + */ +@RestController +@RequestMapping("/api/integration/nbevents" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + "/related") +public class NBEventRestController { + @Autowired + protected Utils utils; + + @Autowired + private ConverterService converterService; + + @Autowired + private ItemService itemService; + + @Autowired + private NBEventService nbEventService; + + /** + * This method associate an item to a nb event + * + * @param nbeventId The nb event id + * @param response The current response + * @param request The current request + * @param relatedItemUUID The uuid of the related item to associate with the nb + * event + * @return The related item + * @throws SQLException If something goes wrong + * @throws AuthorizeException If something goes wrong + */ + @RequestMapping(method = RequestMethod.POST) + @PreAuthorize("hasAuthority('ADMIN')") + public ResponseEntity> postRelatedItem(@PathVariable(name = "id") String nbeventId, + HttpServletResponse response, HttpServletRequest request, + @RequestParam(required = true, name = "item") UUID relatedItemUUID) + throws SQLException, AuthorizeException { + Context context = ContextUtil.obtainContext(request); + NBEvent nbevent = nbEventService.findEventByEventId(context, nbeventId); + if (nbevent == null) { + throw new ResourceNotFoundException("No such nb event: " + nbeventId); + } + if (nbevent.getRelated() != null) { + throw new UnprocessableEntityException("The nb event with ID: " + nbeventId + " already has " + + "a related item"); + } else if (!StringUtils.endsWith(nbevent.getTopic(), "/PROJECT")) { + return ControllerUtils.toEmptyResponse(HttpStatus.BAD_REQUEST); + } + + Item relatedItem = itemService.find(context, relatedItemUUID); + if (relatedItem != null) { + nbevent.setRelated(relatedItemUUID.toString()); + nbEventService.store(context, nbevent); + } else { + throw new UnprocessableEntityException("The proposed related item was not found"); + } + ItemRest relatedItemRest = converterService.toRest(relatedItem, utils.obtainProjection()); + ItemResource itemResource = converterService.toResource(relatedItemRest); + context.complete(); + return ControllerUtils.toResponseEntity(HttpStatus.CREATED, new HttpHeaders(), itemResource); + } + + /** + * This method remove the association to a related item from a nb event + * + * @param nbeventId The nb event id + * @param response The current response + * @param request The current request + * @return The related item + * @throws SQLException If something goes wrong + * @throws AuthorizeException If something goes wrong + */ + @RequestMapping(method = RequestMethod.DELETE) + @PreAuthorize("hasAuthority('ADMIN')") + public ResponseEntity> deleteAdminGroup(@PathVariable(name = "id") String nbeventId, + HttpServletResponse response, HttpServletRequest request) + throws SQLException, AuthorizeException, IOException { + Context context = ContextUtil.obtainContext(request); + NBEvent nbevent = nbEventService.findEventByEventId(context, nbeventId); + if (nbevent == null) { + throw new ResourceNotFoundException("No such nb event: " + nbeventId); + } + if (nbevent.getRelated() != null) { + nbevent.setRelated(null); + nbEventService.store(context, nbevent); + context.complete(); + } + + return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT); + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index 7c79a85701..3adc55c4f1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -572,6 +572,37 @@ public class RestResourceController implements InitializingBean { return uploadInternal(request, apiCategory, model, uuid, uploadfile); } + /** + * Called in POST, multipart, upload to a specific rest resource the file passed as "file" request parameter + * + * Note that the regular expression in the request mapping accept a String as identifier; + * + * @param request + * the http request + * @param apiCategory + * the api category + * @param model + * the rest model that identify the REST resource collection + * @param id + * the id of the specific rest resource + * @param uploadfile + * the file to upload + * @return the created resource + * @throws HttpRequestMethodNotSupportedException + */ + @RequestMapping(method = RequestMethod.POST, + value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG, + headers = "content-type=multipart/form-data") + public ResponseEntity> upload(HttpServletRequest request, + @PathVariable String apiCategory, + @PathVariable String model, + @PathVariable String id, + @RequestParam("file") MultipartFile + uploadfile) + throws HttpRequestMethodNotSupportedException { + return uploadInternal(request, apiCategory, model, id, uploadfile); + } + /** * Internal upload method. * @@ -684,6 +715,28 @@ public class RestResourceController implements InitializingBean { return patchInternal(request, apiCategory, model, id, jsonNode); } + /** + * PATCH method, using operation on the resources following (JSON) Patch notation (https://tools.ietf + * .org/html/rfc6902) + * + * Note that the regular expression in the request mapping accept a UUID as identifier; + * + * @param request + * @param apiCategory + * @param model + * @param id + * @param jsonNode + * @return + * @throws HttpRequestMethodNotSupportedException + */ + @RequestMapping(method = RequestMethod.PATCH, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG) + public ResponseEntity> patch(HttpServletRequest request, @PathVariable String apiCategory, + @PathVariable String model, + @PathVariable String id, + @RequestBody(required = true) JsonNode jsonNode) { + return patchInternal(request, apiCategory, model, id, jsonNode); + } + /** * Internal patch method * @@ -711,9 +764,13 @@ public class RestResourceController implements InitializingBean { log.error(e.getMessage(), e); throw e; } - DSpaceResource result = converter.toResource(modelObject); - //TODO manage HTTPHeader - return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(), result); + if (modelObject != null) { + DSpaceResource result = converter.toResource(modelObject); + //TODO manage HTTPHeader + return ControllerUtils.toResponseEntity(HttpStatus.OK, new HttpHeaders(), result); + } else { + return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT); + } } @@ -1050,6 +1107,13 @@ public class RestResourceController implements InitializingBean { return deleteInternal(apiCategory, model, uuid); } + @RequestMapping(method = RequestMethod.DELETE, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG) + public ResponseEntity> delete(HttpServletRequest request, @PathVariable String apiCategory, + @PathVariable String model, @PathVariable String id) + throws HttpRequestMethodNotSupportedException { + return deleteInternal(apiCategory, model, id); + } + /** * Internal method to delete resource. * diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java new file mode 100644 index 0000000000..3534e3c310 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java @@ -0,0 +1,74 @@ +/** + * 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.app.rest.converter; + +import java.text.DecimalFormat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.app.rest.model.NBEventMessageRest; +import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.NBEvent; +import org.springframework.stereotype.Component; + +@Component +public class NBEventConverter implements DSpaceConverter { + + private ObjectMapper jsonMapper; + + public NBEventConverter() { + super(); + jsonMapper = new JsonMapper(); + jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + @Override + public NBEventRest convert(NBEvent modelObject, Projection projection) { + NBEventRest rest = new NBEventRest(); + rest.setId(modelObject.getEventId()); + try { + rest.setMessage(convertMessage(jsonMapper.readValue(modelObject.getMessage(), MessageDto.class))); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + rest.setOriginalId(modelObject.getOriginalId()); + rest.setProjection(projection); + rest.setTitle(modelObject.getTitle()); + rest.setTopic(modelObject.getTopic()); + rest.setEventDate(modelObject.getLastUpdate()); + rest.setTrust(new DecimalFormat("0.000").format(modelObject.getTrust())); + // right now only the pending status can be found in persisted nb events + rest.setStatus(modelObject.getStatus()); + return rest; + } + + private NBEventMessageRest convertMessage(MessageDto dto) { + NBEventMessageRest message = new NBEventMessageRest(); + message.setAbstractValue(dto.getAbstracts()); + message.setOpenaireId(dto.getOpenaireId()); + message.setAcronym(dto.getAcronym()); + message.setCode(dto.getCode()); + message.setFunder(dto.getFunder()); + message.setFundingProgram(dto.getFundingProgram()); + message.setJurisdiction(dto.getJurisdiction()); + message.setTitle(dto.getTitle()); + message.setType(dto.getType()); + message.setValue(dto.getValue()); + return message; + } + + @Override + public Class getModelClass() { + return NBEvent.class; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java new file mode 100644 index 0000000000..8a5a284fe1 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java @@ -0,0 +1,34 @@ +/** + * 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.app.rest.converter; + +import org.dspace.app.nbevent.NBTopic; +import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.app.rest.projection.Projection; +import org.springframework.stereotype.Component; + +@Component +public class NBTopicConverter implements DSpaceConverter { + + @Override + public Class getModelClass() { + return NBTopic.class; + } + + @Override + public NBTopicRest convert(NBTopic modelObject, Projection projection) { + NBTopicRest rest = new NBTopicRest(); + rest.setProjection(projection); + rest.setId(modelObject.getKey().replace("/", "!")); + rest.setName(modelObject.getKey()); + rest.setLastEvent(modelObject.getLastEvent()); + rest.setTotalEvents(modelObject.getTotalEvents()); + return rest; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java new file mode 100644 index 0000000000..7d0f24a21d --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java @@ -0,0 +1,88 @@ +/** + * 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.app.rest.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class NBEventMessageRest { + // pids + private String type; + private String value; + // abstract + @JsonProperty(value = "abstract") + private String abstractValue; + // project + private String openaireId; + private String acronym; + private String code; + private String funder; + private String fundingProgram; + private String jurisdiction; + private String title; + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public String getAbstractValue() { + return abstractValue; + } + public void setAbstractValue(String abstractValue) { + this.abstractValue = abstractValue; + } + public String getOpenaireId() { + return openaireId; + } + public void setOpenaireId(String openaireId) { + this.openaireId = openaireId; + } + public String getAcronym() { + return acronym; + } + public void setAcronym(String acronym) { + this.acronym = acronym; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getFunder() { + return funder; + } + public void setFunder(String funder) { + this.funder = funder; + } + public String getFundingProgram() { + return fundingProgram; + } + public void setFundingProgram(String fundingProgram) { + this.fundingProgram = fundingProgram; + } + public String getJurisdiction() { + return jurisdiction; + } + public void setJurisdiction(String jurisdiction) { + this.jurisdiction = jurisdiction; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java new file mode 100644 index 0000000000..de2cea32fa --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java @@ -0,0 +1,115 @@ +/** + * 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.app.rest.model; + +import java.util.Date; + +import org.dspace.app.rest.RestResourceController; + +@LinksRest( + links = { + @LinkRest(name = "topic", method = "getTopic"), + @LinkRest(name = "target", method = "getTarget"), + @LinkRest(name = "related", method = "getRelated") + }) +public class NBEventRest extends BaseObjectRest { + + private static final long serialVersionUID = -5001130073350654793L; + public static final String NAME = "nbevent"; + public static final String CATEGORY = RestAddressableModel.INTEGRATION; + + public static final String TOPIC = "topic"; + public static final String TARGET = "target"; + public static final String RELATED = "related"; + private String originalId; + private String title; + private String topic; + private String trust; + private Date eventDate; + private NBEventMessageRest message; + private String status; + + @Override + public String getType() { + return NAME; + } + + @Override + public String getCategory() { + return CATEGORY; + } + + @Override + public Class getController() { + return RestResourceController.class; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getOriginalId() { + return originalId; + } + + public void setOriginalId(String originalId) { + this.originalId = originalId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getTopic() { + return topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String getTrust() { + return trust; + } + + public void setTrust(String trust) { + this.trust = trust; + } + + public Date getEventDate() { + return eventDate; + } + + public void setEventDate(Date eventDate) { + this.eventDate = eventDate; + } + + public NBEventMessageRest getMessage() { + return message; + } + + public void setMessage(NBEventMessageRest message) { + this.message = message; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java new file mode 100644 index 0000000000..4bebce27e8 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java @@ -0,0 +1,78 @@ +/** + * 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.app.rest.model; + +import java.util.Date; + +import org.dspace.app.rest.RestResourceController; + +/** + * REST Representation of a notification broker topic + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +public class NBTopicRest extends BaseObjectRest { + + private static final long serialVersionUID = -7455358581579629244L; + + public static final String NAME = "nbtopic"; + public static final String CATEGORY = RestAddressableModel.INTEGRATION; + + private String id; + private String name; + private Date lastEvent; + private long totalEvents; + + @Override + public String getType() { + return NAME; + } + + @Override + public String getCategory() { + return CATEGORY; + } + + @Override + public Class getController() { + return RestResourceController.class; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getLastEvent() { + return lastEvent; + } + + public void setLastEvent(Date lastEvent) { + this.lastEvent = lastEvent; + } + + public long getTotalEvents() { + return totalEvents; + } + + public void setTotalEvents(long totalEvents) { + this.totalEvents = totalEvents; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java new file mode 100644 index 0000000000..bd3c266f1e --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java @@ -0,0 +1,21 @@ +/** + * 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.app.rest.model.hateoas; + +import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; +import org.dspace.app.rest.utils.Utils; + +@RelNameDSpaceResource(NBEventRest.NAME) +public class NBEventResource extends DSpaceResource { + + public NBEventResource(NBEventRest data, Utils utils) { + super(data, utils); + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java new file mode 100644 index 0000000000..a2fed4ffc6 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java @@ -0,0 +1,21 @@ +/** + * 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.app.rest.model.hateoas; + +import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; +import org.dspace.app.rest.utils.Utils; + +@RelNameDSpaceResource(NBTopicRest.NAME) +public class NBTopicResource extends DSpaceResource { + + public NBTopicResource(NBTopicRest data, Utils utils) { + super(data, utils); + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java new file mode 100644 index 0000000000..3ec4660c4a --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java @@ -0,0 +1,77 @@ +/** + * 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.app.rest.repository; + +import java.sql.SQLException; +import java.util.UUID; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "related" subresource of a nb event. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME + "." + NBEventRest.RELATED) +public class NBEventRelatedLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { + + @Autowired + private NBEventService nbEventService; + + @Autowired + private ItemService itemService; + + /** + * Returns the item related to the nb event with the given id. This is another + * item that should be linked to the target item as part of the correction + * + * @param request the http servlet request + * @param id the nb event id + * @param pageable the optional pageable + * @param projection the projection object + * @return the item rest representation of the secondary item related to nb event + */ + @PreAuthorize("hasAuthority('ADMIN')") + public ItemRest getRelated(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, + Projection projection) { + Context context = obtainContext(); + NBEvent nbEvent = nbEventService.findEventByEventId(context, id); + if (nbEvent == null) { + throw new ResourceNotFoundException("No nb event with ID: " + id); + } + if (nbEvent.getRelated() == null) { + return null; + } + UUID itemUuid = UUID.fromString(nbEvent.getRelated()); + Item item; + try { + item = itemService.find(context, itemUuid); + if (item == null) { + throw new ResourceNotFoundException("No related item found with id : " + id); + } + return converter.toRest(item, projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java new file mode 100644 index 0000000000..b00688a6ea --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java @@ -0,0 +1,127 @@ +/** + * 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.app.rest.repository; + +import java.sql.SQLException; +import java.util.List; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.nbevent.dao.NBEventsDao; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.Parameter; +import org.dspace.app.rest.SearchRestMethod; +import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; +import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.patch.Patch; +import org.dspace.app.rest.repository.patch.ResourcePatch; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.eperson.service.EPersonService; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort.Direction; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME) +public class NBEventRestRepository extends DSpaceRestRepository { + + final static String ORDER_FIELD = "trust"; + + @Autowired + private NBEventService nbEventService; + + @Autowired + private NBEventsDao nbEventDao; + + @Autowired + private ItemService itemService; + + @Autowired + private EPersonService ePersonService; + + @Autowired + private ResourcePatch resourcePatch; + + private Logger log = org.slf4j.LoggerFactory.getLogger(NBEventRestRepository.class); + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public NBEventRest findOne(Context context, String id) { + NBEvent nbEvent = nbEventService.findEventByEventId(context, id); + if (nbEvent == null) { + // HACK check if this request is part of a patch flow + nbEvent = (NBEvent) requestService.getCurrentRequest().getAttribute("patchedNotificationEvent"); + if (nbEvent != null && nbEvent.getEventId().contentEquals(id)) { + return converter.toRest(nbEvent, utils.obtainProjection()); + } else { + return null; + } + } + return converter.toRest(nbEvent, utils.obtainProjection()); + } + + @SearchRestMethod(name = "findByTopic") + @PreAuthorize("hasAuthority('ADMIN')") + public Page findByTopic(Context context, @Parameter(value = "topic", required = true) String topic, + Pageable pageable) { + List nbEvents = null; + Long count = 0L; + boolean ascending = false; + if (pageable.getSort() != null && pageable.getSort().getOrderFor(ORDER_FIELD) != null) { + ascending = pageable.getSort().getOrderFor(ORDER_FIELD).getDirection() == Direction.ASC; + } + nbEvents = nbEventService.findEventsByTopicAndPage(context, topic, + pageable.getOffset(), pageable.getPageSize(), + ORDER_FIELD, ascending); + count = nbEventService.countEventsByTopic(context, topic); + if (nbEvents == null) { + return null; + } + return converter.toRestPage(nbEvents, pageable, count, utils.obtainProjection()); + } + + @Override + protected void delete(Context context, String id) throws AuthorizeException { + Item item; + try { + item = itemService.find(context, UUID.fromString(id)); + EPerson eperson = context.getCurrentUser(); + nbEventService.deleteEventByEventId(context, id); + nbEventDao.storeEvent(context, id, eperson, item); + } catch (SQLException e) { + throw new RuntimeException("Unable to delete NBEvent " + id, e); + } + } + + @Override + public Page findAll(Context context, Pageable pageable) { + throw new RepositoryMethodNotImplementedException(NBEventRest.NAME, "findAll"); + } + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, + String id, Patch patch) throws SQLException, AuthorizeException { + NBEvent nbEvent = nbEventService.findEventByEventId(context, id); + resourcePatch.patch(context, nbEvent, patch.getOperations()); + } + + @Override + public Class getDomainClass() { + return NBEventRest.class; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java new file mode 100644 index 0000000000..5c73f4d244 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java @@ -0,0 +1,73 @@ +/** + * 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.app.rest.repository; + +import java.sql.SQLException; +import java.util.UUID; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "target" subresource of a nb event. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME + "." + NBEventRest.TARGET) +public class NBEventTargetLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { + + @Autowired + private NBEventService nbEventService; + + @Autowired + private ItemService itemService; + + /** + * Returns the item target of the nb event with the given id. + * + * @param request the http servlet request + * @param id the nb event id + * @param pageable the optional pageable + * @param projection the projection object + * @return the item rest representation of the nb event target + */ + @PreAuthorize("hasAuthority('ADMIN')") + public ItemRest getTarget(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, + Projection projection) { + Context context = obtainContext(); + NBEvent nbEvent = nbEventService.findEventByEventId(context, id); + if (nbEvent == null) { + throw new ResourceNotFoundException("No nb event with ID: " + id); + } + UUID itemUuid = UUID.fromString(nbEvent.getTarget()); + Item item; + try { + item = itemService.find(context, itemUuid); + if (item == null) { + throw new ResourceNotFoundException("No target item found with id : " + id); + } + return converter.toRest(item, projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java new file mode 100644 index 0000000000..94da3b8a50 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java @@ -0,0 +1,61 @@ +/** + * 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.app.rest.repository; + +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.nbevent.NBTopic; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.NBEvent; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "topic" subresource of a nb event. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME + "." + NBEventRest.TOPIC) +public class NBEventTopicLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { + + @Autowired + private NBEventService nbEventService; + + /** + * Returns the topic of the nb event with the given id. + * + * @param request the http servlet request + * @param id the nb event id + * @param pageable the optional pageable + * @param projection the projection object + * @return the nb topic rest representation + */ + @PreAuthorize("hasAuthority('ADMIN')") + public NBTopicRest getTopic(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, + Projection projection) { + Context context = obtainContext(); + NBEvent nbEvent = nbEventService.findEventByEventId(context, id); + if (nbEvent == null) { + throw new ResourceNotFoundException("No nb event with ID: " + id); + } + NBTopic topic = nbEventService.findTopicByTopicId(nbEvent.getTopic().replace("/", "!")); + if (topic == null) { + throw new ResourceNotFoundException("No topic found with id : " + id); + } + return converter.toRest(topic, projection); + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java new file mode 100644 index 0000000000..afaf3c7346 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java @@ -0,0 +1,54 @@ +/** + * 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.app.rest.repository; + +import java.util.List; + +import org.dspace.app.nbevent.NBTopic; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component(NBTopicRest.CATEGORY + "." + NBTopicRest.NAME) +public class NBTopicRestRepository extends DSpaceRestRepository { + + @Autowired + private NBEventService nbEventService; + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public NBTopicRest findOne(Context context, String id) { + NBTopic nbTopic = nbEventService.findTopicByTopicId(id); + if (nbTopic == null) { + return null; + } + return converter.toRest(nbTopic, utils.obtainProjection()); + } + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public Page findAll(Context context, Pageable pageable) { + List nbTopics = nbEventService.findAllTopics(context, pageable.getOffset(), pageable.getPageSize()); + long count = nbEventService.countTopics(context); + if (nbTopics == null) { + return null; + } + return converter.toRestPage(nbTopics, pageable, count, utils.obtainProjection()); + } + + @Override + public Class getDomainClass() { + return NBTopicRest.class; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java new file mode 100644 index 0000000000..bd690ee683 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java @@ -0,0 +1,54 @@ +/** + * 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.app.rest.repository.patch.operation; + +import java.sql.SQLException; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.nbevent.NBEventActionService; +import org.dspace.app.rest.model.patch.Operation; +import org.dspace.content.NBEvent; +import org.dspace.core.Context; +import org.dspace.services.RequestService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class NBEventStatusReplaceOperation extends PatchOperation { + @Autowired + private RequestService requestService; + + @Autowired + private NBEventActionService nbEventActionService; + + @Override + public NBEvent perform(Context context, NBEvent nbevent, Operation operation) throws SQLException { + String value = (String) operation.getValue(); + if (StringUtils.equalsIgnoreCase(value, NBEvent.ACCEPTED)) { + nbEventActionService.accept(context, nbevent); + } else if (StringUtils.equalsIgnoreCase(value, NBEvent.REJECTED)) { + nbEventActionService.reject(context, nbevent); + } else if (StringUtils.equalsIgnoreCase(value, NBEvent.DISCARDED)) { + nbEventActionService.discard(context, nbevent); + } else { + throw new IllegalArgumentException( + "The received operation is not valid: " + operation.getPath() + " - " + value); + } + nbevent.setStatus(value.toUpperCase()); + // HACK, we need to store the temporary object in the request so that a subsequent find would get it + requestService.getCurrentRequest().setAttribute("patchedNotificationEvent", nbevent); + return nbevent; + } + + @Override + public boolean supports(Object objectToMatch, Operation operation) { + return StringUtils.equals(operation.getOp(), "replace") && objectToMatch instanceof NBEvent && StringUtils + .containsAny(operation.getValue().toString().toLowerCase(), NBEvent.ACCEPTED, NBEvent.DISCARDED, + NBEvent.REJECTED); + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java index 8739f6b8d5..8db5a74eef 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java @@ -33,7 +33,7 @@ public class RegexUtils { */ public static final String REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG = "/{id:^(?!^\\d+$)" + "(?!^[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}$)" - + "[\\w+\\-\\.:]+$+}"; + + "[\\w+\\-\\.:!]+$+}"; /** * Regular expression in the request mapping to accept number as identifier diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java new file mode 100644 index 0000000000..ef9abfe978 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java @@ -0,0 +1,709 @@ +/** + * 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.app.rest; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.ArrayList; +import java.util.List; +import javax.ws.rs.core.MediaType; + +import org.dspace.app.rest.matcher.ItemMatcher; +import org.dspace.app.rest.matcher.NBEventMatcher; +import org.dspace.app.rest.model.patch.Operation; +import org.dspace.app.rest.model.patch.ReplaceOperation; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EntityTypeBuilder; +import org.dspace.builder.ItemBuilder; +import org.dspace.builder.NBEventBuilder; +import org.dspace.builder.RelationshipTypeBuilder; +import org.dspace.content.Collection; +import org.dspace.content.EntityType; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.hamcrest.Matchers; +import org.junit.Test; + +public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { + + @Test + public void findAllNotImplementedTest() throws Exception { + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/integration/nbevents")).andExpect(status().isMethodNotAllowed()); + String epersonToken = getAuthToken(admin.getEmail(), password); + getClient(epersonToken).perform(get("/api/integration/nbevents")).andExpect(status().isMethodNotAllowed()); + getClient().perform(get("/api/integration/nbevents")).andExpect(status().isMethodNotAllowed()); + } + + @Test + public void findOneTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbevents/" + event1.getEventId())).andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(event1))); + getClient(authToken).perform(get("/api/integration/nbevents/" + event4.getEventId())).andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(event4))); + } + + @Test + public void findOneWithProjectionTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event5 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + .withTopic("ENRICH/MISSING/PROJECT") + .withMessage( + "{\"projects[0].acronym\":\"PAThs\"," + + "\"projects[0].code\":\"687567\"," + + "\"projects[0].funder\":\"EC\"," + + "\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths: " + + "An Archaeological Atlas of Coptic Literature." + + "\\nLiterary Texts in their Geographical Context: Production, Copying, Usage, " + + "Dissemination and Storage\"}") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event1.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event1))); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event5.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event5))); + } + + @Test + public void findOneUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + context.restoreAuthSystemState(); + getClient().perform(get("/api/integration/nbevents/" + event1.getEventId())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findOneForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbevents/" + event1.getEventId())) + .andExpect(status().isForbidden()); + } + + @Test + public void findByTopicTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder(NBEventMatcher.matchNBEventEntry(event1), + NBEventMatcher.matchNBEventEntry(event2)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!ABSTRACT")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder(NBEventMatcher.matchNBEventEntry(event4)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); + getClient(authToken).perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "not-existing")) + .andExpect(status().isOk()).andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", is(0))); + } + + @Test + public void findByTopicPaginatedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"pmc\",\"pids[0].value\":\"2144303\"}").build(); + NBEvent event5 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .param("size", "2")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder( + NBEventMatcher.matchNBEventEntry(event1), + NBEventMatcher.matchNBEventEntry(event2)))) + .andExpect(jsonPath("$._links.self.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.first.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href").doesNotExist()) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.totalElements", is(5))); + + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .param("size", "2").param("page", "1")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder( + NBEventMatcher.matchNBEventEntry(event3), + NBEventMatcher.matchNBEventEntry(event4)))) + .andExpect(jsonPath("$._links.self.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.last.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.first.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.totalElements", is(5))); + + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .param("size", "2").param("page", "2")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder( + NBEventMatcher.matchNBEventEntry(event5)))) + .andExpect(jsonPath("$._links.self.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.next.href").doesNotExist()) + .andExpect(jsonPath("$._links.last.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.first.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$._links.prev.href", + Matchers.allOf( + Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), + Matchers.containsString("size=2")))) + .andExpect(jsonPath("$.page.size", is(2))) + .andExpect(jsonPath("$.page.totalPages", is(3))) + .andExpect(jsonPath("$.page.totalElements", is(5))); + + } + + @Test + public void findByTopicUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); + context.restoreAuthSystemState(); + getClient().perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findByTopicForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); + context.restoreAuthSystemState(); + String epersonToken = getAuthToken(eperson.getEmail(), password); + getClient(epersonToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isForbidden()); + } + + @Test + public void findByTopicBadRequestTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); + context.restoreAuthSystemState(); + String adminToken = getAuthToken(admin.getEmail(), password); + getClient(adminToken).perform(get("/api/integration/nbevents/search/findByTopic")) + .andExpect(status().isBadRequest()); + } + + @Test + public void recordDecisionTest() throws Exception { + context.turnOffAuthorisationSystem(); + EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType project = EntityTypeBuilder.createEntityTypeBuilder(context, "Project").build(); + RelationshipTypeBuilder.createRelationshipTypeBuilder(context, publication, project, "isProjectOfPublication", + "isPublicationOfProject", 0, null, 0, + null).withCopyToRight(true).build(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withEntityType("Publication") + .withName("Collection 1").build(); + Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection Fundings") + .withEntityType("Project").build(); + Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") + .build(); + NBEvent eventProjectBound = NBEventBuilder.createTarget(context, col1, "Science and Freedom with project") + .withTopic("ENRICH/MISSING/PROJECT") + .withMessage( + "{\"projects[0].acronym\":\"PAThs\"," + + "\"projects[0].code\":\"687567\"," + + "\"projects[0].funder\":\"EC\"," + + "\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths: " + + "An Archaeological Atlas of Coptic Literature." + + "\\nLiterary Texts in their Geographical Context: Production, Copying, Usage, " + + "Dissemination and Storage\"}") + .withRelatedItem(funding.getID().toString()) + .build(); + NBEvent eventProjectNoBound = NBEventBuilder + .createTarget(context, col1, "Science and Freedom with unrelated project") + .withTopic("ENRICH/MISSING/PROJECT") + .withMessage( + "{\"projects[0].acronym\":\"NEW\"," + + "\"projects[0].code\":\"123456\"," + + "\"projects[0].funder\":\"EC\"," + + "\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"newProjectID\"," + + "\"projects[0].title\":\"A new project\"}") + .build(); + NBEvent eventMissingPID1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent eventMissingPID2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent eventMissingUnknownPID = NBEventBuilder.createTarget(context, col1, "Science and Freedom URN PID") + .withTopic("ENRICH/MISSING/PID") + .withMessage( + "{\"pids[0].type\":\"urn\",\"pids[0].value\":\"http://thesis2.sba.units.it/store/handle/item/12937\"}") + .build(); + NBEvent eventMorePID = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144302\"}").build(); + NBEvent eventAbstract = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"An abstract to add...\"}").build(); + NBEvent eventAbstractToDiscard = NBEventBuilder.createTarget(context, col1, "Science and Freedom 7") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage("{\"abstracts[0]\": \"Abstract to discard...\"}").build(); + context.restoreAuthSystemState(); + // prepare the different patches for our decisions + List acceptOp = new ArrayList(); + acceptOp.add(new ReplaceOperation("/status", NBEvent.ACCEPTED)); + List acceptOpUppercase = new ArrayList(); + acceptOpUppercase.add(new ReplaceOperation("/status", NBEvent.ACCEPTED)); + List discardOp = new ArrayList(); + discardOp.add(new ReplaceOperation("/status", NBEvent.DISCARDED)); + List rejectOp = new ArrayList(); + rejectOp.add(new ReplaceOperation("/status", NBEvent.REJECTED)); + String patchAccept = getPatchContent(acceptOp); + String patchAcceptUppercase = getPatchContent(acceptOpUppercase); + String patchDiscard = getPatchContent(discardOp); + String patchReject = getPatchContent(rejectOp); + + String authToken = getAuthToken(admin.getEmail(), password); + // accept pid1, unknownPID, morePID, the two projects and abstract + eventMissingPID1.setStatus(NBEvent.ACCEPTED); + eventMorePID.setStatus(NBEvent.ACCEPTED); + eventMissingUnknownPID.setStatus(NBEvent.ACCEPTED); + eventMissingUnknownPID.setStatus(NBEvent.ACCEPTED); + eventProjectBound.setStatus(NBEvent.ACCEPTED); + eventProjectNoBound.setStatus(NBEvent.ACCEPTED); + eventAbstract.setStatus(NBEvent.ACCEPTED); + + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMissingPID1.getEventId()) + .content(patchAccept) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMissingPID1))); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMorePID.getEventId()) + .content(patchAcceptUppercase) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMorePID))); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMissingUnknownPID.getEventId()) + .content(patchAccept) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMissingUnknownPID))); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventProjectBound.getEventId()) + .content(patchAccept) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventProjectBound))); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventProjectNoBound.getEventId()) + .content(patchAccept) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventProjectNoBound))); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventAbstract.getEventId()) + .content(patchAccept) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventAbstract))); + // check if the item has been updated + getClient(authToken).perform(get("/api/core/items/" + eventMissingPID1.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect( + jsonPath("$", + hasJsonPath("$.metadata['dc.identifier.other'][0].value", is("10.2307/2144300")))); + getClient(authToken).perform(get("/api/core/items/" + eventMorePID.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasJsonPath("$.metadata['dc.identifier.other'][0].value", is("2144302")))); + getClient(authToken).perform(get("/api/core/items/" + eventMissingUnknownPID.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasJsonPath("$.metadata['dc.identifier.other'][0].value", + is("http://thesis2.sba.units.it/store/handle/item/12937")))); + getClient(authToken).perform(get("/api/core/items/" + eventProjectBound.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", + hasJsonPath("$.metadata['relation.isProjectOfPublication'][0].value", + is(funding.getID().toString())))); + getClient(authToken).perform(get("/api/core/items/" + eventProjectNoBound.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", + hasJsonPath("$.metadata['relation.isProjectOfPublication'][0].value", + is(not(empty()))))); + getClient(authToken).perform(get("/api/core/items/" + eventAbstract.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", + hasJsonPath("$.metadata['dc.description.abstract'][0].value", is("An abstract to add...")))); + // reject pid2 + eventMissingPID2.setStatus(NBEvent.REJECTED); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMissingPID2.getEventId()) + .content(patchReject) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMissingPID2))); + getClient(authToken).perform(get("/api/core/items/" + eventMissingPID2.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", + hasNoJsonPath("$.metadata['dc.identifier.other']"))); + // discard abstractToDiscard + eventAbstractToDiscard.setStatus(NBEvent.DISCARDED); + getClient(authToken).perform(patch("/api/integration/nbevents/" + eventAbstractToDiscard.getEventId()) + .content(patchDiscard) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventAbstractToDiscard))); + getClient(authToken).perform(get("/api/core/items/" + eventMissingPID2.getTarget()) + .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", + hasNoJsonPath("$.metadata['dc.description.abstract']"))); + // no pending nb events should be longer available + getClient(authToken).perform(get("/api/integration/nbtopics")).andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(0))); + // we should have stored the decision into the database as well + } + + @Test + public void setRelatedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection Fundings").build(); + NBEvent event = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + .withTopic("ENRICH/MISSING/PROJECT") + .withMessage( + "{\"projects[0].acronym\":\"PAThs\"," + + "\"projects[0].code\":\"687567\"," + + "\"projects[0].funder\":\"EC\"," + + "\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths: " + + "An Archaeological Atlas of Coptic Literature." + + "\\nLiterary Texts in their Geographical Context: Production, Copying, Usage, " + + "Dissemination and Storage\"}") + .build(); + Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + + getClient(authToken) + .perform(post("/api/integration/nbevents/" + event.getEventId() + "/related").param("item", + funding.getID().toString())) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(funding))); + // update our local event copy to reflect the association with the related item + event.setRelated(funding.getID().toString()); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId() + "/related")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(funding))); + } + + @Test + public void unsetRelatedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection Fundings").build(); + Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") + .build(); + NBEvent event = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + .withTopic("ENRICH/MISSING/PROJECT") + .withMessage( + "{\"projects[0].acronym\":\"PAThs\"," + + "\"projects[0].code\":\"687567\"," + + "\"projects[0].funder\":\"EC\"," + + "\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths: " + + "An Archaeological Atlas of Coptic Literature." + + "\\nLiterary Texts in their Geographical Context: Production, Copying, Usage, " + + "Dissemination and Storage\"}") + .withRelatedItem(funding.getID().toString()) + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + getClient(authToken) + .perform(delete("/api/integration/nbevents/" + event.getEventId() + "/related")) + .andExpect(status().isNoContent()); + + // update our local event copy to reflect the association with the related item + event.setRelated(null); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId() + "/related")) + .andExpect(status().isNoContent()); + } + + @Test + public void setInvalidRelatedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection Fundings").build(); + NBEvent event = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + + getClient(authToken) + .perform(post("/api/integration/nbevents/" + event.getEventId() + "/related").param("item", + funding.getID().toString())) + .andExpect(status().isBadRequest()); + // check that no related item has been added to our event + getClient(authToken) + .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + } + + @Test + public void deleteItemWithEventTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder(NBEventMatcher.matchNBEventEntry(event1), + NBEventMatcher.matchNBEventEntry(event2)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); + + getClient(authToken).perform(delete("/api/core/items/" + event1.getTarget())) + .andExpect(status().is(204)); + + getClient(authToken).perform(get("/api/core/items/" + event1.getTarget())) + .andExpect(status().is(404)); + + getClient(authToken) + .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.nbevents", + Matchers.containsInAnyOrder( + NBEventMatcher.matchNBEventEntry(event2)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java new file mode 100644 index 0000000000..2d0095bd8f --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java @@ -0,0 +1,169 @@ +/** + * 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.app.rest; + +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.dspace.app.rest.matcher.NBTopicMatcher; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.NBEventBuilder; +import org.dspace.content.Collection; +import org.dspace.content.NBEvent; +import org.hamcrest.Matchers; +import org.junit.Test; + +public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { + + @Test + public void findAllTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage( + "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics")).andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbtopics", + Matchers.containsInAnyOrder(NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/PID", 2), + NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/ABSTRACT", 1), + NBTopicMatcher.matchNBTopicEntry("ENRICH/MORE/PID", 1)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3))); + + } + + @Test + public void findAllUnauthorizedTest() throws Exception { + getClient().perform(get("/api/integration/nbtopics")).andExpect(status().isUnauthorized()); + } + + @Test + public void findAllForbiddenTest() throws Exception { + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics")).andExpect(status().isForbidden()); + } + + @Test + public void findAllPaginationTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + //create collection + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage( + "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics").param("size", "2")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbtopics", Matchers.hasSize(2))) + .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); + getClient(authToken).perform(get("/api/integration/nbtopics").param("size", "2").param("page", "1")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbtopics", Matchers.hasSize(1))) + .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); + } + + @Test + public void findOneTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage( + "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")) + .andExpect(jsonPath("$", NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/PID", 2))); + getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!ABSTRACT")) + .andExpect(jsonPath("$", NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/ABSTRACT", 1))); + } + + @Test + public void findOneUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID").build(); + context.restoreAuthSystemState(); + getClient().perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")).andExpect(status().isUnauthorized()); + getClient().perform(get("/api/integration/nbtopics/ENRICH!MISSING!ABSTRACT")) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findOneForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")) + .andExpect(status().isForbidden()); + getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!ABSTRACT")) + .andExpect(status().isForbidden()); + } + +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java new file mode 100644 index 0000000000..afb364bb0e --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java @@ -0,0 +1,81 @@ +/** + * 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.app.rest.matcher; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.emptyOrNullString; +import static org.hamcrest.Matchers.is; + +import java.text.DecimalFormat; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.content.NBEvent; +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.hamcrest.core.IsAnything; + +public class NBEventMatcher { + + private NBEventMatcher() { + } + + public static Matcher matchNBEventFullEntry(NBEvent event) { + return allOf( + matchNBEventEntry(event), + hasJsonPath("$._embedded.topic.name", is(event.getTopic())), + hasJsonPath("$._embedded.target.id", is(event.getTarget())), + event.getRelated() != null ? + hasJsonPath("$._embedded.related.id", is(event.getRelated())) : + hasJsonPath("$._embedded.related", is(emptyOrNullString())) + ); + } + + public static Matcher matchNBEventEntry(NBEvent event) { + try { + ObjectMapper jsonMapper = new JsonMapper(); + return allOf(hasJsonPath("$.id", is(event.getEventId())), + hasJsonPath("$.originalId", is(event.getOriginalId())), + hasJsonPath("$.title", is(event.getTitle())), + hasJsonPath("$.trust", is(new DecimalFormat("0.000").format(event.getTrust()))), + hasJsonPath("$.status", Matchers.equalToIgnoringCase(event.getStatus())), + hasJsonPath("$.message", + matchMessage(event.getTopic(), jsonMapper.readValue(event.getMessage(), MessageDto.class))), + hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")), + hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")), + hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")), + hasJsonPath("$.type", is("nbevent"))); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + private static Matcher matchMessage(String topic, MessageDto message) { + if (StringUtils.endsWith(topic, "/ABSTRACT")) { + return allOf(hasJsonPath("$.abstract", is(message.getAbstracts()))); + } else if (StringUtils.endsWith(topic, "/PID")) { + return allOf( + hasJsonPath("$.value", is(message.getValue())), + hasJsonPath("$.type", is(message.getType()))); + } else if (StringUtils.endsWith(topic, "/PROJECT")) { + return allOf( + hasJsonPath("$.openaireId", is(message.getOpenaireId())), + hasJsonPath("$.acronym", is(message.getAcronym())), + hasJsonPath("$.code", is(message.getCode())), + hasJsonPath("$.funder", is(message.getFunder())), + hasJsonPath("$.fundingProgram", is(message.getFundingProgram())), + hasJsonPath("$.jurisdiction", is(message.getJurisdiction())), + hasJsonPath("$.title", is(message.getTitle()))); + } + return IsAnything.anything(); + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java new file mode 100644 index 0000000000..644feeeec4 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java @@ -0,0 +1,38 @@ +/** + * 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.app.rest.matcher; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.is; + +import org.hamcrest.Matcher; + +public class NBTopicMatcher { + + private NBTopicMatcher() { } + + public static Matcher matchNBTopicEntry(String key, int totalEvents) { + return allOf( + hasJsonPath("$.type", is("nbtopic")), + hasJsonPath("$.name", is(key)), + hasJsonPath("$.id", is(key.replace("/", "!"))), + hasJsonPath("$.totalEvents", is(totalEvents)) + ); + } + + + public static Matcher matchNBTopicEntry(String key) { + return allOf( + hasJsonPath("$.type", is("nbtopic")), + hasJsonPath("$.name", is(key)), + hasJsonPath("$.id", is(key.replace("/", "/"))) + ); + } + +} diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 02c618abf4..369d15c9c1 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -714,7 +714,7 @@ event.dispatcher.default.class = org.dspace.event.BasicDispatcher # Adding doi here makes DSpace send metadata updates to your doi registration agency. # Add rdf here, if you are using dspace-rdf to export your repository content as RDF. # Add iiif here, if you are using dspace-iiif. -event.dispatcher.default.consumers = versioning, discovery, eperson +event.dispatcher.default.consumers = versioning, discovery, eperson, nbeventsdelete # The noindex dispatcher will not create search or browse indexes (useful for batch item imports) event.dispatcher.noindex.class = org.dspace.event.BasicDispatcher @@ -740,6 +740,10 @@ event.consumer.rdf.filters = Community|Collection|Item|Bundle|Bitstream|Site+Add #event.consumer.test.class = org.dspace.event.TestConsumer #event.consumer.test.filters = All+All +# nbevents consumer to delete events related to deleted items +event.consumer.nbeventsdelete.class = org.dspace.app.nbevent.NBEventsDeleteCascadeConsumer +event.consumer.nbeventsdelete.filters = Item+Delete + # consumer to maintain versions event.consumer.versioning.class = org.dspace.versioning.VersioningConsumer event.consumer.versioning.filters = Item+Install @@ -1595,6 +1599,7 @@ include = ${module_dir}/healthcheck.cfg include = ${module_dir}/irus-statistics.cfg include = ${module_dir}/oai.cfg include = ${module_dir}/openaire-client.cfg +include = ${module_dir}/oaire-nbevents.cfg include = ${module_dir}/rdf.cfg include = ${module_dir}/rest.cfg include = ${module_dir}/iiif.cfg diff --git a/dspace/config/hibernate.cfg.xml b/dspace/config/hibernate.cfg.xml index 39f5a11378..b686a5672b 100644 --- a/dspace/config/hibernate.cfg.xml +++ b/dspace/config/hibernate.cfg.xml @@ -56,6 +56,8 @@ + + diff --git a/dspace/config/modules/oaire-nbevents.cfg b/dspace/config/modules/oaire-nbevents.cfg new file mode 100644 index 0000000000..68baec3d1d --- /dev/null +++ b/dspace/config/modules/oaire-nbevents.cfg @@ -0,0 +1,14 @@ +#---------------------------------------------------------------# +#-------OAIRE Notification Broker Events CONFIGURATIONS---------# +#---------------------------------------------------------------# +# Configuration properties used by data correction service # +#---------------------------------------------------------------# +oaire-nbevents.solr.server = ${solr.server}/${solr.multicorePrefix}nbevent +# A POST to these url(s) will be done to notify oaire of decision taken for each nbevents +oaire-nbevents.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events +#oaire-nbevents.acknowledge-url = +oaire-nbevents.import.topic = ENRICH/MISSING/ABSTRACT +oaire-nbevents.import.topic = ENRICH/MISSING/PID +oaire-nbevents.import.topic = ENRICH/MORE/PID +oaire-nbevents.import.topic = ENRICH/MISSING/PROJECT +oaire-nbevents.import.topic = ENRICH/MORE/PROJECT \ No newline at end of file diff --git a/dspace/config/spring/api/nbevents.xml b/dspace/config/spring/api/nbevents.xml new file mode 100644 index 0000000000..34dca93ebb --- /dev/null +++ b/dspace/config/spring/api/nbevents.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dspace/config/spring/api/scripts.xml b/dspace/config/spring/api/scripts.xml index e7c55549c7..61b06c2aa9 100644 --- a/dspace/config/spring/api/scripts.xml +++ b/dspace/config/spring/api/scripts.xml @@ -3,6 +3,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> + + + + + + diff --git a/dspace/config/spring/api/solr-services.xml b/dspace/config/spring/api/solr-services.xml index 698a824184..164a4dd835 100644 --- a/dspace/config/spring/api/solr-services.xml +++ b/dspace/config/spring/api/solr-services.xml @@ -31,5 +31,8 @@ + + + diff --git a/dspace/config/spring/rest/scripts.xml b/dspace/config/spring/rest/scripts.xml index 563c639a10..518d81009b 100644 --- a/dspace/config/spring/rest/scripts.xml +++ b/dspace/config/spring/rest/scripts.xml @@ -8,6 +8,11 @@ + + + + + diff --git a/dspace/solr/nbevent/conf/admin-extra.html b/dspace/solr/nbevent/conf/admin-extra.html new file mode 100644 index 0000000000..aa739da862 --- /dev/null +++ b/dspace/solr/nbevent/conf/admin-extra.html @@ -0,0 +1,31 @@ + + + diff --git a/dspace/solr/nbevent/conf/elevate.xml b/dspace/solr/nbevent/conf/elevate.xml new file mode 100644 index 0000000000..7630ebe20f --- /dev/null +++ b/dspace/solr/nbevent/conf/elevate.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + diff --git a/dspace/solr/nbevent/conf/protwords.txt b/dspace/solr/nbevent/conf/protwords.txt new file mode 100644 index 0000000000..1dfc0abecb --- /dev/null +++ b/dspace/solr/nbevent/conf/protwords.txt @@ -0,0 +1,21 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# Use a protected word file to protect against the stemmer reducing two +# unrelated words to the same base word. + +# Some non-words that normally won't be encountered, +# just to test that they won't be stemmed. +dontstems +zwhacky + diff --git a/dspace/solr/nbevent/conf/schema.xml b/dspace/solr/nbevent/conf/schema.xml new file mode 100644 index 0000000000..8ed9b4d5ae --- /dev/null +++ b/dspace/solr/nbevent/conf/schema.xml @@ -0,0 +1,544 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + event_id + + + + + diff --git a/dspace/solr/nbevent/conf/scripts.conf b/dspace/solr/nbevent/conf/scripts.conf new file mode 100644 index 0000000000..f58b262ae0 --- /dev/null +++ b/dspace/solr/nbevent/conf/scripts.conf @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +user= +solr_hostname=localhost +solr_port=8983 +rsyncd_port=18983 +data_dir= +webapp_name=solr +master_host= +master_data_dir= +master_status_dir= diff --git a/dspace/solr/nbevent/conf/solrconfig.xml b/dspace/solr/nbevent/conf/solrconfig.xml new file mode 100644 index 0000000000..a4cfbed4a9 --- /dev/null +++ b/dspace/solr/nbevent/conf/solrconfig.xml @@ -0,0 +1,1943 @@ + + + + + + + + + 7.7.2 + + + + + + + + + + + + + + + ${solr.data.dir:} + + + + + + + + + + + + + + + + + + + + + + + + + 32 + 1000 + + + + + + + + + + + + ${solr.lock.type:native} + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + ${solr.ulog.dir:} + + + + + 10000 + ${solr.autoCommit.maxTime:10000} + false + + + + + + ${solr.autoSoftCommit.maxTime:1000} + + + + + + + + + + + + + + + + + + + + 1024 + + + + + + + + + + + + + + + + + + + + + + true + + + + + + 20 + + + 200 + + + + + + + + + + + + static firstSearcher warming in solrconfig.xml + + + + + + false + + + 2 + + + + + + + + + + + + + + + + + + + + + + + explicit + 10 + event_id + + + + + + + + + + + + + + explicit + json + true + event_id + + + + + + + + true + json + true + + + + + + + + explicit + + + velocity + browse + layout + Solritas + + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 event_id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + event_id + 100% + *:* + 10 + *,score + + + text^0.5 features^1.0 name^1.2 sku^1.5 event_id^10.0 manu^1.1 cat^1.4 + title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 + + text,features,name,sku,event_id,manu,cat,title,description,keywords,author,resourcename + 3 + + + on + cat + manu_exact + content_type + author_s + ipod + GB + 1 + cat,inStock + after + price + 0 + 600 + 50 + popularity + 0 + 10 + 3 + manufacturedate_dt + NOW/YEAR-10YEARS + NOW + +1YEAR + before + after + + + on + content features title name + html + <b> + </b> + 0 + title + 0 + name + 3 + 200 + content + 750 + + + on + false + 5 + 2 + 5 + true + true + 5 + 3 + + + + + spellcheck + + + + + + + + + + + + + + + application/json + + + + + + + application/csv + + + + + + + + true + ignored_ + + + true + links + ignored_ + + + + + + + + + + + + + + + + + + + + + + solrpingquery + + + all + + + + + + + + + explicit + true + + + + + + + + + + + + + + + + textSpell + + + default + name + ./spellchecker + + + + + + + + + + + + false + + false + + 1 + + + spellcheck + + + + + + + + true + + + tvComponent + + + + + + + + + text_general + + + + + + default + event_id + solr.DirectSolrSpellChecker + + internal + + 0.5 + + 2 + + 1 + + 5 + + 4 + + 0.01 + + + + + + wordbreak + solr.WordBreakSolrSpellChecker + name + true + true + 10 + + + + + + + + + + + + + + + + event_id + + default + wordbreak + on + true + 10 + 5 + 5 + true + true + 10 + 5 + + + spellcheck + + + + + + + + + + event_id + true + + + tvComponent + + + + + + + + + default + + + org.carrot2.clustering.lingo.LingoClusteringAlgorithm + + + 20 + + + clustering/carrot2 + + + ENGLISH + + + stc + org.carrot2.clustering.stc.STCClusteringAlgorithm + + + + + + + true + default + true + + name + event_id + + features + + true + + + + false + + edismax + + text^0.5 features^1.0 name^1.2 sku^1.5 event_id^10.0 manu^1.1 cat^1.4 + + *:* + 10 + *,score + + + clustering + + + + + + + + + + true + false + + + terms + + + + + + + + string + elevate.xml + + + + + + explicit + event_id + + + elevator + + + + + + + + + + + 100 + + + + + + + + 70 + + 0.5 + + [-\w ,/\n\"']{20,200} + + + + + + + ]]> + ]]> + + + + + + + + + + + + + + + + + + + + + + + + ,, + ,, + ,, + ,, + ,]]> + ]]> + + + + + + 10 + .,!? + + + + + + + WORD + + + en + US + + + + + + + + + + + + + + + + + + + + + + + + text/plain; charset=UTF-8 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + *:* + + diff --git a/dspace/solr/nbevent/conf/spellings.txt b/dspace/solr/nbevent/conf/spellings.txt new file mode 100644 index 0000000000..d7ede6f561 --- /dev/null +++ b/dspace/solr/nbevent/conf/spellings.txt @@ -0,0 +1,2 @@ +pizza +history \ No newline at end of file diff --git a/dspace/solr/nbevent/conf/stopwords.txt b/dspace/solr/nbevent/conf/stopwords.txt new file mode 100644 index 0000000000..8433c832d2 --- /dev/null +++ b/dspace/solr/nbevent/conf/stopwords.txt @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +# a couple of test stopwords to test that the words are really being +# configured from this file: +stopworda +stopwordb + +#Standard english stop words taken from Lucene's StopAnalyzer +an +and +are +as +at +be +but +by +for +if +in +into +is +it +no +not +of +on +or +s +such +t +that +the +their +then +there +these +they +this +to +was +will +with + diff --git a/dspace/solr/nbevent/conf/synonyms.txt b/dspace/solr/nbevent/conf/synonyms.txt new file mode 100644 index 0000000000..b0e31cb7ec --- /dev/null +++ b/dspace/solr/nbevent/conf/synonyms.txt @@ -0,0 +1,31 @@ +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#----------------------------------------------------------------------- +#some test synonym mappings unlikely to appear in real input text +aaa => aaaa +bbb => bbbb1 bbbb2 +ccc => cccc1,cccc2 +a\=>a => b\=>b +a\,a => b\,b +fooaaa,baraaa,bazaaa + +# Some synonym groups specific to this example +GB,gib,gigabyte,gigabytes +MB,mib,megabyte,megabytes +Television, Televisions, TV, TVs +#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming +#after us won't split it into two words. + +# Synonym mappings can be used for spelling correction too +pixima => pixma + diff --git a/dspace/solr/nbevent/core.properties b/dspace/solr/nbevent/core.properties new file mode 100644 index 0000000000..e69de29bb2 From 2340a44e96ebde2398877ae3a3df839a8c92cefa Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Wed, 16 Feb 2022 15:48:28 +0100 Subject: [PATCH 02/38] [CST-5294] FIxed NBEventRestRepositoryIT test --- .../app/nbevent/NBEntityMetadataAction.java | 8 ++- .../dspace/content/CollectionServiceImpl.java | 52 +++++++++++++++++++ .../content/service/CollectionService.java | 27 ++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java index ad575b5281..2e5622cf4b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java @@ -19,6 +19,7 @@ import org.dspace.content.Item; import org.dspace.content.Relationship; import org.dspace.content.RelationshipType; import org.dspace.content.WorkspaceItem; +import org.dspace.content.service.CollectionService; import org.dspace.content.service.EntityTypeService; import org.dspace.content.service.InstallItemService; import org.dspace.content.service.ItemService; @@ -51,6 +52,9 @@ public class NBEntityMetadataAction implements NBAction { @Autowired private WorkspaceItemService workspaceItemService; + @Autowired + private CollectionService collectionService; + public void setItemService(ItemService itemService) { this.itemService = itemService; } @@ -96,11 +100,11 @@ public class NBEntityMetadataAction implements NBAction { if (relatedItem != null) { link(context, item, relatedItem); } else { - Collection collection = item.getOwningCollection(); + Collection collection = collectionService.retrieveCollectionByEntityType(context, item, entityType); WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); relatedItem = workspaceItem.getItem(); if (StringUtils.isNotBlank(entityType)) { - itemService.addMetadata(context, relatedItem, "relationship", "type", null, null, entityType); + itemService.addMetadata(context, relatedItem, "dspace", "entity", "type", null, entityType); } for (String key : entityMetadata.keySet()) { String value = getValue(message, key); diff --git a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java index e54f609389..7a12c1c545 100644 --- a/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/CollectionServiceImpl.java @@ -1017,6 +1017,58 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl i return resp; } + @Override + public Collection retrieveCollectionByEntityType(Context context, Item item, String entityType) + throws SQLException { + Collection ownCollection = item.getOwningCollection(); + return retrieveCollectionByEntityType(context, ownCollection.getCommunities(), entityType); + } + + private Collection retrieveCollectionByEntityType(Context context, List communities, String entityType) { + + for (Community community : communities) { + Collection collection = retrieveCollectionByCommunityAndEntityType(context, community, entityType); + if (collection != null) { + return collection; + } + } + + for (Community community : communities) { + List parentCommunities = community.getParentCommunities(); + Collection collection = retrieveCollectionByEntityType(context, parentCommunities, entityType); + if (collection != null) { + return collection; + } + } + + return retrieveCollectionByCommunityAndEntityType(context, null, entityType); + } + + @Override + public Collection retrieveCollectionByCommunityAndEntityType(Context context, Community community, + String entityType) { + context.turnOffAuthorisationSystem(); + List collections; + try { + collections = findCollectionsWithSubmit(null, context, community, entityType, 0, 1); + } catch (SQLException | SearchServiceException e) { + throw new RuntimeException(e); + } + context.restoreAuthSystemState(); + if (collections != null && collections.size() > 0) { + return collections.get(0); + } + if (community != null) { + for (Community subCommunity : community.getSubcommunities()) { + Collection collection = retrieveCollectionByCommunityAndEntityType(context, subCommunity, entityType); + if (collection != null) { + return collection; + } + } + } + return null; + } + @Override public List findCollectionsWithSubmit(String q, Context context, Community community, String entityType, int offset, int limit) throws SQLException, SearchServiceException { diff --git a/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java index 522bdac224..07d4d113b7 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/CollectionService.java @@ -412,6 +412,33 @@ public interface CollectionService public List findCollectionsWithSubmit(String q, Context context, Community community, int offset, int limit) throws SQLException, SearchServiceException; + /** + * Retrieve the first collection in the community or its descending that support + * the provided entityType + * + * @param context the DSpace context + * @param community the root from where the search start + * @param entityType the requested entity type + * @return the first collection in the community or its descending + * that support the provided entityType + */ + public Collection retrieveCollectionByCommunityAndEntityType(Context context, Community community, + String entityType); + + /** + * Retrieve the close collection to the item that support the provided + * entityType. Close mean the collection that can be reach with the minimum + * steps starting from the item (owningCollection, brothers collections, etc) + * + * @param context the DSpace context + * @param item the item from where the search start + * @param entityType the requested entity type + * @return the first collection in the community or its descending + * that support the provided entityType + */ + public Collection retrieveCollectionByEntityType(Context context, Item item, String entityType) + throws SQLException; + /** * Counts the number of Collection for which the current user has 'submit' privileges. * NOTE: for better performance, this method retrieves its results from an index (cache) From 8952fa7cf1c493dff1112b9f577b41a84ce130fc Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Wed, 16 Feb 2022 18:50:55 +0100 Subject: [PATCH 03/38] [CST-5246] Added support for multiple providers --- .../app/nbevent/NBEntityMetadataAction.java | 36 ++-- .../app/nbevent/NBEventActionServiceImpl.java | 12 +- .../dspace/app/nbevent/NBEventsRunnable.java | 2 + .../app/nbevent/NBMetadataMapAction.java | 13 +- .../app/nbevent/NBSimpleMetadataAction.java | 3 +- .../java/org/dspace/app/nbevent/NBSource.java | 46 +++++ .../app/nbevent/service/NBEventService.java | 14 +- .../app/nbevent/service/dto/MessageDto.java | 157 +--------------- .../service/dto/OpenaireMessageDto.java | 167 ++++++++++++++++++ .../service/impl/NBEventServiceImpl.java | 75 ++++++++ .../main/java/org/dspace/content/NBEvent.java | 30 ++-- .../java/org/dspace/content/NBSourceName.java | 13 ++ .../org/dspace/builder/NBEventBuilder.java | 7 +- .../app/rest/converter/NBEventConverter.java | 43 +++-- .../app/rest/converter/NBSourceConverter.java | 33 ++++ .../app/rest/model/NBEventMessageRest.java | 78 +------- .../dspace/app/rest/model/NBEventRest.java | 15 ++ .../dspace/app/rest/model/NBSourceRest.java | 69 ++++++++ .../model/OpenaireNBEventMessageRest.java | 88 +++++++++ .../rest/model/hateoas/NBSourceResource.java | 21 +++ .../repository/NBSourceRestRepository.java | 53 ++++++ .../repository/NBTopicRestRepository.java | 14 ++ .../app/rest/matcher/NBEventMatcher.java | 7 +- dspace/solr/nbevent/conf/schema.xml | 1 + 24 files changed, 711 insertions(+), 286 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java create mode 100644 dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java create mode 100644 dspace-api/src/main/java/org/dspace/content/NBSourceName.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java index 2e5622cf4b..5e6b96c0b4 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java @@ -12,6 +12,7 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.EntityType; @@ -141,21 +142,28 @@ public class NBEntityMetadataAction implements NBAction { } private String getValue(MessageDto message, String key) { - if (StringUtils.equals(key, "acronym")) { - return message.getAcronym(); - } else if (StringUtils.equals(key, "code")) { - return message.getCode(); - } else if (StringUtils.equals(key, "funder")) { - return message.getFunder(); - } else if (StringUtils.equals(key, "fundingProgram")) { - return message.getFundingProgram(); - } else if (StringUtils.equals(key, "jurisdiction")) { - return message.getJurisdiction(); - } else if (StringUtils.equals(key, "openaireId")) { - return message.getOpenaireId(); - } else if (StringUtils.equals(key, "title")) { - return message.getTitle(); + if (!(message instanceof OpenaireMessageDto)) { + return null; } + + OpenaireMessageDto openaireMessage = (OpenaireMessageDto) message; + + if (StringUtils.equals(key, "acronym")) { + return openaireMessage.getAcronym(); + } else if (StringUtils.equals(key, "code")) { + return openaireMessage.getCode(); + } else if (StringUtils.equals(key, "funder")) { + return openaireMessage.getFunder(); + } else if (StringUtils.equals(key, "fundingProgram")) { + return openaireMessage.getFundingProgram(); + } else if (StringUtils.equals(key, "jurisdiction")) { + return openaireMessage.getJurisdiction(); + } else if (StringUtils.equals(key, "openaireId")) { + return openaireMessage.getOpenaireId(); + } else if (StringUtils.equals(key, "title")) { + return openaireMessage.getTitle(); + } + return null; } } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java index b34ac6cd25..2d84e8f9ba 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java @@ -26,6 +26,7 @@ import org.apache.http.impl.client.HttpClients; import org.apache.logging.log4j.Logger; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; import org.dspace.content.Item; import org.dspace.content.NBEvent; import org.dspace.content.service.ItemService; @@ -72,7 +73,7 @@ public class NBEventActionServiceImpl implements NBEventActionService { related = itemService.find(context, UUID.fromString(nbevent.getRelated())); } topicsToActions.get(nbevent.getTopic()).applyCorrection(context, item, related, - jsonMapper.readValue(nbevent.getMessage(), MessageDto.class)); + jsonMapper.readValue(nbevent.getMessage(), getMessageDtoClass(nbevent))); nbEventService.deleteEventByEventId(context, nbevent.getEventId()); makeAcknowledgement(nbevent.getEventId(), NBEvent.ACCEPTED); } catch (SQLException | JsonProcessingException e) { @@ -80,6 +81,15 @@ public class NBEventActionServiceImpl implements NBEventActionService { } } + private Class getMessageDtoClass(NBEvent modelObject) { + switch (modelObject.getSource()) { + case OPENAIRE: + return OpenaireMessageDto.class; + default: + throw new IllegalArgumentException("Unknown event's source: " + modelObject.getSource()); + } + } + @Override public void discard(Context context, NBEvent nbevent) { nbEventService.deleteEventByEventId(context, nbevent.getEventId()); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java index fc0e7b9dae..80f7f5dabb 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java @@ -21,6 +21,7 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.StringUtils; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.NBEvent; +import org.dspace.content.NBSourceName; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; @@ -102,6 +103,7 @@ public class NBEventsRunnable extends DSpaceRunnable findAllTopics(Context context, long offset, long pageSize); + public List findAllTopicsBySource(Context context, NBSourceName source, long offset, long count); + public long countTopics(Context context); + public long countTopicsBySource(Context context, NBSourceName source); + public List findEventsByTopicAndPage(Context context, String topic, long offset, int pageSize, String orderField, boolean ascending); @@ -36,4 +40,10 @@ public interface NBEventService { public void deleteEventsByTargetId(Context context, UUID targetId); + public NBTopic findTopicByTopicId(String topicId); + + public NBSource findSource(NBSourceName source); + + public List findAllSources(Context context, long offset, int pageSize); + } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java index 6b72c58ee4..55c1722de8 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java @@ -7,162 +7,7 @@ */ package org.dspace.app.nbevent.service.dto; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class MessageDto { - - @JsonProperty("pids[0].value") - private String value; - - @JsonProperty("pids[0].type") - private String type; - - @JsonProperty("instances[0].hostedby") - private String instanceHostedBy; - - @JsonProperty("instances[0].instancetype") - private String instanceInstanceType; - - @JsonProperty("instances[0].license") - private String instanceLicense; - - @JsonProperty("instances[0].url") - private String instanceUrl; - - @JsonProperty("abstracts[0]") - private String abstracts; - - @JsonProperty("projects[0].acronym") - private String acronym; - - @JsonProperty("projects[0].code") - private String code; - - @JsonProperty("projects[0].funder") - private String funder; - - @JsonProperty("projects[0].fundingProgram") - private String fundingProgram; - - @JsonProperty("projects[0].jurisdiction") - private String jurisdiction; - - @JsonProperty("projects[0].openaireId") - private String openaireId; - - @JsonProperty("projects[0].title") - private String title; +public interface MessageDto { - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getInstanceHostedBy() { - return instanceHostedBy; - } - - public void setInstanceHostedBy(String instanceHostedBy) { - this.instanceHostedBy = instanceHostedBy; - } - - public String getInstanceInstanceType() { - return instanceInstanceType; - } - - public void setInstanceInstanceType(String instanceInstanceType) { - this.instanceInstanceType = instanceInstanceType; - } - - public String getInstanceLicense() { - return instanceLicense; - } - - public void setInstanceLicense(String instanceLicense) { - this.instanceLicense = instanceLicense; - } - - public String getInstanceUrl() { - return instanceUrl; - } - - public void setInstanceUrl(String instanceUrl) { - this.instanceUrl = instanceUrl; - } - - public String getAbstracts() { - return abstracts; - } - - public void setAbstracts(String abstracts) { - this.abstracts = abstracts; - } - - public String getAcronym() { - return acronym; - } - - public void setAcronym(String acronym) { - this.acronym = acronym; - } - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getFunder() { - return funder; - } - - public void setFunder(String funder) { - this.funder = funder; - } - - public String getFundingProgram() { - return fundingProgram; - } - - public void setFundingProgram(String fundingProgram) { - this.fundingProgram = fundingProgram; - } - - public String getJurisdiction() { - return jurisdiction; - } - - public void setJurisdiction(String jurisdiction) { - this.jurisdiction = jurisdiction; - } - - public String getOpenaireId() { - return openaireId; - } - - public void setOpenaireId(String openaireId) { - this.openaireId = openaireId; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java new file mode 100644 index 0000000000..5ae6b29c3a --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java @@ -0,0 +1,167 @@ +/** + * 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.app.nbevent.service.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class OpenaireMessageDto implements MessageDto { + + @JsonProperty("pids[0].value") + private String value; + + @JsonProperty("pids[0].type") + private String type; + + @JsonProperty("instances[0].hostedby") + private String instanceHostedBy; + + @JsonProperty("instances[0].instancetype") + private String instanceInstanceType; + + @JsonProperty("instances[0].license") + private String instanceLicense; + + @JsonProperty("instances[0].url") + private String instanceUrl; + + @JsonProperty("abstracts[0]") + private String abstracts; + + @JsonProperty("projects[0].acronym") + private String acronym; + + @JsonProperty("projects[0].code") + private String code; + + @JsonProperty("projects[0].funder") + private String funder; + + @JsonProperty("projects[0].fundingProgram") + private String fundingProgram; + + @JsonProperty("projects[0].jurisdiction") + private String jurisdiction; + + @JsonProperty("projects[0].openaireId") + private String openaireId; + + @JsonProperty("projects[0].title") + private String title; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getInstanceHostedBy() { + return instanceHostedBy; + } + + public void setInstanceHostedBy(String instanceHostedBy) { + this.instanceHostedBy = instanceHostedBy; + } + + public String getInstanceInstanceType() { + return instanceInstanceType; + } + + public void setInstanceInstanceType(String instanceInstanceType) { + this.instanceInstanceType = instanceInstanceType; + } + + public String getInstanceLicense() { + return instanceLicense; + } + + public void setInstanceLicense(String instanceLicense) { + this.instanceLicense = instanceLicense; + } + + public String getInstanceUrl() { + return instanceUrl; + } + + public void setInstanceUrl(String instanceUrl) { + this.instanceUrl = instanceUrl; + } + + public String getAbstracts() { + return abstracts; + } + + public void setAbstracts(String abstracts) { + this.abstracts = abstracts; + } + + public String getAcronym() { + return acronym; + } + + public void setAcronym(String acronym) { + this.acronym = acronym; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getFunder() { + return funder; + } + + public void setFunder(String funder) { + this.funder = funder; + } + + public String getFundingProgram() { + return fundingProgram; + } + + public void setFundingProgram(String fundingProgram) { + this.fundingProgram = fundingProgram; + } + + public String getJurisdiction() { + return jurisdiction; + } + + public void setJurisdiction(String jurisdiction) { + this.jurisdiction = jurisdiction; + } + + public String getOpenaireId() { + return openaireId; + } + + public void setOpenaireId(String openaireId) { + this.openaireId = openaireId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java index 8901079425..6f745d0800 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java @@ -9,9 +9,11 @@ package org.dspace.app.nbevent.service.impl; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -29,11 +31,13 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; +import org.dspace.app.nbevent.NBSource; import org.dspace.app.nbevent.NBTopic; import org.dspace.app.nbevent.dao.impl.NBEventsDaoImpl; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Item; import org.dspace.content.NBEvent; +import org.dspace.content.NBSourceName; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.handle.service.HandleService; @@ -69,6 +73,7 @@ public class NBEventServiceImpl implements NBEventService { */ protected SolrClient solr = null; + public static final String SOURCE = "source"; public static final String ORIGINAL_ID = "original_id"; public static final String TITLE = "title"; public static final String TOPIC = "topic"; @@ -106,6 +111,25 @@ public class NBEventServiceImpl implements NBEventService { return response.getFacetField(TOPIC).getValueCount(); } + @Override + public long countTopicsBySource(Context context, NBSourceName source) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setRows(0); + solrQuery.setQuery("*:*"); + solrQuery.setFacet(true); + // we would like to get eventually topic that has no longer active nb events + solrQuery.setFacetMinCount(0); + solrQuery.addFacetField(TOPIC); + solrQuery.addFilterQuery("source:" + source); + QueryResponse response; + try { + response = getSolr().query(solrQuery); + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + return response.getFacetField(TOPIC).getValueCount(); + } + @Override public void deleteEventByEventId(Context context, String id) { try { @@ -169,6 +193,11 @@ public class NBEventServiceImpl implements NBEventService { */ @Override public List findAllTopics(Context context, long offset, long count) { + return findAllTopicsBySource(context, null, offset, count); + } + + @Override + public List findAllTopicsBySource(Context context, NBSourceName source, long offset, long count) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); @@ -177,6 +206,9 @@ public class NBEventServiceImpl implements NBEventService { solrQuery.setFacetMinCount(0); solrQuery.setFacetLimit((int) (offset + count)); solrQuery.addFacetField(TOPIC); + if (source != null) { + solrQuery.addFilterQuery("source:" + source); + } QueryResponse response; List nbTopics = null; try { @@ -212,6 +244,7 @@ public class NBEventServiceImpl implements NBEventService { try { if (!nbEventsDao.isEventStored(context, checksum)) { SolrInputDocument doc = new SolrInputDocument(); + doc.addField(SOURCE, dto.getSource().name()); doc.addField(EVENT_ID, checksum); doc.addField(ORIGINAL_ID, dto.getOriginalId()); doc.addField(TITLE, dto.getTitle()); @@ -258,6 +291,7 @@ public class NBEventServiceImpl implements NBEventService { private NBEvent getNBEventFromSOLR(SolrDocument doc) { NBEvent item = new NBEvent(); + item.setSource(NBSourceName.valueOf((String) doc.get(SOURCE))); item.setEventId((String) doc.get(EVENT_ID)); item.setLastUpdate((Date) doc.get(LAST_UPDATE)); item.setMessage((String) doc.get(MESSAGE)); @@ -337,4 +371,45 @@ public class NBEventServiceImpl implements NBEventService { } } + @Override + public NBSource findSource(NBSourceName sourceName) { + SolrQuery solrQuery = new SolrQuery(); + solrQuery.setRows(0); + solrQuery.setQuery(SOURCE + ":" + sourceName); + solrQuery.setFacet(true); + // we would like to get eventually topic that has no longer active nb events + solrQuery.setFacetMinCount(0); + solrQuery.addFacetField(SOURCE); + QueryResponse response; + try { + response = getSolr().query(solrQuery); + FacetField facetField = response.getFacetField(SOURCE); + for (Count c : facetField.getValues()) { + if (c.getName().equalsIgnoreCase(sourceName.name())) { + NBSource source = new NBSource(); + source.setName(c.getName()); + source.setTotalEvents(c.getCount()); + source.setLastEvent(new Date()); + return source; + } + } + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } + + NBSource source = new NBSource(); + source.setName(sourceName.name()); + source.setTotalEvents(0L); + return source; + } + + @Override + public List findAllSources(Context context, long offset, int pageSize) { + return Arrays.stream(NBSourceName.values()).sorted() + .map((sourceName) -> findSource(sourceName)) + .skip(offset) + .limit(pageSize) + .collect(Collectors.toList()); + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/NBEvent.java b/dspace-api/src/main/java/org/dspace/content/NBEvent.java index c920016917..950fc37d01 100644 --- a/dspace-api/src/main/java/org/dspace/content/NBEvent.java +++ b/dspace-api/src/main/java/org/dspace/content/NBEvent.java @@ -13,7 +13,6 @@ import java.security.NoSuchAlgorithmException; import java.util.Date; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import org.apache.solr.client.solrj.beans.Field; import org.dspace.app.nbevent.RawJsonDeserializer; /** @@ -27,32 +26,26 @@ public class NBEvent { public static final String ACCEPTED = "accepted"; public static final String REJECTED = "rejected"; public static final String DISCARDED = "discarded"; - @Field("event_id") + + private NBSourceName source; + private String eventId; - @Field("original_id") private String originalId; - @Field("resource_uuid") private String target; - @Field("related_uuid") private String related; - @Field("title") private String title; - @Field("topic") private String topic; - @Field("trust") private double trust; - @Field("message") @JsonDeserialize(using = RawJsonDeserializer.class) private String message; - @Field("last_update") private Date lastUpdate; private String status = "PENDING"; @@ -60,9 +53,10 @@ public class NBEvent { public NBEvent() { } - public NBEvent(String originalId, String target, String title, String topic, double trust, String message, - Date lastUpdate) { + public NBEvent(NBSourceName source, String originalId, String target, String title, + String topic, double trust, String message, Date lastUpdate) { super(); + this.source = source; this.originalId = originalId; this.target = target; this.title = title; @@ -165,14 +159,22 @@ public class NBEvent { return status; } + public NBSourceName getSource() { + return source != null ? source : NBSourceName.OPENAIRE; + } + + public void setSource(NBSourceName source) { + this.source = source; + } + /* * DTO constructed via Jackson use empty constructor. In this case, the eventId * must be compute on the get method */ private void computedEventId() throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest digester = MessageDigest.getInstance("MD5"); - String dataToString = "originalId=" + originalId + ", title=" + title + ", topic=" + topic + ", trust=" + trust - + ", message=" + message; + String dataToString = "source=" + source + ",originalId=" + originalId + ", title=" + title + ", topic=" + + topic + ", trust=" + trust + ", message=" + message; digester.update(dataToString.getBytes("UTF-8")); byte[] signature = digester.digest(); char[] arr = new char[signature.length << 1]; diff --git a/dspace-api/src/main/java/org/dspace/content/NBSourceName.java b/dspace-api/src/main/java/org/dspace/content/NBSourceName.java new file mode 100644 index 0000000000..705cc26058 --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/content/NBSourceName.java @@ -0,0 +1,13 @@ +/** + * 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.content; + +public enum NBSourceName { + + OPENAIRE; +} diff --git a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java index 9101d3bf5e..57e5c2a2fe 100644 --- a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java @@ -13,6 +13,7 @@ import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.content.NBEvent; +import org.dspace.content.NBSourceName; import org.dspace.core.Context; /** @@ -24,7 +25,7 @@ public class NBEventBuilder extends AbstractBuilder { private Item item; private NBEvent target; - + private NBSourceName source = NBSourceName.OPENAIRE; private String title; private String topic; private String message; @@ -95,8 +96,8 @@ public class NBEventBuilder extends AbstractBuilder { @Override public NBEvent build() { - target = new NBEvent("oai:www.dspace.org:" + item.getHandle(), item.getID().toString(), title, topic, trust, - message, lastUpdate); + target = new NBEvent(source, "oai:www.dspace.org:" + item.getHandle(), item.getID().toString(), title, topic, + trust, message, lastUpdate); target.setRelated(relatedItem); try { nbEventService.store(context, target); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java index 3534e3c310..82230e8eee 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java @@ -14,8 +14,10 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; import org.dspace.app.rest.model.NBEventMessageRest; import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.OpenaireNBEventMessageRest; import org.dspace.app.rest.projection.Projection; import org.dspace.content.NBEvent; import org.springframework.stereotype.Component; @@ -36,7 +38,8 @@ public class NBEventConverter implements DSpaceConverter { NBEventRest rest = new NBEventRest(); rest.setId(modelObject.getEventId()); try { - rest.setMessage(convertMessage(jsonMapper.readValue(modelObject.getMessage(), MessageDto.class))); + rest.setMessage(convertMessage(jsonMapper.readValue(modelObject.getMessage(), + getMessageDtoClass(modelObject)))); } catch (JsonProcessingException e) { throw new RuntimeException(e); } @@ -51,19 +54,33 @@ public class NBEventConverter implements DSpaceConverter { return rest; } + private Class getMessageDtoClass(NBEvent modelObject) { + switch (modelObject.getSource()) { + case OPENAIRE: + return OpenaireMessageDto.class; + default: + throw new IllegalArgumentException("Unknown event's source: " + modelObject.getSource()); + } + } + private NBEventMessageRest convertMessage(MessageDto dto) { - NBEventMessageRest message = new NBEventMessageRest(); - message.setAbstractValue(dto.getAbstracts()); - message.setOpenaireId(dto.getOpenaireId()); - message.setAcronym(dto.getAcronym()); - message.setCode(dto.getCode()); - message.setFunder(dto.getFunder()); - message.setFundingProgram(dto.getFundingProgram()); - message.setJurisdiction(dto.getJurisdiction()); - message.setTitle(dto.getTitle()); - message.setType(dto.getType()); - message.setValue(dto.getValue()); - return message; + if (dto instanceof OpenaireMessageDto) { + OpenaireMessageDto openaireDto = (OpenaireMessageDto) dto; + OpenaireNBEventMessageRest message = new OpenaireNBEventMessageRest(); + message.setAbstractValue(openaireDto.getAbstracts()); + message.setOpenaireId(openaireDto.getOpenaireId()); + message.setAcronym(openaireDto.getAcronym()); + message.setCode(openaireDto.getCode()); + message.setFunder(openaireDto.getFunder()); + message.setFundingProgram(openaireDto.getFundingProgram()); + message.setJurisdiction(openaireDto.getJurisdiction()); + message.setTitle(openaireDto.getTitle()); + message.setType(openaireDto.getType()); + message.setValue(openaireDto.getValue()); + return message; + } + + throw new IllegalArgumentException("Unknown message type: " + dto.getClass()); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java new file mode 100644 index 0000000000..7524cc7975 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java @@ -0,0 +1,33 @@ +/** + * 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.app.rest.converter; + +import org.dspace.app.nbevent.NBSource; +import org.dspace.app.rest.model.NBSourceRest; +import org.dspace.app.rest.projection.Projection; +import org.springframework.stereotype.Component; + +@Component +public class NBSourceConverter implements DSpaceConverter { + + @Override + public Class getModelClass() { + return NBSource.class; + } + + @Override + public NBSourceRest convert(NBSource modelObject, Projection projection) { + NBSourceRest rest = new NBSourceRest(); + rest.setProjection(projection); + rest.setId(modelObject.getName()); + rest.setLastEvent(modelObject.getLastEvent()); + rest.setTotalEvents(modelObject.getTotalEvents()); + return rest; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java index 7d0f24a21d..7c2e03ac34 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java @@ -7,82 +7,6 @@ */ package org.dspace.app.rest.model; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NBEventMessageRest { - // pids - private String type; - private String value; - // abstract - @JsonProperty(value = "abstract") - private String abstractValue; - // project - private String openaireId; - private String acronym; - private String code; - private String funder; - private String fundingProgram; - private String jurisdiction; - private String title; - public String getType() { - return type; - } - public void setType(String type) { - this.type = type; - } - public String getValue() { - return value; - } - public void setValue(String value) { - this.value = value; - } - public String getAbstractValue() { - return abstractValue; - } - public void setAbstractValue(String abstractValue) { - this.abstractValue = abstractValue; - } - public String getOpenaireId() { - return openaireId; - } - public void setOpenaireId(String openaireId) { - this.openaireId = openaireId; - } - public String getAcronym() { - return acronym; - } - public void setAcronym(String acronym) { - this.acronym = acronym; - } - public String getCode() { - return code; - } - public void setCode(String code) { - this.code = code; - } - public String getFunder() { - return funder; - } - public void setFunder(String funder) { - this.funder = funder; - } - public String getFundingProgram() { - return fundingProgram; - } - public void setFundingProgram(String fundingProgram) { - this.fundingProgram = fundingProgram; - } - public String getJurisdiction() { - return jurisdiction; - } - public void setJurisdiction(String jurisdiction) { - this.jurisdiction = jurisdiction; - } - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } +public interface NBEventMessageRest { } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java index de2cea32fa..60dbce6d9b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java @@ -26,6 +26,7 @@ public class NBEventRest extends BaseObjectRest { public static final String TOPIC = "topic"; public static final String TARGET = "target"; public static final String RELATED = "related"; + private String source; private String originalId; private String title; private String topic; @@ -112,4 +113,18 @@ public class NBEventRest extends BaseObjectRest { public void setStatus(String status) { this.status = status; } + + /** + * @return the source + */ + public String getSource() { + return source; + } + + /** + * @param source the source to set + */ + public void setSource(String source) { + this.source = source; + } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java new file mode 100644 index 0000000000..69e230f378 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java @@ -0,0 +1,69 @@ +/** + * 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.app.rest.model; + +import java.util.Date; + +import org.dspace.app.rest.RestResourceController; + +/** + * REST Representation of a notification broker source + * + * @author Luca Giamminonni (luca.giamminonni at 4Science) + * + */ +public class NBSourceRest extends BaseObjectRest { + + private static final long serialVersionUID = -7455358581579629244L; + + public static final String NAME = "nbsource"; + public static final String CATEGORY = RestAddressableModel.INTEGRATION; + + private String id; + private Date lastEvent; + private long totalEvents; + + @Override + public String getType() { + return NAME; + } + + @Override + public String getCategory() { + return CATEGORY; + } + + @Override + public Class getController() { + return RestResourceController.class; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Date getLastEvent() { + return lastEvent; + } + + public void setLastEvent(Date lastEvent) { + this.lastEvent = lastEvent; + } + + public long getTotalEvents() { + return totalEvents; + } + + public void setTotalEvents(long totalEvents) { + this.totalEvents = totalEvents; + } +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java new file mode 100644 index 0000000000..84021abb6e --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java @@ -0,0 +1,88 @@ +/** + * 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.app.rest.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class OpenaireNBEventMessageRest implements NBEventMessageRest { + // pids + private String type; + private String value; + // abstract + @JsonProperty(value = "abstract") + private String abstractValue; + // project + private String openaireId; + private String acronym; + private String code; + private String funder; + private String fundingProgram; + private String jurisdiction; + private String title; + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public String getAbstractValue() { + return abstractValue; + } + public void setAbstractValue(String abstractValue) { + this.abstractValue = abstractValue; + } + public String getOpenaireId() { + return openaireId; + } + public void setOpenaireId(String openaireId) { + this.openaireId = openaireId; + } + public String getAcronym() { + return acronym; + } + public void setAcronym(String acronym) { + this.acronym = acronym; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getFunder() { + return funder; + } + public void setFunder(String funder) { + this.funder = funder; + } + public String getFundingProgram() { + return fundingProgram; + } + public void setFundingProgram(String fundingProgram) { + this.fundingProgram = fundingProgram; + } + public String getJurisdiction() { + return jurisdiction; + } + public void setJurisdiction(String jurisdiction) { + this.jurisdiction = jurisdiction; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java new file mode 100644 index 0000000000..899b684199 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java @@ -0,0 +1,21 @@ +/** + * 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.app.rest.model.hateoas; + +import org.dspace.app.rest.model.NBSourceRest; +import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; +import org.dspace.app.rest.utils.Utils; + +@RelNameDSpaceResource(NBSourceRest.NAME) +public class NBSourceResource extends DSpaceResource { + + public NBSourceResource(NBSourceRest data, Utils utils) { + super(data, utils); + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java new file mode 100644 index 0000000000..95dfa6b61a --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java @@ -0,0 +1,53 @@ +/** + * 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.app.rest.repository; + +import java.util.List; + +import org.dspace.app.nbevent.NBSource; +import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.model.NBSourceRest; +import org.dspace.content.NBSourceName; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component(NBSourceRest.CATEGORY + "." + NBSourceRest.NAME) +public class NBSourceRestRepository extends DSpaceRestRepository { + + @Autowired + private NBEventService nbEventService; + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public NBSourceRest findOne(Context context, String id) { + NBSource nbSource = nbEventService.findSource(NBSourceName.valueOf(id)); + return converter.toRest(nbSource, utils.obtainProjection()); + } + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public Page findAll(Context context, Pageable pageable) { + List nbTopics = nbEventService.findAllSources(context, pageable.getOffset(), pageable.getPageSize()); + long count = nbEventService.countTopics(context); + if (nbTopics == null) { + return null; + } + return converter.toRestPage(nbTopics, pageable, count, utils.obtainProjection()); + } + + + @Override + public Class getDomainClass() { + return NBSourceRest.class; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java index afaf3c7346..c738da7bd6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java @@ -11,7 +11,9 @@ import java.util.List; import org.dspace.app.nbevent.NBTopic; import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.content.NBSourceName; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -46,6 +48,18 @@ public class NBTopicRestRepository extends DSpaceRestRepository findBySource(Context context, String source, Pageable pageable) { + List nbTopics = nbEventService.findAllTopicsBySource(context, NBSourceName.valueOf(source), + pageable.getOffset(), pageable.getPageSize()); + long count = nbEventService.countTopicsBySource(context, NBSourceName.valueOf(source)); + if (nbTopics == null) { + return null; + } + return converter.toRestPage(nbTopics, pageable, count, utils.obtainProjection()); + } + @Override public Class getDomainClass() { return NBTopicRest.class; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java index afb364bb0e..f8dca7e466 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; import org.dspace.content.NBEvent; import org.hamcrest.Matcher; import org.hamcrest.Matchers; @@ -49,7 +49,8 @@ public class NBEventMatcher { hasJsonPath("$.trust", is(new DecimalFormat("0.000").format(event.getTrust()))), hasJsonPath("$.status", Matchers.equalToIgnoringCase(event.getStatus())), hasJsonPath("$.message", - matchMessage(event.getTopic(), jsonMapper.readValue(event.getMessage(), MessageDto.class))), + matchMessage(event.getTopic(), jsonMapper.readValue(event.getMessage(), + OpenaireMessageDto.class))), hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")), hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")), hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")), @@ -59,7 +60,7 @@ public class NBEventMatcher { } } - private static Matcher matchMessage(String topic, MessageDto message) { + private static Matcher matchMessage(String topic, OpenaireMessageDto message) { if (StringUtils.endsWith(topic, "/ABSTRACT")) { return allOf(hasJsonPath("$.abstract", is(message.getAbstracts()))); } else if (StringUtils.endsWith(topic, "/PID")) { diff --git a/dspace/solr/nbevent/conf/schema.xml b/dspace/solr/nbevent/conf/schema.xml index 8ed9b4d5ae..338fbdcdcd 100644 --- a/dspace/solr/nbevent/conf/schema.xml +++ b/dspace/solr/nbevent/conf/schema.xml @@ -509,6 +509,7 @@ when adding a document. --> + From 90e93a3e4075f40c08c105c500b585d156f8275b Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Thu, 17 Feb 2022 11:34:27 +0100 Subject: [PATCH 04/38] [CST-5246] Added missing java docs --- .../java/org/dspace/app/nbevent/NBAction.java | 19 +++- .../app/nbevent/NBEntityMetadataAction.java | 19 +++- .../app/nbevent/NBEventActionService.java | 26 +++++ .../app/nbevent/NBEventActionServiceImpl.java | 19 ++-- .../app/nbevent/NBMetadataMapAction.java | 17 ++- .../app/nbevent/NBSimpleMetadataAction.java | 15 ++- ...OpenaireEventsCliScriptConfiguration.java} | 10 +- ...nable.java => OpenaireEventsRunnable.java} | 13 +-- ...li.java => OpenaireEventsRunnableCli.java} | 14 ++- ...=> OpenaireEventsScriptConfiguration.java} | 11 +- .../app/nbevent/RawJsonDeserializer.java | 6 + .../dspace/app/nbevent/dao/NBEventsDao.java | 44 ++++++-- .../app/nbevent/dao/impl/NBEventsDaoImpl.java | 7 ++ .../app/nbevent/service/NBEventService.java | 106 +++++++++++++++++- .../dto/{MessageDto.java => NBMessage.java} | 10 +- ...reMessageDto.java => OpenaireMessage.java} | 8 +- .../service/impl/NBEventServiceImpl.java | 33 ++++-- .../main/java/org/dspace/content/NBEvent.java | 23 +++- .../java/org/dspace/content/NBSourceName.java | 13 --- ...=> V7.3_2022.02.17__nbevent_processed.sql} | 0 ...=> V7.3_2022.02.17__nbevent_processed.sql} | 0 ...=> V7.3_2022.02.17__nbevent_processed.sql} | 0 .../org/dspace/builder/NBEventBuilder.java | 3 +- .../app/rest/converter/NBEventConverter.java | 28 +++-- .../app/rest/converter/NBSourceConverter.java | 7 ++ .../app/rest/converter/NBTopicConverter.java | 7 ++ .../app/rest/model/NBEventMessageRest.java | 6 + .../dspace/app/rest/model/NBEventRest.java | 6 + .../model/OpenaireNBEventMessageRest.java | 6 + .../rest/model/hateoas/NBEventResource.java | 6 + .../rest/model/hateoas/NBSourceResource.java | 6 + .../rest/model/hateoas/NBTopicResource.java | 6 + .../repository/NBEventRestRepository.java | 6 + .../repository/NBSourceRestRepository.java | 15 ++- .../repository/NBTopicRestRepository.java | 11 +- .../NBEventStatusReplaceOperation.java | 6 + .../app/rest/NBEventRestRepositoryIT.java | 6 + .../app/rest/NBTopicRestRepositoryIT.java | 7 ++ .../app/rest/matcher/NBEventMatcher.java | 12 +- .../app/rest/matcher/NBSourceMatcher.java | 43 +++++++ .../app/rest/matcher/NBTopicMatcher.java | 7 ++ dspace/config/spring/api/scripts.xml | 4 +- dspace/config/spring/rest/scripts.xml | 4 +- 43 files changed, 498 insertions(+), 117 deletions(-) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBEventsCliScriptConfiguration.java => OpenaireEventsCliScriptConfiguration.java} (64%) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBEventsRunnable.java => OpenaireEventsRunnable.java} (90%) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBEventsRunnableCli.java => OpenaireEventsRunnableCli.java} (69%) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBEventsScriptConfiguration.java => OpenaireEventsScriptConfiguration.java} (84%) rename dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/{MessageDto.java => NBMessage.java} (54%) rename dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/{OpenaireMessageDto.java => OpenaireMessage.java} (94%) delete mode 100644 dspace-api/src/main/java/org/dspace/content/NBSourceName.java rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/{V7.0_2020.10.16__nbevent_processed.sql => V7.3_2022.02.17__nbevent_processed.sql} (100%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/{V7.0_2020.10.16__nbevent_processed.sql => V7.3_2022.02.17__nbevent_processed.sql} (100%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/{V7.0_2020.10.16__nbevent_processed.sql => V7.3_2022.02.17__nbevent_processed.sql} (100%) create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java index 782fa53802..70e7624197 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java @@ -7,10 +7,25 @@ */ package org.dspace.app.nbevent; -import org.dspace.app.nbevent.service.dto.MessageDto; +import org.dspace.app.nbevent.service.dto.NBMessage; import org.dspace.content.Item; import org.dspace.core.Context; +/** + * Interface for classes that perform a correction on the given item. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public interface NBAction { - public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message); + + /** + * Perform a correction on the given item. + * + * @param context the DSpace context + * @param item the item to correct + * @param relatedItem the related item, if any + * @param message the message with the correction details + */ + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java index 5e6b96c0b4..f2322fe6b7 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java @@ -11,8 +11,8 @@ import java.sql.SQLException; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.MessageDto; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; +import org.dspace.app.nbevent.service.dto.NBMessage; +import org.dspace.app.nbevent.service.dto.OpenaireMessage; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.EntityType; @@ -30,6 +30,13 @@ import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; +/** + * Implementation of {@link NBAction} that handle the relationship between the + * item to correct and a related item. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBEntityMetadataAction implements NBAction { private String relation; private String entityType; @@ -96,7 +103,7 @@ public class NBEntityMetadataAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message) { + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message) { try { if (relatedItem != null) { link(context, item, relatedItem); @@ -141,12 +148,12 @@ public class NBEntityMetadataAction implements NBAction { relationshipService.update(context, persistedRelationship); } - private String getValue(MessageDto message, String key) { - if (!(message instanceof OpenaireMessageDto)) { + private String getValue(NBMessage message, String key) { + if (!(message instanceof OpenaireMessage)) { return null; } - OpenaireMessageDto openaireMessage = (OpenaireMessageDto) message; + OpenaireMessage openaireMessage = (OpenaireMessage) message; if (StringUtils.equals(key, "acronym")) { return openaireMessage.getAcronym(); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java index 0a4de9c7fb..e6a2917384 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java @@ -10,10 +10,36 @@ package org.dspace.app.nbevent; import org.dspace.content.NBEvent; import org.dspace.core.Context; +/** + * Service that handle the actions that can be done related to an + * {@link NBEvent}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public interface NBEventActionService { + + /** + * Accept the given event. + * + * @param context the DSpace context + * @param nbevent the event to be accepted + */ public void accept(Context context, NBEvent nbevent); + /** + * Discard the given event. + * + * @param context the DSpace context + * @param nbevent the event to be discarded + */ public void discard(Context context, NBEvent nbevent); + /** + * Reject the given event. + * + * @param context the DSpace context + * @param nbevent the event to be rejected + */ public void reject(Context context, NBEvent nbevent); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java index 2d84e8f9ba..970858218b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java @@ -25,8 +25,6 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.logging.log4j.Logger; import org.dspace.app.nbevent.service.NBEventService; -import org.dspace.app.nbevent.service.dto.MessageDto; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; import org.dspace.content.Item; import org.dspace.content.NBEvent; import org.dspace.content.service.ItemService; @@ -34,6 +32,12 @@ import org.dspace.core.Context; import org.dspace.services.ConfigurationService; import org.springframework.beans.factory.annotation.Autowired; +/** + * Implementation of {@link NBEventActionService}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBEventActionServiceImpl implements NBEventActionService { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(NBEventActionServiceImpl.class); @@ -73,7 +77,7 @@ public class NBEventActionServiceImpl implements NBEventActionService { related = itemService.find(context, UUID.fromString(nbevent.getRelated())); } topicsToActions.get(nbevent.getTopic()).applyCorrection(context, item, related, - jsonMapper.readValue(nbevent.getMessage(), getMessageDtoClass(nbevent))); + jsonMapper.readValue(nbevent.getMessage(), nbevent.getMessageDtoClass())); nbEventService.deleteEventByEventId(context, nbevent.getEventId()); makeAcknowledgement(nbevent.getEventId(), NBEvent.ACCEPTED); } catch (SQLException | JsonProcessingException e) { @@ -81,15 +85,6 @@ public class NBEventActionServiceImpl implements NBEventActionService { } } - private Class getMessageDtoClass(NBEvent modelObject) { - switch (modelObject.getSource()) { - case OPENAIRE: - return OpenaireMessageDto.class; - default: - throw new IllegalArgumentException("Unknown event's source: " + modelObject.getSource()); - } - } - @Override public void discard(Context context, NBEvent nbevent) { nbEventService.deleteEventByEventId(context, nbevent.getEventId()); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java index 7e9de849b3..3d7e2114ce 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java @@ -10,14 +10,21 @@ package org.dspace.app.nbevent; import java.sql.SQLException; import java.util.Map; -import org.dspace.app.nbevent.service.dto.MessageDto; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; +import org.dspace.app.nbevent.service.dto.NBMessage; +import org.dspace.app.nbevent.service.dto.OpenaireMessage; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; +/** + * Implementation of {@link NBAction} that add a specific metadata on the given + * item based on the OPENAIRE message type. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBMetadataMapAction implements NBAction { public static final String DEFAULT = "default"; @@ -38,13 +45,13 @@ public class NBMetadataMapAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message) { + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message) { - if (!(message instanceof OpenaireMessageDto)) { + if (!(message instanceof OpenaireMessage)) { throw new IllegalArgumentException("Unsupported message type: " + message.getClass()); } - OpenaireMessageDto openaireMessage = (OpenaireMessageDto) message; + OpenaireMessage openaireMessage = (OpenaireMessage) message; try { String targetMetadata = types.get(openaireMessage.getType()); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java index 910f799ad8..0bff9e05ff 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java @@ -9,14 +9,21 @@ package org.dspace.app.nbevent; import java.sql.SQLException; -import org.dspace.app.nbevent.service.dto.MessageDto; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; +import org.dspace.app.nbevent.service.dto.NBMessage; +import org.dspace.app.nbevent.service.dto.OpenaireMessage; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; +/** + * Implementation of {@link NBAction} that add a simple metadata to the given + * item. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBSimpleMetadataAction implements NBAction { private String metadata; private String metadataSchema; @@ -44,10 +51,10 @@ public class NBSimpleMetadataAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, MessageDto message) { + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message) { try { itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null, - ((OpenaireMessageDto) message).getAbstracts()); + ((OpenaireMessage) message).getAbstracts()); itemService.update(context, item); } catch (SQLException | AuthorizeException e) { throw new RuntimeException(e); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsCliScriptConfiguration.java similarity index 64% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsCliScriptConfiguration.java index d6671676a0..5263bc559b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsCliScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsCliScriptConfiguration.java @@ -9,7 +9,15 @@ package org.dspace.app.nbevent; import org.apache.commons.cli.Options; -public class NBEventsCliScriptConfiguration extends NBEventsScriptConfiguration { +/** + * Extension of {@link OpenaireEventsScriptConfiguration} to run the script on + * console. + * + * @author Alessandro Martelli (alessandro.martelli at 4science.it) + * + */ +public class OpenaireEventsCliScriptConfiguration + extends OpenaireEventsScriptConfiguration { @Override public Options getOptions() { diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java b/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java similarity index 90% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java index 80f7f5dabb..d56858402b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsRunnable.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java @@ -21,7 +21,6 @@ import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.StringUtils; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.NBEvent; -import org.dspace.content.NBSourceName; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; @@ -37,9 +36,9 @@ import org.slf4j.LoggerFactory; * @author Alessandro Martelli (alessandro.martelli at 4science.it) * */ -public class NBEventsRunnable extends DSpaceRunnable> { +public class OpenaireEventsRunnable extends DSpaceRunnable> { - private static final Logger LOGGER = LoggerFactory.getLogger(NBEventsRunnable.class); + private static final Logger LOGGER = LoggerFactory.getLogger(OpenaireEventsRunnable.class); protected NBEventService nbEventService; @@ -55,9 +54,9 @@ public class NBEventsRunnable extends DSpaceRunnable extends ScriptConfiguration { +/** + * Extension of {@link ScriptConfiguration} to perfom a NBEvents import from + * file. + * + * @author Alessandro Martelli (alessandro.martelli at 4science.it) + * + */ +public class OpenaireEventsScriptConfiguration extends ScriptConfiguration { @Autowired private AuthorizeService authorizeService; @@ -30,7 +37,7 @@ public class NBEventsScriptConfiguration extends Scr /** * Generic setter for the dspaceRunnableClass - * @param dspaceRunnableClass The dspaceRunnableClass to be set on this NBEventsScriptConfiguration + * @param dspaceRunnableClass The dspaceRunnableClass to be set on this OpenaireEventsScriptConfiguration */ @Override public void setDspaceRunnableClass(Class dspaceRunnableClass) { diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java b/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java index edc744d586..475cc44a7d 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/RawJsonDeserializer.java @@ -16,6 +16,12 @@ import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +/** + * Extension of {@link JsonDeserializer} that convert a json to a String. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class RawJsonDeserializer extends JsonDeserializer { @Override diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java index f426ddf6ab..db93eb95c5 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java @@ -15,22 +15,48 @@ import org.dspace.content.NBEventProcessed; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +/** + * DAO that handle processed NB Events. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public interface NBEventsDao { + /** * Search a page of notification broker events by notification ID. * - * @param c - * @param eventId - * @param start - * @param size - * @return - * @throws SQLException + * @param context the DSpace context + * @param eventId the event id + * @param start the start index + * @param size the size to be applied + * @return the processed events + * @throws SQLException if an SQL error occurs */ - public List searchByEventId(Context c, String eventId, Integer start, Integer size) + public List searchByEventId(Context context, String eventId, Integer start, Integer size) throws SQLException; - public boolean isEventStored(Context c, String checksum) throws SQLException; + /** + * Check if an event with the given checksum is already stored. + * + * @param context the DSpace context + * @param checksum the checksum to search for + * @return true if the given checksum is related to an already + * stored event, false otherwise + * @throws SQLException if an SQL error occurs + */ + public boolean isEventStored(Context context, String checksum) throws SQLException; - boolean storeEvent(Context c, String checksum, EPerson eperson, Item item); + /** + * Store an event related to the given checksum. + * + * @param context the DSpace context + * @param checksum the checksum of the event to be store + * @param eperson the eperson who handle the event + * @param item the item related to the event + * @return true if the creation is completed with success, false + * otherwise + */ + boolean storeEvent(Context context, String checksum, EPerson eperson, Item item); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java index 49894441b2..db3977c109 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java @@ -19,6 +19,13 @@ import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +/** + * Implementation of {@link NBEventsDao} that store processed events using an + * SQL DBMS. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBEventsDaoImpl extends AbstractHibernateDAO implements NBEventsDao { @Override diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java index bb3b5bbc49..e2c4570129 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java @@ -13,37 +13,135 @@ import java.util.UUID; import org.dspace.app.nbevent.NBSource; import org.dspace.app.nbevent.NBTopic; import org.dspace.content.NBEvent; -import org.dspace.content.NBSourceName; import org.dspace.core.Context; +/** + * Service that handles {@link NBEvent}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public interface NBEventService { + /** + * Find all the event's topics. + * + * @param context the DSpace context + * @param offset the offset to apply + * @param pageSize the page size + * @return the topics list + */ public List findAllTopics(Context context, long offset, long pageSize); - public List findAllTopicsBySource(Context context, NBSourceName source, long offset, long count); + /** + * Find all the event's topics related to the given source. + * + * @param context the DSpace context + * @param source the source to search for + * @param offset the offset to apply + * @param pageSize the page size + * @return the topics list + */ + public List findAllTopicsBySource(Context context, String source, long offset, long count); + /** + * Count all the event's topics. + * + * @param context the DSpace context + * @return the count result + */ public long countTopics(Context context); - public long countTopicsBySource(Context context, NBSourceName source); + /** + * Count all the event's topics related to the given source. + * + * @param context the DSpace context + * @param source the source to search for + * @return the count result + */ + public long countTopicsBySource(Context context, String source); + /** + * Find all the events by topic. + * + * @param context the DSpace context + * @param topic the topic to search for + * @param offset the offset to apply + * @param pageSize the page size + * @param orderField the field to order for + * @param ascending true if the order should be ascending, false otherwise + * @return the events + */ public List findEventsByTopicAndPage(Context context, String topic, long offset, int pageSize, String orderField, boolean ascending); + /** + * Find all the events by topic. + * + * @param context the DSpace context + * @param topic the topic to search for + * @return the events count + */ public long countEventsByTopic(Context context, String topic); + /** + * Find an event by the given id. + * + * @param context the DSpace context + * @param id the id of the event to search for + * @return the event + */ public NBEvent findEventByEventId(Context context, String id); + /** + * Store the given event. + * + * @param context the DSpace context + * @param event the event to store + */ public void store(Context context, NBEvent event); + /** + * Delete an event by the given id. + * + * @param context the DSpace context + * @param id the id of the event to delete + */ public void deleteEventByEventId(Context context, String id); + /** + * Delete events by the given target id. + * + * @param context the DSpace context + * @param id the id of the target id + */ public void deleteEventsByTargetId(Context context, UUID targetId); + /** + * Find a specific topid by the given id. + * + * @param topicId the topic id to search for + * @return the topic + */ public NBTopic findTopicByTopicId(String topicId); - public NBSource findSource(NBSourceName source); + /** + * Find a specific source by the given name. + * + * @param source the source name + * @return the source + */ + public NBSource findSource(String source); + /** + * Find all the event's sources. + * + * @param context the DSpace context + * @param offset the offset to apply + * @param pageSize the page size + * @return the sources list + */ public List findAllSources(Context context, long offset, int pageSize); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessage.java similarity index 54% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessage.java index 55c1722de8..4c59ab1c85 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/MessageDto.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessage.java @@ -7,7 +7,15 @@ */ package org.dspace.app.nbevent.service.dto; -public interface MessageDto { +import org.dspace.content.NBEvent; + +/** + * Interface for classes that contains the details related to a {@link NBEvent}. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public interface NBMessage { } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessage.java similarity index 94% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessage.java index 5ae6b29c3a..188139afef 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDto.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessage.java @@ -9,7 +9,13 @@ package org.dspace.app.nbevent.service.dto; import com.fasterxml.jackson.annotation.JsonProperty; -public class OpenaireMessageDto implements MessageDto { +/** + * Implementation of {@link NBMessage} that model message coming from OPENAIRE. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class OpenaireMessage implements NBMessage { @JsonProperty("pids[0].value") private String value; diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java index 6f745d0800..84853fb5e2 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java @@ -18,6 +18,7 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import org.apache.commons.lang3.ArrayUtils; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; @@ -37,7 +38,6 @@ import org.dspace.app.nbevent.dao.impl.NBEventsDaoImpl; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Item; import org.dspace.content.NBEvent; -import org.dspace.content.NBSourceName; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.handle.service.HandleService; @@ -45,6 +45,12 @@ import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.springframework.beans.factory.annotation.Autowired; +/** + * Implementation of {@link NBEventService} that use Solr to store events. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBEventServiceImpl implements NBEventService { private static final Logger log = Logger.getLogger(NBEventServiceImpl.class); @@ -112,7 +118,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public long countTopicsBySource(Context context, NBSourceName source) { + public long countTopicsBySource(Context context, String source) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); @@ -197,7 +203,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public List findAllTopicsBySource(Context context, NBSourceName source, long offset, long count) { + public List findAllTopicsBySource(Context context, String source, long offset, long count) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); @@ -239,12 +245,17 @@ public class NBEventServiceImpl implements NBEventService { public void store(Context context, NBEvent dto) { UpdateRequest updateRequest = new UpdateRequest(); String topic = dto.getTopic(); + + if (!ArrayUtils.contains(getSupportedSources(), dto.getSource())) { + throw new IllegalArgumentException("The source of the given event is not supported: " + dto.getSource()); + } + if (topic != null) { String checksum = dto.getEventId(); try { if (!nbEventsDao.isEventStored(context, checksum)) { SolrInputDocument doc = new SolrInputDocument(); - doc.addField(SOURCE, dto.getSource().name()); + doc.addField(SOURCE, dto.getSource()); doc.addField(EVENT_ID, checksum); doc.addField(ORIGINAL_ID, dto.getOriginalId()); doc.addField(TITLE, dto.getTitle()); @@ -291,7 +302,7 @@ public class NBEventServiceImpl implements NBEventService { private NBEvent getNBEventFromSOLR(SolrDocument doc) { NBEvent item = new NBEvent(); - item.setSource(NBSourceName.valueOf((String) doc.get(SOURCE))); + item.setSource((String) doc.get(SOURCE)); item.setEventId((String) doc.get(EVENT_ID)); item.setLastUpdate((Date) doc.get(LAST_UPDATE)); item.setMessage((String) doc.get(MESSAGE)); @@ -372,7 +383,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public NBSource findSource(NBSourceName sourceName) { + public NBSource findSource(String sourceName) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery(SOURCE + ":" + sourceName); @@ -385,7 +396,7 @@ public class NBEventServiceImpl implements NBEventService { response = getSolr().query(solrQuery); FacetField facetField = response.getFacetField(SOURCE); for (Count c : facetField.getValues()) { - if (c.getName().equalsIgnoreCase(sourceName.name())) { + if (c.getName().equalsIgnoreCase(sourceName)) { NBSource source = new NBSource(); source.setName(c.getName()); source.setTotalEvents(c.getCount()); @@ -398,18 +409,22 @@ public class NBEventServiceImpl implements NBEventService { } NBSource source = new NBSource(); - source.setName(sourceName.name()); + source.setName(sourceName); source.setTotalEvents(0L); return source; } @Override public List findAllSources(Context context, long offset, int pageSize) { - return Arrays.stream(NBSourceName.values()).sorted() + return Arrays.stream(getSupportedSources()).sorted() .map((sourceName) -> findSource(sourceName)) .skip(offset) .limit(pageSize) .collect(Collectors.toList()); } + private String[] getSupportedSources() { + return configurationService.getArrayProperty("nbevent.sources", new String[] { NBEvent.OPENAIRE_SOURCE }); + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/NBEvent.java b/dspace-api/src/main/java/org/dspace/content/NBEvent.java index 950fc37d01..e99fbaefa1 100644 --- a/dspace-api/src/main/java/org/dspace/content/NBEvent.java +++ b/dspace-api/src/main/java/org/dspace/content/NBEvent.java @@ -14,6 +14,8 @@ import java.util.Date; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.dspace.app.nbevent.RawJsonDeserializer; +import org.dspace.app.nbevent.service.dto.NBMessage; +import org.dspace.app.nbevent.service.dto.OpenaireMessage; /** * This class represent the notification broker data as loaded in our solr @@ -27,7 +29,9 @@ public class NBEvent { public static final String REJECTED = "rejected"; public static final String DISCARDED = "discarded"; - private NBSourceName source; + public static final String OPENAIRE_SOURCE = "openaire"; + + private String source; private String eventId; @@ -53,7 +57,7 @@ public class NBEvent { public NBEvent() { } - public NBEvent(NBSourceName source, String originalId, String target, String title, + public NBEvent(String source, String originalId, String target, String title, String topic, double trust, String message, Date lastUpdate) { super(); this.source = source; @@ -159,11 +163,11 @@ public class NBEvent { return status; } - public NBSourceName getSource() { - return source != null ? source : NBSourceName.OPENAIRE; + public String getSource() { + return source != null ? source : OPENAIRE_SOURCE; } - public void setSource(NBSourceName source) { + public void setSource(String source) { this.source = source; } @@ -188,4 +192,13 @@ public class NBEvent { } + public Class getMessageDtoClass() { + switch (getSource()) { + case OPENAIRE_SOURCE: + return OpenaireMessage.class; + default: + throw new IllegalArgumentException("Unknown event's source: " + getSource()); + } + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/NBSourceName.java b/dspace-api/src/main/java/org/dspace/content/NBSourceName.java deleted file mode 100644 index 705cc26058..0000000000 --- a/dspace-api/src/main/java/org/dspace/content/NBSourceName.java +++ /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/ - */ -package org.dspace.content; - -public enum NBSourceName { - - OPENAIRE; -} diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2020.10.16__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__nbevent_processed.sql similarity index 100% rename from dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2020.10.16__nbevent_processed.sql rename to dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__nbevent_processed.sql diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2020.10.16__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__nbevent_processed.sql similarity index 100% rename from dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.0_2020.10.16__nbevent_processed.sql rename to dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__nbevent_processed.sql diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2020.10.16__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__nbevent_processed.sql similarity index 100% rename from dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.0_2020.10.16__nbevent_processed.sql rename to dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__nbevent_processed.sql diff --git a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java index 57e5c2a2fe..8bf1b206da 100644 --- a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java @@ -13,7 +13,6 @@ import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.content.NBEvent; -import org.dspace.content.NBSourceName; import org.dspace.core.Context; /** @@ -25,7 +24,7 @@ public class NBEventBuilder extends AbstractBuilder { private Item item; private NBEvent target; - private NBSourceName source = NBSourceName.OPENAIRE; + private String source = NBEvent.OPENAIRE_SOURCE; private String title; private String topic; private String message; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java index 82230e8eee..21bbdfff29 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java @@ -13,8 +13,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; -import org.dspace.app.nbevent.service.dto.MessageDto; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; +import org.dspace.app.nbevent.service.dto.NBMessage; +import org.dspace.app.nbevent.service.dto.OpenaireMessage; import org.dspace.app.rest.model.NBEventMessageRest; import org.dspace.app.rest.model.NBEventRest; import org.dspace.app.rest.model.OpenaireNBEventMessageRest; @@ -22,6 +22,13 @@ import org.dspace.app.rest.projection.Projection; import org.dspace.content.NBEvent; import org.springframework.stereotype.Component; +/** + * Implementation of {@link DSpaceConverter} that converts {@link NBEvent} to + * {@link NBEventRest}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @Component public class NBEventConverter implements DSpaceConverter { @@ -39,7 +46,7 @@ public class NBEventConverter implements DSpaceConverter { rest.setId(modelObject.getEventId()); try { rest.setMessage(convertMessage(jsonMapper.readValue(modelObject.getMessage(), - getMessageDtoClass(modelObject)))); + modelObject.getMessageDtoClass()))); } catch (JsonProcessingException e) { throw new RuntimeException(e); } @@ -54,18 +61,9 @@ public class NBEventConverter implements DSpaceConverter { return rest; } - private Class getMessageDtoClass(NBEvent modelObject) { - switch (modelObject.getSource()) { - case OPENAIRE: - return OpenaireMessageDto.class; - default: - throw new IllegalArgumentException("Unknown event's source: " + modelObject.getSource()); - } - } - - private NBEventMessageRest convertMessage(MessageDto dto) { - if (dto instanceof OpenaireMessageDto) { - OpenaireMessageDto openaireDto = (OpenaireMessageDto) dto; + private NBEventMessageRest convertMessage(NBMessage dto) { + if (dto instanceof OpenaireMessage) { + OpenaireMessage openaireDto = (OpenaireMessage) dto; OpenaireNBEventMessageRest message = new OpenaireNBEventMessageRest(); message.setAbstractValue(openaireDto.getAbstracts()); message.setOpenaireId(openaireDto.getOpenaireId()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java index 7524cc7975..a1b496df04 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java @@ -12,6 +12,13 @@ import org.dspace.app.rest.model.NBSourceRest; import org.dspace.app.rest.projection.Projection; import org.springframework.stereotype.Component; +/** + * Implementation of {@link DSpaceConverter} that converts {@link NBSource} to + * {@link NBSourceRest}. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ @Component public class NBSourceConverter implements DSpaceConverter { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java index 8a5a284fe1..f9ab34da89 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java @@ -12,6 +12,13 @@ import org.dspace.app.rest.model.NBTopicRest; import org.dspace.app.rest.projection.Projection; import org.springframework.stereotype.Component; +/** + * Implementation of {@link DSpaceConverter} that converts {@link NBTopic} to + * {@link NBTopicRest}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @Component public class NBTopicConverter implements DSpaceConverter { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java index 7c2e03ac34..df6187651c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java @@ -7,6 +7,12 @@ */ package org.dspace.app.rest.model; +/** + * Interface for classes that model a message with the details of a NB event. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ public interface NBEventMessageRest { } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java index 60dbce6d9b..0ccc1a55da 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java @@ -11,6 +11,12 @@ import java.util.Date; import org.dspace.app.rest.RestResourceController; +/** + * NB event Rest object. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @LinksRest( links = { @LinkRest(name = "topic", method = "getTopic"), diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java index 84021abb6e..ca6ee5d06d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java @@ -9,6 +9,12 @@ package org.dspace.app.rest.model; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * Implementation of {@link NBEventMessageRest} related to OPENAIRE events. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ public class OpenaireNBEventMessageRest implements NBEventMessageRest { // pids private String type; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java index bd3c266f1e..b052d3d4da 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java @@ -11,6 +11,12 @@ import org.dspace.app.rest.model.NBEventRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; +/** + * NB event Rest resource. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @RelNameDSpaceResource(NBEventRest.NAME) public class NBEventResource extends DSpaceResource { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java index 899b684199..55db5d6343 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java @@ -11,6 +11,12 @@ import org.dspace.app.rest.model.NBSourceRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; +/** + * NB source Rest resource. + * + * @author Luca Giamminonni (luca.giamminonni at 4Science) + * + */ @RelNameDSpaceResource(NBSourceRest.NAME) public class NBSourceResource extends DSpaceResource { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java index a2fed4ffc6..78af04a764 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java @@ -11,6 +11,12 @@ import org.dspace.app.rest.model.NBTopicRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; +/** + * NB topic Rest resource. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @RelNameDSpaceResource(NBTopicRest.NAME) public class NBTopicResource extends DSpaceResource { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java index b00688a6ea..d1bc469036 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java @@ -35,6 +35,12 @@ import org.springframework.data.domain.Sort.Direction; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; +/** + * Rest repository that handle NB events. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME) public class NBEventRestRepository extends DSpaceRestRepository { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java index 95dfa6b61a..ceeef3671a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java @@ -12,7 +12,6 @@ import java.util.List; import org.dspace.app.nbevent.NBSource; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.model.NBSourceRest; -import org.dspace.content.NBSourceName; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -20,6 +19,12 @@ import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; +/** + * Rest repository that handle NB soufces. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ @Component(NBSourceRest.CATEGORY + "." + NBSourceRest.NAME) public class NBSourceRestRepository extends DSpaceRestRepository { @@ -29,19 +34,19 @@ public class NBSourceRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List nbTopics = nbEventService.findAllSources(context, pageable.getOffset(), pageable.getPageSize()); + List nbSources = nbEventService.findAllSources(context, pageable.getOffset(), pageable.getPageSize()); long count = nbEventService.countTopics(context); - if (nbTopics == null) { + if (nbSources == null) { return null; } - return converter.toRestPage(nbTopics, pageable, count, utils.obtainProjection()); + return converter.toRestPage(nbSources, pageable, count, utils.obtainProjection()); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java index c738da7bd6..479a606e00 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java @@ -13,7 +13,6 @@ import org.dspace.app.nbevent.NBTopic; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.model.NBTopicRest; -import org.dspace.content.NBSourceName; import org.dspace.core.Context; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -21,6 +20,12 @@ import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; +/** + * Rest repository that handle NB topics. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @Component(NBTopicRest.CATEGORY + "." + NBTopicRest.NAME) public class NBTopicRestRepository extends DSpaceRestRepository { @@ -51,9 +56,9 @@ public class NBTopicRestRepository extends DSpaceRestRepository findBySource(Context context, String source, Pageable pageable) { - List nbTopics = nbEventService.findAllTopicsBySource(context, NBSourceName.valueOf(source), + List nbTopics = nbEventService.findAllTopicsBySource(context, String.valueOf(source), pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countTopicsBySource(context, NBSourceName.valueOf(source)); + long count = nbEventService.countTopicsBySource(context, String.valueOf(source)); if (nbTopics == null) { return null; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java index bd690ee683..55bfe3d2f1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java @@ -18,6 +18,12 @@ import org.dspace.services.RequestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +/** + * Replace operation related to the {@link NBEvent} status. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ @Component public class NBEventStatusReplaceOperation extends PatchOperation { @Autowired diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java index ef9abfe978..a9f5d29427 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java @@ -42,6 +42,12 @@ import org.dspace.content.NBEvent; import org.hamcrest.Matchers; import org.junit.Test; +/** + * Integration tests for {@link NBEventRestRepository}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java index 2d0095bd8f..dea109219a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java @@ -14,6 +14,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import org.dspace.app.rest.matcher.NBTopicMatcher; +import org.dspace.app.rest.repository.NBTopicRestRepository; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; @@ -23,6 +24,12 @@ import org.dspace.content.NBEvent; import org.hamcrest.Matchers; import org.junit.Test; +/** + * Integration tests for {@link NBTopicRestRepository}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { @Test diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java index f8dca7e466..a09d115359 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java @@ -18,12 +18,18 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDto; +import org.dspace.app.nbevent.service.dto.OpenaireMessage; import org.dspace.content.NBEvent; import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.hamcrest.core.IsAnything; +/** + * Matcher related to {@link NBEventResource}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBEventMatcher { private NBEventMatcher() { @@ -50,7 +56,7 @@ public class NBEventMatcher { hasJsonPath("$.status", Matchers.equalToIgnoringCase(event.getStatus())), hasJsonPath("$.message", matchMessage(event.getTopic(), jsonMapper.readValue(event.getMessage(), - OpenaireMessageDto.class))), + OpenaireMessage.class))), hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")), hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")), hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")), @@ -60,7 +66,7 @@ public class NBEventMatcher { } } - private static Matcher matchMessage(String topic, OpenaireMessageDto message) { + private static Matcher matchMessage(String topic, OpenaireMessage message) { if (StringUtils.endsWith(topic, "/ABSTRACT")) { return allOf(hasJsonPath("$.abstract", is(message.getAbstracts()))); } else if (StringUtils.endsWith(topic, "/PID")) { diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java new file mode 100644 index 0000000000..35031202f0 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java @@ -0,0 +1,43 @@ +/** + * 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.app.rest.matcher; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.is; + +import org.dspace.app.rest.model.hateoas.NBSourceResource; +import org.hamcrest.Matcher; + +/** + * Matcher related to {@link NBSourceResource}. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class NBSourceMatcher { + + private NBSourceMatcher() { } + + public static Matcher matchNBSourceEntry(String key, int totalEvents) { + return allOf( + hasJsonPath("$.type", is("nbsource")), + hasJsonPath("$.id", is(key)), + hasJsonPath("$.totalEvents", is(totalEvents)) + ); + } + + + public static Matcher matchNBSourceEntry(String key) { + return allOf( + hasJsonPath("$.type", is("nbsource")), + hasJsonPath("$.id", is(key)) + ); + } + +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java index 644feeeec4..7ad6972b1e 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java @@ -11,8 +11,15 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; +import org.dspace.app.rest.model.hateoas.NBTopicResource; import org.hamcrest.Matcher; +/** + * Matcher related to {@link NBTopicResource}. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ public class NBTopicMatcher { private NBTopicMatcher() { } diff --git a/dspace/config/spring/api/scripts.xml b/dspace/config/spring/api/scripts.xml index 61b06c2aa9..184950a137 100644 --- a/dspace/config/spring/api/scripts.xml +++ b/dspace/config/spring/api/scripts.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - + - + diff --git a/dspace/config/spring/rest/scripts.xml b/dspace/config/spring/rest/scripts.xml index 518d81009b..9dee833089 100644 --- a/dspace/config/spring/rest/scripts.xml +++ b/dspace/config/spring/rest/scripts.xml @@ -8,9 +8,9 @@ - + - + From d856cf31f29e4ad4f42ed97a257f87e89053561d Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Thu, 17 Feb 2022 13:22:16 +0100 Subject: [PATCH 05/38] [CST-5246] Added integration tests for NBSourceRestRepository --- .../app/nbevent/NBEventActionServiceImpl.java | 6 +- .../NBEventsDeleteCascadeConsumer.java | 3 +- .../app/nbevent/service/NBEventService.java | 36 ++-- .../service/impl/NBEventServiceImpl.java | 59 +++--- .../org/dspace/builder/NBEventBuilder.java | 8 +- .../app/rest/NBEventRestController.java | 4 +- .../NBEventRelatedLinkRepository.java | 2 +- .../repository/NBEventRestRepository.java | 13 +- .../NBEventTargetLinkRepository.java | 2 +- .../NBEventTopicLinkRepository.java | 2 +- .../repository/NBSourceRestRepository.java | 10 +- .../repository/NBTopicRestRepository.java | 8 +- .../app/rest/NBSourceRestRepositoryIT.java | 200 ++++++++++++++++++ 13 files changed, 278 insertions(+), 75 deletions(-) create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java index 970858218b..ac9fdd5c3f 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java @@ -78,7 +78,7 @@ public class NBEventActionServiceImpl implements NBEventActionService { } topicsToActions.get(nbevent.getTopic()).applyCorrection(context, item, related, jsonMapper.readValue(nbevent.getMessage(), nbevent.getMessageDtoClass())); - nbEventService.deleteEventByEventId(context, nbevent.getEventId()); + nbEventService.deleteEventByEventId(nbevent.getEventId()); makeAcknowledgement(nbevent.getEventId(), NBEvent.ACCEPTED); } catch (SQLException | JsonProcessingException e) { throw new RuntimeException(e); @@ -87,13 +87,13 @@ public class NBEventActionServiceImpl implements NBEventActionService { @Override public void discard(Context context, NBEvent nbevent) { - nbEventService.deleteEventByEventId(context, nbevent.getEventId()); + nbEventService.deleteEventByEventId(nbevent.getEventId()); makeAcknowledgement(nbevent.getEventId(), NBEvent.DISCARDED); } @Override public void reject(Context context, NBEvent nbevent) { - nbEventService.deleteEventByEventId(context, nbevent.getEventId()); + nbEventService.deleteEventByEventId(nbevent.getEventId()); makeAcknowledgement(nbevent.getEventId(), NBEvent.REJECTED); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java index 0eba13e90b..8297599bc5 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java @@ -26,7 +26,6 @@ public class NBEventsDeleteCascadeConsumer implements Consumer { private NBEventService nbEventService; @Override - @SuppressWarnings("unchecked") public void initialize() throws Exception { nbEventService = new DSpace().getSingletonService(NBEventService.class); } @@ -40,7 +39,7 @@ public class NBEventsDeleteCascadeConsumer implements Consumer { public void consume(Context context, Event event) throws Exception { if (event.getEventType() == Event.DELETE) { if (event.getSubjectType() == Constants.ITEM && event.getSubjectID() != null) { - nbEventService.deleteEventsByTargetId(context, event.getSubjectID()); + nbEventService.deleteEventsByTargetId(event.getSubjectID()); } } } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java index e2c4570129..599806f425 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java @@ -31,7 +31,7 @@ public interface NBEventService { * @param pageSize the page size * @return the topics list */ - public List findAllTopics(Context context, long offset, long pageSize); + public List findAllTopics(long offset, long pageSize); /** * Find all the event's topics related to the given source. @@ -42,7 +42,7 @@ public interface NBEventService { * @param pageSize the page size * @return the topics list */ - public List findAllTopicsBySource(Context context, String source, long offset, long count); + public List findAllTopicsBySource(String source, long offset, long count); /** * Count all the event's topics. @@ -50,7 +50,7 @@ public interface NBEventService { * @param context the DSpace context * @return the count result */ - public long countTopics(Context context); + public long countTopics(); /** * Count all the event's topics related to the given source. @@ -59,12 +59,11 @@ public interface NBEventService { * @param source the source to search for * @return the count result */ - public long countTopicsBySource(Context context, String source); + public long countTopicsBySource(String source); /** * Find all the events by topic. * - * @param context the DSpace context * @param topic the topic to search for * @param offset the offset to apply * @param pageSize the page size @@ -72,27 +71,24 @@ public interface NBEventService { * @param ascending true if the order should be ascending, false otherwise * @return the events */ - public List findEventsByTopicAndPage(Context context, String topic, - long offset, int pageSize, - String orderField, boolean ascending); + public List findEventsByTopicAndPage(String topic, long offset, int pageSize, + String orderField, boolean ascending); /** * Find all the events by topic. * - * @param context the DSpace context * @param topic the topic to search for * @return the events count */ - public long countEventsByTopic(Context context, String topic); + public long countEventsByTopic(String topic); /** * Find an event by the given id. * - * @param context the DSpace context * @param id the id of the event to search for * @return the event */ - public NBEvent findEventByEventId(Context context, String id); + public NBEvent findEventByEventId(String id); /** * Store the given event. @@ -105,18 +101,16 @@ public interface NBEventService { /** * Delete an event by the given id. * - * @param context the DSpace context * @param id the id of the event to delete */ - public void deleteEventByEventId(Context context, String id); + public void deleteEventByEventId(String id); /** * Delete events by the given target id. * - * @param context the DSpace context * @param id the id of the target id */ - public void deleteEventsByTargetId(Context context, UUID targetId); + public void deleteEventsByTargetId(UUID targetId); /** * Find a specific topid by the given id. @@ -137,11 +131,17 @@ public interface NBEventService { /** * Find all the event's sources. * - * @param context the DSpace context * @param offset the offset to apply * @param pageSize the page size * @return the sources list */ - public List findAllSources(Context context, long offset, int pageSize); + public List findAllSources(long offset, int pageSize); + + /** + * Count all the event's sources. + * + * @return the count result + */ + public long countSources(); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java index 84853fb5e2..47c98e1467 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java @@ -7,6 +7,8 @@ */ package org.dspace.app.nbevent.service.impl; +import static java.util.Comparator.comparing; + import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -100,7 +102,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public long countTopics(Context context) { + public long countTopics() { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); @@ -118,7 +120,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public long countTopicsBySource(Context context, String source) { + public long countTopicsBySource(String source) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); @@ -137,7 +139,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public void deleteEventByEventId(Context context, String id) { + public void deleteEventByEventId(String id) { try { getSolr().deleteById(id); getSolr().commit(); @@ -147,7 +149,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public void deleteEventsByTargetId(Context context, UUID targetId) { + public void deleteEventsByTargetId(UUID targetId) { try { getSolr().deleteByQuery(RESOURCE_UUID + ":" + targetId.toString()); getSolr().commit(); @@ -185,25 +187,13 @@ public class NBEventServiceImpl implements NBEventService { return null; } - /** - * Method to get all topics and the number of entries for each topic - * - * @param context DSpace context - * @param offset number of results to skip - * @param count number of result to fetch - * @return list of topics with number of events - * @throws IOException - * @throws SolrServerException - * @throws InvalidEnumeratedDataValueException - * - */ @Override - public List findAllTopics(Context context, long offset, long count) { - return findAllTopicsBySource(context, null, offset, count); + public List findAllTopics(long offset, long count) { + return findAllTopicsBySource(null, offset, count); } @Override - public List findAllTopicsBySource(Context context, String source, long offset, long count) { + public List findAllTopicsBySource(String source, long offset, long count) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); @@ -282,7 +272,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public NBEvent findEventByEventId(Context context, String eventId) { + public NBEvent findEventByEventId(String eventId) { SolrQuery param = new SolrQuery(EVENT_ID + ":" + eventId); QueryResponse response; try { @@ -316,9 +306,8 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public List findEventsByTopicAndPage(Context context, String topic, - long offset, int pageSize, - String orderField, boolean ascending) { + public List findEventsByTopicAndPage(String topic, long offset, + int pageSize, String orderField, boolean ascending) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setStart(((Long) offset).intValue()); solrQuery.setRows(pageSize); @@ -343,7 +332,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public long countEventsByTopic(Context context, String topic) { + public long countEventsByTopic(String topic) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery(TOPIC + ":" + topic.replace("!", "/")); @@ -384,13 +373,18 @@ public class NBEventServiceImpl implements NBEventService { @Override public NBSource findSource(String sourceName) { - SolrQuery solrQuery = new SolrQuery(); + + if (!ArrayUtils.contains(getSupportedSources(), sourceName)) { + return null; + } + + SolrQuery solrQuery = new SolrQuery("*:*"); solrQuery.setRows(0); - solrQuery.setQuery(SOURCE + ":" + sourceName); + solrQuery.addFilterQuery(SOURCE + ":" + sourceName); solrQuery.setFacet(true); - // we would like to get eventually topic that has no longer active nb events solrQuery.setFacetMinCount(0); solrQuery.addFacetField(SOURCE); + QueryResponse response; try { response = getSolr().query(solrQuery); @@ -411,18 +405,25 @@ public class NBEventServiceImpl implements NBEventService { NBSource source = new NBSource(); source.setName(sourceName); source.setTotalEvents(0L); + return source; } @Override - public List findAllSources(Context context, long offset, int pageSize) { - return Arrays.stream(getSupportedSources()).sorted() + public List findAllSources(long offset, int pageSize) { + return Arrays.stream(getSupportedSources()) .map((sourceName) -> findSource(sourceName)) + .sorted(comparing(NBSource::getTotalEvents).reversed()) .skip(offset) .limit(pageSize) .collect(Collectors.toList()); } + @Override + public long countSources() { + return getSupportedSources().length; + } + private String[] getSupportedSources() { return configurationService.getArrayProperty("nbevent.sources", new String[] { NBEvent.OPENAIRE_SOURCE }); } diff --git a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java index 8bf1b206da..3ad22738c3 100644 --- a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java @@ -71,6 +71,10 @@ public class NBEventBuilder extends AbstractBuilder { this.topic = topic; return this; } + public NBEventBuilder withSource(final String source) { + this.source = source; + return this; + } public NBEventBuilder withTitle(final String title) { this.title = title; return this; @@ -108,7 +112,7 @@ public class NBEventBuilder extends AbstractBuilder { @Override public void cleanup() throws Exception { - nbEventService.deleteEventByEventId(context, target.getEventId()); + nbEventService.deleteEventByEventId(target.getEventId()); } @Override @@ -118,7 +122,7 @@ public class NBEventBuilder extends AbstractBuilder { @Override public void delete(Context c, NBEvent dso) throws Exception { - nbEventService.deleteEventByEventId(context, target.getEventId()); + nbEventService.deleteEventByEventId(target.getEventId()); // nbEventService.deleteTarget(dso); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java index 2411f4743d..1245c3854e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java @@ -80,7 +80,7 @@ public class NBEventRestController { @RequestParam(required = true, name = "item") UUID relatedItemUUID) throws SQLException, AuthorizeException { Context context = ContextUtil.obtainContext(request); - NBEvent nbevent = nbEventService.findEventByEventId(context, nbeventId); + NBEvent nbevent = nbEventService.findEventByEventId(nbeventId); if (nbevent == null) { throw new ResourceNotFoundException("No such nb event: " + nbeventId); } @@ -120,7 +120,7 @@ public class NBEventRestController { HttpServletResponse response, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { Context context = ContextUtil.obtainContext(request); - NBEvent nbevent = nbEventService.findEventByEventId(context, nbeventId); + NBEvent nbevent = nbEventService.findEventByEventId(nbeventId); if (nbevent == null) { throw new ResourceNotFoundException("No such nb event: " + nbeventId); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java index 3ec4660c4a..901d600c10 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java @@ -55,7 +55,7 @@ public class NBEventRelatedLinkRepository extends AbstractDSpaceRestRepository i public ItemRest getRelated(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, Projection projection) { Context context = obtainContext(); - NBEvent nbEvent = nbEventService.findEventByEventId(context, id); + NBEvent nbEvent = nbEventService.findEventByEventId(id); if (nbEvent == null) { throw new ResourceNotFoundException("No nb event with ID: " + id); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java index d1bc469036..f173ebebc9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java @@ -66,7 +66,7 @@ public class NBEventRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List nbSources = nbEventService.findAllSources(context, pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countTopics(context); - if (nbSources == null) { - return null; - } + List nbSources = nbEventService.findAllSources(pageable.getOffset(), pageable.getPageSize()); + long count = nbEventService.countSources(); return converter.toRestPage(nbSources, pageable, count, utils.obtainProjection()); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java index 479a606e00..280d7e26d1 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java @@ -45,8 +45,8 @@ public class NBTopicRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List nbTopics = nbEventService.findAllTopics(context, pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countTopics(context); + List nbTopics = nbEventService.findAllTopics(pageable.getOffset(), pageable.getPageSize()); + long count = nbEventService.countTopics(); if (nbTopics == null) { return null; } @@ -56,9 +56,9 @@ public class NBTopicRestRepository extends DSpaceRestRepository findBySource(Context context, String source, Pageable pageable) { - List nbTopics = nbEventService.findAllTopicsBySource(context, String.valueOf(source), + List nbTopics = nbEventService.findAllTopicsBySource(source, pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countTopicsBySource(context, String.valueOf(source)); + long count = nbEventService.countTopicsBySource(source); if (nbTopics == null) { return null; } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java new file mode 100644 index 0000000000..2af54b74da --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java @@ -0,0 +1,200 @@ +/** + * 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.app.rest; + +import static org.dspace.app.rest.matcher.NBSourceMatcher.matchNBSourceEntry; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.ItemBuilder; +import org.dspace.builder.NBEventBuilder; +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.content.NBEvent; +import org.dspace.services.ConfigurationService; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Integration tests for {@link NBSourceRestRepository}. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest { + + @Autowired + private ConfigurationService configurationService; + + private Item target; + + @Before + public void setup() { + + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withTitle("Community") + .build(); + + Collection collection = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection") + .build(); + + target = ItemBuilder.createItem(context, collection) + .withTitle("Item") + .build(); + + context.restoreAuthSystemState(); + + configurationService.setProperty("nbevent.sources", + new String[] { "openaire", "test-source", "test-source-2" }); + + } + + @Test + public void testFindAll() throws Exception { + + context.turnOffAuthorisationSystem(); + + createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); + createEvent("openaire", "TOPIC/OPENAIRE/2", "Title 2"); + createEvent("openaire", "TOPIC/OPENAIRE/2", "Title 3"); + + createEvent("test-source", "TOPIC/TEST/1", "Title 4"); + createEvent("test-source", "TOPIC/TEST/1", "Title 5"); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbsources")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbsources", contains( + matchNBSourceEntry("openaire", 3), + matchNBSourceEntry("test-source", 2), + matchNBSourceEntry("test-source-2", 0)))) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", is(3))); + + } + + @Test + public void testFindAllForbidden() throws Exception { + + context.turnOffAuthorisationSystem(); + + createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); + createEvent("test-source", "TOPIC/TEST/1", "Title 4"); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/integration/nbsources")) + .andExpect(status().isForbidden()); + + } + + @Test + public void testFindAllUnauthorized() throws Exception { + + context.turnOffAuthorisationSystem(); + + createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); + createEvent("test-source", "TOPIC/TEST/1", "Title 4"); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/integration/nbsources")) + .andExpect(status().isUnauthorized()); + + } + + @Test + public void testFindOne() throws Exception { + + context.turnOffAuthorisationSystem(); + + createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); + createEvent("openaire", "TOPIC/OPENAIRE/2", "Title 2"); + createEvent("openaire", "TOPIC/OPENAIRE/2", "Title 3"); + + createEvent("test-source", "TOPIC/TEST/1", "Title 4"); + createEvent("test-source", "TOPIC/TEST/1", "Title 5"); + + context.restoreAuthSystemState(); + + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbsources/openaire")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", matchNBSourceEntry("openaire", 3))); + + getClient(authToken).perform(get("/api/integration/nbsources/test-source")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", matchNBSourceEntry("test-source", 2))); + + getClient(authToken).perform(get("/api/integration/nbsources/test-source-2")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$", matchNBSourceEntry("test-source-2", 0))); + + getClient(authToken).perform(get("/api/integration/nbsources/unknown-test-source")) + .andExpect(status().isNotFound()); + + } + + @Test + public void testFindOneForbidden() throws Exception { + + context.turnOffAuthorisationSystem(); + + createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); + createEvent("test-source", "TOPIC/TEST/1", "Title 4"); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + getClient(token).perform(get("/api/integration/nbsources/openaire")) + .andExpect(status().isForbidden()); + + } + + @Test + public void testFindOneUnauthorized() throws Exception { + + context.turnOffAuthorisationSystem(); + + createEvent("openaire", "TOPIC/OPENAIRE/1", "Title 1"); + createEvent("test-source", "TOPIC/TEST/1", "Title 4"); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/integration/nbsources/openaire")) + .andExpect(status().isUnauthorized()); + + } + + private NBEvent createEvent(String source, String topic, String title) { + return NBEventBuilder.createTarget(context, target) + .withSource(source) + .withTopic(topic) + .withTitle(title) + .build(); + } + +} From 4219a69f7072e4ab00b859c5caf68512aba25e5c Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Thu, 17 Feb 2022 15:04:38 +0100 Subject: [PATCH 06/38] [CST-5246] Added integration tests for search topics by source --- .../service/impl/NBEventServiceImpl.java | 29 ++-- .../repository/NBTopicRestRepository.java | 4 +- .../app/rest/NBTopicRestRepositoryIT.java | 127 +++++++++++++++--- 3 files changed, 132 insertions(+), 28 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java index 47c98e1467..667e446b5b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java @@ -107,8 +107,7 @@ public class NBEventServiceImpl implements NBEventService { solrQuery.setRows(0); solrQuery.setQuery("*:*"); solrQuery.setFacet(true); - // we would like to get eventually topic that has no longer active nb events - solrQuery.setFacetMinCount(0); + solrQuery.setFacetMinCount(1); solrQuery.addFacetField(TOPIC); QueryResponse response; try { @@ -125,8 +124,7 @@ public class NBEventServiceImpl implements NBEventService { solrQuery.setRows(0); solrQuery.setQuery("*:*"); solrQuery.setFacet(true); - // we would like to get eventually topic that has no longer active nb events - solrQuery.setFacetMinCount(0); + solrQuery.setFacetMinCount(1); solrQuery.addFacetField(TOPIC); solrQuery.addFilterQuery("source:" + source); QueryResponse response; @@ -164,8 +162,7 @@ public class NBEventServiceImpl implements NBEventService { solrQuery.setRows(0); solrQuery.setQuery(TOPIC + ":" + topicId.replaceAll("!", "/")); solrQuery.setFacet(true); - // we would like to get eventually topic that has no longer active nb events - solrQuery.setFacetMinCount(0); + solrQuery.setFacetMinCount(1); solrQuery.addFacetField(TOPIC); QueryResponse response; try { @@ -194,16 +191,20 @@ public class NBEventServiceImpl implements NBEventService { @Override public List findAllTopicsBySource(String source, long offset, long count) { + + if (source != null && isNotSupportedSource(source)) { + return null; + } + SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery("*:*"); solrQuery.setFacet(true); - // we would like to get eventually topic that has no longer active nb events - solrQuery.setFacetMinCount(0); + solrQuery.setFacetMinCount(1); solrQuery.setFacetLimit((int) (offset + count)); solrQuery.addFacetField(TOPIC); if (source != null) { - solrQuery.addFilterQuery("source:" + source); + solrQuery.addFilterQuery(SOURCE + ":" + source); } QueryResponse response; List nbTopics = null; @@ -236,7 +237,7 @@ public class NBEventServiceImpl implements NBEventService { UpdateRequest updateRequest = new UpdateRequest(); String topic = dto.getTopic(); - if (!ArrayUtils.contains(getSupportedSources(), dto.getSource())) { + if (isNotSupportedSource(dto.getSource())) { throw new IllegalArgumentException("The source of the given event is not supported: " + dto.getSource()); } @@ -374,7 +375,7 @@ public class NBEventServiceImpl implements NBEventService { @Override public NBSource findSource(String sourceName) { - if (!ArrayUtils.contains(getSupportedSources(), sourceName)) { + if (isNotSupportedSource(sourceName)) { return null; } @@ -382,7 +383,7 @@ public class NBEventServiceImpl implements NBEventService { solrQuery.setRows(0); solrQuery.addFilterQuery(SOURCE + ":" + sourceName); solrQuery.setFacet(true); - solrQuery.setFacetMinCount(0); + solrQuery.setFacetMinCount(1); solrQuery.addFacetField(SOURCE); QueryResponse response; @@ -424,6 +425,10 @@ public class NBEventServiceImpl implements NBEventService { return getSupportedSources().length; } + private boolean isNotSupportedSource(String source) { + return !ArrayUtils.contains(getSupportedSources(), source); + } + private String[] getSupportedSources() { return configurationService.getArrayProperty("nbevent.sources", new String[] { NBEvent.OPENAIRE_SOURCE }); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java index 280d7e26d1..53b1a4be6c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java @@ -11,6 +11,7 @@ import java.util.List; import org.dspace.app.nbevent.NBTopic; import org.dspace.app.nbevent.service.NBEventService; +import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.model.NBTopicRest; import org.dspace.core.Context; @@ -55,7 +56,8 @@ public class NBTopicRestRepository extends DSpaceRestRepository findBySource(Context context, String source, Pageable pageable) { + public Page findBySource(Context context, + @Parameter(value = "source", required = true) String source, Pageable pageable) { List nbTopics = nbEventService.findAllTopicsBySource(source, pageable.getOffset(), pageable.getPageSize()); long count = nbEventService.countTopicsBySource(source); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java index dea109219a..7fe9dbc8b2 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java @@ -20,9 +20,10 @@ import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.NBEventBuilder; import org.dspace.content.Collection; -import org.dspace.content.NBEvent; +import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; /** * Integration tests for {@link NBTopicRestRepository}. @@ -32,6 +33,9 @@ import org.junit.Test; */ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { + @Autowired + private ConfigurationService configurationService; + @Test public void findAllTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -39,16 +43,16 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + NBEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") @@ -84,16 +88,16 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); //create collection Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + NBEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") @@ -119,16 +123,16 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + NBEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") @@ -148,7 +152,7 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + NBEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); getClient().perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")).andExpect(status().isUnauthorized()); @@ -163,7 +167,7 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + NBEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); @@ -173,4 +177,97 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().isForbidden()); } + @Test + public void findBySourceTest() throws Exception { + context.turnOffAuthorisationSystem(); + configurationService.setProperty("nbevent.sources", + new String[] { "openaire", "test-source", "test-source-2" }); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + .withTopic("ENRICH/MORE/PID") + .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + .withTopic("ENRICH/MISSING/ABSTRACT") + .withMessage( + "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") + .build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + .withTopic("TEST/TOPIC") + .withSource("test-source") + .build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom 6") + .withTopic("TEST/TOPIC") + .withSource("test-source") + .build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom 7") + .withTopic("TEST/TOPIC/2") + .withSource("test-source") + .build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + .param("source", "openaire")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbtopics", + Matchers.containsInAnyOrder(NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/PID", 2), + NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/ABSTRACT", 1), + NBTopicMatcher.matchNBTopicEntry("ENRICH/MORE/PID", 1)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3))); + getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + .param("source", "test-source")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbtopics", + Matchers.containsInAnyOrder(NBTopicMatcher.matchNBTopicEntry("TEST/TOPIC/2", 1), + NBTopicMatcher.matchNBTopicEntry("TEST/TOPIC", 2)))) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); + getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + .param("source", "test-source-2")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.nbtopics").doesNotExist()) + .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(0))); + } + + @Test + public void findBySourceUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID").build(); + context.restoreAuthSystemState(); + getClient().perform(get("/api/integration/nbtopics/search/bySource") + .param("source", "openaire")) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findBySourceForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + NBEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID").build(); + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + .param("source", "openaire")) + .andExpect(status().isForbidden()); + } + } From d0498d2863da962b1ea14d40c9818c34883d5e16 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Fri, 18 Feb 2022 17:08:59 +0100 Subject: [PATCH 07/38] [CST-5249] Openaire correction service improvements --- .../org/dspace/app/nbevent/NBEntityMetadataAction.java | 9 ++++++--- .../org/dspace/app/nbevent/OpenaireEventsRunnable.java | 7 ++++--- .../app/nbevent/service/impl/NBEventServiceImpl.java | 7 +++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java index f2322fe6b7..8051362cfa 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java @@ -108,12 +108,15 @@ public class NBEntityMetadataAction implements NBAction { if (relatedItem != null) { link(context, item, relatedItem); } else { + Collection collection = collectionService.retrieveCollectionByEntityType(context, item, entityType); + if (collection == null) { + throw new IllegalStateException("No collection found by entity type: " + collection); + } + WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); relatedItem = workspaceItem.getItem(); - if (StringUtils.isNotBlank(entityType)) { - itemService.addMetadata(context, relatedItem, "dspace", "entity", "type", null, entityType); - } + for (String key : entityMetadata.keySet()) { String value = getValue(message, key); if (StringUtils.isNotBlank(value)) { diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java b/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java index d56858402b..4969267d94 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java @@ -7,6 +7,8 @@ */ package org.dspace.app.nbevent; +import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage; + import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; @@ -96,8 +98,7 @@ public class OpenaireEventsRunnable extends DSpaceRunnable>() { }); } catch (IOException e) { - LOGGER.error("File is not found or not readable: " + fileLocation); - e.printStackTrace(); + LOGGER.error("File is not found or not readable: " + fileLocation, e); System.exit(1); } @@ -110,7 +111,7 @@ public class OpenaireEventsRunnable extends DSpaceRunnable Date: Fri, 22 Apr 2022 16:46:56 +0200 Subject: [PATCH 08/38] [CST-5249] Community feedbacks --- .../java/org/dspace/app/nbevent/NBAction.java | 4 ++-- ...ava => NBEntityOpenaireMetadataAction.java} | 18 +++++++++++------- .../app/nbevent/NBEventActionServiceImpl.java | 13 ++++++++----- ...n.java => NBOpenaireMetadataMapAction.java} | 17 +++++++++++------ ...ava => NBOpenaireSimpleMetadataAction.java} | 10 +++++----- .../java/org/dspace/app/nbevent/NBSource.java | 2 +- .../dto/{NBMessage.java => NBMessageDTO.java} | 2 +- ...ireMessage.java => OpenaireMessageDTO.java} | 4 ++-- .../service/impl/NBEventServiceImpl.java | 3 --- .../main/java/org/dspace/content/NBEvent.java | 8 ++++---- .../app/rest/converter/NBEventConverter.java | 10 +++++----- .../app/rest/matcher/NBEventMatcher.java | 6 +++--- dspace/config/modules/oaire-nbevents.cfg | 4 ++-- dspace/config/spring/api/nbevents.xml | 6 +++--- 14 files changed, 58 insertions(+), 49 deletions(-) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBEntityMetadataAction.java => NBEntityOpenaireMetadataAction.java} (92%) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBMetadataMapAction.java => NBOpenaireMetadataMapAction.java} (82%) rename dspace-api/src/main/java/org/dspace/app/nbevent/{NBSimpleMetadataAction.java => NBOpenaireSimpleMetadataAction.java} (85%) rename dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/{NBMessage.java => NBMessageDTO.java} (93%) rename dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/{OpenaireMessage.java => OpenaireMessageDTO.java} (96%) diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java index 70e7624197..099982d289 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java @@ -7,7 +7,7 @@ */ package org.dspace.app.nbevent; -import org.dspace.app.nbevent.service.dto.NBMessage; +import org.dspace.app.nbevent.service.dto.NBMessageDTO; import org.dspace.content.Item; import org.dspace.core.Context; @@ -27,5 +27,5 @@ public interface NBAction { * @param relatedItem the related item, if any * @param message the message with the correction details */ - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message); + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityOpenaireMetadataAction.java similarity index 92% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityOpenaireMetadataAction.java index 8051362cfa..e16c18edd0 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityOpenaireMetadataAction.java @@ -11,8 +11,8 @@ import java.sql.SQLException; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.NBMessage; -import org.dspace.app.nbevent.service.dto.OpenaireMessage; +import org.dspace.app.nbevent.service.dto.NBMessageDTO; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.EntityType; @@ -37,7 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired; * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEntityMetadataAction implements NBAction { +public class NBEntityOpenaireMetadataAction implements NBAction { private String relation; private String entityType; private Map entityMetadata; @@ -103,7 +103,7 @@ public class NBEntityMetadataAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message) { + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { try { if (relatedItem != null) { link(context, item, relatedItem); @@ -134,6 +134,10 @@ public class NBEntityMetadataAction implements NBAction { } } + /** + * Create a new relationship between the two given item, based on the configured + * relation. + */ private void link(Context context, Item item, Item relatedItem) throws SQLException, AuthorizeException { EntityType project = entityTypeService.findByEntityType(context, entityType); RelationshipType relType = relationshipTypeService.findByEntityType(context, project).stream() @@ -151,12 +155,12 @@ public class NBEntityMetadataAction implements NBAction { relationshipService.update(context, persistedRelationship); } - private String getValue(NBMessage message, String key) { - if (!(message instanceof OpenaireMessage)) { + private String getValue(NBMessageDTO message, String key) { + if (!(message instanceof OpenaireMessageDTO)) { return null; } - OpenaireMessage openaireMessage = (OpenaireMessage) message; + OpenaireMessageDTO openaireMessage = (OpenaireMessageDTO) message; if (StringUtils.equals(key, "acronym")) { return openaireMessage.getAcronym(); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java index ac9fdd5c3f..9ebd796a80 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java @@ -79,7 +79,7 @@ public class NBEventActionServiceImpl implements NBEventActionService { topicsToActions.get(nbevent.getTopic()).applyCorrection(context, item, related, jsonMapper.readValue(nbevent.getMessage(), nbevent.getMessageDtoClass())); nbEventService.deleteEventByEventId(nbevent.getEventId()); - makeAcknowledgement(nbevent.getEventId(), NBEvent.ACCEPTED); + makeAcknowledgement(nbevent.getEventId(), nbevent.getSource(), NBEvent.ACCEPTED); } catch (SQLException | JsonProcessingException e) { throw new RuntimeException(e); } @@ -88,17 +88,20 @@ public class NBEventActionServiceImpl implements NBEventActionService { @Override public void discard(Context context, NBEvent nbevent) { nbEventService.deleteEventByEventId(nbevent.getEventId()); - makeAcknowledgement(nbevent.getEventId(), NBEvent.DISCARDED); + makeAcknowledgement(nbevent.getEventId(), nbevent.getSource(), NBEvent.DISCARDED); } @Override public void reject(Context context, NBEvent nbevent) { nbEventService.deleteEventByEventId(nbevent.getEventId()); - makeAcknowledgement(nbevent.getEventId(), NBEvent.REJECTED); + makeAcknowledgement(nbevent.getEventId(), nbevent.getSource(), NBEvent.REJECTED); } - private void makeAcknowledgement(String eventId, String status) { - String[] ackwnoledgeCallbacks = configurationService.getArrayProperty("oaire-nbevents.acknowledge-url"); + /** + * Make acknowledgement to the configured urls for the event status. + */ + private void makeAcknowledgement(String eventId, String source, String status) { + String[] ackwnoledgeCallbacks = configurationService.getArrayProperty(source + "-nbevents.acknowledge-url"); if (ackwnoledgeCallbacks != null) { for (String ackwnoledgeCallback : ackwnoledgeCallbacks) { if (StringUtils.isNotBlank(ackwnoledgeCallback)) { diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java similarity index 82% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java index 3d7e2114ce..216f44a2d5 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBMetadataMapAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java @@ -10,8 +10,8 @@ package org.dspace.app.nbevent; import java.sql.SQLException; import java.util.Map; -import org.dspace.app.nbevent.service.dto.NBMessage; -import org.dspace.app.nbevent.service.dto.OpenaireMessage; +import org.dspace.app.nbevent.service.dto.NBMessageDTO; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.service.ItemService; @@ -25,7 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired; * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBMetadataMapAction implements NBAction { +public class NBOpenaireMetadataMapAction implements NBAction { public static final String DEFAULT = "default"; private Map types; @@ -44,14 +44,18 @@ public class NBMetadataMapAction implements NBAction { this.types = types; } + /** + * Apply the correction on one metadata field of the given item based on the + * openaire message type. + */ @Override - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message) { + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { - if (!(message instanceof OpenaireMessage)) { + if (!(message instanceof OpenaireMessageDTO)) { throw new IllegalArgumentException("Unsupported message type: " + message.getClass()); } - OpenaireMessage openaireMessage = (OpenaireMessage) message; + OpenaireMessageDTO openaireMessage = (OpenaireMessageDTO) message; try { String targetMetadata = types.get(openaireMessage.getType()); @@ -65,6 +69,7 @@ public class NBMetadataMapAction implements NBAction { } catch (SQLException | AuthorizeException e) { throw new RuntimeException(e); } + } public String[] splitMetadata(String metadata) { diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java similarity index 85% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java index 0bff9e05ff..f08b3f7db4 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSimpleMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java @@ -9,8 +9,8 @@ package org.dspace.app.nbevent; import java.sql.SQLException; -import org.dspace.app.nbevent.service.dto.NBMessage; -import org.dspace.app.nbevent.service.dto.OpenaireMessage; +import org.dspace.app.nbevent.service.dto.NBMessageDTO; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.service.ItemService; @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBSimpleMetadataAction implements NBAction { +public class NBOpenaireSimpleMetadataAction implements NBAction { private String metadata; private String metadataSchema; private String metadataElement; @@ -51,10 +51,10 @@ public class NBSimpleMetadataAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessage message) { + public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { try { itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null, - ((OpenaireMessage) message).getAbstracts()); + ((OpenaireMessageDTO) message).getAbstracts()); itemService.update(context, item); } catch (SQLException | AuthorizeException e) { throw new RuntimeException(e); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java index e74547d531..42a416bf90 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java @@ -10,7 +10,7 @@ package org.dspace.app.nbevent; import java.util.Date; /** - * This model class represent the notification broker source concept + * This model class represent the source/provider of the NB events (as OpenAIRE). * * @author Luca Giamminonni (luca.giamminonni at 4Science) * diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessage.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessageDTO.java similarity index 93% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessage.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessageDTO.java index 4c59ab1c85..e341c9bd60 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessage.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessageDTO.java @@ -15,7 +15,7 @@ import org.dspace.content.NBEvent; * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public interface NBMessage { +public interface NBMessageDTO { } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessage.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDTO.java similarity index 96% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessage.java rename to dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDTO.java index 188139afef..5558aa3cb0 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessage.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDTO.java @@ -10,12 +10,12 @@ package org.dspace.app.nbevent.service.dto; import com.fasterxml.jackson.annotation.JsonProperty; /** - * Implementation of {@link NBMessage} that model message coming from OPENAIRE. + * Implementation of {@link NBMessageDTO} that model message coming from OPENAIRE. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class OpenaireMessage implements NBMessage { +public class OpenaireMessageDTO implements NBMessageDTO { @JsonProperty("pids[0].value") private String value; diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java index 03fbde444a..84f02474ec 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.lang3.ArrayUtils; -import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrQuery.ORDER; @@ -55,8 +54,6 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class NBEventServiceImpl implements NBEventService { - private static final Logger log = Logger.getLogger(NBEventServiceImpl.class); - @Autowired(required = true) protected ConfigurationService configurationService; diff --git a/dspace-api/src/main/java/org/dspace/content/NBEvent.java b/dspace-api/src/main/java/org/dspace/content/NBEvent.java index e99fbaefa1..a029d1f3e3 100644 --- a/dspace-api/src/main/java/org/dspace/content/NBEvent.java +++ b/dspace-api/src/main/java/org/dspace/content/NBEvent.java @@ -14,8 +14,8 @@ import java.util.Date; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import org.dspace.app.nbevent.RawJsonDeserializer; -import org.dspace.app.nbevent.service.dto.NBMessage; -import org.dspace.app.nbevent.service.dto.OpenaireMessage; +import org.dspace.app.nbevent.service.dto.NBMessageDTO; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; /** * This class represent the notification broker data as loaded in our solr @@ -192,10 +192,10 @@ public class NBEvent { } - public Class getMessageDtoClass() { + public Class getMessageDtoClass() { switch (getSource()) { case OPENAIRE_SOURCE: - return OpenaireMessage.class; + return OpenaireMessageDTO.class; default: throw new IllegalArgumentException("Unknown event's source: " + getSource()); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java index 21bbdfff29..1acbbf51bb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java @@ -13,8 +13,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; -import org.dspace.app.nbevent.service.dto.NBMessage; -import org.dspace.app.nbevent.service.dto.OpenaireMessage; +import org.dspace.app.nbevent.service.dto.NBMessageDTO; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.app.rest.model.NBEventMessageRest; import org.dspace.app.rest.model.NBEventRest; import org.dspace.app.rest.model.OpenaireNBEventMessageRest; @@ -61,9 +61,9 @@ public class NBEventConverter implements DSpaceConverter { return rest; } - private NBEventMessageRest convertMessage(NBMessage dto) { - if (dto instanceof OpenaireMessage) { - OpenaireMessage openaireDto = (OpenaireMessage) dto; + private NBEventMessageRest convertMessage(NBMessageDTO dto) { + if (dto instanceof OpenaireMessageDTO) { + OpenaireMessageDTO openaireDto = (OpenaireMessageDTO) dto; OpenaireNBEventMessageRest message = new OpenaireNBEventMessageRest(); message.setAbstractValue(openaireDto.getAbstracts()); message.setOpenaireId(openaireDto.getOpenaireId()); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java index a09d115359..f0a0a12194 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.OpenaireMessage; +import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.content.NBEvent; import org.hamcrest.Matcher; import org.hamcrest.Matchers; @@ -56,7 +56,7 @@ public class NBEventMatcher { hasJsonPath("$.status", Matchers.equalToIgnoringCase(event.getStatus())), hasJsonPath("$.message", matchMessage(event.getTopic(), jsonMapper.readValue(event.getMessage(), - OpenaireMessage.class))), + OpenaireMessageDTO.class))), hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")), hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")), hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")), @@ -66,7 +66,7 @@ public class NBEventMatcher { } } - private static Matcher matchMessage(String topic, OpenaireMessage message) { + private static Matcher matchMessage(String topic, OpenaireMessageDTO message) { if (StringUtils.endsWith(topic, "/ABSTRACT")) { return allOf(hasJsonPath("$.abstract", is(message.getAbstracts()))); } else if (StringUtils.endsWith(topic, "/PID")) { diff --git a/dspace/config/modules/oaire-nbevents.cfg b/dspace/config/modules/oaire-nbevents.cfg index 68baec3d1d..993a637a18 100644 --- a/dspace/config/modules/oaire-nbevents.cfg +++ b/dspace/config/modules/oaire-nbevents.cfg @@ -5,8 +5,8 @@ #---------------------------------------------------------------# oaire-nbevents.solr.server = ${solr.server}/${solr.multicorePrefix}nbevent # A POST to these url(s) will be done to notify oaire of decision taken for each nbevents -oaire-nbevents.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events -#oaire-nbevents.acknowledge-url = +openaire-nbevents.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events +#openaire-nbevents.acknowledge-url = oaire-nbevents.import.topic = ENRICH/MISSING/ABSTRACT oaire-nbevents.import.topic = ENRICH/MISSING/PID oaire-nbevents.import.topic = ENRICH/MORE/PID diff --git a/dspace/config/spring/api/nbevents.xml b/dspace/config/spring/api/nbevents.xml index 34dca93ebb..8cb039c39f 100644 --- a/dspace/config/spring/api/nbevents.xml +++ b/dspace/config/spring/api/nbevents.xml @@ -29,7 +29,7 @@ - + @@ -47,10 +47,10 @@ - + - + + @@ -29,6 +29,8 @@ + @@ -50,6 +52,7 @@ + diff --git a/dspace/solr/nbevent/conf/admin-extra.html b/dspace/solr/nbevent/conf/admin-extra.html deleted file mode 100644 index aa739da862..0000000000 --- a/dspace/solr/nbevent/conf/admin-extra.html +++ /dev/null @@ -1,31 +0,0 @@ - - - diff --git a/dspace/solr/nbevent/conf/elevate.xml b/dspace/solr/nbevent/conf/elevate.xml deleted file mode 100644 index 7630ebe20f..0000000000 --- a/dspace/solr/nbevent/conf/elevate.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/dspace/solr/nbevent/conf/schema.xml b/dspace/solr/nbevent/conf/schema.xml index 338fbdcdcd..68eb79afd0 100644 --- a/dspace/solr/nbevent/conf/schema.xml +++ b/dspace/solr/nbevent/conf/schema.xml @@ -16,221 +16,55 @@ limitations under the License. --> - - - - - - + - - - - - - - - - - - - - - - - - - - - - + @@ -270,9 +102,6 @@ - - - @@ -292,10 +121,6 @@ - - @@ -316,44 +141,14 @@ - - - - - + - - - + - + @@ -370,22 +165,10 @@ - - @@ -393,16 +176,8 @@ - - - - @@ -427,7 +200,6 @@ - @@ -451,10 +223,6 @@ - @@ -483,32 +251,7 @@ - - + @@ -532,14 +275,6 @@ - event_id - - - - + diff --git a/dspace/solr/nbevent/conf/scripts.conf b/dspace/solr/nbevent/conf/scripts.conf deleted file mode 100644 index f58b262ae0..0000000000 --- a/dspace/solr/nbevent/conf/scripts.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -user= -solr_hostname=localhost -solr_port=8983 -rsyncd_port=18983 -data_dir= -webapp_name=solr -master_host= -master_data_dir= -master_status_dir= diff --git a/dspace/solr/nbevent/conf/solrconfig.xml b/dspace/solr/nbevent/conf/solrconfig.xml index a4cfbed4a9..0565e56df4 100644 --- a/dspace/solr/nbevent/conf/solrconfig.xml +++ b/dspace/solr/nbevent/conf/solrconfig.xml @@ -17,1927 +17,105 @@ --> - - - - 7.7.2 - - - - - - - - - - - - - - - ${solr.data.dir:} - - - - - - - - - - - - - - - - - - - - - - - - - 32 - 1000 - - - - - - - - - - - - ${solr.lock.type:native} - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - - - - ${solr.ulog.dir:} - - - - - 10000 - ${solr.autoCommit.maxTime:10000} - false - - - - - - ${solr.autoSoftCommit.maxTime:1000} - - - - - - - - - - - - - - - - - - - - 1024 - - - - - - - - - 8.8.1 + + ${solr.data.dir:} + + + + + + + + + + 32 + 1000 + ${solr.lock.type:native} + + false + + + + + + + 10000 + ${solr.autoCommit.maxTime:10000} + true + + + + ${solr.autoSoftCommit.maxTime:-1} + + + + + + ${solr.max.booleanClauses:1024} + + + - - + + + - - - - + this cache will not be autowarmed. --> + - - + + + + + - - true - - - - - - 20 - - - 200 - - - - - - - - - - - - static firstSearcher warming in solrconfig.xml - - - - - - false - - - 2 - - - - - - - - - - - - - - - - - - - - - + + explicit 10 event_id - - - - - - - - - - - explicit - json - true - event_id - - + + - - - - - true - json - true - - - - - - - - explicit - - - velocity - browse - layout - Solritas - - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 event_id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - event_id - 100% - *:* - 10 - *,score - - - text^0.5 features^1.0 name^1.2 sku^1.5 event_id^10.0 manu^1.1 cat^1.4 - title^10.0 description^5.0 keywords^5.0 author^2.0 resourcename^1.0 - - text,features,name,sku,event_id,manu,cat,title,description,keywords,author,resourcename - 3 - - - on - cat - manu_exact - content_type - author_s - ipod - GB - 1 - cat,inStock - after - price - 0 - 600 - 50 - popularity - 0 - 10 - 3 - manufacturedate_dt - NOW/YEAR-10YEARS - NOW - +1YEAR - before - after - - - on - content features title name - html - <b> - </b> - 0 - title - 0 - name - 3 - 200 - content - 750 - - - on - false - 5 - 2 - 5 - true - true - 5 - 3 - - - - - spellcheck - - - - - - - - - - - - - + - application/json - - - - - - - application/csv - - - - - - - - true - ignored_ - - - true - links - ignored_ - - - - - - - - - - - - - - - - - - - - - - solrpingquery - - - all - - - - - - - - - explicit - true - - - - - - - - - - - - - - - - textSpell - - - default - name - ./spellchecker - - - - - - - - - - - - false - - false - - 1 - - - spellcheck - - - - - - - - true - - - tvComponent - - - - - - - - - text_general - - - - - - default - event_id - solr.DirectSolrSpellChecker - - internal - - 0.5 - - 2 - - 1 - - 5 - - 4 - - 0.01 - - - - - - wordbreak - solr.WordBreakSolrSpellChecker - name - true - true - 10 - - - - - - - - - - - - - - - - event_id - - default - wordbreak - on - true - 10 - 5 - 5 - true - true - 10 - 5 - - - spellcheck - - - - - - - - - - event_id - true - - - tvComponent - - - - - - - - - default - - - org.carrot2.clustering.lingo.LingoClusteringAlgorithm - - - 20 - - - clustering/carrot2 - - - ENGLISH - - - stc - org.carrot2.clustering.stc.STCClusteringAlgorithm - - - - - - - true - default - true - - name - event_id - - features - - true - - - - false - - edismax - - text^0.5 features^1.0 name^1.2 sku^1.5 event_id^10.0 manu^1.1 cat^1.4 - - *:* - 10 - *,score - - - clustering - - - - - - - - - - true - false - - - terms - - - - - - - - string - elevate.xml - - - - - - explicit - event_id - - - elevator - - - - - - - - - - - 100 + application/json - - - - - - - 70 - - 0.5 - - [-\w ,/\n\"']{20,200} - - - - - - - ]]> - ]]> - - - - - - - - - - - - - - - - - - - - - - - - ,, - ,, - ,, - ,, - ,]]> - ]]> - - - - - - 10 - .,!? - - - - - - - WORD - - - en - US - - - - - - - - - - - - - - - - - - - - - - - - text/plain; charset=UTF-8 - - - - - - - - - 5 - - - - - - - - - - - - - - - - - - *:* - + + diff --git a/dspace/solr/nbevent/conf/spellings.txt b/dspace/solr/nbevent/conf/spellings.txt deleted file mode 100644 index d7ede6f561..0000000000 --- a/dspace/solr/nbevent/conf/spellings.txt +++ /dev/null @@ -1,2 +0,0 @@ -pizza -history \ No newline at end of file From 32c6300afaa3122d45c543f5a2cc1422644a2f4f Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 26 Apr 2022 18:10:52 +0200 Subject: [PATCH 10/38] [CST-5249] Reverted related item check --- .../org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java | 4 ---- .../dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java | 5 ----- .../main/java/org/dspace/app/rest/NBEventRestController.java | 2 ++ 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java index c5909de962..216f44a2d5 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java @@ -51,10 +51,6 @@ public class NBOpenaireMetadataMapAction implements NBAction { @Override public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { - if (relatedItem != null) { - throw new IllegalArgumentException("NBOpenaireMetadataMapAction does not support related item"); - } - if (!(message instanceof OpenaireMessageDTO)) { throw new IllegalArgumentException("Unsupported message type: " + message.getClass()); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java index 8666353f8a..f08b3f7db4 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java @@ -52,11 +52,6 @@ public class NBOpenaireSimpleMetadataAction implements NBAction { @Override public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { - - if (relatedItem != null) { - throw new IllegalArgumentException("NBOpenaireSimpleMetadataAction does not support related item"); - } - try { itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null, ((OpenaireMessageDTO) message).getAbstracts()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java index f7bb4b2e48..30875080a0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java @@ -88,6 +88,8 @@ public class NBEventRestController { if (nbevent.getRelated() != null) { throw new UnprocessableEntityException("The nb event with ID: " + nbeventId + " already has " + "a related item"); + } else if (!StringUtils.endsWith(nbevent.getTopic(), "/PROJECT")) { + return ControllerUtils.toEmptyResponse(HttpStatus.BAD_REQUEST); } Item relatedItem = itemService.find(context, relatedItemUUID); From 7013673318fd18ba6bd0c5e00bac1dfa66359cb1 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Thu, 26 May 2022 12:41:15 +0200 Subject: [PATCH 11/38] [CST-5249] Fixed compilation error --- .../src/main/java/org/dspace/app/rest/NBEventRestController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java index 30875080a0..10618288aa 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java @@ -15,6 +15,7 @@ import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.StringUtils; import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.UnprocessableEntityException; From 7259393600140adf7e983cd87989078bc2d1b835 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Mon, 4 Jul 2022 16:40:15 +0200 Subject: [PATCH 12/38] [CST-5249] Renamed NB with QA --- .../content/{NBEvent.java => QAEvent.java} | 16 +- ...ntProcessed.java => QAEventProcessed.java} | 8 +- .../OpenaireEventsCliScriptConfiguration.java | 2 +- .../OpenaireEventsRunnable.java | 34 +- .../OpenaireEventsRunnableCli.java | 4 +- .../OpenaireEventsScriptConfiguration.java | 6 +- .../QAEntityOpenaireMetadataAction.java} | 26 +- .../QAEventActionService.java} | 20 +- .../QAEventActionServiceImpl.java} | 52 +-- .../QAEventsDeleteCascadeConsumer.java} | 14 +- .../QAOpenaireMetadataMapAction.java} | 12 +- .../QAOpenaireSimpleMetadataAction.java} | 12 +- .../NBSource.java => qaevent/QASource.java} | 6 +- .../NBTopic.java => qaevent/QATopic.java} | 6 +- .../QualityAssuranceAction.java} | 8 +- .../dao/QAEventsDao.java} | 12 +- .../dao/impl/QAEventsDaoImpl.java} | 28 +- .../service/QAEventService.java} | 28 +- .../service/dto/OpenaireMessageDTO.java | 6 +- .../service/dto/QAMessageDTO.java} | 8 +- .../service/impl/QAEventServiceImpl.java} | 74 ++--- ...=> V7.3_2022.02.17__qaevent_processed.sql} | 8 +- .../V7.3_2022.02.17__qaevent_processed.sql} | 10 +- .../V7.3_2022.02.17__qaevent_processed.sql} | 10 +- .../test/data/dspaceFolder/config/local.cfg | 4 +- .../config/spring/api/solr-services.xml | 6 +- .../org/dspace/builder/AbstractBuilder.java | 8 +- ...BEventBuilder.java => QAEventBuilder.java} | 58 ++-- .../MockQAEventService.java} | 10 +- ...roller.java => QAEventRestController.java} | 58 ++-- ...ntConverter.java => QAEventConverter.java} | 34 +- ...eConverter.java => QASourceConverter.java} | 18 +- ...icConverter.java => QATopicConverter.java} | 18 +- ...t.java => OpenaireQAEventMessageRest.java} | 4 +- ...ssageRest.java => QAEventMessageRest.java} | 4 +- .../{NBEventRest.java => QAEventRest.java} | 12 +- .../{NBSourceRest.java => QASourceRest.java} | 6 +- .../{NBTopicRest.java => QATopicRest.java} | 6 +- ...ventResource.java => QAEventResource.java} | 10 +- ...rceResource.java => QASourceResource.java} | 10 +- ...opicResource.java => QATopicResource.java} | 10 +- .../repository/NBTopicRestRepository.java | 75 ----- ...java => QAEventRelatedLinkRepository.java} | 30 +- ...sitory.java => QAEventRestRepository.java} | 66 ++-- ....java => QAEventTargetLinkRepository.java} | 28 +- ...y.java => QAEventTopicLinkRepository.java} | 34 +- ...itory.java => QASourceRestRepository.java} | 34 +- .../repository/QATopicRestRepository.java | 75 +++++ ...ava => QAEventStatusReplaceOperation.java} | 36 +- ...ryIT.java => QAEventRestRepositoryIT.java} | 310 +++++++++--------- ...yIT.java => QASourceRestRepositoryIT.java} | 48 +-- ...ryIT.java => QATopicRestRepositoryIT.java} | 122 +++---- ...BEventMatcher.java => QAEventMatcher.java} | 18 +- ...ourceMatcher.java => QASourceMatcher.java} | 16 +- ...BTopicMatcher.java => QATopicMatcher.java} | 16 +- dspace/config/dspace.cfg | 10 +- dspace/config/hibernate.cfg.xml | 2 +- .../modules/{nbevents.cfg => qaevents.cfg} | 22 +- .../spring/api/{nbevents.xml => qaevents.xml} | 18 +- dspace/config/spring/api/scripts.xml | 6 +- dspace/config/spring/api/solr-services.xml | 4 +- dspace/config/spring/rest/scripts.xml | 6 +- .../{nbevent => qaevent}/conf/protwords.txt | 0 .../solr/{nbevent => qaevent}/conf/schema.xml | 0 .../{nbevent => qaevent}/conf/solrconfig.xml | 2 +- .../{nbevent => qaevent}/conf/stopwords.txt | 0 .../{nbevent => qaevent}/conf/synonyms.txt | 0 .../solr/{nbevent => qaevent}/core.properties | 0 68 files changed, 830 insertions(+), 834 deletions(-) rename dspace-api/src/main/java/org/dspace/content/{NBEvent.java => QAEvent.java} (92%) rename dspace-api/src/main/java/org/dspace/content/{NBEventProcessed.java => QAEventProcessed.java} (91%) rename dspace-api/src/main/java/org/dspace/{app/nbevent => qaevent}/OpenaireEventsCliScriptConfiguration.java (96%) rename dspace-api/src/main/java/org/dspace/{app/nbevent => qaevent}/OpenaireEventsRunnable.java (83%) rename dspace-api/src/main/java/org/dspace/{app/nbevent => qaevent}/OpenaireEventsRunnableCli.java (94%) rename dspace-api/src/main/java/org/dspace/{app/nbevent => qaevent}/OpenaireEventsScriptConfiguration.java (93%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBEntityOpenaireMetadataAction.java => qaevent/QAEntityOpenaireMetadataAction.java} (88%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBEventActionService.java => qaevent/QAEventActionService.java} (60%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBEventActionServiceImpl.java => qaevent/QAEventActionServiceImpl.java} (67%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBEventsDeleteCascadeConsumer.java => qaevent/QAEventsDeleteCascadeConsumer.java} (71%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBOpenaireMetadataMapAction.java => qaevent/QAOpenaireMetadataMapAction.java} (87%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBOpenaireSimpleMetadataAction.java => qaevent/QAOpenaireSimpleMetadataAction.java} (82%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBSource.java => qaevent/QASource.java} (87%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBTopic.java => qaevent/QATopic.java} (87%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/NBAction.java => qaevent/QualityAssuranceAction.java} (82%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/dao/NBEventsDao.java => qaevent/dao/QAEventsDao.java} (86%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/dao/impl/NBEventsDaoImpl.java => qaevent/dao/impl/QAEventsDaoImpl.java} (62%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/service/NBEventService.java => qaevent/service/QAEventService.java} (82%) rename dspace-api/src/main/java/org/dspace/{app/nbevent => qaevent}/service/dto/OpenaireMessageDTO.java (95%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/service/dto/NBMessageDTO.java => qaevent/service/dto/QAMessageDTO.java} (73%) rename dspace-api/src/main/java/org/dspace/{app/nbevent/service/impl/NBEventServiceImpl.java => qaevent/service/impl/QAEventServiceImpl.java} (87%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/{V7.3_2022.02.17__nbevent_processed.sql => V7.3_2022.02.17__qaevent_processed.sql} (65%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/{postgres/V7.3_2022.02.17__nbevent_processed.sql => oracle/V7.3_2022.02.17__qaevent_processed.sql} (66%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/{oracle/V7.3_2022.02.17__nbevent_processed.sql => postgres/V7.3_2022.02.17__qaevent_processed.sql} (66%) rename dspace-api/src/test/java/org/dspace/builder/{NBEventBuilder.java => QAEventBuilder.java} (58%) rename dspace-api/src/test/java/org/dspace/{app/nbevent/MockNBEventService.java => qaevent/MockQAEventService.java} (76%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/{NBEventRestController.java => QAEventRestController.java} (75%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/{NBEventConverter.java => QAEventConverter.java} (76%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/{NBSourceConverter.java => QASourceConverter.java} (66%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/{NBTopicConverter.java => QATopicConverter.java} (68%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/{OpenaireNBEventMessageRest.java => OpenaireQAEventMessageRest.java} (94%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/{NBEventMessageRest.java => QAEventMessageRest.java} (88%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/{NBEventRest.java => QAEventRest.java} (90%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/{NBSourceRest.java => QASourceRest.java} (88%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/{NBTopicRest.java => QATopicRest.java} (89%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/{NBEventResource.java => QAEventResource.java} (67%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/{NBSourceResource.java => QASourceResource.java} (67%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/{NBTopicResource.java => QATopicResource.java} (67%) delete mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java rename dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/{NBEventRelatedLinkRepository.java => QAEventRelatedLinkRepository.java} (72%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/{NBEventRestRepository.java => QAEventRestRepository.java} (62%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/{NBEventTargetLinkRepository.java => QAEventTargetLinkRepository.java} (70%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/{NBEventTopicLinkRepository.java => QAEventTopicLinkRepository.java} (61%) rename dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/{NBSourceRestRepository.java => QASourceRestRepository.java} (50%) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java rename dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/{NBEventStatusReplaceOperation.java => QAEventStatusReplaceOperation.java} (60%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/{NBEventRestRepositoryIT.java => QAEventRestRepositoryIT.java} (80%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/{NBSourceRestRepositoryIT.java => QASourceRestRepositoryIT.java} (78%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/{NBTopicRestRepositoryIT.java => QATopicRestRepositoryIT.java} (73%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/{NBEventMatcher.java => QAEventMatcher.java} (88%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/{NBSourceMatcher.java => QASourceMatcher.java} (66%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/{NBTopicMatcher.java => QATopicMatcher.java} (69%) rename dspace/config/modules/{nbevents.cfg => qaevents.cfg} (51%) rename dspace/config/spring/api/{nbevents.xml => qaevents.xml} (78%) rename dspace/solr/{nbevent => qaevent}/conf/protwords.txt (100%) rename dspace/solr/{nbevent => qaevent}/conf/schema.xml (100%) rename dspace/solr/{nbevent => qaevent}/conf/solrconfig.xml (99%) rename dspace/solr/{nbevent => qaevent}/conf/stopwords.txt (100%) rename dspace/solr/{nbevent => qaevent}/conf/synonyms.txt (100%) rename dspace/solr/{nbevent => qaevent}/core.properties (100%) diff --git a/dspace-api/src/main/java/org/dspace/content/NBEvent.java b/dspace-api/src/main/java/org/dspace/content/QAEvent.java similarity index 92% rename from dspace-api/src/main/java/org/dspace/content/NBEvent.java rename to dspace-api/src/main/java/org/dspace/content/QAEvent.java index b53aef2815..64f8a12026 100644 --- a/dspace-api/src/main/java/org/dspace/content/NBEvent.java +++ b/dspace-api/src/main/java/org/dspace/content/QAEvent.java @@ -13,16 +13,16 @@ import java.security.NoSuchAlgorithmException; import java.util.Date; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import org.dspace.app.nbevent.service.dto.NBMessageDTO; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; +import org.dspace.qaevent.service.dto.OpenaireMessageDTO; +import org.dspace.qaevent.service.dto.QAMessageDTO; import org.dspace.util.RawJsonDeserializer; /** - * This class represent the notification broker data as loaded in our solr - * nbevent core + * This class represent the Quality Assurance broker data as loaded in our solr + * qaevent core * */ -public class NBEvent { +public class QAEvent { public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static final String ACCEPTED = "accepted"; @@ -54,10 +54,10 @@ public class NBEvent { private String status = "PENDING"; - public NBEvent() { + public QAEvent() { } - public NBEvent(String source, String originalId, String target, String title, + public QAEvent(String source, String originalId, String target, String title, String topic, double trust, String message, Date lastUpdate) { super(); this.source = source; @@ -193,7 +193,7 @@ public class NBEvent { } - public Class getMessageDtoClass() { + public Class getMessageDtoClass() { switch (getSource()) { case OPENAIRE_SOURCE: return OpenaireMessageDTO.class; diff --git a/dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java b/dspace-api/src/main/java/org/dspace/content/QAEventProcessed.java similarity index 91% rename from dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java rename to dspace-api/src/main/java/org/dspace/content/QAEventProcessed.java index 62f8222e24..3657c2fdc4 100644 --- a/dspace-api/src/main/java/org/dspace/content/NBEventProcessed.java +++ b/dspace-api/src/main/java/org/dspace/content/QAEventProcessed.java @@ -26,17 +26,17 @@ import org.dspace.eperson.EPerson; * */ @Entity -@Table(name = "nbevent_processed") -public class NBEventProcessed implements Serializable { +@Table(name = "qaevent_processed") +public class QAEventProcessed implements Serializable { private static final long serialVersionUID = 3427340199132007814L; @Id - @Column(name = "nbevent_id") + @Column(name = "qaevent_id") private String eventId; @Temporal(TemporalType.TIMESTAMP) - @Column(name = "nbevent_timestamp") + @Column(name = "qaevent_timestamp") private Date eventTimestamp; @JoinColumn(name = "eperson_uuid") diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsCliScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/qaevent/OpenaireEventsCliScriptConfiguration.java similarity index 96% rename from dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsCliScriptConfiguration.java rename to dspace-api/src/main/java/org/dspace/qaevent/OpenaireEventsCliScriptConfiguration.java index 5263bc559b..bad7ec5d5b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsCliScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/OpenaireEventsCliScriptConfiguration.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import org.apache.commons.cli.Options; diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java b/dspace-api/src/main/java/org/dspace/qaevent/OpenaireEventsRunnable.java similarity index 83% rename from dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java rename to dspace-api/src/main/java/org/dspace/qaevent/OpenaireEventsRunnable.java index e2b66cd749..6a0f5cf8e5 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/OpenaireEventsRunnable.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/OpenaireEventsRunnable.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage; @@ -21,11 +21,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.NBEventService; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; +import org.dspace.qaevent.service.QAEventService; import org.dspace.scripts.DSpaceRunnable; import org.dspace.services.ConfigurationService; import org.dspace.utils.DSpace; @@ -33,7 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Implementation of {@link DSpaceRunnable} to perfom a NBEvents import from a + * Implementation of {@link DSpaceRunnable} to perfom a QAEvents import from a * json file. The JSON file contains an array of JSON Events, where each event * has the following structure * @@ -62,7 +62,7 @@ public class OpenaireEventsRunnable extends DSpaceRunnable entries; + protected List entries; protected Context context; @@ -86,17 +86,17 @@ public class OpenaireEventsRunnable extends DSpaceRunnable>() { + this.entries = jsonMapper.readValue(getQAEventsInputStream(), new TypeReference>() { }); } catch (IOException e) { LOGGER.error("File is not found or not readable: " + fileLocation, e); System.exit(1); } - for (NBEvent entry : entries) { - entry.setSource(NBEvent.OPENAIRE_SOURCE); + for (QAEvent entry : entries) { + entry.setSource(QAEvent.OPENAIRE_SOURCE); if (!StringUtils.equalsAny(entry.getTopic(), topicsToImport)) { - LOGGER.info("Skip event for topic " + entry.getTopic() + " is not allowed in the oaire-nbevents.cfg"); + LOGGER.info("Skip event for topic " + entry.getTopic() + " is not allowed in the oaire-qaevents.cfg"); continue; } try { - nbEventService.store(context, entry); + qaEventService.store(context, entry); } catch (RuntimeException e) { handler.logWarning(getRootCauseMessage(e)); } @@ -142,7 +142,7 @@ public class OpenaireEventsRunnable extends DSpaceRunnable if (options == null) { Options options = new Options(); - options.addOption("f", "file", true, "Import data from OpenAIRE notification broker files"); + options.addOption("f", "file", true, "Import data from OpenAIRE quality assurance broker files"); options.getOption("f").setType(InputStream.class); options.getOption("f").setRequired(true); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityOpenaireMetadataAction.java b/dspace-api/src/main/java/org/dspace/qaevent/QAEntityOpenaireMetadataAction.java similarity index 88% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityOpenaireMetadataAction.java rename to dspace-api/src/main/java/org/dspace/qaevent/QAEntityOpenaireMetadataAction.java index 926160aa48..c272df1cf4 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEntityOpenaireMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAEntityOpenaireMetadataAction.java @@ -5,14 +5,12 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import java.sql.SQLException; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.NBMessageDTO; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Collection; import org.dspace.content.EntityType; @@ -28,16 +26,18 @@ import org.dspace.content.service.RelationshipService; import org.dspace.content.service.RelationshipTypeService; import org.dspace.content.service.WorkspaceItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.dto.OpenaireMessageDTO; +import org.dspace.qaevent.service.dto.QAMessageDTO; import org.springframework.beans.factory.annotation.Autowired; /** - * Implementation of {@link NBAction} that handle the relationship between the + * Implementation of {@link QualityAssuranceAction} that handle the relationship between the * item to correct and a related item. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEntityOpenaireMetadataAction implements NBAction { +public class QAEntityOpenaireMetadataAction implements QualityAssuranceAction { private String relation; private String entityType; private Map entityMetadata; @@ -103,7 +103,7 @@ public class NBEntityOpenaireMetadataAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { + public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) { try { if (relatedItem != null) { link(context, item, relatedItem); @@ -145,18 +145,18 @@ public class NBEntityOpenaireMetadataAction implements NBAction { .filter(r -> StringUtils.equals(r.getRightwardType(), relation)).findFirst() .orElseThrow(() -> new IllegalStateException("No relationshipType named " + relation + " was found for the entity type " + entityType - + ". A proper configuration is required to use the NBEntitiyMetadataAction." + + ". A proper configuration is required to use the QAEntitiyMetadataAction." + " If you don't manage funding in your repository please skip this topic in" - + " the oaire-nbevents.cfg")); + + " the qaevents.cfg")); // Create the relationship - int leftPlace = relationshipService.findNextLeftPlaceByLeftItem(context, item); - int rightPlace = relationshipService.findNextRightPlaceByRightItem(context, relatedItem); - Relationship persistedRelationship = relationshipService.create(context, item, relatedItem, - relType, leftPlace, rightPlace); + Relationship persistedRelationship = relationshipService.create(context); + persistedRelationship.setRelationshipType(relType); + persistedRelationship.setLeftItem(item); + persistedRelationship.setRightItem(relatedItem); relationshipService.update(context, persistedRelationship); } - private String getValue(NBMessageDTO message, String key) { + private String getValue(QAMessageDTO message, String key) { if (!(message instanceof OpenaireMessageDTO)) { return null; } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java b/dspace-api/src/main/java/org/dspace/qaevent/QAEventActionService.java similarity index 60% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java rename to dspace-api/src/main/java/org/dspace/qaevent/QAEventActionService.java index e6a2917384..048e2fe775 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionService.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAEventActionService.java @@ -5,41 +5,41 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.core.Context; /** * Service that handle the actions that can be done related to an - * {@link NBEvent}. + * {@link QAEvent}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public interface NBEventActionService { +public interface QAEventActionService { /** * Accept the given event. * * @param context the DSpace context - * @param nbevent the event to be accepted + * @param qaevent the event to be accepted */ - public void accept(Context context, NBEvent nbevent); + public void accept(Context context, QAEvent qaevent); /** * Discard the given event. * * @param context the DSpace context - * @param nbevent the event to be discarded + * @param qaevent the event to be discarded */ - public void discard(Context context, NBEvent nbevent); + public void discard(Context context, QAEvent qaevent); /** * Reject the given event. * * @param context the DSpace context - * @param nbevent the event to be rejected + * @param qaevent the event to be rejected */ - public void reject(Context context, NBEvent nbevent); + public void reject(Context context, QAEvent qaevent); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/QAEventActionServiceImpl.java similarity index 67% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java rename to dspace-api/src/main/java/org/dspace/qaevent/QAEventActionServiceImpl.java index a14dcf5b22..7bfb940cbb 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventActionServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAEventActionServiceImpl.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import java.io.IOException; import java.sql.SQLException; @@ -24,27 +24,27 @@ import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.logging.log4j.Logger; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.QAEventService; import org.dspace.services.ConfigurationService; import org.springframework.beans.factory.annotation.Autowired; /** - * Implementation of {@link NBEventActionService}. + * Implementation of {@link QAEventActionService}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEventActionServiceImpl implements NBEventActionService { - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(NBEventActionServiceImpl.class); +public class QAEventActionServiceImpl implements QAEventActionService { + private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(QAEventActionServiceImpl.class); private ObjectMapper jsonMapper; @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; @Autowired private ItemService itemService; @@ -52,49 +52,49 @@ public class NBEventActionServiceImpl implements NBEventActionService { @Autowired private ConfigurationService configurationService; - private Map topicsToActions; + private Map topicsToActions; - public void setTopicsToActions(Map topicsToActions) { + public void setTopicsToActions(Map topicsToActions) { this.topicsToActions = topicsToActions; } - public Map getTopicsToActions() { + public Map getTopicsToActions() { return topicsToActions; } - public NBEventActionServiceImpl() { + public QAEventActionServiceImpl() { jsonMapper = new JsonMapper(); jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } @Override - public void accept(Context context, NBEvent nbevent) { + public void accept(Context context, QAEvent qaevent) { Item item = null; Item related = null; try { - item = itemService.find(context, UUID.fromString(nbevent.getTarget())); - if (nbevent.getRelated() != null) { - related = itemService.find(context, UUID.fromString(nbevent.getRelated())); + item = itemService.find(context, UUID.fromString(qaevent.getTarget())); + if (qaevent.getRelated() != null) { + related = itemService.find(context, UUID.fromString(qaevent.getRelated())); } - topicsToActions.get(nbevent.getTopic()).applyCorrection(context, item, related, - jsonMapper.readValue(nbevent.getMessage(), nbevent.getMessageDtoClass())); - nbEventService.deleteEventByEventId(nbevent.getEventId()); - makeAcknowledgement(nbevent.getEventId(), nbevent.getSource(), NBEvent.ACCEPTED); + topicsToActions.get(qaevent.getTopic()).applyCorrection(context, item, related, + jsonMapper.readValue(qaevent.getMessage(), qaevent.getMessageDtoClass())); + qaEventService.deleteEventByEventId(qaevent.getEventId()); + makeAcknowledgement(qaevent.getEventId(), qaevent.getSource(), QAEvent.ACCEPTED); } catch (SQLException | JsonProcessingException e) { throw new RuntimeException(e); } } @Override - public void discard(Context context, NBEvent nbevent) { - nbEventService.deleteEventByEventId(nbevent.getEventId()); - makeAcknowledgement(nbevent.getEventId(), nbevent.getSource(), NBEvent.DISCARDED); + public void discard(Context context, QAEvent qaevent) { + qaEventService.deleteEventByEventId(qaevent.getEventId()); + makeAcknowledgement(qaevent.getEventId(), qaevent.getSource(), QAEvent.DISCARDED); } @Override - public void reject(Context context, NBEvent nbevent) { - nbEventService.deleteEventByEventId(nbevent.getEventId()); - makeAcknowledgement(nbevent.getEventId(), nbevent.getSource(), NBEvent.REJECTED); + public void reject(Context context, QAEvent qaevent) { + qaEventService.deleteEventByEventId(qaevent.getEventId()); + makeAcknowledgement(qaevent.getEventId(), qaevent.getSource(), QAEvent.REJECTED); } /** @@ -102,7 +102,7 @@ public class NBEventActionServiceImpl implements NBEventActionService { */ private void makeAcknowledgement(String eventId, String source, String status) { String[] ackwnoledgeCallbacks = configurationService - .getArrayProperty("nbevents." + source + ".acknowledge-url"); + .getArrayProperty("qaevents." + source + ".acknowledge-url"); if (ackwnoledgeCallbacks != null) { for (String ackwnoledgeCallback : ackwnoledgeCallbacks) { if (StringUtils.isNotBlank(ackwnoledgeCallback)) { diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java b/dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java similarity index 71% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java rename to dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java index 8297599bc5..68976430e6 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBEventsDeleteCascadeConsumer.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java @@ -6,28 +6,28 @@ * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.event.Consumer; import org.dspace.event.Event; +import org.dspace.qaevent.service.QAEventService; import org.dspace.utils.DSpace; /** - * Consumer to delete nbevents once the target item is deleted + * Consumer to delete qaevents once the target item is deleted * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEventsDeleteCascadeConsumer implements Consumer { +public class QAEventsDeleteCascadeConsumer implements Consumer { - private NBEventService nbEventService; + private QAEventService qaEventService; @Override public void initialize() throws Exception { - nbEventService = new DSpace().getSingletonService(NBEventService.class); + qaEventService = new DSpace().getSingletonService(QAEventService.class); } @Override @@ -39,7 +39,7 @@ public class NBEventsDeleteCascadeConsumer implements Consumer { public void consume(Context context, Event event) throws Exception { if (event.getEventType() == Event.DELETE) { if (event.getSubjectType() == Constants.ITEM && event.getSubjectID() != null) { - nbEventService.deleteEventsByTargetId(event.getSubjectID()); + qaEventService.deleteEventsByTargetId(event.getSubjectID()); } } } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java b/dspace-api/src/main/java/org/dspace/qaevent/QAOpenaireMetadataMapAction.java similarity index 87% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java rename to dspace-api/src/main/java/org/dspace/qaevent/QAOpenaireMetadataMapAction.java index 216f44a2d5..038c42bb38 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireMetadataMapAction.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAOpenaireMetadataMapAction.java @@ -5,27 +5,27 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import java.sql.SQLException; import java.util.Map; -import org.dspace.app.nbevent.service.dto.NBMessageDTO; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.dto.OpenaireMessageDTO; +import org.dspace.qaevent.service.dto.QAMessageDTO; import org.springframework.beans.factory.annotation.Autowired; /** - * Implementation of {@link NBAction} that add a specific metadata on the given + * Implementation of {@link QualityAssuranceAction} that add a specific metadata on the given * item based on the OPENAIRE message type. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBOpenaireMetadataMapAction implements NBAction { +public class QAOpenaireMetadataMapAction implements QualityAssuranceAction { public static final String DEFAULT = "default"; private Map types; @@ -49,7 +49,7 @@ public class NBOpenaireMetadataMapAction implements NBAction { * openaire message type. */ @Override - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { + public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) { if (!(message instanceof OpenaireMessageDTO)) { throw new IllegalArgumentException("Unsupported message type: " + message.getClass()); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java b/dspace-api/src/main/java/org/dspace/qaevent/QAOpenaireSimpleMetadataAction.java similarity index 82% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java rename to dspace-api/src/main/java/org/dspace/qaevent/QAOpenaireSimpleMetadataAction.java index f08b3f7db4..6f63c2a64f 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBOpenaireSimpleMetadataAction.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAOpenaireSimpleMetadataAction.java @@ -5,26 +5,26 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import java.sql.SQLException; -import org.dspace.app.nbevent.service.dto.NBMessageDTO; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.dto.OpenaireMessageDTO; +import org.dspace.qaevent.service.dto.QAMessageDTO; import org.springframework.beans.factory.annotation.Autowired; /** - * Implementation of {@link NBAction} that add a simple metadata to the given + * Implementation of {@link QualityAssuranceAction} that add a simple metadata to the given * item. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBOpenaireSimpleMetadataAction implements NBAction { +public class QAOpenaireSimpleMetadataAction implements QualityAssuranceAction { private String metadata; private String metadataSchema; private String metadataElement; @@ -51,7 +51,7 @@ public class NBOpenaireSimpleMetadataAction implements NBAction { } @Override - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message) { + public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message) { try { itemService.addMetadata(context, item, metadataSchema, metadataElement, metadataQualifier, null, ((OpenaireMessageDTO) message).getAbstracts()); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java b/dspace-api/src/main/java/org/dspace/qaevent/QASource.java similarity index 87% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java rename to dspace-api/src/main/java/org/dspace/qaevent/QASource.java index 42a416bf90..b3f7be5f52 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBSource.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QASource.java @@ -5,17 +5,17 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import java.util.Date; /** - * This model class represent the source/provider of the NB events (as OpenAIRE). + * This model class represent the source/provider of the QA events (as OpenAIRE). * * @author Luca Giamminonni (luca.giamminonni at 4Science) * */ -public class NBSource { +public class QASource { private String name; private long totalEvents; private Date lastEvent; diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java b/dspace-api/src/main/java/org/dspace/qaevent/QATopic.java similarity index 87% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java rename to dspace-api/src/main/java/org/dspace/qaevent/QATopic.java index afa9990d3d..1ce09fe45d 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBTopic.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QATopic.java @@ -5,17 +5,17 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; import java.util.Date; /** - * This model class represent the notification broker topic concept + * This model class represent the quality assurance broker topic concept * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBTopic { +public class QATopic { private String key; private long totalEvents; private Date lastEvent; diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java b/dspace-api/src/main/java/org/dspace/qaevent/QualityAssuranceAction.java similarity index 82% rename from dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java rename to dspace-api/src/main/java/org/dspace/qaevent/QualityAssuranceAction.java index 099982d289..f2aebba799 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/NBAction.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QualityAssuranceAction.java @@ -5,11 +5,11 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; -import org.dspace.app.nbevent.service.dto.NBMessageDTO; import org.dspace.content.Item; import org.dspace.core.Context; +import org.dspace.qaevent.service.dto.QAMessageDTO; /** * Interface for classes that perform a correction on the given item. @@ -17,7 +17,7 @@ import org.dspace.core.Context; * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public interface NBAction { +public interface QualityAssuranceAction { /** * Perform a correction on the given item. @@ -27,5 +27,5 @@ public interface NBAction { * @param relatedItem the related item, if any * @param message the message with the correction details */ - public void applyCorrection(Context context, Item item, Item relatedItem, NBMessageDTO message); + public void applyCorrection(Context context, Item item, Item relatedItem, QAMessageDTO message); } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java b/dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDao.java similarity index 86% rename from dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java rename to dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDao.java index db93eb95c5..30a74e55ba 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/NBEventsDao.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDao.java @@ -5,26 +5,26 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent.dao; +package org.dspace.qaevent.dao; import java.sql.SQLException; import java.util.List; import org.dspace.content.Item; -import org.dspace.content.NBEventProcessed; +import org.dspace.content.QAEventProcessed; import org.dspace.core.Context; import org.dspace.eperson.EPerson; /** - * DAO that handle processed NB Events. + * DAO that handle processed QA Events. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public interface NBEventsDao { +public interface QAEventsDao { /** - * Search a page of notification broker events by notification ID. + * Search a page of quality assurance broker events by notification ID. * * @param context the DSpace context * @param eventId the event id @@ -33,7 +33,7 @@ public interface NBEventsDao { * @return the processed events * @throws SQLException if an SQL error occurs */ - public List searchByEventId(Context context, String eventId, Integer start, Integer size) + public List searchByEventId(Context context, String eventId, Integer start, Integer size) throws SQLException; /** diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDaoImpl.java similarity index 62% rename from dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java rename to dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDaoImpl.java index db3977c109..550027441b 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/dao/impl/NBEventsDaoImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDaoImpl.java @@ -5,38 +5,38 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent.dao.impl; +package org.dspace.qaevent.dao.impl; import java.sql.SQLException; import java.util.Date; import java.util.List; import javax.persistence.Query; -import org.dspace.app.nbevent.dao.NBEventsDao; import org.dspace.content.Item; -import org.dspace.content.NBEventProcessed; +import org.dspace.content.QAEventProcessed; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.qaevent.dao.QAEventsDao; /** - * Implementation of {@link NBEventsDao} that store processed events using an + * Implementation of {@link QAEventsDao} that store processed events using an * SQL DBMS. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEventsDaoImpl extends AbstractHibernateDAO implements NBEventsDao { +public class QAEventsDaoImpl extends AbstractHibernateDAO implements QAEventsDao { @Override public boolean storeEvent(Context context, String checksum, EPerson eperson, Item item) { - NBEventProcessed nbEvent = new NBEventProcessed(); - nbEvent.setEperson(eperson); - nbEvent.setEventId(checksum); - nbEvent.setItem(item); - nbEvent.setEventTimestamp(new Date()); + QAEventProcessed qaEvent = new QAEventProcessed(); + qaEvent.setEperson(eperson); + qaEvent.setEventId(checksum); + qaEvent.setItem(item); + qaEvent.setEventTimestamp(new Date()); try { - create(context, nbEvent); + create(context, qaEvent); return true; } catch (SQLException e) { return false; @@ -46,16 +46,16 @@ public class NBEventsDaoImpl extends AbstractHibernateDAO impl @Override public boolean isEventStored(Context context, String checksum) throws SQLException { Query query = createQuery(context, - "SELECT count(eventId) FROM NBEventProcessed nbevent WHERE nbevent.eventId = :event_id "); + "SELECT count(eventId) FROM QAEventProcessed qaevent WHERE qaevent.eventId = :event_id "); query.setParameter("event_id", checksum); return count(query) != 0; } @Override - public List searchByEventId(Context context, String eventId, Integer start, Integer size) + public List searchByEventId(Context context, String eventId, Integer start, Integer size) throws SQLException { Query query = createQuery(context, - "SELECT * " + "FROM NBEventProcessed nbevent WHERE nbevent.nbevent_id = :event_id "); + "SELECT * " + "FROM QAEventProcessed qaevent WHERE qaevent.qaevent_id = :event_id "); query.setFirstResult(start); query.setMaxResults(size); query.setParameter("event_id", eventId); diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java similarity index 82% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java rename to dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java index 599806f425..8e840037de 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/NBEventService.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java @@ -5,23 +5,23 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent.service; +package org.dspace.qaevent.service; import java.util.List; import java.util.UUID; -import org.dspace.app.nbevent.NBSource; -import org.dspace.app.nbevent.NBTopic; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.core.Context; +import org.dspace.qaevent.QASource; +import org.dspace.qaevent.QATopic; /** - * Service that handles {@link NBEvent}. + * Service that handles {@link QAEvent}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public interface NBEventService { +public interface QAEventService { /** * Find all the event's topics. @@ -31,7 +31,7 @@ public interface NBEventService { * @param pageSize the page size * @return the topics list */ - public List findAllTopics(long offset, long pageSize); + public List findAllTopics(long offset, long pageSize); /** * Find all the event's topics related to the given source. @@ -42,7 +42,7 @@ public interface NBEventService { * @param pageSize the page size * @return the topics list */ - public List findAllTopicsBySource(String source, long offset, long count); + public List findAllTopicsBySource(String source, long offset, long count); /** * Count all the event's topics. @@ -71,7 +71,7 @@ public interface NBEventService { * @param ascending true if the order should be ascending, false otherwise * @return the events */ - public List findEventsByTopicAndPage(String topic, long offset, int pageSize, + public List findEventsByTopicAndPage(String topic, long offset, int pageSize, String orderField, boolean ascending); /** @@ -88,7 +88,7 @@ public interface NBEventService { * @param id the id of the event to search for * @return the event */ - public NBEvent findEventByEventId(String id); + public QAEvent findEventByEventId(String id); /** * Store the given event. @@ -96,7 +96,7 @@ public interface NBEventService { * @param context the DSpace context * @param event the event to store */ - public void store(Context context, NBEvent event); + public void store(Context context, QAEvent event); /** * Delete an event by the given id. @@ -118,7 +118,7 @@ public interface NBEventService { * @param topicId the topic id to search for * @return the topic */ - public NBTopic findTopicByTopicId(String topicId); + public QATopic findTopicByTopicId(String topicId); /** * Find a specific source by the given name. @@ -126,7 +126,7 @@ public interface NBEventService { * @param source the source name * @return the source */ - public NBSource findSource(String source); + public QASource findSource(String source); /** * Find all the event's sources. @@ -135,7 +135,7 @@ public interface NBEventService { * @param pageSize the page size * @return the sources list */ - public List findAllSources(long offset, int pageSize); + public List findAllSources(long offset, int pageSize); /** * Count all the event's sources. diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDTO.java b/dspace-api/src/main/java/org/dspace/qaevent/service/dto/OpenaireMessageDTO.java similarity index 95% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDTO.java rename to dspace-api/src/main/java/org/dspace/qaevent/service/dto/OpenaireMessageDTO.java index 5558aa3cb0..117b764ca0 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/OpenaireMessageDTO.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/dto/OpenaireMessageDTO.java @@ -5,17 +5,17 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent.service.dto; +package org.dspace.qaevent.service.dto; import com.fasterxml.jackson.annotation.JsonProperty; /** - * Implementation of {@link NBMessageDTO} that model message coming from OPENAIRE. + * Implementation of {@link QAMessageDTO} that model message coming from OPENAIRE. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class OpenaireMessageDTO implements NBMessageDTO { +public class OpenaireMessageDTO implements QAMessageDTO { @JsonProperty("pids[0].value") private String value; diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessageDTO.java b/dspace-api/src/main/java/org/dspace/qaevent/service/dto/QAMessageDTO.java similarity index 73% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessageDTO.java rename to dspace-api/src/main/java/org/dspace/qaevent/service/dto/QAMessageDTO.java index e341c9bd60..2a63f42e61 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/dto/NBMessageDTO.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/dto/QAMessageDTO.java @@ -5,17 +5,17 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent.service.dto; +package org.dspace.qaevent.service.dto; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; /** - * Interface for classes that contains the details related to a {@link NBEvent}. + * Interface for classes that contains the details related to a {@link QAEvent}. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public interface NBMessageDTO { +public interface QAMessageDTO { } diff --git a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java similarity index 87% rename from dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java rename to dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java index 94e9e32eb6..04a830358c 100644 --- a/dspace-api/src/main/java/org/dspace/app/nbevent/service/impl/NBEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java @@ -5,7 +5,7 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent.service.impl; +package org.dspace.qaevent.service.impl; import static java.util.Comparator.comparing; @@ -33,30 +33,30 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; -import org.dspace.app.nbevent.NBSource; -import org.dspace.app.nbevent.NBTopic; -import org.dspace.app.nbevent.dao.NBEventsDao; -import org.dspace.app.nbevent.dao.impl.NBEventsDaoImpl; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +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.QASource; +import org.dspace.qaevent.QATopic; +import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.dao.impl.QAEventsDaoImpl; +import org.dspace.qaevent.service.QAEventService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.springframework.beans.factory.annotation.Autowired; /** - * Implementation of {@link NBEventService} that use Solr to store events. When + * Implementation of {@link QAEventService} that use Solr to store events. When * the user performs an action on the event (such as accepting the suggestion or * rejecting it) then the event is removed from solr and saved in the database - * (see {@link NBEventsDao}) so that it is no longer proposed. + * (see {@link QAEventsDao}) so that it is no longer proposed. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEventServiceImpl implements NBEventService { +public class QAEventServiceImpl implements QAEventService { @Autowired(required = true) protected ConfigurationService configurationService; @@ -68,11 +68,11 @@ public class NBEventServiceImpl implements NBEventService { private HandleService handleService; @Autowired - private NBEventsDaoImpl nbEventsDao; + private QAEventsDaoImpl qaEventsDao; private ObjectMapper jsonMapper; - public NBEventServiceImpl() { + public QAEventServiceImpl() { jsonMapper = new JsonMapper(); jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } @@ -96,7 +96,7 @@ public class NBEventServiceImpl implements NBEventService { protected SolrClient getSolr() { if (solr == null) { String solrService = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("nbevents.solr.server", "http://localhost:8983/solr/nbevent"); + .getProperty("qaevents.solr.server", "http://localhost:8983/solr/qaevent"); return new HttpSolrClient.Builder(solrService).build(); } return solr; @@ -158,7 +158,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public NBTopic findTopicByTopicId(String topicId) { + public QATopic findTopicByTopicId(String topicId) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); solrQuery.setQuery(TOPIC + ":" + topicId.replaceAll("!", "/")); @@ -171,7 +171,7 @@ public class NBEventServiceImpl implements NBEventService { FacetField facetField = response.getFacetField(TOPIC); for (Count c : facetField.getValues()) { if (c.getName().equals(topicId.replace("!", "/"))) { - NBTopic topic = new NBTopic(); + QATopic topic = new QATopic(); topic.setKey(c.getName()); // topic.setName(OpenstarSupportedTopic.sorlToRest(c.getName())); topic.setTotalEvents(c.getCount()); @@ -186,12 +186,12 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public List findAllTopics(long offset, long count) { + public List findAllTopics(long offset, long count) { return findAllTopicsBySource(null, offset, count); } @Override - public List findAllTopicsBySource(String source, long offset, long count) { + public List findAllTopicsBySource(String source, long offset, long count) { if (source != null && isNotSupportedSource(source)) { return null; @@ -208,33 +208,33 @@ public class NBEventServiceImpl implements NBEventService { solrQuery.addFilterQuery(SOURCE + ":" + source); } QueryResponse response; - List nbTopics = null; + List topics = null; try { response = getSolr().query(solrQuery); FacetField facetField = response.getFacetField(TOPIC); - nbTopics = new ArrayList<>(); + topics = new ArrayList<>(); int idx = 0; for (Count c : facetField.getValues()) { if (idx < offset) { idx++; continue; } - NBTopic topic = new NBTopic(); + QATopic topic = new QATopic(); topic.setKey(c.getName()); // topic.setName(c.getName().replaceAll("/", "!")); topic.setTotalEvents(c.getCount()); topic.setLastEvent(new Date()); - nbTopics.add(topic); + topics.add(topic); idx++; } } catch (SolrServerException | IOException e) { throw new RuntimeException(e); } - return nbTopics; + return topics; } @Override - public void store(Context context, NBEvent dto) { + public void store(Context context, QAEvent dto) { UpdateRequest updateRequest = new UpdateRequest(); String topic = dto.getTopic(); @@ -245,7 +245,7 @@ public class NBEventServiceImpl implements NBEventService { if (topic != null) { String checksum = dto.getEventId(); try { - if (!nbEventsDao.isEventStored(context, checksum)) { + if (!qaEventsDao.isEventStored(context, checksum)) { SolrInputDocument doc = new SolrInputDocument(); doc.addField(SOURCE, dto.getSource()); doc.addField(EVENT_ID, checksum); @@ -273,7 +273,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public NBEvent findEventByEventId(String eventId) { + public QAEvent findEventByEventId(String eventId) { SolrQuery param = new SolrQuery(EVENT_ID + ":" + eventId); QueryResponse response; try { @@ -282,7 +282,7 @@ public class NBEventServiceImpl implements NBEventService { SolrDocumentList list = response.getResults(); if (list != null && list.size() == 1) { SolrDocument doc = list.get(0); - return getNBEventFromSOLR(doc); + return getQAEventFromSOLR(doc); } } } catch (SolrServerException | IOException e) { @@ -291,8 +291,8 @@ public class NBEventServiceImpl implements NBEventService { return null; } - private NBEvent getNBEventFromSOLR(SolrDocument doc) { - NBEvent item = new NBEvent(); + private QAEvent getQAEventFromSOLR(SolrDocument doc) { + QAEvent item = new QAEvent(); item.setSource((String) doc.get(SOURCE)); item.setEventId((String) doc.get(EVENT_ID)); item.setLastUpdate((Date) doc.get(LAST_UPDATE)); @@ -307,7 +307,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public List findEventsByTopicAndPage(String topic, long offset, + public List findEventsByTopicAndPage(String topic, long offset, int pageSize, String orderField, boolean ascending) { SolrQuery solrQuery = new SolrQuery(); solrQuery.setStart(((Long) offset).intValue()); @@ -319,9 +319,9 @@ public class NBEventServiceImpl implements NBEventService { response = getSolr().query(solrQuery); if (response != null) { SolrDocumentList list = response.getResults(); - List responseItem = new ArrayList<>(); + List responseItem = new ArrayList<>(); for (SolrDocument doc : list) { - NBEvent item = getNBEventFromSOLR(doc); + QAEvent item = getQAEventFromSOLR(doc); responseItem.add(item); } return responseItem; @@ -373,7 +373,7 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public NBSource findSource(String sourceName) { + public QASource findSource(String sourceName) { if (isNotSupportedSource(sourceName)) { return null; @@ -392,7 +392,7 @@ public class NBEventServiceImpl implements NBEventService { FacetField facetField = response.getFacetField(SOURCE); for (Count c : facetField.getValues()) { if (c.getName().equalsIgnoreCase(sourceName)) { - NBSource source = new NBSource(); + QASource source = new QASource(); source.setName(c.getName()); source.setTotalEvents(c.getCount()); source.setLastEvent(new Date()); @@ -403,7 +403,7 @@ public class NBEventServiceImpl implements NBEventService { throw new RuntimeException(e); } - NBSource source = new NBSource(); + QASource source = new QASource(); source.setName(sourceName); source.setTotalEvents(0L); @@ -411,10 +411,10 @@ public class NBEventServiceImpl implements NBEventService { } @Override - public List findAllSources(long offset, int pageSize) { + public List findAllSources(long offset, int pageSize) { return Arrays.stream(getSupportedSources()) .map((sourceName) -> findSource(sourceName)) - .sorted(comparing(NBSource::getTotalEvents).reversed()) + .sorted(comparing(QASource::getTotalEvents).reversed()) .skip(offset) .limit(pageSize) .collect(Collectors.toList()); @@ -430,7 +430,7 @@ public class NBEventServiceImpl implements NBEventService { } private String[] getSupportedSources() { - return configurationService.getArrayProperty("nbevent.sources", new String[] { NBEvent.OPENAIRE_SOURCE }); + return configurationService.getArrayProperty("qaevent.sources", new String[] { QAEvent.OPENAIRE_SOURCE }); } } diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__qaevent_processed.sql similarity index 65% rename from dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__nbevent_processed.sql rename to dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__qaevent_processed.sql index b64c52248b..467de85f85 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__nbevent_processed.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.3_2022.02.17__qaevent_processed.sql @@ -6,11 +6,11 @@ -- http://www.dspace.org/license/ -- -CREATE TABLE nbevent_processed ( - nbevent_id VARCHAR(255) NOT NULL, - nbevent_timestamp TIMESTAMP NULL, +CREATE TABLE qaevent_processed ( + qaevent_id VARCHAR(255) NOT NULL, + qaevent_timestamp TIMESTAMP NULL, eperson_uuid UUID NULL REFERENCES eperson(uuid), item_uuid uuid NOT NULL REFERENCES item(uuid) ); -CREATE INDEX item_uuid_idx ON nbevent_processed(item_uuid); +CREATE INDEX item_uuid_idx ON qaevent_processed(item_uuid); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__qaevent_processed.sql similarity index 66% rename from dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__nbevent_processed.sql rename to dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__qaevent_processed.sql index 5cf9a0484f..5c3f0fac73 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__nbevent_processed.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__qaevent_processed.sql @@ -6,14 +6,14 @@ -- http://www.dspace.org/license/ -- -CREATE TABLE nbevent_processed ( - nbevent_id VARCHAR(255) NOT NULL, - nbevent_timestamp TIMESTAMP NULL, +CREATE TABLE qaevent_processed ( + qaevent_id VARCHAR(255) NOT NULL, + qaevent_timestamp TIMESTAMP NULL, eperson_uuid UUID NULL, item_uuid UUID NULL, - CONSTRAINT nbevent_pk PRIMARY KEY (nbevent_id), + CONSTRAINT qaevent_pk PRIMARY KEY (qaevent_id), CONSTRAINT eperson_uuid_fkey FOREIGN KEY (eperson_uuid) REFERENCES eperson (uuid), CONSTRAINT item_uuid_fkey FOREIGN KEY (item_uuid) REFERENCES item (uuid) ); -CREATE INDEX item_uuid_idx ON nbevent_processed(item_uuid); +CREATE INDEX item_uuid_idx ON qaevent_processed(item_uuid); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__nbevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__qaevent_processed.sql similarity index 66% rename from dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__nbevent_processed.sql rename to dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__qaevent_processed.sql index 5cf9a0484f..5c3f0fac73 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V7.3_2022.02.17__nbevent_processed.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.3_2022.02.17__qaevent_processed.sql @@ -6,14 +6,14 @@ -- http://www.dspace.org/license/ -- -CREATE TABLE nbevent_processed ( - nbevent_id VARCHAR(255) NOT NULL, - nbevent_timestamp TIMESTAMP NULL, +CREATE TABLE qaevent_processed ( + qaevent_id VARCHAR(255) NOT NULL, + qaevent_timestamp TIMESTAMP NULL, eperson_uuid UUID NULL, item_uuid UUID NULL, - CONSTRAINT nbevent_pk PRIMARY KEY (nbevent_id), + CONSTRAINT qaevent_pk PRIMARY KEY (qaevent_id), CONSTRAINT eperson_uuid_fkey FOREIGN KEY (eperson_uuid) REFERENCES eperson (uuid), CONSTRAINT item_uuid_fkey FOREIGN KEY (item_uuid) REFERENCES item (uuid) ); -CREATE INDEX item_uuid_idx ON nbevent_processed(item_uuid); +CREATE INDEX item_uuid_idx ON qaevent_processed(item_uuid); diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 328daa72be..39d6a6f6b5 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -84,14 +84,14 @@ loglevel.dspace = INFO # IIIF TEST SETTINGS # ######################## iiif.enabled = true -event.dispatcher.default.consumers = versioning, discovery, eperson, orcidqueue, iiif, nbeventsdelete +event.dispatcher.default.consumers = versioning, discovery, eperson, orcidqueue, iiif, qaeventsdelete ########################################### # CUSTOM UNIT / INTEGRATION TEST SETTINGS # ########################################### # custom dispatcher to be used by dspace-api IT that doesn't need SOLR event.dispatcher.exclude-discovery.class = org.dspace.event.BasicDispatcher -event.dispatcher.exclude-discovery.consumers = versioning, eperson, nbeventsdelete +event.dispatcher.exclude-discovery.consumers = versioning, eperson, qaeventsdelete # Configure authority control for Unit Testing (in DSpaceControlledVocabularyTest) # (This overrides default, commented out settings in dspace.cfg) diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml index b71736c468..29703e3ee0 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/solr-services.xml @@ -48,9 +48,9 @@ class="org.dspace.statistics.MockSolrStatisticsCore" autowire-candidate="true"/> - - + + diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java index 107a1a6c02..8053774ea9 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractBuilder.java @@ -13,7 +13,6 @@ import java.util.List; import org.apache.commons.collections4.CollectionUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.requestitem.factory.RequestItemServiceFactory; import org.dspace.app.requestitem.service.RequestItemService; import org.dspace.authorize.AuthorizeException; @@ -47,6 +46,7 @@ import org.dspace.orcid.factory.OrcidServiceFactory; import org.dspace.orcid.service.OrcidHistoryService; import org.dspace.orcid.service.OrcidQueueService; import org.dspace.orcid.service.OrcidTokenService; +import org.dspace.qaevent.service.QAEventService; import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.service.ProcessService; import org.dspace.services.factory.DSpaceServicesFactory; @@ -104,7 +104,7 @@ public abstract class AbstractBuilder { static OrcidHistoryService orcidHistoryService; static OrcidQueueService orcidQueueService; static OrcidTokenService orcidTokenService; - static NBEventService nbEventService; + static QAEventService qaEventService; protected Context context; @@ -164,7 +164,7 @@ public abstract class AbstractBuilder { orcidHistoryService = OrcidServiceFactory.getInstance().getOrcidHistoryService(); orcidQueueService = OrcidServiceFactory.getInstance().getOrcidQueueService(); orcidTokenService = OrcidServiceFactory.getInstance().getOrcidTokenService(); - nbEventService = new DSpace().getSingletonService(NBEventService.class); + qaEventService = new DSpace().getSingletonService(QAEventService.class); } @@ -198,7 +198,7 @@ public abstract class AbstractBuilder { requestItemService = null; versioningService = null; orcidTokenService = null; - nbEventService = null; + qaEventService = null; } diff --git a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java b/dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java similarity index 58% rename from dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java rename to dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java index 3ad22738c3..154bf737d9 100644 --- a/dspace-api/src/test/java/org/dspace/builder/NBEventBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java @@ -9,22 +9,22 @@ package org.dspace.builder; import java.util.Date; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.content.Collection; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.core.Context; +import org.dspace.qaevent.service.QAEventService; /** - * Builder to construct Notification Broker Event objects + * Builder to construct Quality Assurance Broker Event objects * * @author Andrea Bollini (andrea.bollini at 4science.it) */ -public class NBEventBuilder extends AbstractBuilder { +public class QAEventBuilder extends AbstractBuilder { private Item item; - private NBEvent target; - private String source = NBEvent.OPENAIRE_SOURCE; + private QAEvent target; + private String source = QAEvent.OPENAIRE_SOURCE; private String title; private String topic; private String message; @@ -32,21 +32,21 @@ public class NBEventBuilder extends AbstractBuilder { private double trust = 0.5; private Date lastUpdate = new Date(); - protected NBEventBuilder(Context context) { + protected QAEventBuilder(Context context) { super(context); } - public static NBEventBuilder createTarget(final Context context, final Collection col, final String name) { - NBEventBuilder builder = new NBEventBuilder(context); + public static QAEventBuilder createTarget(final Context context, final Collection col, final String name) { + QAEventBuilder builder = new QAEventBuilder(context); return builder.create(context, col, name); } - public static NBEventBuilder createTarget(final Context context, final Item item) { - NBEventBuilder builder = new NBEventBuilder(context); + public static QAEventBuilder createTarget(final Context context, final Item item) { + QAEventBuilder builder = new QAEventBuilder(context); return builder.create(context, item); } - private NBEventBuilder create(final Context context, final Collection col, final String name) { + private QAEventBuilder create(final Context context, final Collection col, final String name) { this.context = context; try { @@ -61,49 +61,49 @@ public class NBEventBuilder extends AbstractBuilder { return this; } - private NBEventBuilder create(final Context context, final Item item) { + private QAEventBuilder create(final Context context, final Item item) { this.context = context; this.item = item; return this; } - public NBEventBuilder withTopic(final String topic) { + public QAEventBuilder withTopic(final String topic) { this.topic = topic; return this; } - public NBEventBuilder withSource(final String source) { + public QAEventBuilder withSource(final String source) { this.source = source; return this; } - public NBEventBuilder withTitle(final String title) { + public QAEventBuilder withTitle(final String title) { this.title = title; return this; } - public NBEventBuilder withMessage(final String message) { + public QAEventBuilder withMessage(final String message) { this.message = message; return this; } - public NBEventBuilder withTrust(final double trust) { + public QAEventBuilder withTrust(final double trust) { this.trust = trust; return this; } - public NBEventBuilder withLastUpdate(final Date lastUpdate) { + public QAEventBuilder withLastUpdate(final Date lastUpdate) { this.lastUpdate = lastUpdate; return this; } - public NBEventBuilder withRelatedItem(String relatedItem) { + public QAEventBuilder withRelatedItem(String relatedItem) { this.relatedItem = relatedItem; return this; } @Override - public NBEvent build() { - target = new NBEvent(source, "oai:www.dspace.org:" + item.getHandle(), item.getID().toString(), title, topic, + public QAEvent build() { + target = new QAEvent(source, "oai:www.dspace.org:" + item.getHandle(), item.getID().toString(), title, topic, trust, message, lastUpdate); target.setRelated(relatedItem); try { - nbEventService.store(context, target); + qaEventService.store(context, target); } catch (Exception e) { e.printStackTrace(); } @@ -112,18 +112,18 @@ public class NBEventBuilder extends AbstractBuilder { @Override public void cleanup() throws Exception { - nbEventService.deleteEventByEventId(target.getEventId()); + qaEventService.deleteEventByEventId(target.getEventId()); } @Override - protected NBEventService getService() { - return nbEventService; + protected QAEventService getService() { + return qaEventService; } @Override - public void delete(Context c, NBEvent dso) throws Exception { - nbEventService.deleteEventByEventId(target.getEventId()); + public void delete(Context c, QAEvent dso) throws Exception { + qaEventService.deleteEventByEventId(target.getEventId()); -// nbEventService.deleteTarget(dso); +// qaEventService.deleteTarget(dso); } } \ No newline at end of file diff --git a/dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java b/dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java similarity index 76% rename from dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java rename to dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java index 12058fbf73..443e6f8d39 100644 --- a/dspace-api/src/test/java/org/dspace/app/nbevent/MockNBEventService.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java @@ -5,24 +5,24 @@ * * http://www.dspace.org/license/ */ -package org.dspace.app.nbevent; +package org.dspace.qaevent; -import org.dspace.app.nbevent.service.impl.NBEventServiceImpl; +import org.dspace.qaevent.service.impl.QAEventServiceImpl; import org.dspace.solr.MockSolrServer; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; /** - * Mock SOLR service for the nbevents Core. + * Mock SOLR service for the qaevents Core. */ @Service -public class MockNBEventService extends NBEventServiceImpl implements InitializingBean, DisposableBean { +public class MockQAEventService extends QAEventServiceImpl implements InitializingBean, DisposableBean { private MockSolrServer mockSolrServer; @Override public void afterPropertiesSet() throws Exception { - mockSolrServer = new MockSolrServer("nbevent"); + mockSolrServer = new MockSolrServer("qaevent"); solr = mockSolrServer.getSolrServer(); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRestController.java similarity index 75% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRestController.java index 10618288aa..1584c48e65 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/NBEventRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRestController.java @@ -16,19 +16,19 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.exception.UnprocessableEntityException; import org.dspace.app.rest.model.ItemRest; -import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.model.hateoas.ItemResource; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.Utils; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.QAEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.rest.webmvc.ControllerUtils; import org.springframework.data.rest.webmvc.ResourceNotFoundException; @@ -44,13 +44,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** - * This RestController will take care to manipulate the related item eventually associated with a nb event - * "/api/integration/nbevents/{nbeventid}/related" + * This RestController will take care to manipulate the related item eventually associated with a qa event + * "/api/integration/qaevents/{qaeventid}/related" */ @RestController -@RequestMapping("/api/" + NBEventRest.CATEGORY + "/nbevents" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG +@RequestMapping("/api/" + QAEventRest.CATEGORY + "/qaevents" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + "/related") -public class NBEventRestController { +public class QAEventRestController { @Autowired protected Utils utils; @@ -61,15 +61,15 @@ public class NBEventRestController { private ItemService itemService; @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; /** - * This method associate an item to a nb event + * This method associate an item to a qa event * - * @param nbeventId The nb event id + * @param qaeventId The qa event id * @param response The current response * @param request The current request - * @param relatedItemUUID The uuid of the related item to associate with the nb + * @param relatedItemUUID The uuid of the related item to associate with the qa * event * @return The related item * @throws SQLException If something goes wrong @@ -77,26 +77,26 @@ public class NBEventRestController { */ @RequestMapping(method = RequestMethod.POST) @PreAuthorize("hasAuthority('ADMIN')") - public ResponseEntity> postRelatedItem(@PathVariable(name = "id") String nbeventId, + public ResponseEntity> postRelatedItem(@PathVariable(name = "id") String qaeventId, HttpServletResponse response, HttpServletRequest request, @RequestParam(required = true, name = "item") UUID relatedItemUUID) throws SQLException, AuthorizeException { Context context = ContextUtil.obtainContext(request); - NBEvent nbevent = nbEventService.findEventByEventId(nbeventId); - if (nbevent == null) { - throw new ResourceNotFoundException("No such nb event: " + nbeventId); + QAEvent qaevent = qaEventService.findEventByEventId(qaeventId); + if (qaevent == null) { + throw new ResourceNotFoundException("No such qa event: " + qaeventId); } - if (nbevent.getRelated() != null) { - throw new UnprocessableEntityException("The nb event with ID: " + nbeventId + " already has " + + if (qaevent.getRelated() != null) { + throw new UnprocessableEntityException("The qa event with ID: " + qaeventId + " already has " + "a related item"); - } else if (!StringUtils.endsWith(nbevent.getTopic(), "/PROJECT")) { + } else if (!StringUtils.endsWith(qaevent.getTopic(), "/PROJECT")) { return ControllerUtils.toEmptyResponse(HttpStatus.BAD_REQUEST); } Item relatedItem = itemService.find(context, relatedItemUUID); if (relatedItem != null) { - nbevent.setRelated(relatedItemUUID.toString()); - nbEventService.store(context, nbevent); + qaevent.setRelated(relatedItemUUID.toString()); + qaEventService.store(context, qaevent); } else { throw new UnprocessableEntityException("The proposed related item was not found"); } @@ -107,9 +107,9 @@ public class NBEventRestController { } /** - * This method remove the association to a related item from a nb event + * This method remove the association to a related item from a qa event * - * @param nbeventId The nb event id + * @param qaeventId The qa event id * @param response The current response * @param request The current request * @return The related item @@ -118,17 +118,17 @@ public class NBEventRestController { */ @RequestMapping(method = RequestMethod.DELETE) @PreAuthorize("hasAuthority('ADMIN')") - public ResponseEntity> deleteAdminGroup(@PathVariable(name = "id") String nbeventId, + public ResponseEntity> deleteAdminGroup(@PathVariable(name = "id") String qaeventId, HttpServletResponse response, HttpServletRequest request) throws SQLException, AuthorizeException, IOException { Context context = ContextUtil.obtainContext(request); - NBEvent nbevent = nbEventService.findEventByEventId(nbeventId); - if (nbevent == null) { - throw new ResourceNotFoundException("No such nb event: " + nbeventId); + QAEvent qaevent = qaEventService.findEventByEventId(qaeventId); + if (qaevent == null) { + throw new ResourceNotFoundException("No such qa event: " + qaeventId); } - if (nbevent.getRelated() != null) { - nbevent.setRelated(null); - nbEventService.store(context, nbevent); + if (qaevent.getRelated() != null) { + qaevent.setRelated(null); + qaEventService.store(context, qaevent); context.complete(); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QAEventConverter.java similarity index 76% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QAEventConverter.java index 1acbbf51bb..06c83d0d4e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBEventConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QAEventConverter.java @@ -13,36 +13,36 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; -import org.dspace.app.nbevent.service.dto.NBMessageDTO; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; -import org.dspace.app.rest.model.NBEventMessageRest; -import org.dspace.app.rest.model.NBEventRest; -import org.dspace.app.rest.model.OpenaireNBEventMessageRest; +import org.dspace.app.rest.model.OpenaireQAEventMessageRest; +import org.dspace.app.rest.model.QAEventMessageRest; +import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.projection.Projection; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; +import org.dspace.qaevent.service.dto.OpenaireMessageDTO; +import org.dspace.qaevent.service.dto.QAMessageDTO; import org.springframework.stereotype.Component; /** - * Implementation of {@link DSpaceConverter} that converts {@link NBEvent} to - * {@link NBEventRest}. + * Implementation of {@link DSpaceConverter} that converts {@link QAEvent} to + * {@link QAEventRest}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ @Component -public class NBEventConverter implements DSpaceConverter { +public class QAEventConverter implements DSpaceConverter { private ObjectMapper jsonMapper; - public NBEventConverter() { + public QAEventConverter() { super(); jsonMapper = new JsonMapper(); jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } @Override - public NBEventRest convert(NBEvent modelObject, Projection projection) { - NBEventRest rest = new NBEventRest(); + public QAEventRest convert(QAEvent modelObject, Projection projection) { + QAEventRest rest = new QAEventRest(); rest.setId(modelObject.getEventId()); try { rest.setMessage(convertMessage(jsonMapper.readValue(modelObject.getMessage(), @@ -56,15 +56,15 @@ public class NBEventConverter implements DSpaceConverter { rest.setTopic(modelObject.getTopic()); rest.setEventDate(modelObject.getLastUpdate()); rest.setTrust(new DecimalFormat("0.000").format(modelObject.getTrust())); - // right now only the pending status can be found in persisted nb events + // right now only the pending status can be found in persisted qa events rest.setStatus(modelObject.getStatus()); return rest; } - private NBEventMessageRest convertMessage(NBMessageDTO dto) { + private QAEventMessageRest convertMessage(QAMessageDTO dto) { if (dto instanceof OpenaireMessageDTO) { OpenaireMessageDTO openaireDto = (OpenaireMessageDTO) dto; - OpenaireNBEventMessageRest message = new OpenaireNBEventMessageRest(); + OpenaireQAEventMessageRest message = new OpenaireQAEventMessageRest(); message.setAbstractValue(openaireDto.getAbstracts()); message.setOpenaireId(openaireDto.getOpenaireId()); message.setAcronym(openaireDto.getAcronym()); @@ -82,8 +82,8 @@ public class NBEventConverter implements DSpaceConverter { } @Override - public Class getModelClass() { - return NBEvent.class; + public Class getModelClass() { + return QAEvent.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QASourceConverter.java similarity index 66% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QASourceConverter.java index a1b496df04..6c1bc0d66c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBSourceConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QASourceConverter.java @@ -7,29 +7,29 @@ */ package org.dspace.app.rest.converter; -import org.dspace.app.nbevent.NBSource; -import org.dspace.app.rest.model.NBSourceRest; +import org.dspace.app.rest.model.QASourceRest; import org.dspace.app.rest.projection.Projection; +import org.dspace.qaevent.QASource; import org.springframework.stereotype.Component; /** - * Implementation of {@link DSpaceConverter} that converts {@link NBSource} to - * {@link NBSourceRest}. + * Implementation of {@link DSpaceConverter} that converts {@link QASource} to + * {@link QASourceRest}. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ @Component -public class NBSourceConverter implements DSpaceConverter { +public class QASourceConverter implements DSpaceConverter { @Override - public Class getModelClass() { - return NBSource.class; + public Class getModelClass() { + return QASource.class; } @Override - public NBSourceRest convert(NBSource modelObject, Projection projection) { - NBSourceRest rest = new NBSourceRest(); + public QASourceRest convert(QASource modelObject, Projection projection) { + QASourceRest rest = new QASourceRest(); rest.setProjection(projection); rest.setId(modelObject.getName()); rest.setLastEvent(modelObject.getLastEvent()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QATopicConverter.java similarity index 68% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QATopicConverter.java index f9ab34da89..efa32baba2 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/NBTopicConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/QATopicConverter.java @@ -7,29 +7,29 @@ */ package org.dspace.app.rest.converter; -import org.dspace.app.nbevent.NBTopic; -import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.app.rest.model.QATopicRest; import org.dspace.app.rest.projection.Projection; +import org.dspace.qaevent.QATopic; import org.springframework.stereotype.Component; /** - * Implementation of {@link DSpaceConverter} that converts {@link NBTopic} to - * {@link NBTopicRest}. + * Implementation of {@link DSpaceConverter} that converts {@link QATopic} to + * {@link QATopicRest}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ @Component -public class NBTopicConverter implements DSpaceConverter { +public class QATopicConverter implements DSpaceConverter { @Override - public Class getModelClass() { - return NBTopic.class; + public Class getModelClass() { + return QATopic.class; } @Override - public NBTopicRest convert(NBTopic modelObject, Projection projection) { - NBTopicRest rest = new NBTopicRest(); + public QATopicRest convert(QATopic modelObject, Projection projection) { + QATopicRest rest = new QATopicRest(); rest.setProjection(projection); rest.setId(modelObject.getKey().replace("/", "!")); rest.setName(modelObject.getKey()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireQAEventMessageRest.java similarity index 94% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireQAEventMessageRest.java index ca6ee5d06d..c8c4c88909 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireNBEventMessageRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OpenaireQAEventMessageRest.java @@ -10,12 +10,12 @@ package org.dspace.app.rest.model; import com.fasterxml.jackson.annotation.JsonProperty; /** - * Implementation of {@link NBEventMessageRest} related to OPENAIRE events. + * Implementation of {@link QAEventMessageRest} related to OPENAIRE events. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class OpenaireNBEventMessageRest implements NBEventMessageRest { +public class OpenaireQAEventMessageRest implements QAEventMessageRest { // pids private String type; private String value; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventMessageRest.java similarity index 88% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventMessageRest.java index df6187651c..cc460f604c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventMessageRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventMessageRest.java @@ -8,11 +8,11 @@ package org.dspace.app.rest.model; /** - * Interface for classes that model a message with the details of a NB event. + * Interface for classes that model a message with the details of a QA event. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public interface NBEventMessageRest { +public interface QAEventMessageRest { } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java similarity index 90% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java index 0ccc1a55da..e02755d2ec 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBEventRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java @@ -12,7 +12,7 @@ import java.util.Date; import org.dspace.app.rest.RestResourceController; /** - * NB event Rest object. + * QA event Rest object. * * @author Andrea Bollini (andrea.bollini at 4science.it) * @@ -23,10 +23,10 @@ import org.dspace.app.rest.RestResourceController; @LinkRest(name = "target", method = "getTarget"), @LinkRest(name = "related", method = "getRelated") }) -public class NBEventRest extends BaseObjectRest { +public class QAEventRest extends BaseObjectRest { private static final long serialVersionUID = -5001130073350654793L; - public static final String NAME = "nbevent"; + public static final String NAME = "qaevent"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; public static final String TOPIC = "topic"; @@ -38,7 +38,7 @@ public class NBEventRest extends BaseObjectRest { private String topic; private String trust; private Date eventDate; - private NBEventMessageRest message; + private QAEventMessageRest message; private String status; @Override @@ -104,11 +104,11 @@ public class NBEventRest extends BaseObjectRest { this.eventDate = eventDate; } - public NBEventMessageRest getMessage() { + public QAEventMessageRest getMessage() { return message; } - public void setMessage(NBEventMessageRest message) { + public void setMessage(QAEventMessageRest message) { this.message = message; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java similarity index 88% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java index 69e230f378..15c8096e02 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBSourceRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java @@ -12,16 +12,16 @@ import java.util.Date; import org.dspace.app.rest.RestResourceController; /** - * REST Representation of a notification broker source + * REST Representation of a quality assurance broker source * * @author Luca Giamminonni (luca.giamminonni at 4Science) * */ -public class NBSourceRest extends BaseObjectRest { +public class QASourceRest extends BaseObjectRest { private static final long serialVersionUID = -7455358581579629244L; - public static final String NAME = "nbsource"; + public static final String NAME = "qasource"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; private String id; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java similarity index 89% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java index 4bebce27e8..34d5655eb7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/NBTopicRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java @@ -12,16 +12,16 @@ import java.util.Date; import org.dspace.app.rest.RestResourceController; /** - * REST Representation of a notification broker topic + * REST Representation of a quality assurance broker topic * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBTopicRest extends BaseObjectRest { +public class QATopicRest extends BaseObjectRest { private static final long serialVersionUID = -7455358581579629244L; - public static final String NAME = "nbtopic"; + public static final String NAME = "qatopic"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; private String id; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QAEventResource.java similarity index 67% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QAEventResource.java index b052d3d4da..43e1584a25 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBEventResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QAEventResource.java @@ -7,20 +7,20 @@ */ package org.dspace.app.rest.model.hateoas; -import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; /** - * NB event Rest resource. + * QA event Rest resource. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -@RelNameDSpaceResource(NBEventRest.NAME) -public class NBEventResource extends DSpaceResource { +@RelNameDSpaceResource(QAEventRest.NAME) +public class QAEventResource extends DSpaceResource { - public NBEventResource(NBEventRest data, Utils utils) { + public QAEventResource(QAEventRest data, Utils utils) { super(data, utils); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QASourceResource.java similarity index 67% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QASourceResource.java index 55db5d6343..860e16cee3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBSourceResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QASourceResource.java @@ -7,20 +7,20 @@ */ package org.dspace.app.rest.model.hateoas; -import org.dspace.app.rest.model.NBSourceRest; +import org.dspace.app.rest.model.QASourceRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; /** - * NB source Rest resource. + * QA source Rest resource. * * @author Luca Giamminonni (luca.giamminonni at 4Science) * */ -@RelNameDSpaceResource(NBSourceRest.NAME) -public class NBSourceResource extends DSpaceResource { +@RelNameDSpaceResource(QASourceRest.NAME) +public class QASourceResource extends DSpaceResource { - public NBSourceResource(NBSourceRest data, Utils utils) { + public QASourceResource(QASourceRest data, Utils utils) { super(data, utils); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QATopicResource.java similarity index 67% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QATopicResource.java index 78af04a764..139d1e59eb 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/NBTopicResource.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/hateoas/QATopicResource.java @@ -7,20 +7,20 @@ */ package org.dspace.app.rest.model.hateoas; -import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.app.rest.model.QATopicRest; import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource; import org.dspace.app.rest.utils.Utils; /** - * NB topic Rest resource. + * QA topic Rest resource. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -@RelNameDSpaceResource(NBTopicRest.NAME) -public class NBTopicResource extends DSpaceResource { +@RelNameDSpaceResource(QATopicRest.NAME) +public class QATopicResource extends DSpaceResource { - public NBTopicResource(NBTopicRest data, Utils utils) { + public QATopicResource(QATopicRest data, Utils utils) { super(data, utils); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java deleted file mode 100644 index 53b1a4be6c..0000000000 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBTopicRestRepository.java +++ /dev/null @@ -1,75 +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/ - */ -package org.dspace.app.rest.repository; - -import java.util.List; - -import org.dspace.app.nbevent.NBTopic; -import org.dspace.app.nbevent.service.NBEventService; -import org.dspace.app.rest.Parameter; -import org.dspace.app.rest.SearchRestMethod; -import org.dspace.app.rest.model.NBTopicRest; -import org.dspace.core.Context; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Component; - -/** - * Rest repository that handle NB topics. - * - * @author Andrea Bollini (andrea.bollini at 4science.it) - * - */ -@Component(NBTopicRest.CATEGORY + "." + NBTopicRest.NAME) -public class NBTopicRestRepository extends DSpaceRestRepository { - - @Autowired - private NBEventService nbEventService; - - @Override - @PreAuthorize("hasAuthority('ADMIN')") - public NBTopicRest findOne(Context context, String id) { - NBTopic nbTopic = nbEventService.findTopicByTopicId(id); - if (nbTopic == null) { - return null; - } - return converter.toRest(nbTopic, utils.obtainProjection()); - } - - @Override - @PreAuthorize("hasAuthority('ADMIN')") - public Page findAll(Context context, Pageable pageable) { - List nbTopics = nbEventService.findAllTopics(pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countTopics(); - if (nbTopics == null) { - return null; - } - return converter.toRestPage(nbTopics, pageable, count, utils.obtainProjection()); - } - - @SearchRestMethod(name = "bySource") - @PreAuthorize("hasAuthority('ADMIN')") - public Page findBySource(Context context, - @Parameter(value = "source", required = true) String source, Pageable pageable) { - List nbTopics = nbEventService.findAllTopicsBySource(source, - pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countTopicsBySource(source); - if (nbTopics == null) { - return null; - } - return converter.toRestPage(nbTopics, pageable, count, utils.obtainProjection()); - } - - @Override - public Class getDomainClass() { - return NBTopicRest.class; - } - -} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRelatedLinkRepository.java similarity index 72% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRelatedLinkRepository.java index 901d600c10..c711d2ec37 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRelatedLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRelatedLinkRepository.java @@ -12,14 +12,14 @@ import java.util.UUID; import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.model.ItemRest; -import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.projection.Projection; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.QAEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; @@ -27,42 +27,42 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; /** - * Link repository for "related" subresource of a nb event. + * Link repository for "related" subresource of a qa event. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME + "." + NBEventRest.RELATED) -public class NBEventRelatedLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { +@Component(QAEventRest.CATEGORY + "." + QAEventRest.NAME + "." + QAEventRest.RELATED) +public class QAEventRelatedLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; @Autowired private ItemService itemService; /** - * Returns the item related to the nb event with the given id. This is another + * Returns the item related to the qa event with the given id. This is another * item that should be linked to the target item as part of the correction * * @param request the http servlet request - * @param id the nb event id + * @param id the qa event id * @param pageable the optional pageable * @param projection the projection object - * @return the item rest representation of the secondary item related to nb event + * @return the item rest representation of the secondary item related to qa event */ @PreAuthorize("hasAuthority('ADMIN')") public ItemRest getRelated(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, Projection projection) { Context context = obtainContext(); - NBEvent nbEvent = nbEventService.findEventByEventId(id); - if (nbEvent == null) { - throw new ResourceNotFoundException("No nb event with ID: " + id); + QAEvent qaEvent = qaEventService.findEventByEventId(id); + if (qaEvent == null) { + throw new ResourceNotFoundException("No qa event with ID: " + id); } - if (nbEvent.getRelated() == null) { + if (qaEvent.getRelated() == null) { return null; } - UUID itemUuid = UUID.fromString(nbEvent.getRelated()); + UUID itemUuid = UUID.fromString(qaEvent.getRelated()); Item item; try { item = itemService.find(context, itemUuid); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java similarity index 62% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java index f173ebebc9..110ebe0e13 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java @@ -12,21 +12,21 @@ import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.nbevent.dao.NBEventsDao; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.Parameter; import org.dspace.app.rest.SearchRestMethod; import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException; -import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.model.patch.Patch; import org.dspace.app.rest.repository.patch.ResourcePatch; import org.dspace.authorize.AuthorizeException; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; +import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.service.QAEventService; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; @@ -36,21 +36,21 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; /** - * Rest repository that handle NB events. + * Rest repository that handle QA events. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME) -public class NBEventRestRepository extends DSpaceRestRepository { +@Component(QAEventRest.CATEGORY + "." + QAEventRest.NAME) +public class QAEventRestRepository extends DSpaceRestRepository { final static String ORDER_FIELD = "trust"; @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; @Autowired - private NBEventsDao nbEventDao; + private QAEventsDao qaEventDao; @Autowired private ItemService itemService; @@ -59,43 +59,43 @@ public class NBEventRestRepository extends DSpaceRestRepository resourcePatch; + private ResourcePatch resourcePatch; - private Logger log = org.slf4j.LoggerFactory.getLogger(NBEventRestRepository.class); + private Logger log = org.slf4j.LoggerFactory.getLogger(QAEventRestRepository.class); @Override @PreAuthorize("hasAuthority('ADMIN')") - public NBEventRest findOne(Context context, String id) { - NBEvent nbEvent = nbEventService.findEventByEventId(id); - if (nbEvent == null) { + public QAEventRest findOne(Context context, String id) { + QAEvent qaEvent = qaEventService.findEventByEventId(id); + if (qaEvent == null) { // HACK check if this request is part of a patch flow - nbEvent = (NBEvent) requestService.getCurrentRequest().getAttribute("patchedNotificationEvent"); - if (nbEvent != null && nbEvent.getEventId().contentEquals(id)) { - return converter.toRest(nbEvent, utils.obtainProjection()); + qaEvent = (QAEvent) requestService.getCurrentRequest().getAttribute("patchedNotificationEvent"); + if (qaEvent != null && qaEvent.getEventId().contentEquals(id)) { + return converter.toRest(qaEvent, utils.obtainProjection()); } else { return null; } } - return converter.toRest(nbEvent, utils.obtainProjection()); + return converter.toRest(qaEvent, utils.obtainProjection()); } @SearchRestMethod(name = "findByTopic") @PreAuthorize("hasAuthority('ADMIN')") - public Page findByTopic(Context context, @Parameter(value = "topic", required = true) String topic, + public Page findByTopic(Context context, @Parameter(value = "topic", required = true) String topic, Pageable pageable) { - List nbEvents = null; + List qaEvents = null; Long count = 0L; boolean ascending = false; if (pageable.getSort() != null && pageable.getSort().getOrderFor(ORDER_FIELD) != null) { ascending = pageable.getSort().getOrderFor(ORDER_FIELD).getDirection() == Direction.ASC; } - nbEvents = nbEventService.findEventsByTopicAndPage(topic, + qaEvents = qaEventService.findEventsByTopicAndPage(topic, pageable.getOffset(), pageable.getPageSize(), ORDER_FIELD, ascending); - count = nbEventService.countEventsByTopic(topic); - if (nbEvents == null) { + count = qaEventService.countEventsByTopic(topic); + if (qaEvents == null) { return null; } - return converter.toRestPage(nbEvents, pageable, count, utils.obtainProjection()); + return converter.toRestPage(qaEvents, pageable, count, utils.obtainProjection()); } @Override @@ -104,29 +104,29 @@ public class NBEventRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - throw new RepositoryMethodNotImplementedException(NBEventRest.NAME, "findAll"); + public Page findAll(Context context, Pageable pageable) { + throw new RepositoryMethodNotImplementedException(QAEventRest.NAME, "findAll"); } @Override @PreAuthorize("hasAuthority('ADMIN')") protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, String id, Patch patch) throws SQLException, AuthorizeException { - NBEvent nbEvent = nbEventService.findEventByEventId(id); - resourcePatch.patch(context, nbEvent, patch.getOperations()); + QAEvent qaEvent = qaEventService.findEventByEventId(id); + resourcePatch.patch(context, qaEvent, patch.getOperations()); } @Override - public Class getDomainClass() { - return NBEventRest.class; + public Class getDomainClass() { + return QAEventRest.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventTargetLinkRepository.java similarity index 70% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventTargetLinkRepository.java index 76584c4179..2df3836b9b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTargetLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventTargetLinkRepository.java @@ -12,14 +12,14 @@ import java.util.UUID; import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.nbevent.service.NBEventService; import org.dspace.app.rest.model.ItemRest; -import org.dspace.app.rest.model.NBEventRest; +import org.dspace.app.rest.model.QAEventRest; import org.dspace.app.rest.projection.Projection; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; import org.dspace.core.Context; +import org.dspace.qaevent.service.QAEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; @@ -27,38 +27,38 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; /** - * Link repository for "target" subresource of a nb event. + * Link repository for "target" subresource of a qa event. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME + "." + NBEventRest.TARGET) -public class NBEventTargetLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { +@Component(QAEventRest.CATEGORY + "." + QAEventRest.NAME + "." + QAEventRest.TARGET) +public class QAEventTargetLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; @Autowired private ItemService itemService; /** - * Returns the item target of the nb event with the given id. + * Returns the item target of the qa event with the given id. * * @param request the http servlet request - * @param id the nb event id + * @param id the qa event id * @param pageable the optional pageable * @param projection the projection object - * @return the item rest representation of the nb event target + * @return the item rest representation of the qa event target */ @PreAuthorize("hasAuthority('ADMIN')") public ItemRest getTarget(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, Projection projection) { Context context = obtainContext(); - NBEvent nbEvent = nbEventService.findEventByEventId(id); - if (nbEvent == null) { - throw new ResourceNotFoundException("No nb event with ID: " + id); + QAEvent qaEvent = qaEventService.findEventByEventId(id); + if (qaEvent == null) { + throw new ResourceNotFoundException("No qa event with ID: " + id); } - UUID itemUuid = UUID.fromString(nbEvent.getTarget()); + UUID itemUuid = UUID.fromString(qaEvent.getTarget()); Item item; try { item = itemService.find(context, itemUuid); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventTopicLinkRepository.java similarity index 61% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventTopicLinkRepository.java index 9b3ac3fd5c..f9ed484428 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBEventTopicLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventTopicLinkRepository.java @@ -10,13 +10,13 @@ package org.dspace.app.rest.repository; import javax.annotation.Nullable; import javax.servlet.http.HttpServletRequest; -import org.dspace.app.nbevent.NBTopic; -import org.dspace.app.nbevent.service.NBEventService; -import org.dspace.app.rest.model.NBEventRest; -import org.dspace.app.rest.model.NBTopicRest; +import org.dspace.app.rest.model.QAEventRest; +import org.dspace.app.rest.model.QATopicRest; import org.dspace.app.rest.projection.Projection; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.core.Context; +import org.dspace.qaevent.QATopic; +import org.dspace.qaevent.service.QAEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; import org.springframework.data.rest.webmvc.ResourceNotFoundException; @@ -24,35 +24,35 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; /** - * Link repository for "topic" subresource of a nb event. + * Link repository for "topic" subresource of a qa event. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -@Component(NBEventRest.CATEGORY + "." + NBEventRest.NAME + "." + NBEventRest.TOPIC) -public class NBEventTopicLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { +@Component(QAEventRest.CATEGORY + "." + QAEventRest.NAME + "." + QAEventRest.TOPIC) +public class QAEventTopicLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository { @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; /** - * Returns the topic of the nb event with the given id. + * Returns the topic of the qa event with the given id. * * @param request the http servlet request - * @param id the nb event id + * @param id the qa event id * @param pageable the optional pageable * @param projection the projection object - * @return the nb topic rest representation + * @return the qa topic rest representation */ @PreAuthorize("hasAuthority('ADMIN')") - public NBTopicRest getTopic(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, + public QATopicRest getTopic(@Nullable HttpServletRequest request, String id, @Nullable Pageable pageable, Projection projection) { Context context = obtainContext(); - NBEvent nbEvent = nbEventService.findEventByEventId(id); - if (nbEvent == null) { - throw new ResourceNotFoundException("No nb event with ID: " + id); + QAEvent qaEvent = qaEventService.findEventByEventId(id); + if (qaEvent == null) { + throw new ResourceNotFoundException("No qa event with ID: " + id); } - NBTopic topic = nbEventService.findTopicByTopicId(nbEvent.getTopic().replace("/", "!")); + QATopic topic = qaEventService.findTopicByTopicId(qaEvent.getTopic().replace("/", "!")); if (topic == null) { throw new ResourceNotFoundException("No topic found with id : " + id); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QASourceRestRepository.java similarity index 50% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QASourceRestRepository.java index 872aa4d439..dad2310a77 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/NBSourceRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QASourceRestRepository.java @@ -9,10 +9,10 @@ package org.dspace.app.rest.repository; import java.util.List; -import org.dspace.app.nbevent.NBSource; -import org.dspace.app.nbevent.service.NBEventService; -import org.dspace.app.rest.model.NBSourceRest; +import org.dspace.app.rest.model.QASourceRest; import org.dspace.core.Context; +import org.dspace.qaevent.QASource; +import org.dspace.qaevent.service.QAEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -20,39 +20,39 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; /** - * Rest repository that handle NB soufces. + * Rest repository that handle QA sources. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -@Component(NBSourceRest.CATEGORY + "." + NBSourceRest.NAME) -public class NBSourceRestRepository extends DSpaceRestRepository { +@Component(QASourceRest.CATEGORY + "." + QASourceRest.NAME) +public class QASourceRestRepository extends DSpaceRestRepository { @Autowired - private NBEventService nbEventService; + private QAEventService qaEventService; @Override @PreAuthorize("hasAuthority('ADMIN')") - public NBSourceRest findOne(Context context, String id) { - NBSource nbSource = nbEventService.findSource(id); - if (nbSource == null) { + public QASourceRest findOne(Context context, String id) { + QASource qaSource = qaEventService.findSource(id); + if (qaSource == null) { return null; } - return converter.toRest(nbSource, utils.obtainProjection()); + return converter.toRest(qaSource, utils.obtainProjection()); } @Override @PreAuthorize("hasAuthority('ADMIN')") - public Page findAll(Context context, Pageable pageable) { - List nbSources = nbEventService.findAllSources(pageable.getOffset(), pageable.getPageSize()); - long count = nbEventService.countSources(); - return converter.toRestPage(nbSources, pageable, count, utils.obtainProjection()); + public Page findAll(Context context, Pageable pageable) { + List qaSources = qaEventService.findAllSources(pageable.getOffset(), pageable.getPageSize()); + long count = qaEventService.countSources(); + return converter.toRestPage(qaSources, pageable, count, utils.obtainProjection()); } @Override - public Class getDomainClass() { - return NBSourceRest.class; + public Class getDomainClass() { + return QASourceRest.class; } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java new file mode 100644 index 0000000000..a279cac83a --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java @@ -0,0 +1,75 @@ +/** + * 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.app.rest.repository; + +import java.util.List; + +import org.dspace.app.rest.Parameter; +import org.dspace.app.rest.SearchRestMethod; +import org.dspace.app.rest.model.QATopicRest; +import org.dspace.core.Context; +import org.dspace.qaevent.QATopic; +import org.dspace.qaevent.service.QAEventService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Rest repository that handle QA topics. + * + * @author Andrea Bollini (andrea.bollini at 4science.it) + * + */ +@Component(QATopicRest.CATEGORY + "." + QATopicRest.NAME) +public class QATopicRestRepository extends DSpaceRestRepository { + + @Autowired + private QAEventService qaEventService; + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public QATopicRest findOne(Context context, String id) { + QATopic topic = qaEventService.findTopicByTopicId(id); + if (topic == null) { + return null; + } + return converter.toRest(topic, utils.obtainProjection()); + } + + @Override + @PreAuthorize("hasAuthority('ADMIN')") + public Page findAll(Context context, Pageable pageable) { + List topics = qaEventService.findAllTopics(pageable.getOffset(), pageable.getPageSize()); + long count = qaEventService.countTopics(); + if (topics == null) { + return null; + } + return converter.toRestPage(topics, pageable, count, utils.obtainProjection()); + } + + @SearchRestMethod(name = "bySource") + @PreAuthorize("hasAuthority('ADMIN')") + public Page findBySource(Context context, + @Parameter(value = "source", required = true) String source, Pageable pageable) { + List topics = qaEventService.findAllTopicsBySource(source, + pageable.getOffset(), pageable.getPageSize()); + long count = qaEventService.countTopicsBySource(source); + if (topics == null) { + return null; + } + return converter.toRestPage(topics, pageable, count, utils.obtainProjection()); + } + + @Override + public Class getDomainClass() { + return QATopicRest.class; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java similarity index 60% rename from dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java rename to dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java index 55bfe3d2f1..5f58f014ab 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/NBEventStatusReplaceOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java @@ -10,51 +10,51 @@ package org.dspace.app.rest.repository.patch.operation; import java.sql.SQLException; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.NBEventActionService; import org.dspace.app.rest.model.patch.Operation; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.core.Context; +import org.dspace.qaevent.QAEventActionService; import org.dspace.services.RequestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** - * Replace operation related to the {@link NBEvent} status. + * Replace operation related to the {@link QAEvent} status. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ @Component -public class NBEventStatusReplaceOperation extends PatchOperation { +public class QAEventStatusReplaceOperation extends PatchOperation { @Autowired private RequestService requestService; @Autowired - private NBEventActionService nbEventActionService; + private QAEventActionService qaEventActionService; @Override - public NBEvent perform(Context context, NBEvent nbevent, Operation operation) throws SQLException { + public QAEvent perform(Context context, QAEvent qaevent, Operation operation) throws SQLException { String value = (String) operation.getValue(); - if (StringUtils.equalsIgnoreCase(value, NBEvent.ACCEPTED)) { - nbEventActionService.accept(context, nbevent); - } else if (StringUtils.equalsIgnoreCase(value, NBEvent.REJECTED)) { - nbEventActionService.reject(context, nbevent); - } else if (StringUtils.equalsIgnoreCase(value, NBEvent.DISCARDED)) { - nbEventActionService.discard(context, nbevent); + if (StringUtils.equalsIgnoreCase(value, QAEvent.ACCEPTED)) { + qaEventActionService.accept(context, qaevent); + } else if (StringUtils.equalsIgnoreCase(value, QAEvent.REJECTED)) { + qaEventActionService.reject(context, qaevent); + } else if (StringUtils.equalsIgnoreCase(value, QAEvent.DISCARDED)) { + qaEventActionService.discard(context, qaevent); } else { throw new IllegalArgumentException( "The received operation is not valid: " + operation.getPath() + " - " + value); } - nbevent.setStatus(value.toUpperCase()); + qaevent.setStatus(value.toUpperCase()); // HACK, we need to store the temporary object in the request so that a subsequent find would get it - requestService.getCurrentRequest().setAttribute("patchedNotificationEvent", nbevent); - return nbevent; + requestService.getCurrentRequest().setAttribute("patchedNotificationEvent", qaevent); + return qaevent; } @Override public boolean supports(Object objectToMatch, Operation operation) { - return StringUtils.equals(operation.getOp(), "replace") && objectToMatch instanceof NBEvent && StringUtils - .containsAny(operation.getValue().toString().toLowerCase(), NBEvent.ACCEPTED, NBEvent.DISCARDED, - NBEvent.REJECTED); + return StringUtils.equals(operation.getOp(), "replace") && objectToMatch instanceof QAEvent && StringUtils + .containsAny(operation.getValue().toString().toLowerCase(), QAEvent.ACCEPTED, QAEvent.DISCARDED, + QAEvent.REJECTED); } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java similarity index 80% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java index a9f5d29427..5ccbc98d95 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBEventRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java @@ -25,7 +25,7 @@ import java.util.List; import javax.ws.rs.core.MediaType; import org.dspace.app.rest.matcher.ItemMatcher; -import org.dspace.app.rest.matcher.NBEventMatcher; +import org.dspace.app.rest.matcher.QAEventMatcher; import org.dspace.app.rest.model.patch.Operation; import org.dspace.app.rest.model.patch.ReplaceOperation; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; @@ -33,30 +33,30 @@ import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EntityTypeBuilder; import org.dspace.builder.ItemBuilder; -import org.dspace.builder.NBEventBuilder; +import org.dspace.builder.QAEventBuilder; import org.dspace.builder.RelationshipTypeBuilder; import org.dspace.content.Collection; import org.dspace.content.EntityType; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.hamcrest.Matchers; import org.junit.Test; /** - * Integration tests for {@link NBEventRestRepository}. + * Integration tests for {@link QAEventRestRepository}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { +public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { @Test public void findAllNotImplementedTest() throws Exception { String adminToken = getAuthToken(admin.getEmail(), password); - getClient(adminToken).perform(get("/api/integration/nbevents")).andExpect(status().isMethodNotAllowed()); + getClient(adminToken).perform(get("/api/integration/qaevents")).andExpect(status().isMethodNotAllowed()); String epersonToken = getAuthToken(admin.getEmail(), password); - getClient(epersonToken).perform(get("/api/integration/nbevents")).andExpect(status().isMethodNotAllowed()); - getClient().perform(get("/api/integration/nbevents")).andExpect(status().isMethodNotAllowed()); + getClient(epersonToken).perform(get("/api/integration/qaevents")).andExpect(status().isMethodNotAllowed()); + getClient().perform(get("/api/integration/qaevents")).andExpect(status().isMethodNotAllowed()); } @Test @@ -64,18 +64,18 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbevents/" + event1.getEventId())).andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(event1))); - getClient(authToken).perform(get("/api/integration/nbevents/" + event4.getEventId())).andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(event4))); + getClient(authToken).perform(get("/api/integration/qaevents/" + event1.getEventId())).andExpect(status().isOk()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(event1))); + getClient(authToken).perform(get("/api/integration/qaevents/" + event4.getEventId())).andExpect(status().isOk()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(event4))); } @Test @@ -83,10 +83,10 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event5 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + QAEvent event5 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") .withTopic("ENRICH/MISSING/PROJECT") .withMessage( "{\"projects[0].acronym\":\"PAThs\"," @@ -103,13 +103,13 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event1.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event1.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event1))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event1))); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event5.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event5.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event5))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event5))); } @Test @@ -117,11 +117,11 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/nbevents/" + event1.getEventId())) + getClient().perform(get("/api/integration/qaevents/" + event1.getEventId())) .andExpect(status().isUnauthorized()); } @@ -130,12 +130,12 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbevents/" + event1.getEventId())) + getClient(authToken).perform(get("/api/integration/qaevents/" + event1.getEventId())) .andExpect(status().isForbidden()); } @@ -144,34 +144,34 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.nbevents", - Matchers.containsInAnyOrder(NBEventMatcher.matchNBEventEntry(event1), - NBEventMatcher.matchNBEventEntry(event2)))) + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qaevents", + Matchers.containsInAnyOrder(QAEventMatcher.matchQAEventEntry(event1), + QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!ABSTRACT")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(1))) - .andExpect(jsonPath("$._embedded.nbevents", - Matchers.containsInAnyOrder(NBEventMatcher.matchNBEventEntry(event4)))) + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!ABSTRACT")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qaevents", + Matchers.containsInAnyOrder(QAEventMatcher.matchQAEventEntry(event4)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); - getClient(authToken).perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "not-existing")) + getClient(authToken).perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "not-existing")) .andExpect(status().isOk()).andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.totalElements", is(0))); } @@ -181,49 +181,49 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"pmc\",\"pids[0].value\":\"2144303\"}").build(); - NBEvent event5 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + QAEvent event5 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144304\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") .param("size", "2")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.nbevents", + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qaevents", Matchers.containsInAnyOrder( - NBEventMatcher.matchNBEventEntry(event1), - NBEventMatcher.matchNBEventEntry(event2)))) + QAEventMatcher.matchQAEventEntry(event1), + QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.prev.href").doesNotExist()) @@ -232,36 +232,36 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$.page.totalElements", is(5))); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") .param("size", "2").param("page", "1")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.nbevents", + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qaevents", Matchers.containsInAnyOrder( - NBEventMatcher.matchNBEventEntry(event3), - NBEventMatcher.matchNBEventEntry(event4)))) + QAEventMatcher.matchQAEventEntry(event3), + QAEventMatcher.matchQAEventEntry(event4)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) @@ -269,31 +269,31 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$.page.totalElements", is(5))); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") .param("size", "2").param("page", "2")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(1))) - .andExpect(jsonPath("$._embedded.nbevents", + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qaevents", Matchers.containsInAnyOrder( - NBEventMatcher.matchNBEventEntry(event5)))) + QAEventMatcher.matchQAEventEntry(event5)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.next.href").doesNotExist()) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( - Matchers.containsString("/api/integration/nbevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) @@ -307,20 +307,20 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + getClient().perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) .andExpect(status().isUnauthorized()); } @@ -329,22 +329,22 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); String epersonToken = getAuthToken(eperson.getEmail(), password); getClient(epersonToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) .andExpect(status().isForbidden()); } @@ -353,21 +353,21 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent event3 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEvent event3 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEvent event4 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent event4 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); String adminToken = getAuthToken(admin.getEmail(), password); - getClient(adminToken).perform(get("/api/integration/nbevents/search/findByTopic")) + getClient(adminToken).perform(get("/api/integration/qaevents/search/findByTopic")) .andExpect(status().isBadRequest()); } @@ -388,7 +388,7 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withEntityType("Project").build(); Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") .build(); - NBEvent eventProjectBound = NBEventBuilder.createTarget(context, col1, "Science and Freedom with project") + QAEvent eventProjectBound = QAEventBuilder.createTarget(context, col1, "Science and Freedom with project") .withTopic("ENRICH/MISSING/PROJECT") .withMessage( "{\"projects[0].acronym\":\"PAThs\"," @@ -403,7 +403,7 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { + "Dissemination and Storage\"}") .withRelatedItem(funding.getID().toString()) .build(); - NBEvent eventProjectNoBound = NBEventBuilder + QAEvent eventProjectNoBound = QAEventBuilder .createTarget(context, col1, "Science and Freedom with unrelated project") .withTopic("ENRICH/MISSING/PROJECT") .withMessage( @@ -415,36 +415,36 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { + "\"projects[0].openaireId\":\"newProjectID\"," + "\"projects[0].title\":\"A new project\"}") .build(); - NBEvent eventMissingPID1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent eventMissingPID1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent eventMissingPID2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent eventMissingPID2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEvent eventMissingUnknownPID = NBEventBuilder.createTarget(context, col1, "Science and Freedom URN PID") + QAEvent eventMissingUnknownPID = QAEventBuilder.createTarget(context, col1, "Science and Freedom URN PID") .withTopic("ENRICH/MISSING/PID") .withMessage( "{\"pids[0].type\":\"urn\",\"pids[0].value\":\"http://thesis2.sba.units.it/store/handle/item/12937\"}") .build(); - NBEvent eventMorePID = NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEvent eventMorePID = QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"2144302\"}").build(); - NBEvent eventAbstract = NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEvent eventAbstract = QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"An abstract to add...\"}").build(); - NBEvent eventAbstractToDiscard = NBEventBuilder.createTarget(context, col1, "Science and Freedom 7") + QAEvent eventAbstractToDiscard = QAEventBuilder.createTarget(context, col1, "Science and Freedom 7") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Abstract to discard...\"}").build(); context.restoreAuthSystemState(); // prepare the different patches for our decisions List acceptOp = new ArrayList(); - acceptOp.add(new ReplaceOperation("/status", NBEvent.ACCEPTED)); + acceptOp.add(new ReplaceOperation("/status", QAEvent.ACCEPTED)); List acceptOpUppercase = new ArrayList(); - acceptOpUppercase.add(new ReplaceOperation("/status", NBEvent.ACCEPTED)); + acceptOpUppercase.add(new ReplaceOperation("/status", QAEvent.ACCEPTED)); List discardOp = new ArrayList(); - discardOp.add(new ReplaceOperation("/status", NBEvent.DISCARDED)); + discardOp.add(new ReplaceOperation("/status", QAEvent.DISCARDED)); List rejectOp = new ArrayList(); - rejectOp.add(new ReplaceOperation("/status", NBEvent.REJECTED)); + rejectOp.add(new ReplaceOperation("/status", QAEvent.REJECTED)); String patchAccept = getPatchContent(acceptOp); String patchAcceptUppercase = getPatchContent(acceptOpUppercase); String patchDiscard = getPatchContent(discardOp); @@ -452,44 +452,44 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { String authToken = getAuthToken(admin.getEmail(), password); // accept pid1, unknownPID, morePID, the two projects and abstract - eventMissingPID1.setStatus(NBEvent.ACCEPTED); - eventMorePID.setStatus(NBEvent.ACCEPTED); - eventMissingUnknownPID.setStatus(NBEvent.ACCEPTED); - eventMissingUnknownPID.setStatus(NBEvent.ACCEPTED); - eventProjectBound.setStatus(NBEvent.ACCEPTED); - eventProjectNoBound.setStatus(NBEvent.ACCEPTED); - eventAbstract.setStatus(NBEvent.ACCEPTED); + eventMissingPID1.setStatus(QAEvent.ACCEPTED); + eventMorePID.setStatus(QAEvent.ACCEPTED); + eventMissingUnknownPID.setStatus(QAEvent.ACCEPTED); + eventMissingUnknownPID.setStatus(QAEvent.ACCEPTED); + eventProjectBound.setStatus(QAEvent.ACCEPTED); + eventProjectNoBound.setStatus(QAEvent.ACCEPTED); + eventAbstract.setStatus(QAEvent.ACCEPTED); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMissingPID1.getEventId()) + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMissingPID1.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMissingPID1))); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMorePID.getEventId()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMissingPID1))); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMorePID.getEventId()) .content(patchAcceptUppercase) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMorePID))); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMissingUnknownPID.getEventId()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMorePID))); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMissingUnknownPID.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMissingUnknownPID))); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventProjectBound.getEventId()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMissingUnknownPID))); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventProjectBound.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventProjectBound))); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventProjectNoBound.getEventId()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventProjectBound))); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventProjectNoBound.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventProjectNoBound))); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventAbstract.getEventId()) + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventProjectNoBound))); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventAbstract.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventAbstract))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventAbstract))); // check if the item has been updated getClient(authToken).perform(get("/api/core/items/" + eventMissingPID1.getTarget()) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) @@ -524,31 +524,31 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$", hasJsonPath("$.metadata['dc.description.abstract'][0].value", is("An abstract to add...")))); // reject pid2 - eventMissingPID2.setStatus(NBEvent.REJECTED); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventMissingPID2.getEventId()) + eventMissingPID2.setStatus(QAEvent.REJECTED); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMissingPID2.getEventId()) .content(patchReject) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventMissingPID2))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMissingPID2))); getClient(authToken).perform(get("/api/core/items/" + eventMissingPID2.getTarget()) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasNoJsonPath("$.metadata['dc.identifier.other']"))); // discard abstractToDiscard - eventAbstractToDiscard.setStatus(NBEvent.DISCARDED); - getClient(authToken).perform(patch("/api/integration/nbevents/" + eventAbstractToDiscard.getEventId()) + eventAbstractToDiscard.setStatus(QAEvent.DISCARDED); + getClient(authToken).perform(patch("/api/integration/qaevents/" + eventAbstractToDiscard.getEventId()) .content(patchDiscard) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventEntry(eventAbstractToDiscard))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventAbstractToDiscard))); getClient(authToken).perform(get("/api/core/items/" + eventMissingPID2.getTarget()) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasNoJsonPath("$.metadata['dc.description.abstract']"))); - // no pending nb events should be longer available - getClient(authToken).perform(get("/api/integration/nbtopics")).andExpect(status().isOk()) + // no pending qa events should be longer available + getClient(authToken).perform(get("/api/integration/qatopics")).andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(status().isOk()) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(0))); @@ -562,7 +562,7 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) .withName("Collection Fundings").build(); - NBEvent event = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") .withTopic("ENRICH/MISSING/PROJECT") .withMessage( "{\"projects[0].acronym\":\"PAThs\"," @@ -581,23 +581,23 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(post("/api/integration/nbevents/" + event.getEventId() + "/related").param("item", + .perform(post("/api/integration/qaevents/" + event.getEventId() + "/related").param("item", funding.getID().toString())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(funding))); // update our local event copy to reflect the association with the related item event.setRelated(funding.getID().toString()); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId() + "/related")) + .perform(get("/api/integration/qaevents/" + event.getEventId() + "/related")) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(funding))); } @@ -611,7 +611,7 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Collection Fundings").build(); Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") .build(); - NBEvent event = NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") .withTopic("ENRICH/MISSING/PROJECT") .withMessage( "{\"projects[0].acronym\":\"PAThs\"," @@ -629,21 +629,21 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(delete("/api/integration/nbevents/" + event.getEventId() + "/related")) + .perform(delete("/api/integration/qaevents/" + event.getEventId() + "/related")) .andExpect(status().isNoContent()); // update our local event copy to reflect the association with the related item event.setRelated(null); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId() + "/related")) + .perform(get("/api/integration/qaevents/" + event.getEventId() + "/related")) .andExpect(status().isNoContent()); } @@ -654,7 +654,7 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); Collection colFunding = CollectionBuilder.createCollection(context, parentCommunity) .withName("Collection Fundings").build(); - NBEvent event = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); Item funding = ItemBuilder.createItem(context, colFunding).withTitle("Tracking Papyrus and Parchment Paths") @@ -662,19 +662,19 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(post("/api/integration/nbevents/" + event.getEventId() + "/related").param("item", + .perform(post("/api/integration/qaevents/" + event.getEventId() + "/related").param("item", funding.getID().toString())) .andExpect(status().isBadRequest()); // check that no related item has been added to our event getClient(authToken) - .perform(get("/api/integration/nbevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) - .andExpect(jsonPath("$", NBEventMatcher.matchNBEventFullEntry(event))); + .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); } @Test @@ -682,20 +682,20 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.turnOffAuthorisationSystem(); parentCommunity = CommunityBuilder.createCommunity(context).withName("Parent Community").build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEvent event1 = NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEvent event1 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEvent event2 = NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.nbevents", - Matchers.containsInAnyOrder(NBEventMatcher.matchNBEventEntry(event1), - NBEventMatcher.matchNBEventEntry(event2)))) + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qaevents", + Matchers.containsInAnyOrder(QAEventMatcher.matchQAEventEntry(event1), + QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); getClient(authToken).perform(delete("/api/core/items/" + event1.getTarget())) @@ -705,11 +705,11 @@ public class NBEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().is(404)); getClient(authToken) - .perform(get("/api/integration/nbevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.nbevents", Matchers.hasSize(1))) - .andExpect(jsonPath("$._embedded.nbevents", + .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qaevents", Matchers.containsInAnyOrder( - NBEventMatcher.matchNBEventEntry(event2)))) + QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java similarity index 78% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java index 2af54b74da..1fdcd5e0df 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBSourceRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java @@ -7,7 +7,7 @@ */ package org.dspace.app.rest; -import static org.dspace.app.rest.matcher.NBSourceMatcher.matchNBSourceEntry; +import static org.dspace.app.rest.matcher.QASourceMatcher.matchQASourceEntry; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -19,22 +19,22 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; -import org.dspace.builder.NBEventBuilder; +import org.dspace.builder.QAEventBuilder; import org.dspace.content.Collection; import org.dspace.content.Item; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; import org.dspace.services.ConfigurationService; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; /** - * Integration tests for {@link NBSourceRestRepository}. + * Integration tests for {@link QASourceRestRepository}. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest { +public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest { @Autowired private ConfigurationService configurationService; @@ -60,7 +60,7 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); - configurationService.setProperty("nbevent.sources", + configurationService.setProperty("qaevent.sources", new String[] { "openaire", "test-source", "test-source-2" }); } @@ -80,13 +80,13 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbsources")) + getClient(authToken).perform(get("/api/integration/qasources")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbsources", contains( - matchNBSourceEntry("openaire", 3), - matchNBSourceEntry("test-source", 2), - matchNBSourceEntry("test-source-2", 0)))) + .andExpect(jsonPath("$._embedded.qasources", contains( + matchQASourceEntry("openaire", 3), + matchQASourceEntry("test-source", 2), + matchQASourceEntry("test-source-2", 0)))) .andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.totalElements", is(3))); @@ -103,7 +103,7 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); - getClient(token).perform(get("/api/integration/nbsources")) + getClient(token).perform(get("/api/integration/qasources")) .andExpect(status().isForbidden()); } @@ -118,7 +118,7 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/nbsources")) + getClient().perform(get("/api/integration/qasources")) .andExpect(status().isUnauthorized()); } @@ -138,22 +138,22 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbsources/openaire")) + getClient(authToken).perform(get("/api/integration/qasources/openaire")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$", matchNBSourceEntry("openaire", 3))); + .andExpect(jsonPath("$", matchQASourceEntry("openaire", 3))); - getClient(authToken).perform(get("/api/integration/nbsources/test-source")) + getClient(authToken).perform(get("/api/integration/qasources/test-source")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$", matchNBSourceEntry("test-source", 2))); + .andExpect(jsonPath("$", matchQASourceEntry("test-source", 2))); - getClient(authToken).perform(get("/api/integration/nbsources/test-source-2")) + getClient(authToken).perform(get("/api/integration/qasources/test-source-2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$", matchNBSourceEntry("test-source-2", 0))); + .andExpect(jsonPath("$", matchQASourceEntry("test-source-2", 0))); - getClient(authToken).perform(get("/api/integration/nbsources/unknown-test-source")) + getClient(authToken).perform(get("/api/integration/qasources/unknown-test-source")) .andExpect(status().isNotFound()); } @@ -169,7 +169,7 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); - getClient(token).perform(get("/api/integration/nbsources/openaire")) + getClient(token).perform(get("/api/integration/qasources/openaire")) .andExpect(status().isForbidden()); } @@ -184,13 +184,13 @@ public class NBSourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/nbsources/openaire")) + getClient().perform(get("/api/integration/qasources/openaire")) .andExpect(status().isUnauthorized()); } - private NBEvent createEvent(String source, String topic, String title) { - return NBEventBuilder.createTarget(context, target) + private QAEvent createEvent(String source, String topic, String title) { + return QAEventBuilder.createTarget(context, target) .withSource(source) .withTopic(topic) .withTitle(title) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java similarity index 73% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java index 7fe9dbc8b2..d510d713a0 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/NBTopicRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java @@ -13,12 +13,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.dspace.app.rest.matcher.NBTopicMatcher; -import org.dspace.app.rest.repository.NBTopicRestRepository; +import org.dspace.app.rest.matcher.QATopicMatcher; +import org.dspace.app.rest.repository.QATopicRestRepository; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; -import org.dspace.builder.NBEventBuilder; +import org.dspace.builder.QAEventBuilder; import org.dspace.content.Collection; import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; @@ -26,12 +26,12 @@ import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; /** - * Integration tests for {@link NBTopicRestRepository}. + * Integration tests for {@link QATopicRestRepository}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { +public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { @Autowired private ConfigurationService configurationService; @@ -43,41 +43,41 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics")).andExpect(status().isOk()) + getClient(authToken).perform(get("/api/integration/qatopics")).andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbtopics", - Matchers.containsInAnyOrder(NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/PID", 2), - NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/ABSTRACT", 1), - NBTopicMatcher.matchNBTopicEntry("ENRICH/MORE/PID", 1)))) + .andExpect(jsonPath("$._embedded.qatopics", + Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2), + QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1), + QATopicMatcher.matchQATopicEntry("ENRICH/MORE/PID", 1)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3))); } @Test public void findAllUnauthorizedTest() throws Exception { - getClient().perform(get("/api/integration/nbtopics")).andExpect(status().isUnauthorized()); + getClient().perform(get("/api/integration/qatopics")).andExpect(status().isUnauthorized()); } @Test public void findAllForbiddenTest() throws Exception { String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics")).andExpect(status().isForbidden()); + getClient(authToken).perform(get("/api/integration/qatopics")).andExpect(status().isForbidden()); } @Test @@ -88,31 +88,31 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); //create collection Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics").param("size", "2")) + getClient(authToken).perform(get("/api/integration/qatopics").param("size", "2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbtopics", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qatopics", Matchers.hasSize(2))) .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); - getClient(authToken).perform(get("/api/integration/nbtopics").param("size", "2").param("page", "1")) + getClient(authToken).perform(get("/api/integration/qatopics").param("size", "2").param("page", "1")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbtopics", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qatopics", Matchers.hasSize(1))) .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); } @@ -123,26 +123,26 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")) - .andExpect(jsonPath("$", NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/PID", 2))); - getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!ABSTRACT")) - .andExpect(jsonPath("$", NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/ABSTRACT", 1))); + getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!PID")) + .andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2))); + getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!ABSTRACT")) + .andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1))); } @Test @@ -152,11 +152,11 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")).andExpect(status().isUnauthorized()); - getClient().perform(get("/api/integration/nbtopics/ENRICH!MISSING!ABSTRACT")) + getClient().perform(get("/api/integration/qatopics/ENRICH!MISSING!PID")).andExpect(status().isUnauthorized()); + getClient().perform(get("/api/integration/qatopics/ENRICH!MISSING!ABSTRACT")) .andExpect(status().isUnauthorized()); } @@ -167,75 +167,75 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!PID")) + getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!PID")) .andExpect(status().isForbidden()); - getClient(authToken).perform(get("/api/integration/nbtopics/ENRICH!MISSING!ABSTRACT")) + getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!ABSTRACT")) .andExpect(status().isForbidden()); } @Test public void findBySourceTest() throws Exception { context.turnOffAuthorisationSystem(); - configurationService.setProperty("nbevent.sources", + configurationService.setProperty("qaevent.sources", new String[] { "openaire", "test-source", "test-source-2" }); parentCommunity = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 2") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 2") .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144301\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 3") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 3") .withTopic("ENRICH/MORE/PID") .withMessage("{\"pids[0].type\":\"pmid\",\"pids[0].value\":\"10.2307/2144302\"}").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 4") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 4") .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage( "{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}") .build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 5") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 5") .withTopic("TEST/TOPIC") .withSource("test-source") .build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 6") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 6") .withTopic("TEST/TOPIC") .withSource("test-source") .build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom 7") + QAEventBuilder.createTarget(context, col1, "Science and Freedom 7") .withTopic("TEST/TOPIC/2") .withSource("test-source") .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") .param("source", "openaire")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbtopics", - Matchers.containsInAnyOrder(NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/PID", 2), - NBTopicMatcher.matchNBTopicEntry("ENRICH/MISSING/ABSTRACT", 1), - NBTopicMatcher.matchNBTopicEntry("ENRICH/MORE/PID", 1)))) + .andExpect(jsonPath("$._embedded.qatopics", + Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2), + QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1), + QATopicMatcher.matchQATopicEntry("ENRICH/MORE/PID", 1)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3))); - getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") .param("source", "test-source")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbtopics", - Matchers.containsInAnyOrder(NBTopicMatcher.matchNBTopicEntry("TEST/TOPIC/2", 1), - NBTopicMatcher.matchNBTopicEntry("TEST/TOPIC", 2)))) + .andExpect(jsonPath("$._embedded.qatopics", + Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("TEST/TOPIC/2", 1), + QATopicMatcher.matchQATopicEntry("TEST/TOPIC", 2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); - getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") .param("source", "test-source-2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.nbtopics").doesNotExist()) + .andExpect(jsonPath("$._embedded.qatopics").doesNotExist()) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(0))); } @@ -246,10 +246,10 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/nbtopics/search/bySource") + getClient().perform(get("/api/integration/qatopics/search/bySource") .param("source", "openaire")) .andExpect(status().isUnauthorized()); } @@ -261,11 +261,11 @@ public class NBTopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withName("Parent Community") .build(); Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); - NBEventBuilder.createTarget(context, col1, "Science and Freedom") + QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/nbtopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") .param("source", "openaire")) .andExpect(status().isForbidden()); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java similarity index 88% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java index f0a0a12194..ab696aa338 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBEventMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java @@ -18,26 +18,26 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; import org.apache.commons.lang3.StringUtils; -import org.dspace.app.nbevent.service.dto.OpenaireMessageDTO; -import org.dspace.content.NBEvent; +import org.dspace.content.QAEvent; +import org.dspace.qaevent.service.dto.OpenaireMessageDTO; import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.hamcrest.core.IsAnything; /** - * Matcher related to {@link NBEventResource}. + * Matcher related to {@link QAEventResource}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBEventMatcher { +public class QAEventMatcher { - private NBEventMatcher() { + private QAEventMatcher() { } - public static Matcher matchNBEventFullEntry(NBEvent event) { + public static Matcher matchQAEventFullEntry(QAEvent event) { return allOf( - matchNBEventEntry(event), + matchQAEventEntry(event), hasJsonPath("$._embedded.topic.name", is(event.getTopic())), hasJsonPath("$._embedded.target.id", is(event.getTarget())), event.getRelated() != null ? @@ -46,7 +46,7 @@ public class NBEventMatcher { ); } - public static Matcher matchNBEventEntry(NBEvent event) { + public static Matcher matchQAEventEntry(QAEvent event) { try { ObjectMapper jsonMapper = new JsonMapper(); return allOf(hasJsonPath("$.id", is(event.getEventId())), @@ -60,7 +60,7 @@ public class NBEventMatcher { hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")), hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")), hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")), - hasJsonPath("$.type", is("nbevent"))); + hasJsonPath("$.type", is("qaevent"))); } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java similarity index 66% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java index 35031202f0..0340315600 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBSourceMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java @@ -11,31 +11,31 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; -import org.dspace.app.rest.model.hateoas.NBSourceResource; +import org.dspace.app.rest.model.hateoas.QASourceResource; import org.hamcrest.Matcher; /** - * Matcher related to {@link NBSourceResource}. + * Matcher related to {@link QASourceResource}. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class NBSourceMatcher { +public class QASourceMatcher { - private NBSourceMatcher() { } + private QASourceMatcher() { } - public static Matcher matchNBSourceEntry(String key, int totalEvents) { + public static Matcher matchQASourceEntry(String key, int totalEvents) { return allOf( - hasJsonPath("$.type", is("nbsource")), + hasJsonPath("$.type", is("qasource")), hasJsonPath("$.id", is(key)), hasJsonPath("$.totalEvents", is(totalEvents)) ); } - public static Matcher matchNBSourceEntry(String key) { + public static Matcher matchQASourceEntry(String key) { return allOf( - hasJsonPath("$.type", is("nbsource")), + hasJsonPath("$.type", is("qasource")), hasJsonPath("$.id", is(key)) ); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java similarity index 69% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java index 7ad6972b1e..26ef1e92e9 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/NBTopicMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java @@ -11,22 +11,22 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; -import org.dspace.app.rest.model.hateoas.NBTopicResource; +import org.dspace.app.rest.model.hateoas.QATopicResource; import org.hamcrest.Matcher; /** - * Matcher related to {@link NBTopicResource}. + * Matcher related to {@link QATopicResource}. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class NBTopicMatcher { +public class QATopicMatcher { - private NBTopicMatcher() { } + private QATopicMatcher() { } - public static Matcher matchNBTopicEntry(String key, int totalEvents) { + public static Matcher matchQATopicEntry(String key, int totalEvents) { return allOf( - hasJsonPath("$.type", is("nbtopic")), + hasJsonPath("$.type", is("qatopic")), hasJsonPath("$.name", is(key)), hasJsonPath("$.id", is(key.replace("/", "!"))), hasJsonPath("$.totalEvents", is(totalEvents)) @@ -34,9 +34,9 @@ public class NBTopicMatcher { } - public static Matcher matchNBTopicEntry(String key) { + public static Matcher matchQATopicEntry(String key) { return allOf( - hasJsonPath("$.type", is("nbtopic")), + hasJsonPath("$.type", is("qatopic")), hasJsonPath("$.name", is(key)), hasJsonPath("$.id", is(key.replace("/", "/"))) ); diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index c5bb2207bd..b2ff6b0581 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -757,7 +757,7 @@ event.dispatcher.default.class = org.dspace.event.BasicDispatcher # Add rdf here, if you are using dspace-rdf to export your repository content as RDF. # Add iiif here, if you are using dspace-iiif. # Add orcidqueue here, if the integration with ORCID is configured and wish to enable the synchronization queue functionality -event.dispatcher.default.consumers = versioning, discovery, eperson, nbeventsdelete +event.dispatcher.default.consumers = versioning, discovery, eperson, qaeventsdelete # The noindex dispatcher will not create search or browse indexes (useful for batch item imports) event.dispatcher.noindex.class = org.dspace.event.BasicDispatcher @@ -783,9 +783,9 @@ event.consumer.rdf.filters = Community|Collection|Item|Bundle|Bitstream|Site+Add #event.consumer.test.class = org.dspace.event.TestConsumer #event.consumer.test.filters = All+All -# nbevents consumer to delete events related to deleted items -event.consumer.nbeventsdelete.class = org.dspace.app.nbevent.NBEventsDeleteCascadeConsumer -event.consumer.nbeventsdelete.filters = Item+Delete +# qaevents consumer to delete events related to deleted items +event.consumer.qaeventsdelete.class = org.dspace.qaevent.QAEventsDeleteCascadeConsumer +event.consumer.qaeventsdelete.filters = Item+Delete # consumer to maintain versions event.consumer.versioning.class = org.dspace.versioning.VersioningConsumer @@ -1590,7 +1590,7 @@ include = ${module_dir}/irus-statistics.cfg include = ${module_dir}/oai.cfg include = ${module_dir}/openaire-client.cfg include = ${module_dir}/orcid.cfg -include = ${module_dir}/nbevents.cfg +include = ${module_dir}/qaevents.cfg include = ${module_dir}/rdf.cfg include = ${module_dir}/rest.cfg include = ${module_dir}/iiif.cfg diff --git a/dspace/config/hibernate.cfg.xml b/dspace/config/hibernate.cfg.xml index 24d9f04d90..f8b1c2d56d 100644 --- a/dspace/config/hibernate.cfg.xml +++ b/dspace/config/hibernate.cfg.xml @@ -61,7 +61,7 @@ - + diff --git a/dspace/config/modules/nbevents.cfg b/dspace/config/modules/qaevents.cfg similarity index 51% rename from dspace/config/modules/nbevents.cfg rename to dspace/config/modules/qaevents.cfg index d2b5dd12f9..79870b1979 100644 --- a/dspace/config/modules/nbevents.cfg +++ b/dspace/config/modules/qaevents.cfg @@ -1,21 +1,21 @@ #---------------------------------------------------------------# -#-------OAIRE Notification Broker Events CONFIGURATIONS---------# +#------- Quality Assurance Broker Events CONFIGURATIONS --------# #---------------------------------------------------------------# # Configuration properties used by data correction service # #---------------------------------------------------------------# -nbevents.solr.server = ${solr.server}/${solr.multicorePrefix}nbevent -# A POST to these url(s) will be done to notify oaire of decision taken for each nbevents -nbevents.openaire.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events -#nbevents.openaire.acknowledge-url +qaevents.solr.server = ${solr.server}/${solr.multicorePrefix}qaevent +# A POST to these url(s) will be done to notify oaire of decision taken for each qaevents +qaevents.openaire.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events +#qaevents.openaire.acknowledge-url -# The list of the supported events incoming from openaire (see also dspace/config/spring/api/nbevents.xml) +# The list of the supported events incoming from openaire (see also dspace/config/spring/api/qaevents.xml) # add missing abstract suggestion -nbevents.openaire.import.topic = ENRICH/MISSING/ABSTRACT +qaevents.openaire.import.topic = ENRICH/MISSING/ABSTRACT # add missing publication id suggestion -nbevents.openaire.import.topic = ENRICH/MISSING/PID +qaevents.openaire.import.topic = ENRICH/MISSING/PID # add more publication id suggestion -nbevents.openaire.import.topic = ENRICH/MORE/PID +qaevents.openaire.import.topic = ENRICH/MORE/PID # add missing project suggestion -nbevents.openaire.import.topic = ENRICH/MISSING/PROJECT +qaevents.openaire.import.topic = ENRICH/MISSING/PROJECT # add more project suggestion -nbevents.openaire.import.topic = ENRICH/MORE/PROJECT \ No newline at end of file +qaevents.openaire.import.topic = ENRICH/MORE/PROJECT \ No newline at end of file diff --git a/dspace/config/spring/api/nbevents.xml b/dspace/config/spring/api/qaevents.xml similarity index 78% rename from dspace/config/spring/api/nbevents.xml rename to dspace/config/spring/api/qaevents.xml index 90acf62b18..8818b8a9cc 100644 --- a/dspace/config/spring/api/nbevents.xml +++ b/dspace/config/spring/api/qaevents.xml @@ -9,17 +9,13 @@ - - - + - + + org.dspace.qaevent.QAEventAction interface --> @@ -31,14 +27,14 @@ - + - @@ -49,11 +45,11 @@ - + - + - + + diff --git a/dspace/config/spring/rest/scripts.xml b/dspace/config/spring/rest/scripts.xml index e71072314c..93f6b93faf 100644 --- a/dspace/config/spring/rest/scripts.xml +++ b/dspace/config/spring/rest/scripts.xml @@ -8,9 +8,9 @@ - - - + + + diff --git a/dspace/solr/nbevent/conf/protwords.txt b/dspace/solr/qaevent/conf/protwords.txt similarity index 100% rename from dspace/solr/nbevent/conf/protwords.txt rename to dspace/solr/qaevent/conf/protwords.txt diff --git a/dspace/solr/nbevent/conf/schema.xml b/dspace/solr/qaevent/conf/schema.xml similarity index 100% rename from dspace/solr/nbevent/conf/schema.xml rename to dspace/solr/qaevent/conf/schema.xml diff --git a/dspace/solr/nbevent/conf/solrconfig.xml b/dspace/solr/qaevent/conf/solrconfig.xml similarity index 99% rename from dspace/solr/nbevent/conf/solrconfig.xml rename to dspace/solr/qaevent/conf/solrconfig.xml index 0565e56df4..76f17a3ef3 100644 --- a/dspace/solr/nbevent/conf/solrconfig.xml +++ b/dspace/solr/qaevent/conf/solrconfig.xml @@ -17,7 +17,7 @@ --> diff --git a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java index e27fb19a68..6884b949a6 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java +++ b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java @@ -29,6 +29,8 @@ import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.GroupService; import org.dspace.kernel.ServiceManager; +import org.dspace.qaevent.MockQAEventService; +import org.dspace.qaevent.service.QAEventService; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.statistics.MockSolrLoggerServiceImpl; import org.dspace.statistics.MockSolrStatisticsCore; @@ -196,6 +198,10 @@ public class AbstractIntegrationTestWithDatabase extends AbstractDSpaceIntegrati .getServiceByName(AuthoritySearchService.class.getName(), MockAuthoritySolrServiceImpl.class); authorityService.reset(); + MockQAEventService qaEventService = serviceManager + .getServiceByName(QAEventService.class.getName(), MockQAEventService.class); + qaEventService.reset(); + // Reload our ConfigurationService (to reset configs to defaults again) DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); diff --git a/dspace-api/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java b/dspace-api/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java index aced81cbdf..7cc1e8cb45 100644 --- a/dspace-api/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java +++ b/dspace-api/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java @@ -61,6 +61,12 @@ public class TestDSpaceRunnableHandler extends CommandLineDSpaceRunnableHandler errorMessages.add(message); } + @Override + public void logError(String message, Throwable throwable) { + super.logError(message, throwable); + errorMessages.add(message); + } + public List getInfoMessages() { return infoMessages; } diff --git a/dspace-api/src/test/java/org/dspace/matcher/QAEventMatcher.java b/dspace-api/src/test/java/org/dspace/matcher/QAEventMatcher.java new file mode 100644 index 0000000000..1e53bff4f9 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/matcher/QAEventMatcher.java @@ -0,0 +1,104 @@ +/** + * 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.matcher; + +import static org.dspace.content.QAEvent.OPENAIRE_SOURCE; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +import org.dspace.content.Item; +import org.dspace.content.QAEvent; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +/** + * Implementation of {@link org.hamcrest.Matcher} to match a QAEvent by all its + * attributes. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class QAEventMatcher extends TypeSafeMatcher { + + private Matcher eventIdMatcher; + + private Matcher originalIdMatcher; + + private Matcher relatedMatcher; + + private Matcher sourceMatcher; + + private Matcher statusMatcher; + + private Matcher targetMatcher; + + private Matcher titleMatcher; + + private Matcher messageMatcher; + + private Matcher topicMatcher; + + private Matcher trustMatcher; + + private QAEventMatcher(Matcher eventIdMatcher, Matcher originalIdMatcher, + Matcher relatedMatcher, Matcher sourceMatcher, Matcher statusMatcher, + Matcher targetMatcher, Matcher titleMatcher, Matcher messageMatcher, + Matcher topicMatcher, Matcher trustMatcher) { + this.eventIdMatcher = eventIdMatcher; + this.originalIdMatcher = originalIdMatcher; + this.relatedMatcher = relatedMatcher; + this.sourceMatcher = sourceMatcher; + this.statusMatcher = statusMatcher; + this.targetMatcher = targetMatcher; + this.titleMatcher = titleMatcher; + this.messageMatcher = messageMatcher; + this.topicMatcher = topicMatcher; + this.trustMatcher = trustMatcher; + } + + public static QAEventMatcher pendingOpenaireEventWith(String originalId, Item target, + String title, String message, String topic, Double trust) { + + return new QAEventMatcher(notNullValue(String.class), is(originalId), nullValue(String.class), + is(OPENAIRE_SOURCE), is("PENDING"), is(target.getID().toString()), is(title), is(message), is(topic), + is(trust)); + + } + + @Override + public boolean matchesSafely(QAEvent event) { + return eventIdMatcher.matches(event.getEventId()) + && originalIdMatcher.matches(event.getOriginalId()) + && relatedMatcher.matches(event.getRelated()) + && sourceMatcher.matches(event.getSource()) + && statusMatcher.matches(event.getStatus()) + && targetMatcher.matches(event.getTarget()) + && titleMatcher.matches(event.getTitle()) + && messageMatcher.matches(event.getMessage()) + && topicMatcher.matches(event.getTopic()) + && trustMatcher.matches(event.getTrust()); + } + + @Override + public void describeTo(Description description) { + description.appendText("a QA event with the following attributes:") + .appendText(" event id ").appendDescriptionOf(eventIdMatcher) + .appendText(", original id ").appendDescriptionOf(originalIdMatcher) + .appendText(", related ").appendDescriptionOf(relatedMatcher) + .appendText(", source ").appendDescriptionOf(sourceMatcher) + .appendText(", status ").appendDescriptionOf(statusMatcher) + .appendText(", target ").appendDescriptionOf(targetMatcher) + .appendText(", title ").appendDescriptionOf(titleMatcher) + .appendText(", message ").appendDescriptionOf(messageMatcher) + .appendText(", topic ").appendDescriptionOf(topicMatcher) + .appendText(" and trust ").appendDescriptionOf(trustMatcher); + } + +} diff --git a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsRunnableIT.java b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsRunnableIT.java new file mode 100644 index 0000000000..0392efd3b1 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsRunnableIT.java @@ -0,0 +1,247 @@ +/** + * 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.script; + +import static org.dspace.app.matcher.LambdaMatcher.matches; +import static org.dspace.content.QAEvent.OPENAIRE_SOURCE; +import static org.dspace.matcher.QAEventMatcher.pendingOpenaireEventWith; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; + +import java.io.File; +import java.net.URL; +import java.util.List; + +import org.dspace.AbstractIntegrationTestWithDatabase; +import org.dspace.app.launcher.ScriptLauncher; +import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.ItemBuilder; +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.qaevent.QASource; +import org.dspace.qaevent.QATopic; +import org.dspace.qaevent.service.QAEventService; +import org.dspace.utils.DSpace; +import org.junit.Before; +import org.junit.Test; + +/** + * Integration tests for {@link OpenaireEventsRunnable}. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class OpenaireEventsRunnableIT extends AbstractIntegrationTestWithDatabase { + + private static final String BASE_JSON_DIR_PATH = "org/dspace/app/openaire-events/"; + + private QAEventService qaEventService = new DSpace().getSingletonService(QAEventService.class); + + private Collection collection; + + @Before + public void setup() { + + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + collection = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection") + .build(); + + context.restoreAuthSystemState(); + } + + @Test + @SuppressWarnings("unchecked") + public void testManyEventsImport() throws Exception { + + context.turnOffAuthorisationSystem(); + + Item firstItem = ItemBuilder.createItem(context, collection) + .withTitle("Egypt, crossroad of translations and literary interweavings") + .withHandle("123456789/99998") + .build(); + + Item secondItem = ItemBuilder.createItem(context, collection) + .withTitle("Test item") + .withHandle("123456789/99999") + .build(); + + context.restoreAuthSystemState(); + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("events.json") }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), empty()); + assertThat(handler.getWarningMessages(), empty()); + assertThat(handler.getInfoMessages(), contains("Found 2 events to store")); + + List sources = qaEventService.findAllSources(0, 20); + assertThat(sources, hasSize(1)); + + assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); + assertThat(sources.get(0).getTotalEvents(), is(2L)); + + List topics = qaEventService.findAllTopics(0, 20); + assertThat(topics, hasSize(2)); + assertThat(topics, containsInAnyOrder( + matches(topic -> topic.getKey().equals("ENRICH/MORE/PROJECT") && topic.getTotalEvents() == 1L), + matches(topic -> topic.getKey().equals("ENRICH/MISSING/ABSTRACT") && topic.getTotalEvents() == 1L))); + + String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," + + "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths\"}"; + + assertThat(qaEventService.findEventsByTopic("ENRICH/MORE/PROJECT"), contains( + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99998", firstItem, + "Egypt, crossroad of translations and literary interweavings", projectMessage, + "ENRICH/MORE/PROJECT", 1.00d))); + + String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; + + assertThat(qaEventService.findEventsByTopic("ENRICH/MISSING/ABSTRACT"), contains( + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", + abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + + } + + @Test + public void testManyEventsImportWithUnknownHandle() throws Exception { + + context.turnOffAuthorisationSystem(); + + Item item = ItemBuilder.createItem(context, collection) + .withTitle("Test item") + .withHandle("123456789/99999") + .build(); + + context.restoreAuthSystemState(); + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("events.json") }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), empty()); + assertThat(handler.getWarningMessages(), + contains("IllegalArgumentException: Skipped event b4e09c71312cd7c397969f56c900823f" + + " related to the oai record oai:www.openstarts.units.it:123456789/99998 as the record was not found")); + assertThat(handler.getInfoMessages(), contains("Found 2 events to store")); + + List sources = qaEventService.findAllSources(0, 20); + assertThat(sources, hasSize(1)); + + assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); + assertThat(sources.get(0).getTotalEvents(), is(1L)); + + List topics = qaEventService.findAllTopics(0, 20); + assertThat(topics, hasSize(1)); + QATopic topic = topics.get(0); + assertThat(topic.getKey(), is("ENRICH/MISSING/ABSTRACT")); + assertThat(topic.getTotalEvents(), is(1L)); + + String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; + + assertThat(qaEventService.findEventsByTopic("ENRICH/MISSING/ABSTRACT"), contains( + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", item, "Test Publication", + abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + + } + + @Test + public void testManyEventsImportWithUnknownTopic() throws Exception { + + context.turnOffAuthorisationSystem(); + + ItemBuilder.createItem(context, collection) + .withTitle("Egypt, crossroad of translations and literary interweavings") + .withHandle("123456789/99998") + .build(); + + Item secondItem = ItemBuilder.createItem(context, collection) + .withTitle("Test item") + .withHandle("123456789/99999") + .build(); + + context.restoreAuthSystemState(); + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("unknown-topic-events.json") }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), empty()); + assertThat(handler.getWarningMessages(), + contains("Event for topic ENRICH/MORE/UNKNOWN is not allowed in the qaevents.cfg")); + assertThat(handler.getInfoMessages(), contains("Found 2 events to store")); + + List sources = qaEventService.findAllSources(0, 20); + assertThat(sources, hasSize(1)); + + assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); + assertThat(sources.get(0).getTotalEvents(), is(1L)); + + List topics = qaEventService.findAllTopics(0, 20); + assertThat(topics, hasSize(1)); + QATopic topic = topics.get(0); + assertThat(topic.getKey(), is("ENRICH/MISSING/ABSTRACT")); + assertThat(topic.getTotalEvents(), is(1L)); + + String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; + + assertThat(qaEventService.findEventsByTopic("ENRICH/MISSING/ABSTRACT"), contains( + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", + abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + + } + + @Test + public void testWithoutEvents() throws Exception { + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("empty-events.json") }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), + contains(containsString("A not recoverable error occurs during OPENAIRE events import."))); + assertThat(handler.getWarningMessages(),empty()); + assertThat(handler.getInfoMessages(), empty()); + + List sources = qaEventService.findAllSources(0, 20); + assertThat(sources, hasSize(1)); + + assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); + assertThat(sources.get(0).getTotalEvents(), is(0L)); + + assertThat(qaEventService.findAllTopics(0, 20), empty()); + } + + private String getFileLocation(String fileName) throws Exception { + URL resource = getClass().getClassLoader().getResource(BASE_JSON_DIR_PATH + fileName); + if (resource == null) { + throw new IllegalStateException("No resource found named " + BASE_JSON_DIR_PATH + fileName); + } + return new File(resource.getFile()).getAbsolutePath(); + } +} diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json new file mode 100644 index 0000000000..7d8dbd37f1 --- /dev/null +++ b/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json @@ -0,0 +1,29 @@ +[ + + { + "originalId": "oai:www.openstarts.units.it:123456789/99998", + "title": "Egypt, crossroad of translations and literary interweavings", + "topic": "ENRICH/MORE/PROJECT", + "trust": 1.0, + "message": { + "projects[0].acronym": "PAThs", + "projects[0].code": "687567", + "projects[0].funder": "EC", + "projects[0].fundingProgram": "H2020", + "projects[0].jurisdiction": "EU", + "projects[0].openaireId": "40|corda__h2020::6e32f5eb912688f2424c68b851483ea4", + "projects[0].title": "Tracking Papyrus and Parchment Paths" + } + }, + + { + "originalId": "oai:www.openstarts.units.it:123456789/99999", + "title": "Test Publication", + "topic": "ENRICH/MISSING/ABSTRACT", + "trust": 1.0, + "message": { + "abstracts[0]": "Missing Abstract" + } + } + +] \ No newline at end of file diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json new file mode 100644 index 0000000000..d281db450f --- /dev/null +++ b/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json @@ -0,0 +1,20 @@ +[ + + { + "originalId": "oai:www.openstarts.units.it:123456789/99998", + "title": "Egypt, crossroad of translations and literary interweavings (3rd-6th centuries). A reconsideration of earlier Coptic literature", + "topic": "ENRICH/MORE/UNKNOWN", + "trust": 1.0 + }, + + { + "originalId": "oai:www.openstarts.units.it:123456789/99999", + "title": "Test Publication", + "topic": "ENRICH/MISSING/ABSTRACT", + "trust": 1.0, + "message": { + "abstracts[0]": "Missing Abstract" + } + } + +] \ No newline at end of file diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java index 5f58f014ab..5f6ff02acc 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/QAEventStatusReplaceOperation.java @@ -13,7 +13,7 @@ import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.model.patch.Operation; import org.dspace.content.QAEvent; import org.dspace.core.Context; -import org.dspace.qaevent.QAEventActionService; +import org.dspace.qaevent.service.QAEventActionService; import org.dspace.services.RequestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/dspace/config/spring/api/qaevents.xml b/dspace/config/spring/api/qaevents.xml index 8818b8a9cc..c292cb4beb 100644 --- a/dspace/config/spring/api/qaevents.xml +++ b/dspace/config/spring/api/qaevents.xml @@ -11,7 +11,7 @@ - + - + @@ -45,11 +45,11 @@ - + - + - + - + From 6f8e722c030acf4f2950c157a9f6d06538747fc0 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 12 Jul 2022 09:34:44 +0200 Subject: [PATCH 17/38] [CST-5249] Fixed OpenaireEventsRunnable test --- .../test/java/org/dspace/qaevent/MockQAEventService.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java b/dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java index 443e6f8d39..3d460015f7 100644 --- a/dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/MockQAEventService.java @@ -7,6 +7,9 @@ */ package org.dspace.qaevent; +import java.io.IOException; + +import org.apache.solr.client.solrj.SolrServerException; import org.dspace.qaevent.service.impl.QAEventServiceImpl; import org.dspace.solr.MockSolrServer; import org.springframework.beans.factory.DisposableBean; @@ -29,6 +32,11 @@ public class MockQAEventService extends QAEventServiceImpl implements Initializi /** Clear all records from the search core. */ public void reset() { mockSolrServer.reset(); + try { + mockSolrServer.getSolrServer().commit(); + } catch (SolrServerException | IOException e) { + throw new RuntimeException(e); + } } @Override From edb7282b56055add0859862dc692c672f309fde2 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 12 Jul 2022 09:43:14 +0200 Subject: [PATCH 18/38] [CST-5249] Fixed LGTM alerts --- .../java/org/dspace/qaevent/service/QAEventService.java | 6 +----- .../org/dspace/qaevent/service/impl/QAEventServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java index a7519aa7b0..dc3ca914e6 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java @@ -26,7 +26,6 @@ public interface QAEventService { /** * Find all the event's topics. * - * @param context the DSpace context * @param offset the offset to apply * @param pageSize the page size * @return the topics list @@ -36,7 +35,6 @@ public interface QAEventService { /** * Find all the event's topics related to the given source. * - * @param context the DSpace context * @param source the source to search for * @param offset the offset to apply * @param pageSize the page size @@ -47,7 +45,6 @@ public interface QAEventService { /** * Count all the event's topics. * - * @param context the DSpace context * @return the count result */ public long countTopics(); @@ -55,7 +52,6 @@ public interface QAEventService { /** * Count all the event's topics related to the given source. * - * @param context the DSpace context * @param source the source to search for * @return the count result */ @@ -116,7 +112,7 @@ public interface QAEventService { /** * Delete events by the given target id. * - * @param id the id of the target id + * @param targetId the id of the target id */ public void deleteEventsByTargetId(UUID targetId); diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java index d536c8a1e9..bbb6990bb6 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java @@ -429,7 +429,7 @@ public class QAEventServiceImpl implements QAEventService { // oai:www.openstarts.units.it:10077/21486 private String getHandleFromOriginalId(String originalId) { - Integer startPosition = originalId.lastIndexOf(':'); + int startPosition = originalId.lastIndexOf(':'); if (startPosition != -1) { return originalId.substring(startPosition + 1, originalId.length()); } else { From c0e71ba26339d3fb9056b5b74d27e76e449d64ca Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 12 Jul 2022 10:21:31 +0200 Subject: [PATCH 19/38] [CST-5249] Fixed LGTM alerts --- .../java/org/dspace/qaevent/service/QAEventService.java | 8 ++++---- .../dspace/app/rest/repository/QAEventRestRepository.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java index dc3ca914e6..ea923251b8 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java @@ -35,10 +35,10 @@ public interface QAEventService { /** * Find all the event's topics related to the given source. * - * @param source the source to search for - * @param offset the offset to apply - * @param pageSize the page size - * @return the topics list + * @param source the source to search for + * @param offset the offset to apply + * @param count the page size + * @return the topics list */ public List findAllTopicsBySource(String source, long offset, long count); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java index 431c236de7..bd9b31e14c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java @@ -77,7 +77,7 @@ public class QAEventRestRepository extends DSpaceRestRepository findByTopic(Context context, @Parameter(value = "topic", required = true) String topic, Pageable pageable) { List qaEvents = null; - Long count = 0L; + long count = 0L; boolean ascending = false; if (pageable.getSort() != null && pageable.getSort().getOrderFor(ORDER_FIELD) != null) { ascending = pageable.getSort().getOrderFor(ORDER_FIELD).getDirection() == Direction.ASC; From dd46e54b811f31e29b9634e0b1507ae074f896c3 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 12 Jul 2022 12:53:01 +0200 Subject: [PATCH 20/38] [CST-5247] Renamed OpenaireEventsRunnable to OpenaireEventsImport --- dspace-api/pom.xml | 6 ++++++ ...aireEventsRunnable.java => OpenaireEventsImport.java} | 9 +++++---- ...entsRunnableCli.java => OpenaireEventsImportCli.java} | 8 ++++---- ...a => OpenaireEventsImportCliScriptConfiguration.java} | 6 +++--- ...java => OpenaireEventsImportScriptConfiguration.java} | 4 ++-- .../test/data/dspaceFolder/config/spring/api/scripts.xml | 4 ++-- ...EventsRunnableIT.java => OpenaireEventsImportIT.java} | 4 ++-- dspace/config/spring/api/scripts.xml | 4 ++-- dspace/config/spring/rest/scripts.xml | 4 ++-- 9 files changed, 28 insertions(+), 21 deletions(-) rename dspace-api/src/main/java/org/dspace/qaevent/script/{OpenaireEventsRunnable.java => OpenaireEventsImport.java} (94%) rename dspace-api/src/main/java/org/dspace/qaevent/script/{OpenaireEventsRunnableCli.java => OpenaireEventsImportCli.java} (79%) rename dspace-api/src/main/java/org/dspace/qaevent/script/{OpenaireEventsCliScriptConfiguration.java => OpenaireEventsImportCliScriptConfiguration.java} (74%) rename dspace-api/src/main/java/org/dspace/qaevent/script/{OpenaireEventsScriptConfiguration.java => OpenaireEventsImportScriptConfiguration.java} (91%) rename dspace-api/src/test/java/org/dspace/qaevent/script/{OpenaireEventsRunnableIT.java => OpenaireEventsImportIT.java} (98%) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index cf37158fdc..dc67ae8d71 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -877,6 +877,12 @@ funders-model 2.0.0 + + + eu.openaire + broker-client + 1.1.1 + org.mock-server diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsRunnable.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java similarity index 94% rename from dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsRunnable.java rename to dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java index ecc6cef116..d0d21d2e4f 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsRunnable.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java @@ -54,7 +54,8 @@ import org.dspace.utils.DSpace; * @author Alessandro Martelli (alessandro.martelli at 4science.it) * */ -public class OpenaireEventsRunnable extends DSpaceRunnable> { +public class OpenaireEventsImport + extends DSpaceRunnable> { private QAEventService qaEventService; @@ -68,9 +69,9 @@ public class OpenaireEventsRunnable extends DSpaceRunnable - extends OpenaireEventsScriptConfiguration { +public class OpenaireEventsImportCliScriptConfiguration + extends OpenaireEventsImportScriptConfiguration { @Override public Options getOptions() { diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java similarity index 91% rename from dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsScriptConfiguration.java rename to dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java index fc32aa6818..1bf5ea85d8 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java @@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; * @author Alessandro Martelli (alessandro.martelli at 4science.it) * */ -public class OpenaireEventsScriptConfiguration extends ScriptConfiguration { +public class OpenaireEventsImportScriptConfiguration extends ScriptConfiguration { @Autowired private AuthorizeService authorizeService; @@ -37,7 +37,7 @@ public class OpenaireEventsScriptConfiguration /** * Generic setter for the dspaceRunnableClass - * @param dspaceRunnableClass The dspaceRunnableClass to be set on this OpenaireEventsScriptConfiguration + * @param dspaceRunnableClass The dspaceRunnableClass to be set on this OpenaireEventsImportScriptConfiguration */ @Override public void setDspaceRunnableClass(Class dspaceRunnableClass) { diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml index 55b21da4f2..512c34aa26 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml @@ -65,9 +65,9 @@ - + - + diff --git a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsRunnableIT.java b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java similarity index 98% rename from dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsRunnableIT.java rename to dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java index 0392efd3b1..258ede4ef0 100644 --- a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsRunnableIT.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java @@ -38,12 +38,12 @@ import org.junit.Before; import org.junit.Test; /** - * Integration tests for {@link OpenaireEventsRunnable}. + * Integration tests for {@link OpenaireEventsImport}. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class OpenaireEventsRunnableIT extends AbstractIntegrationTestWithDatabase { +public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase { private static final String BASE_JSON_DIR_PATH = "org/dspace/app/openaire-events/"; diff --git a/dspace/config/spring/api/scripts.xml b/dspace/config/spring/api/scripts.xml index 132dd347c8..de4072b44f 100644 --- a/dspace/config/spring/api/scripts.xml +++ b/dspace/config/spring/api/scripts.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - + - + diff --git a/dspace/config/spring/rest/scripts.xml b/dspace/config/spring/rest/scripts.xml index b86427bb8b..39f55fc2f7 100644 --- a/dspace/config/spring/rest/scripts.xml +++ b/dspace/config/spring/rest/scripts.xml @@ -8,9 +8,9 @@ - + - + From ca36903cdee953461327792d4ff7cdde5c61c38b Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 12 Jul 2022 18:17:23 +0200 Subject: [PATCH 21/38] [CST-5247] Added OPENAIRE broker client to directly download events --- .../qaevent/script/OpenaireEventsImport.java | 197 ++++++++-- ...enaireEventsImportScriptConfiguration.java | 10 +- .../qaevent/service/BrokerClientFactory.java | 31 ++ .../service/impl/BrokerClientFactoryImpl.java | 35 ++ .../org/dspace/matcher/QAEventMatcher.java | 13 + .../org/dspace/matcher/QASourceMatcher.java | 58 +++ .../org/dspace/matcher/QATopicMatcher.java | 58 +++ .../script/OpenaireEventsImportIT.java | 370 ++++++++++++++---- .../openaire-events/empty-events-list.json | 1 + .../{empty-events.json => empty-file.json} | 0 .../openaire-events/unknown-topic-events.json | 4 +- dspace/config/modules/qaevents.cfg | 5 +- dspace/config/spring/api/qaevents.xml | 4 + 13 files changed, 671 insertions(+), 115 deletions(-) create mode 100644 dspace-api/src/main/java/org/dspace/qaevent/service/BrokerClientFactory.java create mode 100644 dspace-api/src/main/java/org/dspace/qaevent/service/impl/BrokerClientFactoryImpl.java create mode 100644 dspace-api/src/test/java/org/dspace/matcher/QASourceMatcher.java create mode 100644 dspace-api/src/test/java/org/dspace/matcher/QATopicMatcher.java create mode 100644 dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events-list.json rename dspace-api/src/test/resources/org/dspace/app/openaire-events/{empty-events.json => empty-file.json} (100%) diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java index d0d21d2e4f..e45dc3e159 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java @@ -7,15 +7,24 @@ */ package org.dspace.qaevent.script; -import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCauseMessage; +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.apache.commons.lang3.StringUtils.substringAfter; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import java.sql.SQLException; +import java.util.List; import java.util.UUID; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import eu.dnetlib.broker.BrokerClient; import org.apache.commons.cli.ParseException; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -23,9 +32,11 @@ import org.dspace.content.QAEvent; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; +import org.dspace.qaevent.service.BrokerClientFactory; import org.dspace.qaevent.service.QAEventService; import org.dspace.scripts.DSpaceRunnable; import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.utils.DSpace; /** @@ -52,6 +63,7 @@ import org.dspace.utils.DSpace; * * * @author Alessandro Martelli (alessandro.martelli at 4science.it) + * @author Luca Giamminonni (luca.giamminonni at 4Science.it) * */ public class OpenaireEventsImport @@ -63,8 +75,16 @@ public class OpenaireEventsImport private ConfigurationService configurationService; + private BrokerClient brokerClient; + + private ObjectMapper jsonMapper; + + private URL openaireBrokerURL; + private String fileLocation; + private String email; + private Context context; @Override @@ -77,81 +97,100 @@ public class OpenaireEventsImport @Override public void setup() throws ParseException { - DSpace dspace = new DSpace(); - qaEventService = dspace.getSingletonService(QAEventService.class); - if (qaEventService == null) { - throw new IllegalStateException("qaEventService is NULL. Error in spring configuration"); - } + jsonMapper = new JsonMapper(); + jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - configurationService = dspace.getConfigurationService(); + qaEventService = new DSpace().getSingletonService(QAEventService.class); + configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + brokerClient = BrokerClientFactory.getInstance().getBrokerClient(); topicsToImport = configurationService.getArrayProperty("qaevents.openaire.import.topic"); + openaireBrokerURL = getOpenaireBrokerUri(); fileLocation = commandLine.getOptionValue("f"); + email = commandLine.getOptionValue("e"); } @Override public void internalRun() throws Exception { - if (StringUtils.isEmpty(fileLocation)) { - throw new IllegalArgumentException("No file location was entered"); + if (StringUtils.isAllBlank(fileLocation, email)) { + throw new IllegalArgumentException("One parameter between the location of the file and the email " + + "must be entered to proceed with the import."); + } + + if (StringUtils.isNoneBlank(fileLocation, email)) { + throw new IllegalArgumentException("Only one parameter between the location of the file and the email " + + "must be entered to proceed with the import."); } context = new Context(); assignCurrentUserInContext(); try { - runOpenaireEventsImport(); + importOpenaireEvents(); } catch (Exception ex) { - handler.logError("A not recoverable error occurs during OPENAIRE events import. " - + ExceptionUtils.getRootCauseMessage(ex), ex); + handler.logError("A not recoverable error occurs during OPENAIRE events import: " + getMessage(ex), ex); throw ex; } } /** - * Read the OPENAIRE events from the given JSON file and try to store them. + * Read the OPENAIRE events from the given JSON file or directly from the + * OPENAIRE broker and try to store them. */ - private void runOpenaireEventsImport() { + private void importOpenaireEvents() throws Exception { - QAEvent[] qaEvents = readOpenaireQAEventsFromJsonFile(); - handler.logInfo("Found " + qaEvents.length + " events to store"); - - for (QAEvent event : qaEvents) { - try { - storeOpenaireQAEvent(event); - } catch (RuntimeException e) { - handler.logWarning(getRootCauseMessage(e)); - } + if (StringUtils.isNotBlank(fileLocation)) { + handler.logInfo("Trying to read the QA events from the provided file"); + importOpenaireEventsFromFile(); + } else { + handler.logInfo("Trying to read the QA events from the OPENAIRE broker"); + importOpenaireEventsFromBroker(); } } /** - * Read all the QAEvent present in the given file. - * - * @return the QA events to be imported - * @throws Exception if an oerror occurs during the file reading + * Read the OPENAIRE events from the given file location and try to store them. */ - private QAEvent[] readOpenaireQAEventsFromJsonFile() { - try { + private void importOpenaireEventsFromFile() throws Exception { - ObjectMapper jsonMapper = new JsonMapper(); - jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return jsonMapper.readValue(getQAEventsFileInputStream(), QAEvent[].class); + InputStream eventsFileInputStream = getQAEventsFileInputStream(); + List qaEvents = readOpenaireQAEventsFromJson(eventsFileInputStream); + + handler.logInfo("Found " + qaEvents.size() + " events in the given file"); + + storeOpenaireQAEvents(qaEvents); + + } + + /** + * Import the OPENAIRE events from the Broker using the subscription related to + * the given email and try to store them. + */ + private void importOpenaireEventsFromBroker() { + + List subscriptionIds = listEmailSubscriptions(); + + handler.logInfo("Found " + subscriptionIds.size() + " subscriptions related to the given email"); + + for (String subscriptionId : subscriptionIds) { + + List events = readOpenaireQAEventsFromBroker(subscriptionId); + + handler.logInfo("Found " + events.size() + " events from the subscription " + subscriptionId); + + storeOpenaireQAEvents(events); - } catch (Exception ex) { - throw new IllegalArgumentException("An error occurs parsing the OPENAIRE QA events json", ex); } } /** * Obtain an InputStream from the runnable instance. - * @return - * @throws Exception */ private InputStream getQAEventsFileInputStream() throws Exception { return handler.getFileStream(context, fileLocation) @@ -159,6 +198,50 @@ public class OpenaireEventsImport + "found for filename: " + fileLocation)); } + /** + * Read all the QAEvent from the OPENAIRE Broker related to the subscription + * with the given id. + */ + private List readOpenaireQAEventsFromBroker(String subscriptionId) { + + try { + InputStream eventsInputStream = getEventsBySubscriptions(subscriptionId); + return readOpenaireQAEventsFromJson(eventsInputStream); + } catch (Exception ex) { + handler.logError("An error occurs downloading the events related to the subscription " + + subscriptionId + ": " + getMessage(ex), ex); + } + + return List.of(); + + } + + /** + * Read all the QAEvent present in the given input stream. + * + * @return the QA events to be imported + */ + private List readOpenaireQAEventsFromJson(InputStream inputStream) throws Exception { + return jsonMapper.readValue(inputStream, new TypeReference>() { + }); + } + + /** + * Store the given QAEvents. + * + * @param events the event to be stored + */ + private void storeOpenaireQAEvents(List events) { + for (QAEvent event : events) { + try { + storeOpenaireQAEvent(event); + } catch (RuntimeException e) { + handler.logWarning("An error occurs storing the event with id " + + event.getEventId() + ": " + getMessage(e)); + } + } + } + /** * Store the given QAEvent, skipping it if it is not supported. * @@ -177,6 +260,48 @@ public class OpenaireEventsImport } + /** + * Download the events related to the given subscription from the OPENAIRE broker. + * + * @param subscriptionId the subscription id + * @return an input stream from which to read the events in json format + */ + private InputStream getEventsBySubscriptions(String subscriptionId) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + brokerClient.downloadEvents(openaireBrokerURL, subscriptionId, outputStream); + return new ByteArrayInputStream(outputStream.toByteArray()); + } + + /** + * Takes all the subscription related to the given email from the OPENAIRE + * broker. + */ + private List listEmailSubscriptions() { + try { + return brokerClient.listSubscriptions(openaireBrokerURL, email); + } catch (Exception ex) { + throw new IllegalArgumentException("An error occurs retriving the subscriptions " + + "from the OPENAIRE broker: " + getMessage(ex), ex); + } + } + + private URL getOpenaireBrokerUri() { + try { + return new URL(configurationService.getProperty("qaevents.openaire.broker-url", "http://api.openaire.eu/broker")); + } catch (MalformedURLException e) { + throw new IllegalStateException("The configured OPENAIRE broker URL is not valid.", e); + } + } + + /** + * Get the root exception message from the given exception. + */ + private String getMessage(Exception ex) { + String message = ExceptionUtils.getRootCauseMessage(ex); + // Remove the Exception name from the message + return isNotBlank(message) ? substringAfter(message, ":").trim() : ""; + } + private void assignCurrentUserInContext() throws SQLException { UUID uuid = getEpersonIdentifier(); if (uuid != null) { diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java index 1bf5ea85d8..1a6f94f6a5 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java @@ -58,9 +58,15 @@ public class OpenaireEventsImportScriptConfiguration { this.trustMatcher = trustMatcher; } + /** + * Creates an instance of {@link QAEventMatcher} that matches an OPENAIRE + * QAEvent with PENDING status, with an event id, without a related item and + * with the given attributes. + * + * @param originalId the original id to match + * @param target the target to match + * @param title the title to match + * @param message the message to match + * @param topic the topic to match + * @param trust the trust to match + * @return the matcher istance + */ public static QAEventMatcher pendingOpenaireEventWith(String originalId, Item target, String title, String message, String topic, Double trust) { diff --git a/dspace-api/src/test/java/org/dspace/matcher/QASourceMatcher.java b/dspace-api/src/test/java/org/dspace/matcher/QASourceMatcher.java new file mode 100644 index 0000000000..fe3b7130b5 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/matcher/QASourceMatcher.java @@ -0,0 +1,58 @@ +/** + * 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.matcher; + +import static org.hamcrest.Matchers.is; + +import org.dspace.qaevent.QASource; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +/** + * Implementation of {@link org.hamcrest.Matcher} to match a QASource by all its + * attributes. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class QASourceMatcher extends TypeSafeMatcher { + + private Matcher nameMatcher; + + private Matcher totalEventsMatcher; + + private QASourceMatcher(Matcher nameMatcher, Matcher totalEventsMatcher) { + this.nameMatcher = nameMatcher; + this.totalEventsMatcher = totalEventsMatcher; + } + + /** + * Creates an instance of {@link QASourceMatcher} that matches a QATopic with + * the given name and total events count. + * @param name the name to match + * @param totalEvents the total events count to match + * @return the matcher instance + */ + public static QASourceMatcher with(String name, long totalEvents) { + return new QASourceMatcher(is(name), is(totalEvents)); + } + + @Override + public boolean matchesSafely(QASource event) { + return nameMatcher.matches(event.getName()) && totalEventsMatcher.matches(event.getTotalEvents()); + } + + @Override + public void describeTo(Description description) { + description.appendText("a QA source with the following attributes:") + .appendText(" name ").appendDescriptionOf(nameMatcher) + .appendText(" and total events ").appendDescriptionOf(totalEventsMatcher); + } + +} diff --git a/dspace-api/src/test/java/org/dspace/matcher/QATopicMatcher.java b/dspace-api/src/test/java/org/dspace/matcher/QATopicMatcher.java new file mode 100644 index 0000000000..dd93972814 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/matcher/QATopicMatcher.java @@ -0,0 +1,58 @@ +/** + * 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.matcher; + +import static org.hamcrest.Matchers.is; + +import org.dspace.qaevent.QATopic; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +/** + * Implementation of {@link org.hamcrest.Matcher} to match a QATopic by all its + * attributes. + * + * @author Luca Giamminonni (luca.giamminonni at 4science.it) + * + */ +public class QATopicMatcher extends TypeSafeMatcher { + + private Matcher keyMatcher; + + private Matcher totalEventsMatcher; + + private QATopicMatcher(Matcher keyMatcher, Matcher totalEventsMatcher) { + this.keyMatcher = keyMatcher; + this.totalEventsMatcher = totalEventsMatcher; + } + + /** + * Creates an instance of {@link QATopicMatcher} that matches a QATopic with the + * given key and total events count. + * @param key the key to match + * @param totalEvents the total events count to match + * @return the matcher instance + */ + public static QATopicMatcher with(String key, long totalEvents) { + return new QATopicMatcher(is(key), is(totalEvents)); + } + + @Override + public boolean matchesSafely(QATopic event) { + return keyMatcher.matches(event.getKey()) && totalEventsMatcher.matches(event.getTotalEvents()); + } + + @Override + public void describeTo(Description description) { + description.appendText("a QA topic with the following attributes:") + .appendText(" key ").appendDescriptionOf(keyMatcher) + .appendText(" and total events ").appendDescriptionOf(totalEventsMatcher); + } + +} diff --git a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java index 258ede4ef0..22da785d31 100644 --- a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java @@ -7,7 +7,7 @@ */ package org.dspace.qaevent.script; -import static org.dspace.app.matcher.LambdaMatcher.matches; +import static java.util.List.of; import static org.dspace.content.QAEvent.OPENAIRE_SOURCE; import static org.dspace.matcher.QAEventMatcher.pendingOpenaireEventWith; import static org.hamcrest.MatcherAssert.assertThat; @@ -16,12 +16,25 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; import java.io.File; +import java.io.FileInputStream; +import java.io.OutputStream; import java.net.URL; -import java.util.List; +import eu.dnetlib.broker.BrokerClient; +import org.apache.commons.io.IOUtils; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.app.launcher.ScriptLauncher; import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; @@ -30,10 +43,13 @@ import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Item; -import org.dspace.qaevent.QASource; -import org.dspace.qaevent.QATopic; +import org.dspace.matcher.QASourceMatcher; +import org.dspace.matcher.QATopicMatcher; +import org.dspace.qaevent.service.BrokerClientFactory; import org.dspace.qaevent.service.QAEventService; +import org.dspace.qaevent.service.impl.BrokerClientFactoryImpl; import org.dspace.utils.DSpace; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -51,6 +67,10 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase private Collection collection; + private BrokerClient brokerClient = BrokerClientFactory.getInstance().getBrokerClient(); + + private BrokerClient mockBrokerClient = mock(BrokerClient.class); + @Before public void setup() { @@ -65,23 +85,62 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase .build(); context.restoreAuthSystemState(); + + ((BrokerClientFactoryImpl) BrokerClientFactory.getInstance()).setBrokerClient(mockBrokerClient); + } + + @After + public void after() { + ((BrokerClientFactoryImpl) BrokerClientFactory.getInstance()).setBrokerClient(brokerClient); + } + + @Test + public void testWithoutParameters() throws Exception { + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events" }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), empty()); + assertThat(handler.getWarningMessages(), empty()); + assertThat(handler.getInfoMessages(), empty()); + + Exception exception = handler.getException(); + assertThat(exception, instanceOf(IllegalArgumentException.class)); + assertThat(exception.getMessage(), is("One parameter between the location of the file and the email " + + "must be entered to proceed with the import.")); + + verifyNoInteractions(mockBrokerClient); + } + + @Test + public void testWithBothFileAndEmailParameters() throws Exception { + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("events.json"), + "-e", "test@user.com" }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), empty()); + assertThat(handler.getWarningMessages(), empty()); + assertThat(handler.getInfoMessages(), empty()); + + Exception exception = handler.getException(); + assertThat(exception, instanceOf(IllegalArgumentException.class)); + assertThat(exception.getMessage(), is("Only one parameter between the location of the file and the email " + + "must be entered to proceed with the import.")); + + verifyNoInteractions(mockBrokerClient); } @Test @SuppressWarnings("unchecked") - public void testManyEventsImport() throws Exception { + public void testManyEventsImportFromFile() throws Exception { context.turnOffAuthorisationSystem(); - Item firstItem = ItemBuilder.createItem(context, collection) - .withTitle("Egypt, crossroad of translations and literary interweavings") - .withHandle("123456789/99998") - .build(); - - Item secondItem = ItemBuilder.createItem(context, collection) - .withTitle("Test item") - .withHandle("123456789/99999") - .build(); + Item firstItem = createItem("Test item", "123456789/99998"); + Item secondItem = createItem("Test item 2", "123456789/99999"); context.restoreAuthSystemState(); @@ -92,19 +151,15 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getErrorMessages(), empty()); assertThat(handler.getWarningMessages(), empty()); - assertThat(handler.getInfoMessages(), contains("Found 2 events to store")); + assertThat(handler.getInfoMessages(), contains( + "Trying to read the QA events from the provided file", + "Found 2 events in the given file")); - List sources = qaEventService.findAllSources(0, 20); - assertThat(sources, hasSize(1)); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 2L))); - assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); - assertThat(sources.get(0).getTotalEvents(), is(2L)); - - List topics = qaEventService.findAllTopics(0, 20); - assertThat(topics, hasSize(2)); - assertThat(topics, containsInAnyOrder( - matches(topic -> topic.getKey().equals("ENRICH/MORE/PROJECT") && topic.getTotalEvents() == 1L), - matches(topic -> topic.getKey().equals("ENRICH/MISSING/ABSTRACT") && topic.getTotalEvents() == 1L))); + assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," + "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\"," @@ -123,17 +178,16 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + verifyNoInteractions(mockBrokerClient); + } @Test - public void testManyEventsImportWithUnknownHandle() throws Exception { + public void testManyEventsImportFromFileWithUnknownHandle() throws Exception { context.turnOffAuthorisationSystem(); - Item item = ItemBuilder.createItem(context, collection) - .withTitle("Test item") - .withHandle("123456789/99999") - .build(); + Item item = createItem("Test item", "123456789/99999"); context.restoreAuthSystemState(); @@ -144,21 +198,16 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getErrorMessages(), empty()); assertThat(handler.getWarningMessages(), - contains("IllegalArgumentException: Skipped event b4e09c71312cd7c397969f56c900823f" + - " related to the oai record oai:www.openstarts.units.it:123456789/99998 as the record was not found")); - assertThat(handler.getInfoMessages(), contains("Found 2 events to store")); + contains("An error occurs storing the event with id b4e09c71312cd7c397969f56c900823f: " + + "Skipped event b4e09c71312cd7c397969f56c900823f related to the oai record " + + "oai:www.openstarts.units.it:123456789/99998 as the record was not found")); + assertThat(handler.getInfoMessages(), contains( + "Trying to read the QA events from the provided file", + "Found 2 events in the given file")); - List sources = qaEventService.findAllSources(0, 20); - assertThat(sources, hasSize(1)); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 1L))); - assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); - assertThat(sources.get(0).getTotalEvents(), is(1L)); - - List topics = qaEventService.findAllTopics(0, 20); - assertThat(topics, hasSize(1)); - QATopic topic = topics.get(0); - assertThat(topic.getKey(), is("ENRICH/MISSING/ABSTRACT")); - assertThat(topic.getTotalEvents(), is(1L)); + assertThat(qaEventService.findAllTopics(0, 20), contains(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; @@ -166,22 +215,17 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", item, "Test Publication", abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + verifyNoInteractions(mockBrokerClient); + } @Test - public void testManyEventsImportWithUnknownTopic() throws Exception { + public void testManyEventsImportFromFileWithUnknownTopic() throws Exception { context.turnOffAuthorisationSystem(); - ItemBuilder.createItem(context, collection) - .withTitle("Egypt, crossroad of translations and literary interweavings") - .withHandle("123456789/99998") - .build(); - - Item secondItem = ItemBuilder.createItem(context, collection) - .withTitle("Test item") - .withHandle("123456789/99999") - .build(); + createItem("Test item", "123456789/99999"); + Item secondItem = createItem("Test item 2", "123456789/999991"); context.restoreAuthSystemState(); @@ -193,48 +237,226 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getErrorMessages(), empty()); assertThat(handler.getWarningMessages(), contains("Event for topic ENRICH/MORE/UNKNOWN is not allowed in the qaevents.cfg")); - assertThat(handler.getInfoMessages(), contains("Found 2 events to store")); + assertThat(handler.getInfoMessages(), contains( + "Trying to read the QA events from the provided file", + "Found 2 events in the given file")); - List sources = qaEventService.findAllSources(0, 20); - assertThat(sources, hasSize(1)); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 1L))); - assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); - assertThat(sources.get(0).getTotalEvents(), is(1L)); - - List topics = qaEventService.findAllTopics(0, 20); - assertThat(topics, hasSize(1)); - QATopic topic = topics.get(0); - assertThat(topic.getKey(), is("ENRICH/MISSING/ABSTRACT")); - assertThat(topic.getTotalEvents(), is(1L)); + assertThat(qaEventService.findAllTopics(0, 20), contains(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; assertThat(qaEventService.findEventsByTopic("ENRICH/MISSING/ABSTRACT"), contains( - pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/999991", secondItem, "Test Publication 2", abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + verifyNoInteractions(mockBrokerClient); + } @Test - public void testWithoutEvents() throws Exception { + public void testImportFromFileWithoutEvents() throws Exception { TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); - String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("empty-events.json") }; + String[] args = new String[] { "import-openaire-events", "-f", getFileLocation("empty-file.json") }; ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); assertThat(handler.getErrorMessages(), - contains(containsString("A not recoverable error occurs during OPENAIRE events import."))); + contains(containsString("A not recoverable error occurs during OPENAIRE events import"))); assertThat(handler.getWarningMessages(),empty()); - assertThat(handler.getInfoMessages(), empty()); + assertThat(handler.getInfoMessages(), contains("Trying to read the QA events from the provided file")); - List sources = qaEventService.findAllSources(0, 20); - assertThat(sources, hasSize(1)); - - assertThat(sources.get(0).getName(), is(OPENAIRE_SOURCE)); - assertThat(sources.get(0).getTotalEvents(), is(0L)); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 0L))); assertThat(qaEventService.findAllTopics(0, 20), empty()); + + verifyNoInteractions(mockBrokerClient); + } + + @Test + @SuppressWarnings("unchecked") + public void testImportFromOpenaireBroker() throws Exception { + + context.turnOffAuthorisationSystem(); + + Item firstItem = createItem("Test item", "123456789/99998"); + Item secondItem = createItem("Test item 2", "123456789/99999"); + Item thirdItem = createItem("Test item 3", "123456789/999991"); + + context.restoreAuthSystemState(); + + URL openaireURL = new URL("http://api.openaire.eu/broker"); + + when(mockBrokerClient.listSubscriptions(openaireURL, "user@test.com")).thenReturn(of("sub1", "sub2", "sub3")); + + doAnswer(i -> writeToOutputStream(i.getArgument(2, OutputStream.class), "events.json")) + .when(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub1"), any()); + + doAnswer(i -> writeToOutputStream(i.getArgument(2, OutputStream.class), "empty-events-list.json")) + .when(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub2"), any()); + + doAnswer(i -> writeToOutputStream(i.getArgument(2, OutputStream.class), "unknown-topic-events.json")) + .when(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub3"), any()); + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-e", "user@test.com" }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), empty()); + assertThat(handler.getWarningMessages(), + contains("Event for topic ENRICH/MORE/UNKNOWN is not allowed in the qaevents.cfg")); + assertThat(handler.getInfoMessages(), contains( + "Trying to read the QA events from the OPENAIRE broker", + "Found 3 subscriptions related to the given email", + "Found 2 events from the subscription sub1", + "Found 0 events from the subscription sub2", + "Found 2 events from the subscription sub3")); + + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); + + assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 2L))); + + String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," + + "\"projects[0].funder\":\"EC\",\"projects[0].fundingProgram\":\"H2020\"," + + "\"projects[0].jurisdiction\":\"EU\"," + + "\"projects[0].openaireId\":\"40|corda__h2020::6e32f5eb912688f2424c68b851483ea4\"," + + "\"projects[0].title\":\"Tracking Papyrus and Parchment Paths\"}"; + + assertThat(qaEventService.findEventsByTopic("ENRICH/MORE/PROJECT"), contains( + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99998", firstItem, + "Egypt, crossroad of translations and literary interweavings", projectMessage, + "ENRICH/MORE/PROJECT", 1.00d))); + + String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; + + assertThat(qaEventService.findEventsByTopic("ENRICH/MISSING/ABSTRACT"), containsInAnyOrder( + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/99999", secondItem, "Test Publication", + abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d), + pendingOpenaireEventWith("oai:www.openstarts.units.it:123456789/999991", thirdItem, "Test Publication 2", + abstractMessage, "ENRICH/MISSING/ABSTRACT", 1.00d))); + + verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com"); + verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub1"), any()); + verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub2"), any()); + verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub3"), any()); + + verifyNoMoreInteractions(mockBrokerClient); + } + + @Test + public void testImportFromOpenaireBrokerWithErrorDuringListSubscription() throws Exception { + + URL openaireURL = new URL("http://api.openaire.eu/broker"); + + when(mockBrokerClient.listSubscriptions(openaireURL, "user@test.com")) + .thenThrow(new RuntimeException("Connection refused")); + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-e", "user@test.com" }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), + contains("A not recoverable error occurs during OPENAIRE events import: Connection refused")); + assertThat(handler.getWarningMessages(), empty()); + assertThat(handler.getInfoMessages(), contains("Trying to read the QA events from the OPENAIRE broker")); + + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 0L))); + + assertThat(qaEventService.findAllTopics(0, 20), empty()); + + verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com"); + + verifyNoMoreInteractions(mockBrokerClient); + + } + + @Test + @SuppressWarnings("unchecked") + public void testImportFromOpenaireBrokerWithErrorDuringEventsDownload() throws Exception { + + context.turnOffAuthorisationSystem(); + + createItem("Test item", "123456789/99998"); + createItem("Test item 2", "123456789/99999"); + createItem("Test item 3", "123456789/999991"); + + context.restoreAuthSystemState(); + + URL openaireURL = new URL("http://api.openaire.eu/broker"); + + when(mockBrokerClient.listSubscriptions(openaireURL, "user@test.com")).thenReturn(of("sub1", "sub2", "sub3")); + + doAnswer(i -> writeToOutputStream(i.getArgument(2, OutputStream.class), "events.json")) + .when(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub1"), any()); + + doThrow(new RuntimeException("Invalid subscription id")) + .when(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub2"), any()); + + doAnswer(i -> writeToOutputStream(i.getArgument(2, OutputStream.class), "unknown-topic-events.json")) + .when(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub3"), any()); + + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); + + String[] args = new String[] { "import-openaire-events", "-e", "user@test.com" }; + ScriptLauncher.handleScript(args, ScriptLauncher.getConfig(kernelImpl), handler, kernelImpl); + + assertThat(handler.getErrorMessages(), contains("An error occurs downloading the events " + + "related to the subscription sub2: Invalid subscription id")); + assertThat(handler.getWarningMessages(), + contains("Event for topic ENRICH/MORE/UNKNOWN is not allowed in the qaevents.cfg")); + assertThat(handler.getInfoMessages(), contains( + "Trying to read the QA events from the OPENAIRE broker", + "Found 3 subscriptions related to the given email", + "Found 2 events from the subscription sub1", + "Found 0 events from the subscription sub2", + "Found 2 events from the subscription sub3")); + + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); + + assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 2L))); + + assertThat(qaEventService.findEventsByTopic("ENRICH/MORE/PROJECT"), hasSize(1)); + assertThat(qaEventService.findEventsByTopic("ENRICH/MISSING/ABSTRACT"), hasSize(2)); + + verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com"); + verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub1"), any()); + verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub2"), any()); + verify(mockBrokerClient).downloadEvents(eq(openaireURL), eq("sub3"), any()); + + verifyNoMoreInteractions(mockBrokerClient); + + } + + private Item createItem(String title, String handle) { + return ItemBuilder.createItem(context, collection) + .withTitle(title) + .withHandle(handle) + .build(); + } + + private Void writeToOutputStream(OutputStream outputStream, String fileName) { + try { + byte[] fileContent = getFileContent(fileName); + IOUtils.write(fileContent, outputStream); + return null; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private byte[] getFileContent(String fileName) throws Exception { + String fileLocation = getFileLocation(fileName); + try (FileInputStream fis = new FileInputStream(new File(fileLocation))) { + return IOUtils.toByteArray(fis); + } } private String getFileLocation(String fileName) throws Exception { diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events-list.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events-list.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events-list.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-file.json similarity index 100% rename from dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-events.json rename to dspace-api/src/test/resources/org/dspace/app/openaire-events/empty-file.json diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json index d281db450f..3caa72cf35 100644 --- a/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json +++ b/dspace-api/src/test/resources/org/dspace/app/openaire-events/unknown-topic-events.json @@ -8,8 +8,8 @@ }, { - "originalId": "oai:www.openstarts.units.it:123456789/99999", - "title": "Test Publication", + "originalId": "oai:www.openstarts.units.it:123456789/999991", + "title": "Test Publication 2", "topic": "ENRICH/MISSING/ABSTRACT", "trust": 1.0, "message": { diff --git a/dspace/config/modules/qaevents.cfg b/dspace/config/modules/qaevents.cfg index d30c5181f5..d9a6fba962 100644 --- a/dspace/config/modules/qaevents.cfg +++ b/dspace/config/modules/qaevents.cfg @@ -27,4 +27,7 @@ qaevents.openaire.pid-href-prefix.urn = qaevents.openaire.pid-href-prefix.doi = https://doi.org/ qaevents.openaire.pid-href-prefix.pmc = https://www.ncbi.nlm.nih.gov/pmc/articles/ qaevents.openaire.pid-href-prefix.pmid = https://pubmed.ncbi.nlm.nih.gov/ -qaevents.openaire.pid-href-prefix.ncid = https://ci.nii.ac.jp/ncid/ \ No newline at end of file +qaevents.openaire.pid-href-prefix.ncid = https://ci.nii.ac.jp/ncid/ + +# The URI used by the OPENAIRE broker client to import QA events +qaevents.openaire.broker-url = http://api.openaire.eu/broker \ No newline at end of file diff --git a/dspace/config/spring/api/qaevents.xml b/dspace/config/spring/api/qaevents.xml index c292cb4beb..25bb282672 100644 --- a/dspace/config/spring/api/qaevents.xml +++ b/dspace/config/spring/api/qaevents.xml @@ -10,6 +10,10 @@ + + + + From 3a9d68cf8cb70408c9c531e251dfff2485326e91 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Thu, 14 Jul 2022 09:25:59 +0200 Subject: [PATCH 22/38] [CST-5247] Upgraded OPENAIRE broker client --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index dc67ae8d71..d09fcf004d 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -881,7 +881,7 @@ eu.openaire broker-client - 1.1.1 + 1.1.2 From 85f708a1e63b4e85e7235fcaa563a1e980193755 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Thu, 1 Sep 2022 10:49:30 +0200 Subject: [PATCH 23/38] [CST-5247] Updated qaevent core configuration --- dspace/solr/qaevent/conf/schema.xml | 231 +++++++++++------------- dspace/solr/qaevent/conf/solrconfig.xml | 6 + 2 files changed, 113 insertions(+), 124 deletions(-) diff --git a/dspace/solr/qaevent/conf/schema.xml b/dspace/solr/qaevent/conf/schema.xml index 68eb79afd0..d523e99c9f 100644 --- a/dspace/solr/qaevent/conf/schema.xml +++ b/dspace/solr/qaevent/conf/schema.xml @@ -16,52 +16,50 @@ limitations under the License. --> - + + - + - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + @@ -69,8 +67,14 @@ ignoreCase="true" words="stopwords.txt" /> - - + + @@ -81,32 +85,52 @@ ignoreCase="true" words="stopwords.txt" /> - - + + - + + - + - + - - + + @@ -116,83 +140,29 @@ ignoreCase="true" words="stopwords.txt" /> - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -200,6 +170,7 @@ + @@ -223,28 +194,30 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -252,15 +225,25 @@ + + + + + + + + + + diff --git a/dspace/solr/qaevent/conf/solrconfig.xml b/dspace/solr/qaevent/conf/solrconfig.xml index 76f17a3ef3..2a5f1ef4e9 100644 --- a/dspace/solr/qaevent/conf/solrconfig.xml +++ b/dspace/solr/qaevent/conf/solrconfig.xml @@ -24,6 +24,12 @@ --> 8.8.1 + + + + ${solr.data.dir:} From 5c9aaa0a8c38410c25c49c15c7a4c25f4bc8440a Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Wed, 9 Nov 2022 15:14:08 +0100 Subject: [PATCH 24/38] [CST-5249] Renamed qa endpoints --- .../rest/QAEventRelatedRestController.java | 9 +- .../dspace/app/rest/model/QAEventRest.java | 2 +- .../dspace/app/rest/model/QASourceRest.java | 2 +- .../dspace/app/rest/model/QATopicRest.java | 2 +- .../app/rest/QAEventRestRepositoryIT.java | 158 ++++++++++-------- .../app/rest/QASourceRestRepositoryIT.java | 20 +-- .../app/rest/QATopicRestRepositoryIT.java | 54 +++--- .../app/rest/matcher/QAEventMatcher.java | 2 +- .../app/rest/matcher/QASourceMatcher.java | 4 +- .../app/rest/matcher/QATopicMatcher.java | 4 +- 10 files changed, 140 insertions(+), 117 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRelatedRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRelatedRestController.java index 8716d07937..538d99b3ce 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRelatedRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/QAEventRelatedRestController.java @@ -42,12 +42,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** - * This RestController will take care to manipulate the related item eventually associated with a qa event - * "/api/integration/qaevents/{qaeventid}/related" + * This RestController will take care to manipulate the related item eventually + * associated with a qa event + * "/api/integration/qualityassuranceevents/{qaeventid}/related" */ @RestController -@RequestMapping("/api/" + QAEventRest.CATEGORY + "/qaevents" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG - + "/related") +@RequestMapping("/api/" + QAEventRest.CATEGORY + "/qualityassuranceevents" + + REGEX_REQUESTMAPPING_IDENTIFIER_AS_STRING_VERSION_STRONG + "/related") public class QAEventRelatedRestController { @Autowired diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java index e02755d2ec..7a12ade61d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QAEventRest.java @@ -26,7 +26,7 @@ import org.dspace.app.rest.RestResourceController; public class QAEventRest extends BaseObjectRest { private static final long serialVersionUID = -5001130073350654793L; - public static final String NAME = "qaevent"; + public static final String NAME = "qualityassuranceevent"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; public static final String TOPIC = "topic"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java index 15c8096e02..a1480f409c 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QASourceRest.java @@ -21,7 +21,7 @@ public class QASourceRest extends BaseObjectRest { private static final long serialVersionUID = -7455358581579629244L; - public static final String NAME = "qasource"; + public static final String NAME = "qualityassurancesource"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; private String id; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java index 34d5655eb7..05820b9194 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/QATopicRest.java @@ -21,7 +21,7 @@ public class QATopicRest extends BaseObjectRest { private static final long serialVersionUID = -7455358581579629244L; - public static final String NAME = "qatopic"; + public static final String NAME = "qualityassurancetopic"; public static final String CATEGORY = RestAddressableModel.INTEGRATION; private String id; diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java index 173f233de0..dc021f2904 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java @@ -63,10 +63,12 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { @Test public void findAllNotImplementedTest() throws Exception { String adminToken = getAuthToken(admin.getEmail(), password); - getClient(adminToken).perform(get("/api/integration/qaevents")).andExpect(status().isMethodNotAllowed()); + getClient(adminToken).perform(get("/api/integration/qualityassuranceevents")) + .andExpect(status().isMethodNotAllowed()); String epersonToken = getAuthToken(admin.getEmail(), password); - getClient(epersonToken).perform(get("/api/integration/qaevents")).andExpect(status().isMethodNotAllowed()); - getClient().perform(get("/api/integration/qaevents")).andExpect(status().isMethodNotAllowed()); + getClient(epersonToken).perform(get("/api/integration/qualityassuranceevents")) + .andExpect(status().isMethodNotAllowed()); + getClient().perform(get("/api/integration/qualityassuranceevents")).andExpect(status().isMethodNotAllowed()); } @Test @@ -82,9 +84,11 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qaevents/" + event1.getEventId())).andExpect(status().isOk()) + getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event1.getEventId())) + .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(event1))); - getClient(authToken).perform(get("/api/integration/qaevents/" + event4.getEventId())).andExpect(status().isOk()) + getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event4.getEventId())) + .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(event4))); } @@ -113,11 +117,11 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event1.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event1.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event1))); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event5.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event5.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event5))); } @@ -131,7 +135,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withTopic("ENRICH/MISSING/PID") .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/qaevents/" + event1.getEventId())) + getClient().perform(get("/api/integration/qualityassuranceevents/" + event1.getEventId())) .andExpect(status().isUnauthorized()); } @@ -145,7 +149,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qaevents/" + event1.getEventId())) + getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event1.getEventId())) .andExpect(status().isForbidden()); } @@ -169,19 +173,22 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.qaevents", + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder(QAEventMatcher.matchQAEventEntry(event1), QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!ABSTRACT")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(1))) - .andExpect(jsonPath("$._embedded.qaevents", + .perform(get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", + "ENRICH!MISSING!ABSTRACT")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder(QAEventMatcher.matchQAEventEntry(event4)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); - getClient(authToken).perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "not-existing")) + getClient(authToken) + .perform(get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "not-existing")) .andExpect(status().isOk()).andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.totalElements", is(0))); } @@ -209,31 +216,32 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") .param("size", "2")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.qaevents", + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder( QAEventMatcher.matchQAEventEntry(event1), QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.prev.href").doesNotExist()) @@ -242,36 +250,37 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$.page.totalElements", is(5))); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") .param("size", "2").param("page", "1")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.qaevents", + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder( QAEventMatcher.matchQAEventEntry(event3), QAEventMatcher.matchQAEventEntry(event4)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.next.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) @@ -279,31 +288,32 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$.page.totalElements", is(5))); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID") .param("size", "2").param("page", "2")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(1))) - .andExpect(jsonPath("$._embedded.qaevents", + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder( QAEventMatcher.matchQAEventEntry(event5)))) .andExpect(jsonPath("$._links.self.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.next.href").doesNotExist()) .andExpect(jsonPath("$._links.last.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=2"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=0"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$._links.prev.href", Matchers.allOf( - Matchers.containsString("/api/integration/qaevents/search/findByTopic?"), + Matchers.containsString("/api/integration/qualityassuranceevents/search/findByTopic?"), Matchers.containsString("topic=ENRICH!MISSING!PID"), Matchers.containsString("page=1"), Matchers.containsString("size=2")))) .andExpect(jsonPath("$.page.size", is(2))) @@ -330,7 +340,9 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withTopic("ENRICH/MISSING/ABSTRACT") .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + getClient() + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) .andExpect(status().isUnauthorized()); } @@ -354,7 +366,8 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String epersonToken = getAuthToken(eperson.getEmail(), password); getClient(epersonToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) .andExpect(status().isForbidden()); } @@ -377,7 +390,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withMessage("{\"abstracts[0]\": \"Descrizione delle caratteristiche...\"}").build(); context.restoreAuthSystemState(); String adminToken = getAuthToken(admin.getEmail(), password); - getClient(adminToken).perform(get("/api/integration/qaevents/search/findByTopic")) + getClient(adminToken).perform(get("/api/integration/qualityassuranceevents/search/findByTopic")) .andExpect(status().isBadRequest()); } @@ -470,32 +483,34 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { eventProjectNoBound.setStatus(QAEvent.ACCEPTED); eventAbstract.setStatus(QAEvent.ACCEPTED); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMissingPID1.getEventId()) + getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/" + eventMissingPID1.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMissingPID1))); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMorePID.getEventId()) + getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/" + eventMorePID.getEventId()) .content(patchAcceptUppercase) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMorePID))); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMissingUnknownPID.getEventId()) + getClient(authToken) + .perform(patch("/api/integration/qualityassuranceevents/" + eventMissingUnknownPID.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventMissingUnknownPID))); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventProjectBound.getEventId()) + getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/" + eventProjectBound.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventProjectBound))); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventProjectNoBound.getEventId()) + getClient(authToken) + .perform(patch("/api/integration/qualityassuranceevents/" + eventProjectNoBound.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventEntry(eventProjectNoBound))); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventAbstract.getEventId()) + getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/" + eventAbstract.getEventId()) .content(patchAccept) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) @@ -535,7 +550,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { hasJsonPath("$.metadata['dc.description.abstract'][0].value", is("An abstract to add...")))); // reject pid2 eventMissingPID2.setStatus(QAEvent.REJECTED); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventMissingPID2.getEventId()) + getClient(authToken).perform(patch("/api/integration/qualityassuranceevents/" + eventMissingPID2.getEventId()) .content(patchReject) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) @@ -547,7 +562,8 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { hasNoJsonPath("$.metadata['dc.identifier.other']"))); // discard abstractToDiscard eventAbstractToDiscard.setStatus(QAEvent.DISCARDED); - getClient(authToken).perform(patch("/api/integration/qaevents/" + eventAbstractToDiscard.getEventId()) + getClient(authToken) + .perform(patch("/api/integration/qualityassuranceevents/" + eventAbstractToDiscard.getEventId()) .content(patchDiscard) .contentType(MediaType.APPLICATION_JSON_PATCH_JSON)) .andExpect(status().isOk()) @@ -558,7 +574,7 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(jsonPath("$", hasNoJsonPath("$.metadata['dc.description.abstract']"))); // no pending qa events should be longer available - getClient(authToken).perform(get("/api/integration/qatopics")).andExpect(status().isOk()) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics")).andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(status().isOk()) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(0))); @@ -591,23 +607,23 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(post("/api/integration/qaevents/" + event.getEventId() + "/related").param("item", + .perform(post("/api/integration/qualityassuranceevents/" + event.getEventId() + "/related").param("item", funding.getID().toString())) .andExpect(status().isCreated()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(funding))); // update our local event copy to reflect the association with the related item event.setRelated(funding.getID().toString()); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId() + "/related")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId() + "/related")) .andExpect(status().isOk()) .andExpect(jsonPath("$", ItemMatcher.matchItemProperties(funding))); } @@ -639,21 +655,21 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(delete("/api/integration/qaevents/" + event.getEventId() + "/related")) + .perform(delete("/api/integration/qualityassuranceevents/" + event.getEventId() + "/related")) .andExpect(status().isNoContent()); // update our local event copy to reflect the association with the related item event.setRelated(null); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId() + "/related")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId() + "/related")) .andExpect(status().isNoContent()); } @@ -672,17 +688,17 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); getClient(authToken) - .perform(post("/api/integration/qaevents/" + event.getEventId() + "/related").param("item", + .perform(post("/api/integration/qualityassuranceevents/" + event.getEventId() + "/related").param("item", funding.getID().toString())) .andExpect(status().isUnprocessableEntity()); // check that no related item has been added to our event getClient(authToken) - .perform(get("/api/integration/qaevents/" + event.getEventId()).param("projection", "full")) + .perform(get("/api/integration/qualityassuranceevents/" + event.getEventId()).param("projection", "full")) .andExpect(status().isOk()) .andExpect(jsonPath("$", QAEventMatcher.matchQAEventFullEntry(event))); } @@ -701,9 +717,10 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(2))) - .andExpect(jsonPath("$._embedded.qaevents", + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(2))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder(QAEventMatcher.matchQAEventEntry(event1), QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); @@ -715,9 +732,10 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .andExpect(status().is(404)); getClient(authToken) - .perform(get("/api/integration/qaevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) - .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qaevents", Matchers.hasSize(1))) - .andExpect(jsonPath("$._embedded.qaevents", + .perform( + get("/api/integration/qualityassuranceevents/search/findByTopic").param("topic", "ENRICH!MISSING!PID")) + .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qualityassuranceevents", Matchers.containsInAnyOrder( QAEventMatcher.matchQAEventEntry(event2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(1))); @@ -745,17 +763,17 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qaevents/" + event.getEventId())) + getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId())) .andExpect(status().isOk()) .andExpect(jsonPath("$", matchQAEventEntry(event))); List processedEvents = qaEventsDao.findAll(context); assertThat(processedEvents, empty()); - getClient(authToken).perform(delete("/api/integration/qaevents/" + event.getEventId())) + getClient(authToken).perform(delete("/api/integration/qualityassuranceevents/" + event.getEventId())) .andExpect(status().isNoContent()); - getClient(authToken).perform(get("/api/integration/qaevents/" + event.getEventId())) + getClient(authToken).perform(get("/api/integration/qualityassuranceevents/" + event.getEventId())) .andExpect(status().isNotFound()); processedEvents = qaEventsDao.findAll(context); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java index 1fdcd5e0df..ac0ccc4cce 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QASourceRestRepositoryIT.java @@ -80,10 +80,10 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qasources")) + getClient(authToken).perform(get("/api/integration/qualityassurancesources")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qasources", contains( + .andExpect(jsonPath("$._embedded.qualityassurancesources", contains( matchQASourceEntry("openaire", 3), matchQASourceEntry("test-source", 2), matchQASourceEntry("test-source-2", 0)))) @@ -103,7 +103,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); - getClient(token).perform(get("/api/integration/qasources")) + getClient(token).perform(get("/api/integration/qualityassurancesources")) .andExpect(status().isForbidden()); } @@ -118,7 +118,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/qasources")) + getClient().perform(get("/api/integration/qualityassurancesources")) .andExpect(status().isUnauthorized()); } @@ -138,22 +138,22 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qasources/openaire")) + getClient(authToken).perform(get("/api/integration/qualityassurancesources/openaire")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$", matchQASourceEntry("openaire", 3))); - getClient(authToken).perform(get("/api/integration/qasources/test-source")) + getClient(authToken).perform(get("/api/integration/qualityassurancesources/test-source")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$", matchQASourceEntry("test-source", 2))); - getClient(authToken).perform(get("/api/integration/qasources/test-source-2")) + getClient(authToken).perform(get("/api/integration/qualityassurancesources/test-source-2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) .andExpect(jsonPath("$", matchQASourceEntry("test-source-2", 0))); - getClient(authToken).perform(get("/api/integration/qasources/unknown-test-source")) + getClient(authToken).perform(get("/api/integration/qualityassurancesources/unknown-test-source")) .andExpect(status().isNotFound()); } @@ -169,7 +169,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); - getClient(token).perform(get("/api/integration/qasources/openaire")) + getClient(token).perform(get("/api/integration/qualityassurancesources/openaire")) .andExpect(status().isForbidden()); } @@ -184,7 +184,7 @@ public class QASourceRestRepositoryIT extends AbstractControllerIntegrationTest context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/qasources/openaire")) + getClient().perform(get("/api/integration/qualityassurancesources/openaire")) .andExpect(status().isUnauthorized()); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java index d510d713a0..55bfd0feca 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QATopicRestRepositoryIT.java @@ -59,9 +59,9 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics")).andExpect(status().isOk()) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics")).andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qatopics", + .andExpect(jsonPath("$._embedded.qualityassurancetopics", Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2), QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1), QATopicMatcher.matchQATopicEntry("ENRICH/MORE/PID", 1)))) @@ -71,13 +71,13 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { @Test public void findAllUnauthorizedTest() throws Exception { - getClient().perform(get("/api/integration/qatopics")).andExpect(status().isUnauthorized()); + getClient().perform(get("/api/integration/qualityassurancetopics")).andExpect(status().isUnauthorized()); } @Test public void findAllForbiddenTest() throws Exception { String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics")).andExpect(status().isForbidden()); + getClient(authToken).perform(get("/api/integration/qualityassurancetopics")).andExpect(status().isForbidden()); } @Test @@ -104,16 +104,19 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics").param("size", "2")) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics").param("size", "2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qatopics", Matchers.hasSize(2))) - .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); - getClient(authToken).perform(get("/api/integration/qatopics").param("size", "2").param("page", "1")) - .andExpect(status().isOk()) - .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qatopics", Matchers.hasSize(1))) + .andExpect(jsonPath("$._embedded.qualityassurancetopics", Matchers.hasSize(2))) .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); + getClient(authToken) + .perform(get("/api/integration/qualityassurancetopics") + .param("size", "2") + .param("page", "1")) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$._embedded.qualityassurancetopics", Matchers.hasSize(1))) + .andExpect(jsonPath("$.page.size", is(2))).andExpect(jsonPath("$.page.totalElements", is(3))); } @Test @@ -139,9 +142,9 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!PID")) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/ENRICH!MISSING!PID")) .andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2))); - getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!ABSTRACT")) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/ENRICH!MISSING!ABSTRACT")) .andExpect(jsonPath("$", QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1))); } @@ -155,8 +158,9 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/qatopics/ENRICH!MISSING!PID")).andExpect(status().isUnauthorized()); - getClient().perform(get("/api/integration/qatopics/ENRICH!MISSING!ABSTRACT")) + getClient().perform(get("/api/integration/qualityassurancetopics/ENRICH!MISSING!PID")) + .andExpect(status().isUnauthorized()); + getClient().perform(get("/api/integration/qualityassurancetopics/ENRICH!MISSING!ABSTRACT")) .andExpect(status().isUnauthorized()); } @@ -171,9 +175,9 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!PID")) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/ENRICH!MISSING!PID")) .andExpect(status().isForbidden()); - getClient(authToken).perform(get("/api/integration/qatopics/ENRICH!MISSING!ABSTRACT")) + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/ENRICH!MISSING!ABSTRACT")) .andExpect(status().isForbidden()); } @@ -214,28 +218,28 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { .build(); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource") .param("source", "openaire")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qatopics", + .andExpect(jsonPath("$._embedded.qualityassurancetopics", Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/PID", 2), QATopicMatcher.matchQATopicEntry("ENRICH/MISSING/ABSTRACT", 1), QATopicMatcher.matchQATopicEntry("ENRICH/MORE/PID", 1)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(3))); - getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource") .param("source", "test-source")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qatopics", + .andExpect(jsonPath("$._embedded.qualityassurancetopics", Matchers.containsInAnyOrder(QATopicMatcher.matchQATopicEntry("TEST/TOPIC/2", 1), QATopicMatcher.matchQATopicEntry("TEST/TOPIC", 2)))) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(2))); - getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource") .param("source", "test-source-2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.qatopics").doesNotExist()) + .andExpect(jsonPath("$._embedded.qualityassurancetopics").doesNotExist()) .andExpect(jsonPath("$.page.size", is(20))).andExpect(jsonPath("$.page.totalElements", is(0))); } @@ -249,7 +253,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { QAEventBuilder.createTarget(context, col1, "Science and Freedom") .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); - getClient().perform(get("/api/integration/qatopics/search/bySource") + getClient().perform(get("/api/integration/qualityassurancetopics/search/bySource") .param("source", "openaire")) .andExpect(status().isUnauthorized()); } @@ -265,7 +269,7 @@ public class QATopicRestRepositoryIT extends AbstractControllerIntegrationTest { .withTopic("ENRICH/MISSING/PID").build(); context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform(get("/api/integration/qatopics/search/bySource") + getClient(authToken).perform(get("/api/integration/qualityassurancetopics/search/bySource") .param("source", "openaire")) .andExpect(status().isForbidden()); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java index afd2ff0358..68359023e3 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java @@ -60,7 +60,7 @@ public class QAEventMatcher { hasJsonPath("$._links.target.href", Matchers.endsWith(event.getEventId() + "/target")), hasJsonPath("$._links.related.href", Matchers.endsWith(event.getEventId() + "/related")), hasJsonPath("$._links.topic.href", Matchers.endsWith(event.getEventId() + "/topic")), - hasJsonPath("$.type", is("qaevent"))); + hasJsonPath("$.type", is("qualityassuranceevent"))); } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java index 0340315600..c0466ee408 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QASourceMatcher.java @@ -26,7 +26,7 @@ public class QASourceMatcher { public static Matcher matchQASourceEntry(String key, int totalEvents) { return allOf( - hasJsonPath("$.type", is("qasource")), + hasJsonPath("$.type", is("qualityassurancesource")), hasJsonPath("$.id", is(key)), hasJsonPath("$.totalEvents", is(totalEvents)) ); @@ -35,7 +35,7 @@ public class QASourceMatcher { public static Matcher matchQASourceEntry(String key) { return allOf( - hasJsonPath("$.type", is("qasource")), + hasJsonPath("$.type", is("qualityassurancesource")), hasJsonPath("$.id", is(key)) ); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java index 26ef1e92e9..6428a97125 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QATopicMatcher.java @@ -26,7 +26,7 @@ public class QATopicMatcher { public static Matcher matchQATopicEntry(String key, int totalEvents) { return allOf( - hasJsonPath("$.type", is("qatopic")), + hasJsonPath("$.type", is("qualityassurancetopic")), hasJsonPath("$.name", is(key)), hasJsonPath("$.id", is(key.replace("/", "!"))), hasJsonPath("$.totalEvents", is(totalEvents)) @@ -36,7 +36,7 @@ public class QATopicMatcher { public static Matcher matchQATopicEntry(String key) { return allOf( - hasJsonPath("$.type", is("qatopic")), + hasJsonPath("$.type", is("qualityassurancetopic")), hasJsonPath("$.name", is(key)), hasJsonPath("$.id", is(key.replace("/", "/"))) ); From d5dd2c93bb5dc3fef58080adb71fddc0f7d105b3 Mon Sep 17 00:00:00 2001 From: Francesco Bacchelli Date: Mon, 7 Aug 2023 08:59:01 +0200 Subject: [PATCH 25/38] CST-11298 sql file renaming and junit java fix --- .../OpenaireEventsImportScriptConfiguration.java | 12 ++++-------- ...ed.sql => V8.0_2023.08.07__qaevent_processed.sql} | 0 ...ed.sql => V8.0_2023.08.07__qaevent_processed.sql} | 0 ...ed.sql => V8.0_2023.08.07__qaevent_processed.sql} | 0 4 files changed, 4 insertions(+), 8 deletions(-) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/{V7.3_2022.02.17__qaevent_processed.sql => V8.0_2023.08.07__qaevent_processed.sql} (100%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/{V7.3_2022.02.17__qaevent_processed.sql => V8.0_2023.08.07__qaevent_processed.sql} (100%) rename dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/{V7.3_2022.02.17__qaevent_processed.sql => V8.0_2023.08.07__qaevent_processed.sql} (100%) diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java index 1a6f94f6a5..14737de635 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java @@ -8,13 +8,9 @@ package org.dspace.qaevent.script; import java.io.InputStream; -import java.sql.SQLException; import org.apache.commons.cli.Options; -import org.dspace.authorize.service.AuthorizeService; -import org.dspace.core.Context; import org.dspace.scripts.configuration.ScriptConfiguration; -import org.springframework.beans.factory.annotation.Autowired; /** * Extension of {@link ScriptConfiguration} to perfom a QAEvents import from @@ -25,9 +21,9 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class OpenaireEventsImportScriptConfiguration extends ScriptConfiguration { - @Autowired + /* private AuthorizeService authorizeService; - + */ private Class dspaceRunnableClass; @Override @@ -43,7 +39,7 @@ public class OpenaireEventsImportScriptConfiguration dspaceRunnableClass) { this.dspaceRunnableClass = dspaceRunnableClass; } - +/* @Override public boolean isAllowedToExecute(Context context) { try { @@ -52,7 +48,7 @@ public class OpenaireEventsImportScriptConfiguration Date: Mon, 7 Aug 2023 13:37:22 +0200 Subject: [PATCH 26/38] CST-11298 openaire test fix --- .../script/OpenaireEventsImportIT.java | 34 ++++++++++++----- .../dspace/app/openaire-events/events.json | 37 ++++++++++++++++++- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java index 22da785d31..dbe44fd2e7 100644 --- a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java @@ -153,12 +153,15 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getWarningMessages(), empty()); assertThat(handler.getInfoMessages(), contains( "Trying to read the QA events from the provided file", - "Found 2 events in the given file")); + "Found 5 events in the given file")); - assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 2L))); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 5L))); assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MORE/PID", 1L), + QATopicMatcher.with("ENRICH/MISSING/PID", 1L), + QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L), QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," @@ -200,14 +203,21 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getWarningMessages(), contains("An error occurs storing the event with id b4e09c71312cd7c397969f56c900823f: " + "Skipped event b4e09c71312cd7c397969f56c900823f related to the oai record " + + "oai:www.openstarts.units.it:123456789/99998 as the record was not found", + "An error occurs storing the event with id d050d2c4399c6c6ccf27d52d479d26e4: " + + "Skipped event d050d2c4399c6c6ccf27d52d479d26e4 related to the oai record " + "oai:www.openstarts.units.it:123456789/99998 as the record was not found")); assertThat(handler.getInfoMessages(), contains( "Trying to read the QA events from the provided file", - "Found 2 events in the given file")); + "Found 5 events in the given file")); - assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 1L))); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); - assertThat(qaEventService.findAllTopics(0, 20), contains(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); + assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L), + QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MORE/PID", 1L) + )); String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; @@ -311,14 +321,17 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getInfoMessages(), contains( "Trying to read the QA events from the OPENAIRE broker", "Found 3 subscriptions related to the given email", - "Found 2 events from the subscription sub1", + "Found 5 events from the subscription sub1", "Found 0 events from the subscription sub2", "Found 2 events from the subscription sub3")); - assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 6L))); assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MORE/PID", 1L), + QATopicMatcher.with("ENRICH/MISSING/PID", 1L), + QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L), QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 2L))); String projectMessage = "{\"projects[0].acronym\":\"PAThs\",\"projects[0].code\":\"687567\"," @@ -413,14 +426,17 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(handler.getInfoMessages(), contains( "Trying to read the QA events from the OPENAIRE broker", "Found 3 subscriptions related to the given email", - "Found 2 events from the subscription sub1", + "Found 5 events from the subscription sub1", "Found 0 events from the subscription sub2", "Found 2 events from the subscription sub3")); - assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); + assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 6L))); assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), + QATopicMatcher.with("ENRICH/MISSING/PID", 1L), + QATopicMatcher.with("ENRICH/MORE/PID", 1L), + QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L), QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 2L))); assertThat(qaEventService.findEventsByTopic("ENRICH/MORE/PROJECT"), hasSize(1)); diff --git a/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json b/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json index 7d8dbd37f1..9bb8daae36 100644 --- a/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json +++ b/dspace-api/src/test/resources/org/dspace/app/openaire-events/events.json @@ -24,6 +24,39 @@ "message": { "abstracts[0]": "Missing Abstract" } - } - + }, + { + "originalId": "oai:www.openstarts.units.it:123456789/99998", + "title": "Egypt, crossroad of translations and literary interweavings", + "topic": "ENRICH/MISSING/PID", + "trust": 1.0, + "message": { + "pids[0].type": "doi", + "pids[0].value": "10.13137/2282-572x/987" + } + }, + { + "originalId": "oai:www.openstarts.units.it:123456789/99999", + "title": "Test Publication", + "topic": "ENRICH/MORE/PID", + "trust": 0.375, + "message": { + "pids[0].type": "doi", + "pids[0].value": "987654" + } + }, + { + "originalId": "oai:www.openstarts.units.it:123456789/99999", + "title": "Test Publication", + "topic": "ENRICH/MISSING/PROJECT", + "trust": 1.0, + "message": { + "projects[0].acronym": "02.SNES missing project acronym", + "projects[0].code": "prjcode_snes", + "projects[0].funder": "02.SNES missing project funder", + "projects[0].fundingProgram": "02.SNES missing project fundingProgram", + "projects[0].jurisdiction": "02.SNES missing project jurisdiction", + "projects[0].title": "Project01" + } + } ] \ No newline at end of file From f51975bea191ee9c06073f8a31a9107703770479 Mon Sep 17 00:00:00 2001 From: frabacche Date: Mon, 25 Sep 2023 11:53:49 +0200 Subject: [PATCH 27/38] CST-5249 add qaevents to docker-compose.yml configuration --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index e623d96079..d67c9ae1d8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -120,6 +120,8 @@ services: cp -r /opt/solr/server/solr/configsets/search/* search precreate-core statistics /opt/solr/server/solr/configsets/statistics cp -r /opt/solr/server/solr/configsets/statistics/* statistics + precreate-core qaevents /opt/solr/server/solr/configsets/qaevents + cp -r /opt/solr/server/solr/configsets/qaevents/* qaevents exec solr -f volumes: assetstore: From ae0ecb3dc14b1987a6ad4e9b431693ed19b6f5f0 Mon Sep 17 00:00:00 2001 From: frabacche Date: Wed, 27 Sep 2023 10:04:08 +0200 Subject: [PATCH 28/38] Docker solr configuration qaevents new solr collection --- dspace/src/main/docker/dspace-solr/Dockerfile | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dspace/src/main/docker/dspace-solr/Dockerfile b/dspace/src/main/docker/dspace-solr/Dockerfile index 9fe9adf944..5f9b266999 100644 --- a/dspace/src/main/docker/dspace-solr/Dockerfile +++ b/dspace/src/main/docker/dspace-solr/Dockerfile @@ -17,19 +17,22 @@ FROM solr:${SOLR_VERSION}-slim ENV AUTHORITY_CONFIGSET_PATH=/opt/solr/server/solr/configsets/authority/conf \ OAI_CONFIGSET_PATH=/opt/solr/server/solr/configsets/oai/conf \ SEARCH_CONFIGSET_PATH=/opt/solr/server/solr/configsets/search/conf \ - STATISTICS_CONFIGSET_PATH=/opt/solr/server/solr/configsets/statistics/conf - + STATISTICS_CONFIGSET_PATH=/opt/solr/server/solr/configsets/statistics/conf \ + QAEVENTS_CONFIGSET_PATH=/opt/solr/server/solr/configsets/qaevents/conf + USER root RUN mkdir -p $AUTHORITY_CONFIGSET_PATH && \ mkdir -p $OAI_CONFIGSET_PATH && \ mkdir -p $SEARCH_CONFIGSET_PATH && \ - mkdir -p $STATISTICS_CONFIGSET_PATH + mkdir -p $STATISTICS_CONFIGSET_PATH && \ + mkdir -p $QAEVENTS_CONFIGSET_PATH COPY dspace/solr/authority/conf/* $AUTHORITY_CONFIGSET_PATH/ COPY dspace/solr/oai/conf/* $OAI_CONFIGSET_PATH/ COPY dspace/solr/search/conf/* $SEARCH_CONFIGSET_PATH/ COPY dspace/solr/statistics/conf/* $STATISTICS_CONFIGSET_PATH/ +COPY dspace/solr/qaevents/conf/* $QAEVENTS_CONFIGSET_PATH/ RUN chown -R solr:solr /opt/solr/server/solr/configsets From d377f314ff38ece314354c6eac3ac2a15b53fc4f Mon Sep 17 00:00:00 2001 From: frabacche Date: Wed, 27 Sep 2023 10:26:05 +0200 Subject: [PATCH 29/38] Docker solr configuration qaevents new solr collection (typo) --- dspace/src/main/docker/dspace-solr/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace/src/main/docker/dspace-solr/Dockerfile b/dspace/src/main/docker/dspace-solr/Dockerfile index 5f9b266999..5d02d0db81 100644 --- a/dspace/src/main/docker/dspace-solr/Dockerfile +++ b/dspace/src/main/docker/dspace-solr/Dockerfile @@ -18,7 +18,7 @@ ENV AUTHORITY_CONFIGSET_PATH=/opt/solr/server/solr/configsets/authority/conf \ OAI_CONFIGSET_PATH=/opt/solr/server/solr/configsets/oai/conf \ SEARCH_CONFIGSET_PATH=/opt/solr/server/solr/configsets/search/conf \ STATISTICS_CONFIGSET_PATH=/opt/solr/server/solr/configsets/statistics/conf \ - QAEVENTS_CONFIGSET_PATH=/opt/solr/server/solr/configsets/qaevents/conf + QAEVENT_CONFIGSET_PATH=/opt/solr/server/solr/configsets/qaevent/conf USER root @@ -26,13 +26,13 @@ RUN mkdir -p $AUTHORITY_CONFIGSET_PATH && \ mkdir -p $OAI_CONFIGSET_PATH && \ mkdir -p $SEARCH_CONFIGSET_PATH && \ mkdir -p $STATISTICS_CONFIGSET_PATH && \ - mkdir -p $QAEVENTS_CONFIGSET_PATH + mkdir -p $QAEVENT_CONFIGSET_PATH COPY dspace/solr/authority/conf/* $AUTHORITY_CONFIGSET_PATH/ COPY dspace/solr/oai/conf/* $OAI_CONFIGSET_PATH/ COPY dspace/solr/search/conf/* $SEARCH_CONFIGSET_PATH/ COPY dspace/solr/statistics/conf/* $STATISTICS_CONFIGSET_PATH/ -COPY dspace/solr/qaevents/conf/* $QAEVENTS_CONFIGSET_PATH/ +COPY dspace/solr/qaevent/conf/* $QAEVENT_CONFIGSET_PATH/ RUN chown -R solr:solr /opt/solr/server/solr/configsets From b2dddca6fb47874bfe6ceef862c07568e456deb0 Mon Sep 17 00:00:00 2001 From: frabacche Date: Wed, 27 Sep 2023 10:27:35 +0200 Subject: [PATCH 30/38] docker-compose.yml typo --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index d67c9ae1d8..a9aa161e9e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -120,8 +120,8 @@ services: cp -r /opt/solr/server/solr/configsets/search/* search precreate-core statistics /opt/solr/server/solr/configsets/statistics cp -r /opt/solr/server/solr/configsets/statistics/* statistics - precreate-core qaevents /opt/solr/server/solr/configsets/qaevents - cp -r /opt/solr/server/solr/configsets/qaevents/* qaevents + precreate-core qaevent /opt/solr/server/solr/configsets/qaevent + cp -r /opt/solr/server/solr/configsets/qaevent/* qaevent exec solr -f volumes: assetstore: From c5e2e4fac755a44ea3761f2d164c67844f25605c Mon Sep 17 00:00:00 2001 From: frabacche Date: Mon, 16 Oct 2023 10:46:32 +0200 Subject: [PATCH 31/38] CST-5249 configuration review --- .../V8.0_2023.08.07__qaevent_processed.sql | 19 ------------------- .../app/rest/matcher/QAEventMatcher.java | 2 +- dspace/config/modules/qaevents.cfg | 3 +-- 3 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V8.0_2023.08.07__qaevent_processed.sql diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V8.0_2023.08.07__qaevent_processed.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V8.0_2023.08.07__qaevent_processed.sql deleted file mode 100644 index 5c3f0fac73..0000000000 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/oracle/V8.0_2023.08.07__qaevent_processed.sql +++ /dev/null @@ -1,19 +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 TABLE qaevent_processed ( - qaevent_id VARCHAR(255) NOT NULL, - qaevent_timestamp TIMESTAMP NULL, - eperson_uuid UUID NULL, - item_uuid UUID NULL, - CONSTRAINT qaevent_pk PRIMARY KEY (qaevent_id), - CONSTRAINT eperson_uuid_fkey FOREIGN KEY (eperson_uuid) REFERENCES eperson (uuid), - CONSTRAINT item_uuid_fkey FOREIGN KEY (item_uuid) REFERENCES item (uuid) -); - -CREATE INDEX item_uuid_idx ON qaevent_processed(item_uuid); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java index 68359023e3..b85746c64c 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/QAEventMatcher.java @@ -99,7 +99,7 @@ public class QAEventMatcher { hrefPrefix = "https://arxiv.org/abs/"; break; case "handle": - hrefPrefix = "https://arxiv.org/abs/"; + hrefPrefix = "https://hdl.handle.net/"; break; case "urn": hrefPrefix = ""; diff --git a/dspace/config/modules/qaevents.cfg b/dspace/config/modules/qaevents.cfg index d9a6fba962..da5080d589 100644 --- a/dspace/config/modules/qaevents.cfg +++ b/dspace/config/modules/qaevents.cfg @@ -5,8 +5,7 @@ #---------------------------------------------------------------# qaevents.solr.server = ${solr.server}/${solr.multicorePrefix}qaevent # A POST to these url(s) will be done to notify oaire of decision taken for each qaevents -qaevents.openaire.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events -#qaevents.openaire.acknowledge-url +# qaevents.openaire.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events # The list of the supported events incoming from openaire (see also dspace/config/spring/api/qaevents.xml) # add missing abstract suggestion From ff5f3fa74f2b3ac0144d6e59ed824ada016167cc Mon Sep 17 00:00:00 2001 From: frabacche Date: Tue, 12 Dec 2023 16:15:25 +0100 Subject: [PATCH 32/38] CST-5249 rename OpenAIRE to Openaire, other minor issues --- .../org/dspace/content/ItemServiceImpl.java | 4 +- .../dspace/eperson/EPersonServiceImpl.java | 4 +- ...nector.java => OpenaireRestConnector.java} | 40 +++++------ ...ERestToken.java => OpenaireRestToken.java} | 6 +- ....java => OpenaireFundingDataProvider.java} | 30 ++++----- .../QAEventsDeleteCascadeConsumer.java | 2 +- .../java/org/dspace/qaevent/QASource.java | 2 +- .../{QAEventsDao.java => QAEventsDAO.java} | 2 +- ...ventsDaoImpl.java => QAEventsDAOImpl.java} | 8 +-- .../qaevent/script/OpenaireEventsImport.java | 4 +- ...enaireEventsImportScriptConfiguration.java | 4 +- .../service/dto/OpenaireMessageDTO.java | 2 +- .../service/impl/QAEventServiceImpl.java | 8 +-- .../config/spring/api/external-openaire.xml | 8 +-- .../config/spring/api/item-filters.xml | 4 +- .../config/spring/api/scripts.xml | 2 +- .../org/dspace/content/CollectionTest.java | 67 +++++++++++++++++++ ...or.java => MockOpenaireRestConnector.java} | 6 +- ...a => OpenaireFundingDataProviderTest.java} | 48 ++++++------- .../app/rest/RestResourceController.java | 11 +++ .../repository/QAEventRestRepository.java | 5 +- .../dspaceFolder/config/item-submission.xml | 32 ++++----- .../config/spring/api/external-openaire.xml | 10 +-- .../config/spring/api/test-discovery.xml | 4 +- .../app/rest/DiscoveryVersioningIT.java | 4 +- .../rest/ExternalSourcesRestControllerIT.java | 2 +- ... => OpenaireFundingExternalSourcesIT.java} | 26 +++---- .../app/rest/QAEventRestRepositoryIT.java | 15 ++++- ...a => MockOpenaireFundingDataProvider.java} | 8 +-- .../crosswalks/oai/transformers/openaire4.xsl | 4 +- dspace/config/crosswalks/oai/xoai.xml | 36 +++++----- dspace/config/item-submission.xml | 32 ++++----- dspace/config/modules/openaire-client.cfg | 8 +-- dspace/config/registries/openaire4-types.xml | 8 +-- .../registries/relationship-formats.xml | 2 +- .../registries/schema-organization-types.xml | 4 +- .../config/registries/schema-person-types.xml | 10 +-- .../registries/schema-project-types.xml | 4 +- dspace/config/spring/api/discovery.xml | 6 +- .../config/spring/api/external-openaire.xml | 8 +-- dspace/config/spring/api/item-filters.xml | 4 +- dspace/config/spring/api/qaevents.xml | 2 +- dspace/config/spring/api/scripts.xml | 2 +- dspace/config/spring/rest/scripts.xml | 2 +- dspace/config/submission-forms.xml | 20 +++--- dspace/solr/qaevent/conf/schema.xml | 23 ------- 46 files changed, 306 insertions(+), 237 deletions(-) rename dspace-api/src/main/java/org/dspace/external/{OpenAIRERestConnector.java => OpenaireRestConnector.java} (92%) rename dspace-api/src/main/java/org/dspace/external/{OpenAIRERestToken.java => OpenaireRestToken.java} (89%) rename dspace-api/src/main/java/org/dspace/external/provider/impl/{OpenAIREFundingDataProvider.java => OpenaireFundingDataProvider.java} (94%) rename dspace-api/src/main/java/org/dspace/qaevent/dao/{QAEventsDao.java => QAEventsDAO.java} (98%) rename dspace-api/src/main/java/org/dspace/qaevent/dao/impl/{QAEventsDaoImpl.java => QAEventsDAOImpl.java} (89%) rename dspace-api/src/test/java/org/dspace/external/{MockOpenAIRERestConnector.java => MockOpenaireRestConnector.java} (90%) rename dspace-api/src/test/java/org/dspace/external/provider/impl/{OpenAIREFundingDataProviderTest.java => OpenaireFundingDataProviderTest.java} (59%) rename dspace-server-webapp/src/test/java/org/dspace/app/rest/{OpenAIREFundingExternalSourcesIT.java => OpenaireFundingExternalSourcesIT.java} (83%) rename dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/{MockOpenAIREFundingDataProvider.java => MockOpenaireFundingDataProvider.java} (91%) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index e09e4725ca..f6144961c6 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -77,7 +77,7 @@ import org.dspace.orcid.service.OrcidQueueService; import org.dspace.orcid.service.OrcidSynchronizationService; import org.dspace.orcid.service.OrcidTokenService; import org.dspace.profile.service.ResearcherProfileService; -import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.dao.QAEventsDAO; import org.dspace.services.ConfigurationService; import org.dspace.versioning.service.VersioningService; import org.dspace.workflow.WorkflowItemService; @@ -172,7 +172,7 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It protected SubscribeService subscribeService; @Autowired - private QAEventsDao qaEventsDao; + private QAEventsDAO qaEventsDao; protected ItemServiceImpl() { super(); diff --git a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java index 0a8f6d6f3d..b9fde450c2 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/EPersonServiceImpl.java @@ -48,7 +48,7 @@ import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.SubscribeService; import org.dspace.event.Event; import org.dspace.orcid.service.OrcidTokenService; -import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.dao.QAEventsDAO; import org.dspace.services.ConfigurationService; import org.dspace.util.UUIDUtils; import org.dspace.versioning.Version; @@ -109,7 +109,7 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl impleme @Autowired protected OrcidTokenService orcidTokenService; @Autowired - protected QAEventsDao qaEventsDao; + protected QAEventsDAO qaEventsDao; protected EPersonServiceImpl() { super(); diff --git a/dspace-api/src/main/java/org/dspace/external/OpenAIRERestConnector.java b/dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java similarity index 92% rename from dspace-api/src/main/java/org/dspace/external/OpenAIRERestConnector.java rename to dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java index b0aa4aba13..2ec08be055 100644 --- a/dspace-api/src/main/java/org/dspace/external/OpenAIRERestConnector.java +++ b/dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java @@ -40,20 +40,20 @@ import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; /** - * based on OrcidRestConnector it's a rest connector for OpenAIRE API providing + * based on OrcidRestConnector it's a rest connector for Openaire API providing * ways to perform searches and token grabbing * * @author paulo-graca * */ -public class OpenAIRERestConnector { +public class OpenaireRestConnector { /** * log4j logger */ - private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenAIRERestConnector.class); + private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenaireRestConnector.class); /** - * OpenAIRE API Url + * Openaire API Url * and can be configured with: openaire.api.url */ private String url = "https://api.openaire.eu"; @@ -65,30 +65,30 @@ public class OpenAIRERestConnector { boolean tokenEnabled = false; /** - * OpenAIRE Authorization and Authentication Token Service URL + * Openaire Authorization and Authentication Token Service URL * and can be configured with: openaire.token.url */ private String tokenServiceUrl; /** - * OpenAIRE clientId + * Openaire clientId * and can be configured with: openaire.token.clientId */ private String clientId; /** - * OpenAIRERest access token + * OpenaireRest access token */ - private OpenAIRERestToken accessToken; + private OpenaireRestToken accessToken; /** - * OpenAIRE clientSecret + * Openaire clientSecret * and can be configured with: openaire.token.clientSecret */ private String clientSecret; - public OpenAIRERestConnector(String url) { + public OpenaireRestConnector(String url) { this.url = url; } @@ -99,11 +99,11 @@ public class OpenAIRERestConnector { * * @throws IOException */ - public OpenAIRERestToken grabNewAccessToken() throws IOException { + public OpenaireRestToken grabNewAccessToken() throws IOException { if (StringUtils.isBlank(tokenServiceUrl) || StringUtils.isBlank(clientId) || StringUtils.isBlank(clientSecret)) { - throw new IOException("Cannot grab OpenAIRE token with nulls service url, client id or secret"); + throw new IOException("Cannot grab Openaire token with nulls service url, client id or secret"); } String auth = clientId + ":" + clientSecret; @@ -145,13 +145,13 @@ public class OpenAIRERestConnector { throw new IOException("Unable to grab the access token using provided service url, client id and secret"); } - return new OpenAIRERestToken(responseObject.get("access_token").toString(), + return new OpenaireRestToken(responseObject.get("access_token").toString(), Long.valueOf(responseObject.get("expires_in").toString())); } /** - * Perform a GET request to the OpenAIRE API + * Perform a GET request to the Openaire API * * @param file * @param accessToken @@ -218,12 +218,12 @@ public class OpenAIRERestConnector { } /** - * Perform an OpenAIRE Project Search By Keywords + * Perform an Openaire Project Search By Keywords * * @param page * @param size * @param keywords - * @return OpenAIRE Response + * @return Openaire Response */ public Response searchProjectByKeywords(int page, int size, String... keywords) { String path = "search/projects?keywords=" + String.join("+", keywords); @@ -231,13 +231,13 @@ public class OpenAIRERestConnector { } /** - * Perform an OpenAIRE Project Search By ID and by Funder + * Perform an Openaire Project Search By ID and by Funder * * @param projectID * @param projectFunder * @param page * @param size - * @return OpenAIRE Response + * @return Openaire Response */ public Response searchProjectByIDAndFunder(String projectID, String projectFunder, int page, int size) { String path = "search/projects?grantID=" + projectID + "&funder=" + projectFunder; @@ -245,12 +245,12 @@ public class OpenAIRERestConnector { } /** - * Perform an OpenAIRE Search request + * Perform an Openaire Search request * * @param path * @param page * @param size - * @return OpenAIRE Response + * @return Openaire Response */ public Response search(String path, int page, int size) { String[] queryStringPagination = { "page=" + page, "size=" + size }; diff --git a/dspace-api/src/main/java/org/dspace/external/OpenAIRERestToken.java b/dspace-api/src/main/java/org/dspace/external/OpenaireRestToken.java similarity index 89% rename from dspace-api/src/main/java/org/dspace/external/OpenAIRERestToken.java rename to dspace-api/src/main/java/org/dspace/external/OpenaireRestToken.java index 203f09b3c6..f5dc2b27f8 100644 --- a/dspace-api/src/main/java/org/dspace/external/OpenAIRERestToken.java +++ b/dspace-api/src/main/java/org/dspace/external/OpenaireRestToken.java @@ -8,13 +8,13 @@ package org.dspace.external; /** - * OpenAIRE rest API token to be used when grabbing an accessToken.
+ * Openaire rest API token to be used when grabbing an accessToken.
* Based on https://develop.openaire.eu/basic.html * * @author paulo-graca * */ -public class OpenAIRERestToken { +public class OpenaireRestToken { /** * Stored access token @@ -32,7 +32,7 @@ public class OpenAIRERestToken { * @param accessToken * @param expiresIn */ - public OpenAIRERestToken(String accessToken, Long expiresIn) { + public OpenaireRestToken(String accessToken, Long expiresIn) { this.accessToken = accessToken; this.setExpirationDate(expiresIn); } diff --git a/dspace-api/src/main/java/org/dspace/external/provider/impl/OpenAIREFundingDataProvider.java b/dspace-api/src/main/java/org/dspace/external/provider/impl/OpenaireFundingDataProvider.java similarity index 94% rename from dspace-api/src/main/java/org/dspace/external/provider/impl/OpenAIREFundingDataProvider.java rename to dspace-api/src/main/java/org/dspace/external/provider/impl/OpenaireFundingDataProvider.java index 8ca5b7c0ea..62cef508c5 100644 --- a/dspace-api/src/main/java/org/dspace/external/provider/impl/OpenAIREFundingDataProvider.java +++ b/dspace-api/src/main/java/org/dspace/external/provider/impl/OpenaireFundingDataProvider.java @@ -31,7 +31,7 @@ import eu.openaire.oaf.model.base.Project; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.Logger; import org.dspace.content.dto.MetadataValueDTO; -import org.dspace.external.OpenAIRERestConnector; +import org.dspace.external.OpenaireRestConnector; import org.dspace.external.model.ExternalDataObject; import org.dspace.external.provider.AbstractExternalDataProvider; import org.dspace.importer.external.metadatamapping.MetadataFieldConfig; @@ -39,13 +39,13 @@ import org.springframework.beans.factory.annotation.Autowired; /** * This class is the implementation of the ExternalDataProvider interface that - * will deal with the OpenAIRE External Data lookup + * will deal with the Openaire External Data lookup * * @author paulo-graca */ -public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { +public class OpenaireFundingDataProvider extends AbstractExternalDataProvider { - private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenAIREFundingDataProvider.class); + private static Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenaireFundingDataProvider.class); /** * GrantAgreement prefix @@ -75,7 +75,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { /** * Connector to handle token and requests */ - protected OpenAIRERestConnector connector; + protected OpenaireRestConnector connector; protected Map metadataFields; @@ -93,7 +93,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { // characters that must be escaped for the <:entry-id> String decodedId = new String(Base64.getDecoder().decode(id)); if (!isValidProjectURI(decodedId)) { - log.error("Invalid ID for OpenAIREFunding - " + id); + log.error("Invalid ID for OpenaireFunding - " + id); return Optional.empty(); } Response response = searchByProjectURI(decodedId); @@ -101,7 +101,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { try { if (response.getHeader() != null && Integer.parseInt(response.getHeader().getTotal()) > 0) { Project project = response.getResults().getResult().get(0).getMetadata().getEntity().getProject(); - ExternalDataObject externalDataObject = new OpenAIREFundingDataProvider + ExternalDataObject externalDataObject = new OpenaireFundingDataProvider .ExternalDataObjectBuilder(project) .setId(generateProjectURI(project)) .setSource(sourceIdentifier) @@ -123,7 +123,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { limit = LIMIT_DEFAULT; } - // OpenAIRE uses pages and first page starts with 1 + // Openaire uses pages and first page starts with 1 int page = (start / limit) + 1; // escaping query @@ -148,7 +148,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { if (projects.size() > 0) { return projects.stream() - .map(project -> new OpenAIREFundingDataProvider + .map(project -> new OpenaireFundingDataProvider .ExternalDataObjectBuilder(project) .setId(generateProjectURI(project)) .setSource(sourceIdentifier) @@ -176,24 +176,24 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { * Generic setter for the sourceIdentifier * * @param sourceIdentifier The sourceIdentifier to be set on this - * OpenAIREFunderDataProvider + * OpenaireFunderDataProvider */ @Autowired(required = true) public void setSourceIdentifier(String sourceIdentifier) { this.sourceIdentifier = sourceIdentifier; } - public OpenAIRERestConnector getConnector() { + public OpenaireRestConnector getConnector() { return connector; } /** - * Generic setter for OpenAIRERestConnector + * Generic setter for OpenaireRestConnector * * @param connector */ @Autowired(required = true) - public void setConnector(OpenAIRERestConnector connector) { + public void setConnector(OpenaireRestConnector connector) { this.connector = connector; } @@ -219,7 +219,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { } /** - * This method returns an URI based on OpenAIRE 3.0 guidelines + * This method returns an URI based on Openaire 3.0 guidelines * https://guidelines.openaire.eu/en/latest/literature/field_projectid.html that * can be used as an ID if is there any missing part, that part it will be * replaced by the character '+' @@ -281,7 +281,7 @@ public class OpenAIREFundingDataProvider extends AbstractExternalDataProvider { } /** - * OpenAIRE Funding External Data Builder Class + * Openaire Funding External Data Builder Class * * @author pgraca */ diff --git a/dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java b/dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java index 68976430e6..6460c360ec 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QAEventsDeleteCascadeConsumer.java @@ -16,7 +16,7 @@ import org.dspace.qaevent.service.QAEventService; import org.dspace.utils.DSpace; /** - * Consumer to delete qaevents once the target item is deleted + * Consumer to delete qaevents from solr due to the target item deletion * * @author Andrea Bollini (andrea.bollini at 4science.it) * diff --git a/dspace-api/src/main/java/org/dspace/qaevent/QASource.java b/dspace-api/src/main/java/org/dspace/qaevent/QASource.java index b3f7be5f52..e22f7d32a7 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/QASource.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/QASource.java @@ -10,7 +10,7 @@ package org.dspace.qaevent; import java.util.Date; /** - * This model class represent the source/provider of the QA events (as OpenAIRE). + * This model class represent the source/provider of the QA events (as Openaire). * * @author Luca Giamminonni (luca.giamminonni at 4Science) * diff --git a/dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDao.java b/dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDAO.java similarity index 98% rename from dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDao.java rename to dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDAO.java index 9de2d12460..98c38ca3f5 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDao.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/dao/QAEventsDAO.java @@ -22,7 +22,7 @@ import org.dspace.eperson.EPerson; * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public interface QAEventsDao extends GenericDAO { +public interface QAEventsDAO extends GenericDAO { /** * Returns all the stored QAEventProcessed entities. diff --git a/dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDaoImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDAOImpl.java similarity index 89% rename from dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDaoImpl.java rename to dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDAOImpl.java index 3263ae9de9..ac9b96045e 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDaoImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/dao/impl/QAEventsDAOImpl.java @@ -17,16 +17,16 @@ import org.dspace.content.QAEventProcessed; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.dao.QAEventsDAO; /** - * Implementation of {@link QAEventsDao} that store processed events using an + * Implementation of {@link QAEventsDAO} that store processed events using an * SQL DBMS. * * @author Andrea Bollini (andrea.bollini at 4science.it) * */ -public class QAEventsDaoImpl extends AbstractHibernateDAO implements QAEventsDao { +public class QAEventsDAOImpl extends AbstractHibernateDAO implements QAEventsDAO { @Override public List findAll(Context context) throws SQLException { @@ -60,7 +60,7 @@ public class QAEventsDaoImpl extends AbstractHibernateDAO impl public List searchByEventId(Context context, String eventId, Integer start, Integer size) throws SQLException { Query query = createQuery(context, - "SELECT * " + "FROM QAEventProcessed qaevent WHERE qaevent.qaevent_id = :event_id "); + "SELECT * FROM QAEventProcessed qaevent WHERE qaevent.qaevent_id = :event_id "); query.setFirstResult(start); query.setMaxResults(size); query.setParameter("event_id", eventId); diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java index e45dc3e159..8bd864d7da 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java @@ -42,7 +42,9 @@ import org.dspace.utils.DSpace; /** * Implementation of {@link DSpaceRunnable} to perfom a QAEvents import from a * json file. The JSON file contains an array of JSON Events, where each event - * has the following structure + * has the following structure. The message attribute follows the structure + * documented at + * @see see * *
* {
diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java index 14737de635..60001e7350 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImportScriptConfiguration.java @@ -54,12 +54,12 @@ public class OpenaireEventsImportScriptConfiguration see * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java index bbb6990bb6..9be4af2d08 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java @@ -43,8 +43,8 @@ import org.dspace.core.Context; import org.dspace.handle.service.HandleService; 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.dao.QAEventsDAO; +import org.dspace.qaevent.dao.impl.QAEventsDAOImpl; import org.dspace.qaevent.service.QAEventService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; @@ -54,7 +54,7 @@ import org.springframework.beans.factory.annotation.Autowired; * Implementation of {@link QAEventService} that use Solr to store events. When * the user performs an action on the event (such as accepting the suggestion or * rejecting it) then the event is removed from solr and saved in the database - * (see {@link QAEventsDao}) so that it is no longer proposed. + * (see {@link QAEventsDAO}) so that it is no longer proposed. * * @author Andrea Bollini (andrea.bollini at 4science.it) * @@ -71,7 +71,7 @@ public class QAEventServiceImpl implements QAEventService { private HandleService handleService; @Autowired - private QAEventsDaoImpl qaEventsDao; + private QAEventsDAOImpl qaEventsDao; private ObjectMapper jsonMapper; diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml index f1e6c30d13..8a5277ab2d 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml @@ -7,7 +7,7 @@ http://www.springframework.org/schema/util/spring-util.xsd" default-lazy-init="true"> - + @@ -15,10 +15,10 @@ - - + + diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/item-filters.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/item-filters.xml index 836d4f0896..8bae32eaef 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/item-filters.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/item-filters.xml @@ -286,7 +286,7 @@ - @@ -329,7 +329,7 @@
- diff --git a/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml b/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml index b80330564f..a197b2910b 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/spring/api/scripts.xml @@ -66,7 +66,7 @@ - + diff --git a/dspace-api/src/test/java/org/dspace/content/CollectionTest.java b/dspace-api/src/test/java/org/dspace/content/CollectionTest.java index 13d037abf8..a177571ffa 100644 --- a/dspace-api/src/test/java/org/dspace/content/CollectionTest.java +++ b/dspace-api/src/test/java/org/dspace/content/CollectionTest.java @@ -1200,4 +1200,71 @@ public class CollectionTest extends AbstractDSpaceObjectTest { equalTo(owningCommunity)); } + /** + * Test of retrieveCollectionWithSubmitByEntityType method getting the closest + * collection of non-item type starting from an item + */ + @Test + public void testRetrieveCollectionWithSubmitByEntityType() throws SQLException, AuthorizeException { + context.setDispatcher("default"); + context.turnOffAuthorisationSystem(); + Community com = communityService.create(null, context); + Group submitters = groupService.create(context); + Collection collection = collectionService.create(context, com); + collectionService.addMetadata(context, collection, "dspace", "entity", "type", + null, "Publication"); + com.addCollection(collection); + WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); + Item item = installItemService.installItem(context, workspaceItem); + EPerson epersonA = ePersonService.create(context); + Collection collectionPerson = collectionService.create(context, com); + collectionService.addMetadata(context, collectionPerson, "dspace", "entity", "type", + null, "Person"); + collectionPerson.setSubmitters(submitters); + groupService.addMember(context, submitters, epersonA); + context.setCurrentUser(epersonA); + context.commit(); + context.restoreAuthSystemState(); + Collection resultCollection = collectionService.retrieveCollectionWithSubmitByEntityType + (context, item, "Person"); + + assertThat("testRetrieveCollectionWithSubmitByEntityType 0", resultCollection, notNullValue()); + assertThat("testRetrieveCollectionWithSubmitByEntityType 1", resultCollection, equalTo(collectionPerson)); + + context.setDispatcher("exclude-discovery"); + } + + /** + * Test of rretrieveCollectionWithSubmitByCommunityAndEntityType method getting the closest + * collection of non-community type starting from an community + */ + @Test + public void testRetrieveCollectionWithSubmitByCommunityAndEntityType() throws SQLException, AuthorizeException { + context.setDispatcher("default"); + context.turnOffAuthorisationSystem(); + Community com = communityService.create(null, context); + Group submitters = groupService.create(context); + Collection collection = collectionService.create(context, com); + collectionService.addMetadata(context, collection, "dspace", "entity", "type", + null, "Publication"); + com.addCollection(collection); + WorkspaceItem workspaceItem = workspaceItemService.create(context, collection, false); + Item item = installItemService.installItem(context, workspaceItem); + EPerson epersonA = ePersonService.create(context); + Collection collectionPerson = collectionService.create(context, com); + collectionService.addMetadata(context, collectionPerson, "dspace", "entity", "type", + null, "Person"); + collectionPerson.setSubmitters(submitters); + groupService.addMember(context, submitters, epersonA); + context.setCurrentUser(epersonA); + context.commit(); + context.restoreAuthSystemState(); + Collection resultCollection = collectionService.retrieveCollectionWithSubmitByCommunityAndEntityType + (context, com, "Person"); + + assertThat("testRetrieveCollectionWithSubmitByEntityType 0", resultCollection, notNullValue()); + assertThat("testRetrieveCollectionWithSubmitByEntityType 1", resultCollection, equalTo(collectionPerson)); + + context.setDispatcher("exclude-discovery"); + } } diff --git a/dspace-api/src/test/java/org/dspace/external/MockOpenAIRERestConnector.java b/dspace-api/src/test/java/org/dspace/external/MockOpenaireRestConnector.java similarity index 90% rename from dspace-api/src/test/java/org/dspace/external/MockOpenAIRERestConnector.java rename to dspace-api/src/test/java/org/dspace/external/MockOpenaireRestConnector.java index bac80e196c..c67402dfdc 100644 --- a/dspace-api/src/test/java/org/dspace/external/MockOpenAIRERestConnector.java +++ b/dspace-api/src/test/java/org/dspace/external/MockOpenaireRestConnector.java @@ -14,15 +14,15 @@ import eu.openaire.jaxb.helper.OpenAIREHandler; import eu.openaire.jaxb.model.Response; /** - * Mock the OpenAIRE rest connector for unit testing
+ * Mock the Openaire rest connector for unit testing
* will be resolved against static test xml files * * @author pgraca * */ -public class MockOpenAIRERestConnector extends OpenAIRERestConnector { +public class MockOpenaireRestConnector extends OpenaireRestConnector { - public MockOpenAIRERestConnector(String url) { + public MockOpenaireRestConnector(String url) { super(url); } diff --git a/dspace-api/src/test/java/org/dspace/external/provider/impl/OpenAIREFundingDataProviderTest.java b/dspace-api/src/test/java/org/dspace/external/provider/impl/OpenaireFundingDataProviderTest.java similarity index 59% rename from dspace-api/src/test/java/org/dspace/external/provider/impl/OpenAIREFundingDataProviderTest.java rename to dspace-api/src/test/java/org/dspace/external/provider/impl/OpenaireFundingDataProviderTest.java index 5e96f06ac8..d14dc99035 100644 --- a/dspace-api/src/test/java/org/dspace/external/provider/impl/OpenAIREFundingDataProviderTest.java +++ b/dspace-api/src/test/java/org/dspace/external/provider/impl/OpenaireFundingDataProviderTest.java @@ -23,15 +23,15 @@ import org.junit.Before; import org.junit.Test; /** - * Unit tests for OpenAIREFundingDataProvider + * Unit tests for OpenaireFundingDataProvider * * @author pgraca * */ -public class OpenAIREFundingDataProviderTest extends AbstractDSpaceTest { +public class OpenaireFundingDataProviderTest extends AbstractDSpaceTest { ExternalDataService externalDataService; - ExternalDataProvider openAIREFundingDataProvider; + ExternalDataProvider openaireFundingDataProvider; /** * This method will be run before every test as per @Before. It will initialize @@ -44,38 +44,38 @@ public class OpenAIREFundingDataProviderTest extends AbstractDSpaceTest { public void init() { // Set up External Service Factory and set data providers externalDataService = ExternalServiceFactory.getInstance().getExternalDataService(); - openAIREFundingDataProvider = externalDataService.getExternalDataProvider("openAIREFunding"); + openaireFundingDataProvider = externalDataService.getExternalDataProvider("openaireFunding"); } @Test public void testNumberOfResultsWSingleKeyword() { - assertNotNull("openAIREFundingDataProvider is not null", openAIREFundingDataProvider); - assertEquals("openAIREFunding.numberOfResults.query:mock", 77, - openAIREFundingDataProvider.getNumberOfResults("mock")); + assertNotNull("openaireFundingDataProvider is not null", openaireFundingDataProvider); + assertEquals("openaireFunding.numberOfResults.query:mock", 77, + openaireFundingDataProvider.getNumberOfResults("mock")); } @Test public void testNumberOfResultsWKeywords() { - assertNotNull("openAIREFundingDataProvider is not null", openAIREFundingDataProvider); - assertEquals("openAIREFunding.numberOfResults.query:mock+test", 77, - openAIREFundingDataProvider.getNumberOfResults("mock+test")); + assertNotNull("openaireFundingDataProvider is not null", openaireFundingDataProvider); + assertEquals("openaireFunding.numberOfResults.query:mock+test", 77, + openaireFundingDataProvider.getNumberOfResults("mock+test")); } @Test public void testQueryResultsWSingleKeyword() { - assertNotNull("openAIREFundingDataProvider is not null", openAIREFundingDataProvider); - List results = openAIREFundingDataProvider.searchExternalDataObjects("mock", 0, 10); - assertEquals("openAIREFunding.searchExternalDataObjects.size", 10, results.size()); + assertNotNull("openaireFundingDataProvider is not null", openaireFundingDataProvider); + List results = openaireFundingDataProvider.searchExternalDataObjects("mock", 0, 10); + assertEquals("openaireFunding.searchExternalDataObjects.size", 10, results.size()); } @Test public void testQueryResultsWKeywords() { String value = "Mushroom Robo-Pic - Development of an autonomous robotic mushroom picking system"; - assertNotNull("openAIREFundingDataProvider is not null", openAIREFundingDataProvider); - List results = openAIREFundingDataProvider.searchExternalDataObjects("mock+test", 0, 10); - assertEquals("openAIREFunding.searchExternalDataObjects.size", 10, results.size()); - assertTrue("openAIREFunding.searchExternalDataObjects.first.value", value.equals(results.get(0).getValue())); + assertNotNull("openaireFundingDataProvider is not null", openaireFundingDataProvider); + List results = openaireFundingDataProvider.searchExternalDataObjects("mock+test", 0, 10); + assertEquals("openaireFunding.searchExternalDataObjects.size", 10, results.size()); + assertTrue("openaireFunding.searchExternalDataObjects.first.value", value.equals(results.get(0).getValue())); } @Test @@ -84,22 +84,22 @@ public class OpenAIREFundingDataProviderTest extends AbstractDSpaceTest { String value = "Portuguese Wild Mushrooms: Chemical characterization and functional study" + " of antiproliferative and proapoptotic properties in cancer cell lines"; - assertNotNull("openAIREFundingDataProvider is not null", openAIREFundingDataProvider); + assertNotNull("openaireFundingDataProvider is not null", openaireFundingDataProvider); - Optional result = openAIREFundingDataProvider.getExternalDataObject(id); + Optional result = openaireFundingDataProvider.getExternalDataObject(id); - assertTrue("openAIREFunding.getExternalDataObject.exists", result.isPresent()); - assertTrue("openAIREFunding.getExternalDataObject.value", value.equals(result.get().getValue())); + assertTrue("openaireFunding.getExternalDataObject.exists", result.isPresent()); + assertTrue("openaireFunding.getExternalDataObject.value", value.equals(result.get().getValue())); } @Test public void testGetDataObjectWInvalidId() { String id = "WRONGID"; - assertNotNull("openAIREFundingDataProvider is not null", openAIREFundingDataProvider); + assertNotNull("openaireFundingDataProvider is not null", openaireFundingDataProvider); - Optional result = openAIREFundingDataProvider.getExternalDataObject(id); + Optional result = openaireFundingDataProvider.getExternalDataObject(id); - assertTrue("openAIREFunding.getExternalDataObject.notExists:WRONGID", result.isEmpty()); + assertTrue("openaireFunding.getExternalDataObject.notExists:WRONGID", result.isEmpty()); } } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java index e1b7cc89cf..03bea35597 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/RestResourceController.java @@ -1093,6 +1093,17 @@ public class RestResourceController implements InitializingBean { return uriComponentsBuilder.encode().build().toString(); } + /** + * Method to delete an entity by ID + * Note that the regular expression in the request mapping accept a number as identifier; + * + * @param request + * @param apiCategory + * @param model + * @param id + * @return + * @throws HttpRequestMethodNotSupportedException + */ @RequestMapping(method = RequestMethod.DELETE, value = REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT) public ResponseEntity> delete(HttpServletRequest request, @PathVariable String apiCategory, @PathVariable String model, @PathVariable Integer id) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java index bd9b31e14c..dc0654ee49 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QAEventRestRepository.java @@ -23,7 +23,7 @@ import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; -import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.dao.QAEventsDAO; import org.dspace.qaevent.service.QAEventService; import org.dspace.util.UUIDUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -48,7 +48,7 @@ public class QAEventRestRepository extends DSpaceRestRepositoryfake.workflow.readonly org.dspace.submit.step.SampleStep sample workflow --> - - + + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form @@ -259,13 +259,13 @@ - - + + - - + + @@ -274,17 +274,17 @@ - + - + - + - + - + - + diff --git a/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml b/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml index 9db02440e4..b045865fe0 100644 --- a/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml +++ b/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-lazy-init="true"> - + - - + + Project diff --git a/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/test-discovery.xml b/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/test-discovery.xml index 4a91ef051e..ea654ac55c 100644 --- a/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/test-discovery.xml +++ b/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/test-discovery.xml @@ -86,8 +86,8 @@ - - + + diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryVersioningIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryVersioningIT.java index 083b27d0e5..7b9cad70e9 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryVersioningIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryVersioningIT.java @@ -1057,8 +1057,8 @@ public class DiscoveryVersioningIT extends AbstractControllerIntegrationTest { } @Test - public void test_discoveryXml_openAIREFundingAgency_expectLatestVersionsOnly() throws Exception { - final String configuration = "openAIREFundingAgency"; + public void test_discoveryXml_openaireFundingAgency_expectLatestVersionsOnly() throws Exception { + final String configuration = "openaireFundingAgency"; Collection collection = createCollection("OrgUnit"); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java index 65492cbbe8..2b03b50c55 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ExternalSourcesRestControllerIT.java @@ -51,7 +51,7 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati ExternalSourceMatcher.matchExternalSource( "pubmed", "pubmed", false), ExternalSourceMatcher.matchExternalSource( - "openAIREFunding", "openAIREFunding", false) + "openaireFunding", "openaireFunding", false) ))) .andExpect(jsonPath("$.page.totalElements", Matchers.is(10))); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenAIREFundingExternalSourcesIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenaireFundingExternalSourcesIT.java similarity index 83% rename from dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenAIREFundingExternalSourcesIT.java rename to dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenaireFundingExternalSourcesIT.java index b8f886b2e4..8c76c7adea 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenAIREFundingExternalSourcesIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenaireFundingExternalSourcesIT.java @@ -19,7 +19,7 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.hamcrest.Matchers; import org.junit.Test; -public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrationTest { +public class OpenaireFundingExternalSourcesIT extends AbstractControllerIntegrationTest { /** * Test openaire funding external source @@ -27,10 +27,10 @@ public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrat * @throws Exception */ @Test - public void findOneOpenAIREFundingExternalSourceTest() throws Exception { + public void findOneOpenaireFundingExternalSourceTest() throws Exception { getClient().perform(get("/api/integration/externalsources")).andExpect(status().isOk()) .andExpect(jsonPath("$._embedded.externalsources", Matchers.hasItem( - ExternalSourceMatcher.matchExternalSource("openAIREFunding", "openAIREFunding", false)))); + ExternalSourceMatcher.matchExternalSource("openaireFunding", "openaireFunding", false)))); } /** @@ -39,9 +39,9 @@ public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrat * @throws Exception */ @Test - public void findOneOpenAIREFundingExternalSourceEntriesEmptyWithQueryTest() throws Exception { + public void findOneOpenaireFundingExternalSourceEntriesEmptyWithQueryTest() throws Exception { - getClient().perform(get("/api/integration/externalsources/openAIREFunding/entries").param("query", "empty")) + getClient().perform(get("/api/integration/externalsources/openaireFunding/entries").param("query", "empty")) .andExpect(status().isOk()).andExpect(jsonPath("$.page.number", is(0))); } @@ -52,11 +52,11 @@ public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrat * @throws Exception */ @Test - public void findOneOpenAIREFundingExternalSourceEntriesWithQueryMultipleKeywordsTest() throws Exception { + public void findOneOpenaireFundingExternalSourceEntriesWithQueryMultipleKeywordsTest() throws Exception { getClient() .perform( - get("/api/integration/externalsources/openAIREFunding/entries").param("query", "empty+results")) + get("/api/integration/externalsources/openaireFunding/entries").param("query", "empty+results")) .andExpect(status().isOk()).andExpect(jsonPath("$.page.number", is(0))); } @@ -66,14 +66,14 @@ public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrat * @throws Exception */ @Test - public void findOneOpenAIREFundingExternalSourceEntriesWithQueryTest() throws Exception { - getClient().perform(get("/api/integration/externalsources/openAIREFunding/entries").param("query", "mushroom")) + public void findOneOpenaireFundingExternalSourceEntriesWithQueryTest() throws Exception { + getClient().perform(get("/api/integration/externalsources/openaireFunding/entries").param("query", "mushroom")) .andExpect(status().isOk()) .andExpect(jsonPath("$._embedded.externalSourceEntries", Matchers.hasItem(ExternalSourceEntryMatcher.matchExternalSourceEntry( "aW5mbzpldS1yZXBvL2dyYW50QWdyZWVtZW50L05XTy8rLzIzMDAxNDc3MjgvTkw=", "Master switches of initiation of mushroom formation", - "Master switches of initiation of mushroom formation", "openAIREFunding")))); + "Master switches of initiation of mushroom formation", "openaireFunding")))); } @@ -83,19 +83,19 @@ public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrat * @throws Exception */ @Test - public void findOneOpenAIREFundingExternalSourceEntryValueTest() throws Exception { + public void findOneOpenaireFundingExternalSourceEntryValueTest() throws Exception { // "info:eu-repo/grantAgreement/mock/mock/mock/mock" base64 encoded String projectID = "aW5mbzpldS1yZXBvL2dyYW50QWdyZWVtZW50L0ZDVC81ODc2LVBQQ0RUSS8xMTAwNjIvUFQ="; String projectName = "Portuguese Wild Mushrooms: Chemical characterization and functional study" + " of antiproliferative and proapoptotic properties in cancer cell lines"; - getClient().perform(get("/api/integration/externalsources/openAIREFunding/entryValues/" + projectID)) + getClient().perform(get("/api/integration/externalsources/openaireFunding/entryValues/" + projectID)) .andExpect(status().isOk()) .andExpect(jsonPath("$", Matchers.allOf(hasJsonPath("$.id", is(projectID)), hasJsonPath("$.display", is(projectName)), hasJsonPath("$.value", is(projectName)), - hasJsonPath("$.externalSource", is("openAIREFunding")), + hasJsonPath("$.externalSource", is("openaireFunding")), hasJsonPath("$.type", is("externalSourceEntry"))))); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java index dc021f2904..592b659457 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/QAEventRestRepositoryIT.java @@ -44,7 +44,7 @@ import org.dspace.content.EntityType; import org.dspace.content.Item; import org.dspace.content.QAEvent; import org.dspace.content.QAEventProcessed; -import org.dspace.qaevent.dao.QAEventsDao; +import org.dspace.qaevent.dao.QAEventsDAO; import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -58,7 +58,7 @@ import org.springframework.beans.factory.annotation.Autowired; public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { @Autowired - private QAEventsDao qaEventsDao; + private QAEventsDAO qaEventsDao; @Test public void findAllNotImplementedTest() throws Exception { @@ -759,6 +759,11 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}") .build(); + QAEvent event2 = QAEventBuilder.createTarget(context, col1, "Science and Freedom") + .withTopic("ENRICH/MISSING/PID") + .withMessage("{\"pids[0].type\":\"doi\",\"pids[0].value\":\"10.2307/2144300\"}") + .build(); + context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); @@ -786,5 +791,11 @@ public class QAEventRestRepositoryIT extends AbstractControllerIntegrationTest { assertThat(processedEvent.getEventTimestamp(), notNullValue()); assertThat(processedEvent.getEperson().getID(), is(admin.getID())); + getClient(authToken).perform(delete("/api/integration/qualityassuranceevents/" + event.getEventId())) + .andExpect(status().isInternalServerError()); + + authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform(delete("/api/integration/qualityassuranceevents/" + event2.getEventId())) + .andExpect(status().isForbidden()); } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenAIREFundingDataProvider.java b/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenaireFundingDataProvider.java similarity index 91% rename from dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenAIREFundingDataProvider.java rename to dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenaireFundingDataProvider.java index baf1041ab5..34f1ae16c7 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenAIREFundingDataProvider.java +++ b/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenaireFundingDataProvider.java @@ -14,7 +14,7 @@ import javax.xml.bind.JAXBException; import eu.openaire.jaxb.helper.OpenAIREHandler; import eu.openaire.jaxb.model.Response; -import org.dspace.external.OpenAIRERestConnector; +import org.dspace.external.OpenaireRestConnector; import org.mockito.AdditionalMatchers; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; @@ -22,14 +22,14 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** - * Mock the OpenAIRE external source using a mock rest connector so that query + * Mock the Openaire external source using a mock rest connector so that query * will be resolved against static test files * */ -public class MockOpenAIREFundingDataProvider extends OpenAIREFundingDataProvider { +public class MockOpenaireFundingDataProvider extends OpenaireFundingDataProvider { @Override public void init() throws IOException { - OpenAIRERestConnector restConnector = Mockito.mock(OpenAIRERestConnector.class); + OpenaireRestConnector restConnector = Mockito.mock(OpenaireRestConnector.class); when(restConnector.searchProjectByKeywords(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt(), ArgumentMatchers.startsWith("mushroom"))).thenAnswer(new Answer() { diff --git a/dspace/config/crosswalks/oai/transformers/openaire4.xsl b/dspace/config/crosswalks/oai/transformers/openaire4.xsl index cece890450..8ac703609d 100644 --- a/dspace/config/crosswalks/oai/transformers/openaire4.xsl +++ b/dspace/config/crosswalks/oai/transformers/openaire4.xsl @@ -1,5 +1,5 @@ - + @@ -12,7 +12,7 @@ - + - + @@ -66,12 +66,12 @@ - This contexts complies with OpenAIRE Guidelines for Literature Repositories v3.0. + This contexts complies with Openaire Guidelines for Literature Repositories v3.0. - + - - + + - This contexts complies with OpenAIRE Guidelines for Literature Repositories v4.0. + This contexts complies with Openaire Guidelines for Literature Repositories v4.0. @@ -176,7 +176,7 @@ http://irdb.nii.ac.jp/oai http://irdb.nii.ac.jp/oai/junii2-3-1.xsd - @@ -250,13 +250,13 @@ - @@ -319,7 +319,7 @@ - - + @@ -457,7 +457,7 @@ + OR "openAccess", which is required by Openaire. --> org.dspace.xoai.filter.DSpaceAtLeastOneMetadataFilter @@ -483,7 +483,7 @@ + which specifies the openaire project ID. --> org.dspace.xoai.filter.DSpaceAtLeastOneMetadataFilter @@ -526,7 +526,7 @@ openaire - OpenAIRE + Openaire diff --git a/dspace/config/item-submission.xml b/dspace/config/item-submission.xml index 1060a33031..e5175c3c4e 100644 --- a/dspace/config/item-submission.xml +++ b/dspace/config/item-submission.xml @@ -185,28 +185,28 @@ extract - - + + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form - + submit.progressbar.describe.stepone org.dspace.app.rest.submit.step.DescribeStep submission-form @@ -361,13 +361,13 @@ - - + + - - + + @@ -376,17 +376,17 @@ - + - + - + - + - + - + diff --git a/dspace/config/modules/openaire-client.cfg b/dspace/config/modules/openaire-client.cfg index ded99d0120..b43ef781ee 100644 --- a/dspace/config/modules/openaire-client.cfg +++ b/dspace/config/modules/openaire-client.cfg @@ -16,20 +16,20 @@ # The accessToken it only has a validity of one hour # For more details about the token, please check: https://develop.openaire.eu/personalToken.html # -# the current OpenAIRE Rest client implementation uses basic authentication +# the current Openaire Rest client implementation uses basic authentication # Described here: https://develop.openaire.eu/basic.html # # ---- Token usage required definitions ---- # you can override this settings in your local.cfg file - can be true/false openaire.token.enabled = false -# URL of the OpenAIRE authentication and authorization service +# URL of the Openaire authentication and authorization service openaire.token.url = https://aai.openaire.eu/oidc/token -# you will be required to register at OpenAIRE (https://services.openaire.eu/uoa-user-management/registeredServices) +# you will be required to register at Openaire (https://services.openaire.eu/uoa-user-management/registeredServices) # and create your service in order to get the following data: openaire.token.clientId = CLIENT_ID_HERE openaire.token.clientSecret = CLIENT_SECRET_HERE -# URL of OpenAIRE Rest API +# URL of Openaire Rest API openaire.api.url = https://api.openaire.eu \ No newline at end of file diff --git a/dspace/config/registries/openaire4-types.xml b/dspace/config/registries/openaire4-types.xml index b3290ac120..b46802a46f 100644 --- a/dspace/config/registries/openaire4-types.xml +++ b/dspace/config/registries/openaire4-types.xml @@ -2,13 +2,13 @@ - OpenAIRE4 fields definition + Openaire4 fields definition @@ -108,7 +108,7 @@ datacite @@ -116,7 +116,7 @@ Spatial region or named place where the data was gathered or about which the data is focused. - + datacite subject diff --git a/dspace/config/registries/relationship-formats.xml b/dspace/config/registries/relationship-formats.xml index f2f50182fa..53d15d4d43 100644 --- a/dspace/config/registries/relationship-formats.xml +++ b/dspace/config/registries/relationship-formats.xml @@ -237,7 +237,7 @@ Contains all uuids of PUBLICATIONS which link to the current ISSUE via a "latest" relationship. In other words, this stores all relationships pointing to the current ISSUE from any PUBLICATION, implying that the ISSUE is marked as "latest". Internally used by DSpace to support versioning. Do not manually add, remove or edit values. - + relation diff --git a/dspace/config/registries/schema-organization-types.xml b/dspace/config/registries/schema-organization-types.xml index 91ee203ae9..0b31851078 100644 --- a/dspace/config/registries/schema-organization-types.xml +++ b/dspace/config/registries/schema-organization-types.xml @@ -42,10 +42,10 @@ - + - + organization diff --git a/dspace/config/registries/schema-person-types.xml b/dspace/config/registries/schema-person-types.xml index 3a8f79732d..0a40060e51 100644 --- a/dspace/config/registries/schema-person-types.xml +++ b/dspace/config/registries/schema-person-types.xml @@ -17,7 +17,7 @@ --> @@ -29,7 +29,7 @@ @@ -74,7 +74,7 @@ @@ -84,10 +84,10 @@ The organizational or institutional affiliation of the creator - + - + person identifier diff --git a/dspace/config/registries/schema-project-types.xml b/dspace/config/registries/schema-project-types.xml index c2f844d2b2..4da07b6a79 100644 --- a/dspace/config/registries/schema-project-types.xml +++ b/dspace/config/registries/schema-project-types.xml @@ -18,7 +18,7 @@ --> @@ -29,7 +29,7 @@ diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index fb25f11598..83896feb45 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -110,8 +110,8 @@ - - + +
@@ -2027,7 +2027,7 @@
- diff --git a/dspace/config/spring/api/external-openaire.xml b/dspace/config/spring/api/external-openaire.xml index 25a23a1739..9800e42bd1 100644 --- a/dspace/config/spring/api/external-openaire.xml +++ b/dspace/config/spring/api/external-openaire.xml @@ -7,7 +7,7 @@ http://www.springframework.org/schema/util/spring-util.xsd" default-lazy-init="true"> - + @@ -15,9 +15,9 @@ - - - + + + diff --git a/dspace/config/spring/api/item-filters.xml b/dspace/config/spring/api/item-filters.xml index 24c463fb53..1460c19fe4 100644 --- a/dspace/config/spring/api/item-filters.xml +++ b/dspace/config/spring/api/item-filters.xml @@ -286,7 +286,7 @@ - @@ -329,7 +329,7 @@ - diff --git a/dspace/config/spring/api/qaevents.xml b/dspace/config/spring/api/qaevents.xml index 25bb282672..300a47c8f2 100644 --- a/dspace/config/spring/api/qaevents.xml +++ b/dspace/config/spring/api/qaevents.xml @@ -9,7 +9,7 @@ - + diff --git a/dspace/config/spring/api/scripts.xml b/dspace/config/spring/api/scripts.xml index 8c81ed392b..fdb22bad48 100644 --- a/dspace/config/spring/api/scripts.xml +++ b/dspace/config/spring/api/scripts.xml @@ -5,7 +5,7 @@ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> - + diff --git a/dspace/config/spring/rest/scripts.xml b/dspace/config/spring/rest/scripts.xml index c32ea8d40b..e6a667697d 100644 --- a/dspace/config/spring/rest/scripts.xml +++ b/dspace/config/spring/rest/scripts.xml @@ -9,7 +9,7 @@ - + diff --git a/dspace/config/submission-forms.xml b/dspace/config/submission-forms.xml index 39a4778356..d888e0990e 100644 --- a/dspace/config/submission-forms.xml +++ b/dspace/config/submission-forms.xml @@ -819,9 +819,9 @@ - + -
+ dc @@ -1071,7 +1071,7 @@
-
+ dc @@ -1129,7 +1129,7 @@ relation onebox - openAIREFunding + openaireFunding @@ -1182,7 +1182,7 @@
-
+ person @@ -1246,7 +1246,7 @@
-
+ dc @@ -1269,7 +1269,7 @@ isFundingAgencyOfProject - openAIREFundingAgency + openaireFundingAgency false false @@ -1302,7 +1302,7 @@ -
+ organization @@ -1537,7 +1537,7 @@ - + @@ -1579,7 +1579,7 @@ - - - - - - - - - - - - - - - - - - - - - From 5f992e0b71c9d3da4fc94c138dd616c2a388e73f Mon Sep 17 00:00:00 2001 From: frabacche Date: Wed, 13 Dec 2023 16:14:36 +0100 Subject: [PATCH 33/38] CST-5249 add openaire to custom BrokerClient instance and factory --- .../dspace/qaevent/script/OpenaireEventsImport.java | 4 ++-- ...erClientFactory.java => OpenaireClientFactory.java} | 6 +++--- ...FactoryImpl.java => OpenaireClientFactoryImpl.java} | 6 +++--- .../dspace/qaevent/script/OpenaireEventsImportIT.java | 10 +++++----- dspace/config/spring/api/qaevents.xml | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) rename dspace-api/src/main/java/org/dspace/qaevent/service/{BrokerClientFactory.java => OpenaireClientFactory.java} (81%) rename dspace-api/src/main/java/org/dspace/qaevent/service/impl/{BrokerClientFactoryImpl.java => OpenaireClientFactoryImpl.java} (78%) diff --git a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java index 8bd864d7da..9087606aa6 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/script/OpenaireEventsImport.java @@ -32,7 +32,7 @@ import org.dspace.content.QAEvent; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; -import org.dspace.qaevent.service.BrokerClientFactory; +import org.dspace.qaevent.service.OpenaireClientFactory; import org.dspace.qaevent.service.QAEventService; import org.dspace.scripts.DSpaceRunnable; import org.dspace.services.ConfigurationService; @@ -105,7 +105,7 @@ public class OpenaireEventsImport qaEventService = new DSpace().getSingletonService(QAEventService.class); configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); - brokerClient = BrokerClientFactory.getInstance().getBrokerClient(); + brokerClient = OpenaireClientFactory.getInstance().getBrokerClient(); topicsToImport = configurationService.getArrayProperty("qaevents.openaire.import.topic"); openaireBrokerURL = getOpenaireBrokerUri(); diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/BrokerClientFactory.java b/dspace-api/src/main/java/org/dspace/qaevent/service/OpenaireClientFactory.java similarity index 81% rename from dspace-api/src/main/java/org/dspace/qaevent/service/BrokerClientFactory.java rename to dspace-api/src/main/java/org/dspace/qaevent/service/OpenaireClientFactory.java index c17a7a3ff5..e7a7be33c1 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/BrokerClientFactory.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/OpenaireClientFactory.java @@ -16,7 +16,7 @@ import org.dspace.utils.DSpace; * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public interface BrokerClientFactory { +public interface OpenaireClientFactory { /** * Returns an instance of the {@link BrokerClient}. @@ -25,7 +25,7 @@ public interface BrokerClientFactory { */ public BrokerClient getBrokerClient(); - public static BrokerClientFactory getInstance() { - return new DSpace().getServiceManager().getServiceByName("brokerClientFactory", BrokerClientFactory.class); + public static OpenaireClientFactory getInstance() { + return new DSpace().getServiceManager().getServiceByName("openaireClientFactory", OpenaireClientFactory.class); } } diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/BrokerClientFactoryImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/OpenaireClientFactoryImpl.java similarity index 78% rename from dspace-api/src/main/java/org/dspace/qaevent/service/impl/BrokerClientFactoryImpl.java rename to dspace-api/src/main/java/org/dspace/qaevent/service/impl/OpenaireClientFactoryImpl.java index 8d3f2cdaac..5839f5e877 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/BrokerClientFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/OpenaireClientFactoryImpl.java @@ -8,17 +8,17 @@ package org.dspace.qaevent.service.impl; import eu.dnetlib.broker.BrokerClient; -import org.dspace.qaevent.service.BrokerClientFactory; +import org.dspace.qaevent.service.OpenaireClientFactory; import org.springframework.beans.factory.annotation.Autowired; /** - * Implementation of {@link BrokerClientFactory} that returns the instance of + * Implementation of {@link OpenaireClientFactory} that returns the instance of * {@link BrokerClient} managed by the Spring context. * * @author Luca Giamminonni (luca.giamminonni at 4science.it) * */ -public class BrokerClientFactoryImpl implements BrokerClientFactory { +public class OpenaireClientFactoryImpl implements OpenaireClientFactory { @Autowired private BrokerClient brokerClient; diff --git a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java index dbe44fd2e7..35d9231ea5 100644 --- a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java @@ -45,9 +45,9 @@ import org.dspace.content.Collection; import org.dspace.content.Item; import org.dspace.matcher.QASourceMatcher; import org.dspace.matcher.QATopicMatcher; -import org.dspace.qaevent.service.BrokerClientFactory; +import org.dspace.qaevent.service.OpenaireClientFactory; import org.dspace.qaevent.service.QAEventService; -import org.dspace.qaevent.service.impl.BrokerClientFactoryImpl; +import org.dspace.qaevent.service.impl.OpenaireClientFactoryImpl; import org.dspace.utils.DSpace; import org.junit.After; import org.junit.Before; @@ -67,7 +67,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase private Collection collection; - private BrokerClient brokerClient = BrokerClientFactory.getInstance().getBrokerClient(); + private BrokerClient brokerClient = OpenaireClientFactory.getInstance().getBrokerClient(); private BrokerClient mockBrokerClient = mock(BrokerClient.class); @@ -86,12 +86,12 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase context.restoreAuthSystemState(); - ((BrokerClientFactoryImpl) BrokerClientFactory.getInstance()).setBrokerClient(mockBrokerClient); + ((OpenaireClientFactoryImpl) OpenaireClientFactory.getInstance()).setBrokerClient(mockBrokerClient); } @After public void after() { - ((BrokerClientFactoryImpl) BrokerClientFactory.getInstance()).setBrokerClient(brokerClient); + ((OpenaireClientFactoryImpl) OpenaireClientFactory.getInstance()).setBrokerClient(brokerClient); } @Test diff --git a/dspace/config/spring/api/qaevents.xml b/dspace/config/spring/api/qaevents.xml index 300a47c8f2..8c52b8b1f2 100644 --- a/dspace/config/spring/api/qaevents.xml +++ b/dspace/config/spring/api/qaevents.xml @@ -13,7 +13,7 @@ - + From 95056d509c0e37630560a14cf4536ff85be766c8 Mon Sep 17 00:00:00 2001 From: frabacche Date: Thu, 14 Dec 2023 17:04:16 +0100 Subject: [PATCH 34/38] CST-5249 find Topic order by QAevent.key, means by the topic name --- .../dspace/qaevent/service/QAEventService.java | 7 +++---- .../service/impl/QAEventServiceImpl.java | 10 +++++++--- .../rest/repository/QATopicRestRepository.java | 17 +++++++++++++++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java index ea923251b8..2332a55caf 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/QAEventService.java @@ -27,11 +27,9 @@ public interface QAEventService { * Find all the event's topics. * * @param offset the offset to apply - * @param pageSize the page size * @return the topics list */ - public List findAllTopics(long offset, long pageSize); - + public List findAllTopics(long offset, long count, String orderField, boolean ascending); /** * Find all the event's topics related to the given source. * @@ -40,7 +38,8 @@ public interface QAEventService { * @param count the page size * @return the topics list */ - public List findAllTopicsBySource(String source, long offset, long count); + public List findAllTopicsBySource(String source, long offset, long count, + String orderField, boolean ascending); /** * Count all the event's topics. diff --git a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java index 9be4af2d08..1dfcc1b6d9 100644 --- a/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/qaevent/service/impl/QAEventServiceImpl.java @@ -36,6 +36,7 @@ import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.params.FacetParams; import org.dspace.content.Item; import org.dspace.content.QAEvent; import org.dspace.content.service.ItemService; @@ -188,12 +189,13 @@ public class QAEventServiceImpl implements QAEventService { } @Override - public List findAllTopics(long offset, long count) { - return findAllTopicsBySource(null, offset, count); + public List findAllTopics(long offset, long count, String orderField, boolean ascending) { + return findAllTopicsBySource(null, offset, count, orderField, ascending); } @Override - public List findAllTopicsBySource(String source, long offset, long count) { + public List findAllTopicsBySource(String source, long offset, long count, + String orderField, boolean ascending) { if (source != null && isNotSupportedSource(source)) { return null; @@ -201,6 +203,8 @@ public class QAEventServiceImpl implements QAEventService { SolrQuery solrQuery = new SolrQuery(); solrQuery.setRows(0); + solrQuery.setSort(orderField, ascending ? ORDER.asc : ORDER.desc); + solrQuery.setFacetSort(FacetParams.FACET_SORT_INDEX); solrQuery.setQuery("*:*"); solrQuery.setFacet(true); solrQuery.setFacetMinCount(1); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java index a279cac83a..97a0ee9781 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/QATopicRestRepository.java @@ -18,6 +18,7 @@ import org.dspace.qaevent.service.QAEventService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort.Direction; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Component; @@ -30,6 +31,8 @@ import org.springframework.stereotype.Component; @Component(QATopicRest.CATEGORY + "." + QATopicRest.NAME) public class QATopicRestRepository extends DSpaceRestRepository { + final static String ORDER_FIELD = "topic"; + @Autowired private QAEventService qaEventService; @@ -46,7 +49,13 @@ public class QATopicRestRepository extends DSpaceRestRepository findAll(Context context, Pageable pageable) { - List topics = qaEventService.findAllTopics(pageable.getOffset(), pageable.getPageSize()); + boolean ascending = false; + if (pageable.getSort() != null && pageable.getSort().getOrderFor(ORDER_FIELD) != null) { + ascending = pageable.getSort() + .getOrderFor(ORDER_FIELD).getDirection() == Direction.ASC; + } + List topics = qaEventService.findAllTopics(pageable.getOffset(), pageable.getPageSize(), + ORDER_FIELD, ascending); long count = qaEventService.countTopics(); if (topics == null) { return null; @@ -58,8 +67,12 @@ public class QATopicRestRepository extends DSpaceRestRepository findBySource(Context context, @Parameter(value = "source", required = true) String source, Pageable pageable) { + boolean ascending = false; + if (pageable.getSort() != null && pageable.getSort().getOrderFor(ORDER_FIELD) != null) { + ascending = pageable.getSort().getOrderFor(ORDER_FIELD).getDirection() == Direction.ASC; + } List topics = qaEventService.findAllTopicsBySource(source, - pageable.getOffset(), pageable.getPageSize()); + pageable.getOffset(), pageable.getPageSize(), ORDER_FIELD, ascending); long count = qaEventService.countTopicsBySource(source); if (topics == null) { return null; From f64bbd6c3215576eb89548500ef6e98c75ea3720 Mon Sep 17 00:00:00 2001 From: frabacche Date: Thu, 14 Dec 2023 17:14:20 +0100 Subject: [PATCH 35/38] CST-5249 IT java fixes OpenaireEventsImportIT --- .../qaevent/script/OpenaireEventsImportIT.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java index 35d9231ea5..6bb979f48b 100644 --- a/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java +++ b/dspace-api/src/test/java/org/dspace/qaevent/script/OpenaireEventsImportIT.java @@ -63,6 +63,8 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase private static final String BASE_JSON_DIR_PATH = "org/dspace/app/openaire-events/"; + private static final String ORDER_FIELD = "topic"; + private QAEventService qaEventService = new DSpace().getSingletonService(QAEventService.class); private Collection collection; @@ -157,7 +159,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 5L))); - assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), containsInAnyOrder( QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), QATopicMatcher.with("ENRICH/MORE/PID", 1L), QATopicMatcher.with("ENRICH/MISSING/PID", 1L), @@ -213,7 +215,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 3L))); - assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), containsInAnyOrder( QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L), QATopicMatcher.with("ENRICH/MISSING/PROJECT", 1L), QATopicMatcher.with("ENRICH/MORE/PID", 1L) @@ -253,7 +255,8 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 1L))); - assertThat(qaEventService.findAllTopics(0, 20), contains(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), + contains(QATopicMatcher.with("ENRICH/MISSING/ABSTRACT", 1L))); String abstractMessage = "{\"abstracts[0]\":\"Missing Abstract\"}"; @@ -280,7 +283,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 0L))); - assertThat(qaEventService.findAllTopics(0, 20), empty()); + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), empty()); verifyNoInteractions(mockBrokerClient); } @@ -327,7 +330,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 6L))); - assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), containsInAnyOrder( QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), QATopicMatcher.with("ENRICH/MORE/PID", 1L), QATopicMatcher.with("ENRICH/MISSING/PID", 1L), @@ -381,7 +384,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 0L))); - assertThat(qaEventService.findAllTopics(0, 20), empty()); + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), empty()); verify(mockBrokerClient).listSubscriptions(openaireURL, "user@test.com"); @@ -432,7 +435,7 @@ public class OpenaireEventsImportIT extends AbstractIntegrationTestWithDatabase assertThat(qaEventService.findAllSources(0, 20), contains(QASourceMatcher.with(OPENAIRE_SOURCE, 6L))); - assertThat(qaEventService.findAllTopics(0, 20), containsInAnyOrder( + assertThat(qaEventService.findAllTopics(0, 20, ORDER_FIELD, false), containsInAnyOrder( QATopicMatcher.with("ENRICH/MORE/PROJECT", 1L), QATopicMatcher.with("ENRICH/MISSING/PID", 1L), QATopicMatcher.with("ENRICH/MORE/PID", 1L), From 5c845dbbaa34e950dd1f503776c09849719a1d5f Mon Sep 17 00:00:00 2001 From: frabacche Date: Fri, 15 Dec 2023 10:51:36 +0100 Subject: [PATCH 36/38] CST-5249 new qaevent.enabled config and used for QAAuthorizationFeature --- .../impl/QAAuthorizationFeature.java | 44 +++++++++++++++++++ dspace/config/modules/qaevents.cfg | 2 + 2 files changed, 46 insertions(+) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java new file mode 100644 index 0000000000..ce0644eb91 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java @@ -0,0 +1,44 @@ +/** + * 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.app.rest.authorization.impl; + +import java.sql.SQLException; + +import org.dspace.app.rest.authorization.AuthorizationFeature; +import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation; +import org.dspace.app.rest.model.BaseObjectRest; +import org.dspace.app.rest.model.QAEventRest; +import org.dspace.core.Context; +import org.dspace.services.ConfigurationService; +import org.springframework.stereotype.Component; + +/** + * The QA Event feature. It can be used to verify if Quality Assurance can be seen. + * + * Authorization is granted if the current user has READ permissions on the given bitstream. + */ +@Component +@AuthorizationFeatureDocumentation(name = QAAuthorizationFeature.NAME, + description = "It can be used to verify if the user can manage Quality Assurance events") +public class QAAuthorizationFeature implements AuthorizationFeature { + public final static String NAME = "canSeeQA"; + + private ConfigurationService configurationService; + + @Override + public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException { + return configurationService.getBooleanProperty("qaevent.enabled", false); + } + + @Override + public String[] getSupportedTypes() { + return new String[]{ + QAEventRest.CATEGORY + "." + QAEventRest.NAME, + }; + } +} diff --git a/dspace/config/modules/qaevents.cfg b/dspace/config/modules/qaevents.cfg index da5080d589..6cbaa12084 100644 --- a/dspace/config/modules/qaevents.cfg +++ b/dspace/config/modules/qaevents.cfg @@ -3,6 +3,8 @@ #---------------------------------------------------------------# # Configuration properties used by data correction service # #---------------------------------------------------------------# +# Quality Assurance enable property, false by default +qaevents.enabled = false qaevents.solr.server = ${solr.server}/${solr.multicorePrefix}qaevent # A POST to these url(s) will be done to notify oaire of decision taken for each qaevents # qaevents.openaire.acknowledge-url = https://beta.api-broker.openaire.eu/feedback/events From f931a52001f4a10e815a94ee870aa9f0ca44bbe6 Mon Sep 17 00:00:00 2001 From: frabacche Date: Fri, 15 Dec 2023 12:43:08 +0100 Subject: [PATCH 37/38] CST-5249 typo property qaevents.enabled --- .../app/rest/authorization/impl/QAAuthorizationFeature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java index ce0644eb91..8d45a8a978 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java @@ -32,7 +32,7 @@ public class QAAuthorizationFeature implements AuthorizationFeature { @Override public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException { - return configurationService.getBooleanProperty("qaevent.enabled", false); + return configurationService.getBooleanProperty("qaevents.enabled", false); } @Override From 0a74a941b0371e9f772c95e354c31064a2153a2a Mon Sep 17 00:00:00 2001 From: frabacche Date: Fri, 15 Dec 2023 16:41:48 +0100 Subject: [PATCH 38/38] CST-5249 Restore OpenAIRE on user interfaces, QAAuthorizationFeature fix and IT java class --- .../main/java/org/dspace/content/QAEvent.java | 10 ++- .../external/OpenaireRestConnector.java | 2 +- .../org/dspace/builder/QAEventBuilder.java | 12 +++ .../impl/QAAuthorizationFeature.java | 6 +- .../QAAuthorizationFeatureIT.java | 84 +++++++++++++++++++ dspace/config/crosswalks/oai/xoai.xml | 2 +- 6 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/QAAuthorizationFeatureIT.java diff --git a/dspace-api/src/main/java/org/dspace/content/QAEvent.java b/dspace-api/src/main/java/org/dspace/content/QAEvent.java index 489599ea76..9e90f81be3 100644 --- a/dspace-api/src/main/java/org/dspace/content/QAEvent.java +++ b/dspace-api/src/main/java/org/dspace/content/QAEvent.java @@ -34,9 +34,17 @@ public class QAEvent { private String source; private String eventId; - + /** + * contains the targeted dspace object, + * ie: oai:www.openstarts.units.it:123456789/1120 contains the handle + * of the DSpace pbject in its final part 123456789/1120 + * */ private String originalId; + /** + * evaluated with the targeted dspace object id + * + * */ private String target; private String related; diff --git a/dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java b/dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java index 2ec08be055..c96fad1de0 100644 --- a/dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java +++ b/dspace-api/src/main/java/org/dspace/external/OpenaireRestConnector.java @@ -103,7 +103,7 @@ public class OpenaireRestConnector { if (StringUtils.isBlank(tokenServiceUrl) || StringUtils.isBlank(clientId) || StringUtils.isBlank(clientSecret)) { - throw new IOException("Cannot grab Openaire token with nulls service url, client id or secret"); + throw new IOException("Cannot grab OpenAIRE token with nulls service url, client id or secret"); } String auth = clientId + ":" + clientSecret; diff --git a/dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java b/dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java index 154bf737d9..823080516d 100644 --- a/dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/QAEventBuilder.java @@ -25,9 +25,21 @@ public class QAEventBuilder extends AbstractBuilder { private Item item; private QAEvent target; private String source = QAEvent.OPENAIRE_SOURCE; + /** + * the title of the DSpace object + * */ private String title; + /** + * the name of the Quality Assurance Event Topic + * */ private String topic; + /** + * thr original QA Event imported + * */ private String message; + /** + * uuid of the targeted DSpace object + * */ private String relatedItem; private double trust = 0.5; private Date lastUpdate = new Date(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java index 8d45a8a978..332c7a5989 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/authorization/impl/QAAuthorizationFeature.java @@ -12,9 +12,10 @@ import java.sql.SQLException; import org.dspace.app.rest.authorization.AuthorizationFeature; import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation; import org.dspace.app.rest.model.BaseObjectRest; -import org.dspace.app.rest.model.QAEventRest; +import org.dspace.app.rest.model.SiteRest; import org.dspace.core.Context; import org.dspace.services.ConfigurationService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** @@ -28,6 +29,7 @@ import org.springframework.stereotype.Component; public class QAAuthorizationFeature implements AuthorizationFeature { public final static String NAME = "canSeeQA"; + @Autowired private ConfigurationService configurationService; @Override @@ -38,7 +40,7 @@ public class QAAuthorizationFeature implements AuthorizationFeature { @Override public String[] getSupportedTypes() { return new String[]{ - QAEventRest.CATEGORY + "." + QAEventRest.NAME, + SiteRest.CATEGORY + "." + SiteRest.NAME }; } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/QAAuthorizationFeatureIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/QAAuthorizationFeatureIT.java new file mode 100644 index 0000000000..f3e508485a --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/QAAuthorizationFeatureIT.java @@ -0,0 +1,84 @@ +/** + * 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.app.rest.authorization; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.dspace.app.rest.authorization.impl.QAAuthorizationFeature; +import org.dspace.app.rest.converter.SiteConverter; +import org.dspace.app.rest.matcher.AuthorizationMatcher; +import org.dspace.app.rest.model.SiteRest; +import org.dspace.app.rest.projection.DefaultProjection; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.content.Site; +import org.dspace.content.service.SiteService; +import org.dspace.services.ConfigurationService; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Test suite for the Quality Assurance Authorization feature + * + * @author Francesco Bacchelli (francesco.bacchelli at 4science.it) + * + */ +public class QAAuthorizationFeatureIT extends AbstractControllerIntegrationTest { + + @Autowired + private AuthorizationFeatureService authorizationFeatureService; + + @Autowired + private SiteService siteService; + + @Autowired + private SiteConverter siteConverter; + + @Autowired + private ConfigurationService configurationService; + + + private AuthorizationFeature qaAuthorizationFeature; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + context.turnOffAuthorisationSystem(); + qaAuthorizationFeature = authorizationFeatureService.find(QAAuthorizationFeature.NAME); + context.restoreAuthSystemState(); + } + + @Test + public void testQAAuthorizationSuccess() throws Exception { + configurationService.setProperty("qaevents.enabled", true); + Site site = siteService.findSite(context); + SiteRest siteRest = siteConverter.convert(site, DefaultProjection.DEFAULT); + String tokenAdmin = getAuthToken(admin.getEmail(), password); + Authorization authAdminSite = new Authorization(admin, qaAuthorizationFeature, siteRest); + + getClient(tokenAdmin).perform(get("/api/authz/authorizations/" + authAdminSite.getID())) + .andExpect(jsonPath("$", Matchers.is( + AuthorizationMatcher.matchAuthorization(authAdminSite)))); + } + + @Test + public void testQAAuthorizationFail() throws Exception { + configurationService.setProperty("qaevents.enabled", false); + Site site = siteService.findSite(context); + SiteRest siteRest = siteConverter.convert(site, DefaultProjection.DEFAULT); + String tokenAdmin = getAuthToken(admin.getEmail(), password); + Authorization authAdminSite = new Authorization(admin, qaAuthorizationFeature, siteRest); + + getClient(tokenAdmin).perform(get("/api/authz/authorizations/" + authAdminSite.getID())) + .andExpect(status().isNotFound()); + } +} diff --git a/dspace/config/crosswalks/oai/xoai.xml b/dspace/config/crosswalks/oai/xoai.xml index a7b0d9050c..9bcabdf0e9 100644 --- a/dspace/config/crosswalks/oai/xoai.xml +++ b/dspace/config/crosswalks/oai/xoai.xml @@ -526,7 +526,7 @@ openaire - Openaire + OpenAIRE