mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-18 15:33:09 +00:00
Merge remote-tracking branch 'upstream/main' into #2956
This commit is contained in:
@@ -4,6 +4,13 @@
|
||||
# Can be validated via instructions at:
|
||||
# https://docs.codecov.io/docs/codecov-yaml#validate-your-repository-yaml
|
||||
|
||||
# Tell Codecov not to send a coverage notification until (at least) 2 builds are completed
|
||||
# Since we run Unit & Integration tests in parallel, this lets Codecov know that coverage
|
||||
# needs to be merged across those builds
|
||||
codecov:
|
||||
notify:
|
||||
after_n_builds: 2
|
||||
|
||||
# Settings related to code coverage analysis
|
||||
coverage:
|
||||
status:
|
||||
|
65
.github/workflows/build.yml
vendored
Normal file
65
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# DSpace Continuous Integration/Build via GitHub Actions
|
||||
# Concepts borrowed from
|
||||
# https://docs.github.com/en/free-pro-team@latest/actions/guides/building-and-testing-java-with-maven
|
||||
name: Build
|
||||
|
||||
# Run this Build for all pushes / PRs to current branch
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Give Maven 1GB of memory to work with
|
||||
# Suppress all Maven "downloading" messages in Travis logs (see https://stackoverflow.com/a/35653426)
|
||||
# This also slightly speeds builds, as there is less logging
|
||||
MAVEN_OPTS: "-Xmx1024M -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn"
|
||||
strategy:
|
||||
# Create a matrix of two separate configurations for Unit vs Integration Tests
|
||||
# This will ensure those tasks are run in parallel
|
||||
matrix:
|
||||
include:
|
||||
# NOTE: Unit Tests include deprecated REST API v6 (as it has unit tests)
|
||||
- type: "Unit Tests"
|
||||
mvnflags: "-DskipUnitTests=false -Pdspace-rest"
|
||||
# NOTE: ITs skip all code validation checks, as they are already done by Unit Test job.
|
||||
# - enforcer.skip => Skip maven-enforcer-plugin rules
|
||||
# - checkstyle.skip => Skip all checkstyle checks by maven-checkstyle-plugin
|
||||
# - license.skip => Skip all license header checks by license-maven-plugin
|
||||
# - xml.skip => Skip all XML/XSLT validation by xml-maven-plugin
|
||||
- type: "Integration Tests"
|
||||
mvnflags: "-DskipIntegrationTests=false -Denforcer.skip=true -Dcheckstyle.skip=true -Dlicense.skip=true -Dxml.skip=true"
|
||||
# Do NOT exit immediately if one matrix job fails
|
||||
# This ensures ITs continue running even if Unit Tests fail, or visa versa
|
||||
fail-fast: false
|
||||
# These are the actual CI steps to perform per job
|
||||
steps:
|
||||
# https://github.com/actions/checkout
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v1
|
||||
|
||||
# https://github.com/actions/setup-java
|
||||
- name: Install JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
# https://github.com/actions/cache
|
||||
- name: Cache Maven dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
# Cache entire ~/.m2/repository
|
||||
path: ~/.m2/repository
|
||||
# Cache key is hash of all pom.xml files. Therefore any changes to POMs will invalidate cache
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
|
||||
# Run parallel Maven builds based on the above 'strategy.matrix'
|
||||
- name: Run Maven ${{ matrix.type }}
|
||||
env:
|
||||
TEST_FLAGS: ${{ matrix.mvnflags }}
|
||||
run: mvn install -B -V -P-assembly -Pcoverage-report $TEST_FLAGS
|
||||
|
||||
# https://github.com/codecov/codecov-action
|
||||
- name: Upload coverage to Codecov.io
|
||||
uses: codecov/codecov-action@v1
|
55
.travis.yml
55
.travis.yml
@@ -1,55 +0,0 @@
|
||||
# DSpace's Travis CI Configuration
|
||||
# Builds: https://travis-ci.com/github/DSpace/DSpace
|
||||
# Travis configuration guide/validation: https://config.travis-ci.com/explore
|
||||
language: java
|
||||
# TODO: Upgrade to Bionic
|
||||
dist: trusty
|
||||
os: linux
|
||||
|
||||
jdk:
|
||||
# DS-3384 Oracle JDK has DocLint enabled by default.
|
||||
# Let's use this to catch any newly introduced DocLint issues.
|
||||
- oraclejdk11
|
||||
|
||||
# Define global environment variables (shared across all jobs)
|
||||
env:
|
||||
global:
|
||||
# Suppress all Maven "downloading" messages in Travis logs (see https://stackoverflow.com/a/35653426)
|
||||
# This also slightly speeds builds in Travis, as there is less logging
|
||||
- HIDE_MAVEN_DOWNLOADS="-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn"
|
||||
# Give Maven 1GB of memory to work with
|
||||
- MAVEN_OPTS="-Xmx1024M $HIDE_MAVEN_DOWNLOADS"
|
||||
# Maven options which will skip ALL code validation checks. Includes skipping:
|
||||
# - enforcer.skip => Skip maven-enforcer-plugin rules
|
||||
# - checkstyle.skip => Skip all checkstyle checks by maven-checkstyle-plugin
|
||||
# - license.skip => Skip all license header checks by license-maven-plugin
|
||||
# - xml.skip => Skip all XML/XSLT validation by xml-maven-plugin
|
||||
# (Useful for builds which don't need to repeat code checks)
|
||||
- SKIP_CODE_CHECKS="-Denforcer.skip=true -Dcheckstyle.skip=true -Dlicense.skip=true -Dxml.skip=true"
|
||||
|
||||
# Create two jobs to run Unit & Integration tests in parallel.
|
||||
# These jobs only differ in the TEST_FLAGS defined below,
|
||||
# and otherwise share all the other configs in this file
|
||||
jobs:
|
||||
include:
|
||||
- name: "Run Unit Tests & Check Code"
|
||||
# NOTE: unit tests include deprecated REST API v6 (as it has unit tests)
|
||||
env: TEST_FLAGS="-DskipUnitTests=false -Pdspace-rest"
|
||||
- name: "Run Integration Tests"
|
||||
# NOTE: skips code checks, as they are already done by Unit Test job
|
||||
env: TEST_FLAGS="-DskipIntegrationTests=false $SKIP_CODE_CHECKS"
|
||||
|
||||
# Skip 'install' process to save time. We build/install/test all at once in "script" below.
|
||||
install: skip
|
||||
|
||||
# Build DSpace and run configured tests (see 'jobs' above)
|
||||
# Notes on flags used:
|
||||
# -B => Maven batch/non-interactive mode (recommended for CI)
|
||||
# -V => Display Maven version info before build
|
||||
# -P-assembly => Disable build of dspace-installer in [src]/dspace/, as it can be memory intensive
|
||||
# -Pcoverage-report => Enable aggregate code coverage report (across all modules) via JaCoCo
|
||||
script: mvn install -B -V -P-assembly -Pcoverage-report $TEST_FLAGS
|
||||
|
||||
# After a successful build and test (see 'script'), send aggregate code coverage reports
|
||||
# (generated by -Pcoverage-report above) to CodeCov.io
|
||||
after_success: bash <(curl -s https://codecov.io/bash)
|
@@ -1,7 +1,7 @@
|
||||
|
||||
# DSpace
|
||||
|
||||
[](https://travis-ci.com/DSpace/DSpace)
|
||||
[](https://github.com/DSpace/DSpace/actions?query=workflow%3ABuild)
|
||||
|
||||
[DSpace Documentation](https://wiki.lyrasis.org/display/DSDOC/) |
|
||||
[DSpace Releases](https://github.com/DSpace/DSpace/releases) |
|
||||
@@ -86,7 +86,7 @@ DSpace uses GitHub to track issues:
|
||||
### Running Tests
|
||||
|
||||
By default, in DSpace, Unit Tests and Integration Tests are disabled. However, they are
|
||||
run automatically by [Travis CI](https://travis-ci.com/DSpace/DSpace/) for all Pull Requests and code commits.
|
||||
run automatically by [GitHub Actions](https://github.com/DSpace/DSpace/actions?query=workflow%3ABuild) for all Pull Requests and code commits.
|
||||
|
||||
* How to run both Unit Tests (via `maven-surefire-plugin`) and Integration Tests (via `maven-failsafe-plugin`):
|
||||
```
|
||||
|
@@ -842,12 +842,30 @@
|
||||
<version>1.10.50</version>
|
||||
</dependency>
|
||||
|
||||
<!-- For ORCID v2 integration -->
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>orcid-jaxb-api</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<groupId>org.orcid</groupId>
|
||||
<artifactId>orcid-model</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.jaxrs</groupId>
|
||||
<artifactId>jackson-jaxrs-json-provider</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
|
@@ -37,6 +37,7 @@ public class OrcidRestConnector {
|
||||
}
|
||||
|
||||
public InputStream get(String path, String accessToken) {
|
||||
HttpResponse getResponse = null;
|
||||
InputStream result = null;
|
||||
path = trimSlashes(path);
|
||||
|
||||
@@ -48,7 +49,7 @@ public class OrcidRestConnector {
|
||||
}
|
||||
try {
|
||||
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||
HttpResponse getResponse = httpClient.execute(httpGet);
|
||||
getResponse = httpClient.execute(httpGet);
|
||||
//do not close this httpClient
|
||||
result = getResponse.getEntity().getContent();
|
||||
} catch (Exception e) {
|
||||
@@ -76,6 +77,4 @@ public class OrcidRestConnector {
|
||||
Scanner s = new Scanner(is).useDelimiter("\\A");
|
||||
return s.hasNext() ? s.next() : "";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -32,30 +32,33 @@ import org.dspace.external.model.ExternalDataObject;
|
||||
import org.dspace.external.provider.ExternalDataProvider;
|
||||
import org.dspace.external.provider.orcid.xml.XMLtoBio;
|
||||
import org.json.JSONObject;
|
||||
import org.orcid.jaxb.model.common_v2.OrcidId;
|
||||
import org.orcid.jaxb.model.record_v2.Person;
|
||||
import org.orcid.jaxb.model.search_v2.Result;
|
||||
import org.orcid.jaxb.model.v3.release.common.OrcidIdentifier;
|
||||
import org.orcid.jaxb.model.v3.release.record.Person;
|
||||
import org.orcid.jaxb.model.v3.release.search.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* This class is the implementation of the ExternalDataProvider interface that will deal with the OrcidV2 External
|
||||
* This class is the implementation of the ExternalDataProvider interface that will deal with the OrcidV3 External
|
||||
* Data lookup
|
||||
*/
|
||||
public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
public class OrcidV3AuthorDataProvider implements ExternalDataProvider {
|
||||
|
||||
private static final Logger log = LogManager.getLogger(OrcidV2AuthorDataProvider.class);
|
||||
private static final Logger log = LogManager.getLogger(OrcidV3AuthorDataProvider.class);
|
||||
|
||||
private final OrcidRestConnector orcidRestConnector;
|
||||
private OrcidRestConnector orcidRestConnector;
|
||||
private String OAUTHUrl;
|
||||
private String clientId;
|
||||
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String sourceIdentifier;
|
||||
|
||||
private String orcidUrl;
|
||||
|
||||
private XMLtoBio converter;
|
||||
|
||||
public static final String ORCID_ID_SYNTAX = "\\d{4}-\\d{4}-\\d{4}-(\\d{3}X|\\d{4})";
|
||||
|
||||
@Override
|
||||
@@ -63,13 +66,18 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
return sourceIdentifier;
|
||||
}
|
||||
|
||||
public OrcidV3AuthorDataProvider() {
|
||||
converter = new XMLtoBio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the accessToken that is required for all subsequent calls to ORCID.
|
||||
*
|
||||
* @throws java.io.IOException passed through from HTTPclient.
|
||||
*/
|
||||
public void init() throws IOException {
|
||||
if (StringUtils.isNotBlank(accessToken) && StringUtils.isNotBlank(clientSecret)) {
|
||||
if (StringUtils.isNotBlank(clientSecret) && StringUtils.isNotBlank(clientId)
|
||||
&& StringUtils.isNotBlank(OAUTHUrl)) {
|
||||
String authenticationParameters = "?client_id=" + clientId +
|
||||
"&client_secret=" + clientSecret +
|
||||
"&scope=/read-public&grant_type=client_credentials";
|
||||
@@ -101,14 +109,6 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an instance of the Orcidv2 class based on the provided parameters.
|
||||
* This constructor is called through the spring bean initialization
|
||||
*/
|
||||
private OrcidV2AuthorDataProvider(String url) {
|
||||
this.orcidRestConnector = new OrcidRestConnector(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ExternalDataObject> getExternalDataObject(String id) {
|
||||
Person person = getBio(id);
|
||||
@@ -121,12 +121,12 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
String lastName = "";
|
||||
String firstName = "";
|
||||
if (person.getName().getFamilyName() != null) {
|
||||
lastName = person.getName().getFamilyName().getValue();
|
||||
lastName = person.getName().getFamilyName().getContent();
|
||||
externalDataObject.addMetadata(new MetadataValueDTO("person", "familyName", null, null,
|
||||
lastName));
|
||||
}
|
||||
if (person.getName().getGivenNames() != null) {
|
||||
firstName = person.getName().getGivenNames().getValue();
|
||||
firstName = person.getName().getGivenNames().getContent();
|
||||
externalDataObject.addMetadata(new MetadataValueDTO("person", "givenName", null, null,
|
||||
firstName));
|
||||
|
||||
@@ -150,7 +150,7 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a Person object based on a given orcid identifier
|
||||
* Retrieve a Person object based on a given orcid identifier.
|
||||
* @param id orcid identifier
|
||||
* @return Person
|
||||
*/
|
||||
@@ -160,7 +160,6 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
return null;
|
||||
}
|
||||
InputStream bioDocument = orcidRestConnector.get(id + ((id.endsWith("/person")) ? "" : "/person"), accessToken);
|
||||
XMLtoBio converter = new XMLtoBio();
|
||||
Person person = converter.convertSinglePerson(bioDocument);
|
||||
try {
|
||||
bioDocument.close();
|
||||
@@ -190,14 +189,13 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
+ "&rows=" + limit;
|
||||
log.debug("queryBio searchPath=" + searchPath + " accessToken=" + accessToken);
|
||||
InputStream bioDocument = orcidRestConnector.get(searchPath, accessToken);
|
||||
XMLtoBio converter = new XMLtoBio();
|
||||
List<Result> results = converter.convert(bioDocument);
|
||||
List<Person> bios = new LinkedList<>();
|
||||
for (Result result : results) {
|
||||
OrcidId orcidIdentifier = result.getOrcidIdentifier();
|
||||
OrcidIdentifier orcidIdentifier = result.getOrcidIdentifier();
|
||||
if (orcidIdentifier != null) {
|
||||
log.debug("Found OrcidId=" + orcidIdentifier.toString());
|
||||
String orcid = orcidIdentifier.getUriPath();
|
||||
String orcid = orcidIdentifier.getPath();
|
||||
Person bio = getBio(orcid);
|
||||
if (bio != null) {
|
||||
bios.add(bio);
|
||||
@@ -228,14 +226,13 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
+ "&rows=" + 0;
|
||||
log.debug("queryBio searchPath=" + searchPath + " accessToken=" + accessToken);
|
||||
InputStream bioDocument = orcidRestConnector.get(searchPath, accessToken);
|
||||
XMLtoBio converter = new XMLtoBio();
|
||||
return converter.getNumberOfResultsFromXml(bioDocument);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generic setter for the sourceIdentifier
|
||||
* @param sourceIdentifier The sourceIdentifier to be set on this OrcidV2AuthorDataProvider
|
||||
* @param sourceIdentifier The sourceIdentifier to be set on this OrcidV3AuthorDataProvider
|
||||
*/
|
||||
@Autowired(required = true)
|
||||
public void setSourceIdentifier(String sourceIdentifier) {
|
||||
@@ -244,7 +241,7 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
|
||||
/**
|
||||
* Generic getter for the orcidUrl
|
||||
* @return the orcidUrl value of this OrcidV2AuthorDataProvider
|
||||
* @return the orcidUrl value of this OrcidV3AuthorDataProvider
|
||||
*/
|
||||
public String getOrcidUrl() {
|
||||
return orcidUrl;
|
||||
@@ -252,7 +249,7 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
|
||||
/**
|
||||
* Generic setter for the orcidUrl
|
||||
* @param orcidUrl The orcidUrl to be set on this OrcidV2AuthorDataProvider
|
||||
* @param orcidUrl The orcidUrl to be set on this OrcidV3AuthorDataProvider
|
||||
*/
|
||||
@Autowired(required = true)
|
||||
public void setOrcidUrl(String orcidUrl) {
|
||||
@@ -261,7 +258,7 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
|
||||
/**
|
||||
* Generic setter for the OAUTHUrl
|
||||
* @param OAUTHUrl The OAUTHUrl to be set on this OrcidV2AuthorDataProvider
|
||||
* @param OAUTHUrl The OAUTHUrl to be set on this OrcidV3AuthorDataProvider
|
||||
*/
|
||||
public void setOAUTHUrl(String OAUTHUrl) {
|
||||
this.OAUTHUrl = OAUTHUrl;
|
||||
@@ -269,7 +266,7 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
|
||||
/**
|
||||
* Generic setter for the clientId
|
||||
* @param clientId The clientId to be set on this OrcidV2AuthorDataProvider
|
||||
* @param clientId The clientId to be set on this OrcidV3AuthorDataProvider
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
@@ -277,9 +274,18 @@ public class OrcidV2AuthorDataProvider implements ExternalDataProvider {
|
||||
|
||||
/**
|
||||
* Generic setter for the clientSecret
|
||||
* @param clientSecret The clientSecret to be set on this OrcidV2AuthorDataProvider
|
||||
* @param clientSecret The clientSecret to be set on this OrcidV3AuthorDataProvider
|
||||
*/
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public OrcidRestConnector getOrcidRestConnector() {
|
||||
return orcidRestConnector;
|
||||
}
|
||||
|
||||
public void setOrcidRestConnector(OrcidRestConnector orcidRestConnector) {
|
||||
this.orcidRestConnector = orcidRestConnector;
|
||||
}
|
||||
|
||||
}
|
@@ -13,11 +13,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.orcid.jaxb.model.record_v2.Person;
|
||||
import org.orcid.jaxb.model.search_v2.Result;
|
||||
import org.orcid.jaxb.model.search_v2.Search;
|
||||
import org.orcid.jaxb.model.v3.release.record.Person;
|
||||
import org.orcid.jaxb.model.v3.release.search.Result;
|
||||
import org.orcid.jaxb.model.v3.release.search.Search;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
/**
|
||||
* @author Antoine Snyers (antoine at atmire.com)
|
||||
* @author Kevin Van de Velde (kevin at atmire dot com)
|
||||
@@ -36,7 +37,7 @@ public class XMLtoBio extends Converter<List<Result>> {
|
||||
List<Result> bios = new ArrayList<>();
|
||||
try {
|
||||
Search search = (Search) unmarshall(xml, Search.class);
|
||||
bios = search.getResult();
|
||||
bios = search.getResults();
|
||||
} catch (SAXException | URISyntaxException e) {
|
||||
log.error(e);
|
||||
}
|
||||
@@ -52,6 +53,7 @@ public class XMLtoBio extends Converter<List<Result>> {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Person convertSinglePerson(InputStream xml) {
|
||||
Person person = null;
|
||||
try {
|
||||
|
@@ -10,5 +10,17 @@
|
||||
<property name="sourceIdentifier" value="mock"/>
|
||||
|
||||
</bean>
|
||||
<bean class="org.dspace.external.provider.impl.OrcidV3AuthorDataProvider" init-method="init">
|
||||
<property name="sourceIdentifier" value="orcid"/>
|
||||
<property name="orcidUrl" value="${orcid.url}" />
|
||||
<property name="clientId" value="${orcid.clientid}" />
|
||||
<property name="clientSecret" value="${orcid.clientsecret}" />
|
||||
<property name="OAUTHUrl" value="${orcid.oauth.url}" />
|
||||
<property name="orcidRestConnector" ref="orcidRestConnector"/>
|
||||
</bean>
|
||||
|
||||
<bean id="orcidRestConnector" class="org.dspace.external.OrcidRestConnector">
|
||||
<constructor-arg value="${orcid.api.url}"/>
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
|
@@ -24,10 +24,11 @@ public class ExternalSourcesRestControllerIT extends AbstractControllerIntegrati
|
||||
public void findAllExternalSources() throws Exception {
|
||||
getClient().perform(get("/api/integration/externalsources"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.externalsources", Matchers.hasItem(
|
||||
ExternalSourceMatcher.matchExternalSource("mock", "mock", false)
|
||||
.andExpect(jsonPath("$._embedded.externalsources", Matchers.hasItems(
|
||||
ExternalSourceMatcher.matchExternalSource("mock", "mock", false),
|
||||
ExternalSourceMatcher.matchExternalSource("orcid", "orcid", false)
|
||||
)))
|
||||
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
|
||||
.andExpect(jsonPath("$.page.totalElements", Matchers.is(2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* 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 org.hamcrest.Matchers.is;
|
||||
import static org.mockito.Mockito.when;
|
||||
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 java.io.InputStream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||
import org.dspace.external.OrcidRestConnector;
|
||||
import org.dspace.external.provider.impl.OrcidV3AuthorDataProvider;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* This test suite includes static test with mock data and end to end test to
|
||||
* verify the integration with ORCID as an External Source. The end to end test
|
||||
* run only if the orcid.clientid property is configured but of course also
|
||||
* orcid.clientsecret is needed to successful run the tests. This can be enabled
|
||||
* setting the orcid credentials via env variables, see the comments in the
|
||||
* override section of the config-definition.xml
|
||||
*
|
||||
* @author Mykhaylo Boychuk (4Science.it)
|
||||
*
|
||||
*/
|
||||
public class OrcidExternalSourcesIT extends AbstractControllerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
ConfigurationService configurationService;
|
||||
|
||||
@Autowired
|
||||
private OrcidV3AuthorDataProvider orcidV3AuthorDataProvider;
|
||||
|
||||
public void onlyRunIfConfigExists() {
|
||||
if (StringUtils.isBlank(configurationService.getProperty("orcid.clientid"))) {
|
||||
Assume.assumeNoException(new IllegalStateException("Missing ORCID credentials"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findOneExternalSourcesExistingSources() throws Exception {
|
||||
getClient().perform(get("/api/integration/externalsources/orcid"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.id", is("orcid")),
|
||||
hasJsonPath("$.name", is("orcid")),
|
||||
hasJsonPath("$.hierarchical", is(false)),
|
||||
hasJsonPath("$.type", is("externalsource"))
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findOneExternalSourcesExistingSourcesWithentryValueTest() throws Exception {
|
||||
// this test will query the real ORCID API if configured in the CI otherwise will be skipped
|
||||
onlyRunIfConfigExists();
|
||||
String entry = "0000-0002-9029-1854";
|
||||
getClient().perform(get("/api/integration/externalsources/orcid/entryValues/" + entry))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.id", is(entry)),
|
||||
hasJsonPath("$.display", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.value", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.externalSource", is("orcid")),
|
||||
hasJsonPath("$.type", is("externalSourceEntry"))
|
||||
)))
|
||||
.andExpect(jsonPath("$.metadata['dc.identifier.uri'][0].value",is("https://orcid.org/" + entry)))
|
||||
.andExpect(jsonPath("$.metadata['person.familyName'][0].value",is("Bollini")))
|
||||
.andExpect(jsonPath("$.metadata['person.givenName'][0].value",is("Andrea")))
|
||||
.andExpect(jsonPath("$.metadata['person.identifier.orcid'][0].value",is(entry)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findOneExternalSourceEntriesApplicableQueryTest() throws Exception {
|
||||
// this test will query the real ORCID API if configured in the CI otherwise will be skipped
|
||||
onlyRunIfConfigExists();
|
||||
String q = "orcid:0000-0002-9029-1854";
|
||||
getClient().perform(get("/api/integration/externalsources/orcid/entries")
|
||||
.param("query", q))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0]", Matchers.allOf(
|
||||
hasJsonPath("$.id", is("0000-0002-9029-1854")),
|
||||
hasJsonPath("$.display", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.value", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.externalSource", is("orcid")),
|
||||
hasJsonPath("$.type", is("externalSourceEntry"))
|
||||
)))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['dc.identifier.uri'][0].value",
|
||||
is("https://orcid.org/0000-0002-9029-1854")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.familyName'][0].value",
|
||||
is("Bollini")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.givenName'][0].value",
|
||||
is("Andrea")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.identifier.orcid'][0].value",
|
||||
is("0000-0002-9029-1854")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findOneExternalSourceEntriesApplicableQueryFamilyNameAndGivenNamesTest() throws Exception {
|
||||
// this test will query the real ORCID API if configured in the CI otherwise will be skipped
|
||||
onlyRunIfConfigExists();
|
||||
String q = "family-name:bollini AND given-names:andrea";
|
||||
getClient().perform(get("/api/integration/externalsources/orcid/entries")
|
||||
.param("query", q))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries", Matchers.hasItem(
|
||||
Matchers.allOf(
|
||||
hasJsonPath("$.id", is("0000-0002-9029-1854")),
|
||||
hasJsonPath("$.display", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.value", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.externalSource", is("orcid")),
|
||||
hasJsonPath("$.type", is("externalSourceEntry")))
|
||||
)))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['dc.identifier.uri'][0].value",
|
||||
is("https://orcid.org/0000-0002-9029-1854")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.familyName'][0].value",
|
||||
is("Bollini")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.givenName'][0].value",
|
||||
is("Andrea")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.identifier.orcid'][0].value",
|
||||
is("0000-0002-9029-1854")));
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* This test uses mock data in the orcid-person-record.xml file to simulate the
|
||||
* response from ORCID and verify that it is properly consumed and exposed by
|
||||
* the REST API
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void findOneExternalSourcesMockitoTest() throws Exception {
|
||||
OrcidRestConnector orcidConnector = Mockito.mock(OrcidRestConnector.class);
|
||||
OrcidRestConnector realConnector = orcidV3AuthorDataProvider.getOrcidRestConnector();
|
||||
orcidV3AuthorDataProvider.setOrcidRestConnector(orcidConnector);
|
||||
when(orcidConnector.get(ArgumentMatchers.endsWith("/person"), ArgumentMatchers.any()))
|
||||
.thenAnswer(new Answer<InputStream>() {
|
||||
public InputStream answer(InvocationOnMock invocation) {
|
||||
return getClass().getResourceAsStream("orcid-person-record.xml");
|
||||
}
|
||||
});
|
||||
|
||||
String entry = "0000-0002-9029-1854";
|
||||
getClient().perform(get("/api/integration/externalsources/orcid/entryValues/" + entry))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.id", is(entry)),
|
||||
hasJsonPath("$.display", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.value", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.externalSource", is("orcid")),
|
||||
hasJsonPath("$.type", is("externalSourceEntry"))
|
||||
)));
|
||||
|
||||
orcidV3AuthorDataProvider.setOrcidRestConnector(realConnector);
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* This test uses mock data in the orcid-search.xml and orcid-person-record.xml
|
||||
* file to simulate the response from ORCID and verify that it is properly
|
||||
* consumed and exposed by the REST API. The orcid-search.xml file indeed
|
||||
* contains the ORCID matching the user query, for each of them our integration
|
||||
* need to grab details making a second call to the ORCID profile (this is due
|
||||
* to the ORCID API structure and cannot be avoid)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void findOneExternalSourceEntriesApplicableQueryMockitoTest() throws Exception {
|
||||
OrcidRestConnector orcidConnector = Mockito.mock(OrcidRestConnector.class);
|
||||
OrcidRestConnector realConnector = orcidV3AuthorDataProvider.getOrcidRestConnector();
|
||||
orcidV3AuthorDataProvider.setOrcidRestConnector(orcidConnector);
|
||||
try {
|
||||
when(orcidConnector.get(ArgumentMatchers.startsWith("search?"), ArgumentMatchers.any()))
|
||||
.thenAnswer(new Answer<InputStream>() {
|
||||
public InputStream answer(InvocationOnMock invocation) {
|
||||
return getClass().getResourceAsStream("orcid-search.xml");
|
||||
}
|
||||
});
|
||||
when(orcidConnector.get(ArgumentMatchers.endsWith("/person"), ArgumentMatchers.any()))
|
||||
.thenAnswer(new Answer<InputStream>() {
|
||||
public InputStream answer(InvocationOnMock invocation) {
|
||||
return getClass().getResourceAsStream("orcid-person-record.xml");
|
||||
}
|
||||
});
|
||||
String q = "orcid:0000-0002-9029-1854";
|
||||
getClient().perform(get("/api/integration/externalsources/orcid/entries")
|
||||
.param("query", q))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0]", Matchers.allOf(
|
||||
hasJsonPath("$.id", is("0000-0002-9029-1854")),
|
||||
hasJsonPath("$.display", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.value", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.externalSource", is("orcid")),
|
||||
hasJsonPath("$.type", is("externalSourceEntry"))
|
||||
)))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['dc.identifier.uri'][0].value",
|
||||
is("https://orcid.org/0000-0002-9029-1854")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.familyName'][0].value",
|
||||
is("Bollini")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.givenName'][0].value",
|
||||
is("Andrea")))
|
||||
.andExpect(jsonPath(
|
||||
"$._embedded.externalSourceEntries[0].metadata['person.identifier.orcid'][0].value",
|
||||
is("0000-0002-9029-1854")));
|
||||
} finally {
|
||||
orcidV3AuthorDataProvider.setOrcidRestConnector(realConnector);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* This test uses mock data in the orcid-search.xml and orcid-person-record.xml
|
||||
* file to simulate the response from ORCID and verify that it is properly
|
||||
* consumed and exposed by the REST API. The orcid-search.xml file indeed
|
||||
* contains the ORCID matching the user query, for each of them our integration
|
||||
* need to grab details making a second call to the ORCID profile (this is due
|
||||
* to the ORCID API structure and cannot be avoid)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void findOneExternalSourceEntriesApplicableQueryFamilyNameAndGivenNamesMockitoTest() throws Exception {
|
||||
OrcidRestConnector orcidConnector = Mockito.mock(OrcidRestConnector.class);
|
||||
OrcidRestConnector realConnector = orcidV3AuthorDataProvider.getOrcidRestConnector();
|
||||
orcidV3AuthorDataProvider.setOrcidRestConnector(orcidConnector);
|
||||
try {
|
||||
when(orcidConnector.get(ArgumentMatchers.startsWith("search?"), ArgumentMatchers.any()))
|
||||
.thenAnswer(new Answer<InputStream>() {
|
||||
public InputStream answer(InvocationOnMock invocation) {
|
||||
return getClass().getResourceAsStream("orcid-search.xml");
|
||||
}
|
||||
});
|
||||
when(orcidConnector.get(ArgumentMatchers.endsWith("/person"), ArgumentMatchers.any()))
|
||||
.thenAnswer(new Answer<InputStream>() {
|
||||
public InputStream answer(InvocationOnMock invocation) {
|
||||
return getClass().getResourceAsStream("orcid-person-record.xml");
|
||||
}
|
||||
});
|
||||
String q = "family-name:bollini AND given-names:andrea";
|
||||
getClient().perform(get("/api/integration/externalsources/orcid/entries")
|
||||
.param("query", q))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries", Matchers.hasItem(
|
||||
Matchers.allOf(
|
||||
hasJsonPath("$.id", is("0000-0002-9029-1854")),
|
||||
hasJsonPath("$.display", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.value", is("Bollini, Andrea")),
|
||||
hasJsonPath("$.externalSource", is("orcid")),
|
||||
hasJsonPath("$.type", is("externalSourceEntry")))
|
||||
)))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['dc.identifier.uri'][0].value",
|
||||
is("https://orcid.org/0000-0002-9029-1854")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.familyName'][0].value",
|
||||
is("Bollini")))
|
||||
.andExpect(jsonPath("$._embedded.externalSourceEntries[0].metadata['person.givenName'][0].value",
|
||||
is("Andrea")))
|
||||
.andExpect(jsonPath(
|
||||
"$._embedded.externalSourceEntries[0].metadata['person.identifier.orcid'][0].value",
|
||||
is("0000-0002-9029-1854")));
|
||||
} finally {
|
||||
orcidV3AuthorDataProvider.setOrcidRestConnector(realConnector);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,234 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<person:person path="/0000-0002-9029-1854/person" xmlns:internal="http://www.orcid.org/ns/internal" xmlns:education="http://www.orcid.org/ns/education" xmlns:distinction="http://www.orcid.org/ns/distinction" xmlns:deprecated="http://www.orcid.org/ns/deprecated" xmlns:other-name="http://www.orcid.org/ns/other-name" xmlns:membership="http://www.orcid.org/ns/membership" xmlns:error="http://www.orcid.org/ns/error" xmlns:common="http://www.orcid.org/ns/common" xmlns:record="http://www.orcid.org/ns/record" xmlns:personal-details="http://www.orcid.org/ns/personal-details" xmlns:keyword="http://www.orcid.org/ns/keyword" xmlns:email="http://www.orcid.org/ns/email" xmlns:external-identifier="http://www.orcid.org/ns/external-identifier" xmlns:funding="http://www.orcid.org/ns/funding" xmlns:preferences="http://www.orcid.org/ns/preferences" xmlns:address="http://www.orcid.org/ns/address" xmlns:invited-position="http://www.orcid.org/ns/invited-position" xmlns:work="http://www.orcid.org/ns/work" xmlns:history="http://www.orcid.org/ns/history" xmlns:employment="http://www.orcid.org/ns/employment" xmlns:qualification="http://www.orcid.org/ns/qualification" xmlns:service="http://www.orcid.org/ns/service" xmlns:person="http://www.orcid.org/ns/person" xmlns:activities="http://www.orcid.org/ns/activities" xmlns:researcher-url="http://www.orcid.org/ns/researcher-url" xmlns:peer-review="http://www.orcid.org/ns/peer-review" xmlns:bulk="http://www.orcid.org/ns/bulk" xmlns:research-resource="http://www.orcid.org/ns/research-resource">
|
||||
<common:last-modified-date>2018-02-05T23:27:36.636Z</common:last-modified-date>
|
||||
<person:name visibility="public" path="0000-0002-9029-1854">
|
||||
<common:created-date>2016-04-15T23:17:03.663Z</common:created-date>
|
||||
<common:last-modified-date>2016-04-15T23:17:03.663Z</common:last-modified-date>
|
||||
<personal-details:given-names>Andrea</personal-details:given-names>
|
||||
<personal-details:family-name>Bollini</personal-details:family-name>
|
||||
</person:name>
|
||||
<other-name:other-names path="/0000-0002-9029-1854/other-names"/>
|
||||
<researcher-url:researcher-urls path="/0000-0002-9029-1854/researcher-urls">
|
||||
<common:last-modified-date>2017-07-18T15:10:48.940Z</common:last-modified-date>
|
||||
<researcher-url:researcher-url put-code="1005571" visibility="public" path="/0000-0002-9029-1854/researcher-urls/1005571" display-index="5">
|
||||
<common:created-date>2017-01-16T08:12:12.946Z</common:created-date>
|
||||
<common:last-modified-date>2017-07-18T15:10:48.940Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<researcher-url:url-name>Linkedin</researcher-url:url-name>
|
||||
<researcher-url:url>https://it.linkedin.com/in/andreabollini</researcher-url:url>
|
||||
</researcher-url:researcher-url>
|
||||
<researcher-url:researcher-url put-code="369007" visibility="public" path="/0000-0002-9029-1854/researcher-urls/369007" display-index="4">
|
||||
<common:created-date>2014-11-06T10:37:30.383Z</common:created-date>
|
||||
<common:last-modified-date>2017-07-18T15:10:48.940Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<researcher-url:url-name>4Science</researcher-url:url-name>
|
||||
<researcher-url:url>http://www.4science.it/en/</researcher-url:url>
|
||||
</researcher-url:researcher-url>
|
||||
<researcher-url:researcher-url put-code="369009" visibility="public" path="/0000-0002-9029-1854/researcher-urls/369009" display-index="3">
|
||||
<common:created-date>2014-11-06T10:37:30.412Z</common:created-date>
|
||||
<common:last-modified-date>2017-07-18T15:10:48.940Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<researcher-url:url-name>DSpace</researcher-url:url-name>
|
||||
<researcher-url:url>http://www.dspace.org</researcher-url:url>
|
||||
</researcher-url:researcher-url>
|
||||
<researcher-url:researcher-url put-code="369008" visibility="public" path="/0000-0002-9029-1854/researcher-urls/369008" display-index="2">
|
||||
<common:created-date>2014-11-06T10:37:30.398Z</common:created-date>
|
||||
<common:last-modified-date>2017-07-18T15:10:48.940Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<researcher-url:url-name>DSpace-CRIS</researcher-url:url-name>
|
||||
<researcher-url:url>https://wiki.duraspace.org/display/DSPACECRIS</researcher-url:url>
|
||||
</researcher-url:researcher-url>
|
||||
</researcher-url:researcher-urls>
|
||||
<email:emails path="/0000-0002-9029-1854/email">
|
||||
<common:last-modified-date>2016-09-12T11:22:47.354Z</common:last-modified-date>
|
||||
<email:email visibility="public" verified="true" primary="true">
|
||||
<common:created-date>2016-09-12T10:45:26.123Z</common:created-date>
|
||||
<common:last-modified-date>2016-09-12T11:22:47.354Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<email:email>andrea.bollini@4science.it</email:email>
|
||||
</email:email>
|
||||
</email:emails>
|
||||
<address:addresses path="/0000-0002-9029-1854/address">
|
||||
<common:last-modified-date>2016-06-06T15:29:36.952Z</common:last-modified-date>
|
||||
<address:address put-code="240615" visibility="public" path="/0000-0002-9029-1854/address/240615" display-index="0">
|
||||
<common:created-date>2016-01-24T18:24:26.704Z</common:created-date>
|
||||
<common:last-modified-date>2016-06-06T15:29:36.952Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<address:country>IT</address:country>
|
||||
</address:address>
|
||||
</address:addresses>
|
||||
<keyword:keywords path="/0000-0002-9029-1854/keywords">
|
||||
<common:last-modified-date>2016-03-01T11:03:22.508Z</common:last-modified-date>
|
||||
<keyword:keyword put-code="7508" visibility="public" path="/0000-0002-9029-1854/keywords/7508" display-index="3">
|
||||
<common:created-date>2013-05-30T10:55:45.614Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.508Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content>Software</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="7509" visibility="public" path="/0000-0002-9029-1854/keywords/7509" display-index="2">
|
||||
<common:created-date>2013-05-30T10:55:45.614Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.508Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content> Open Source</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="12596" visibility="public" path="/0000-0002-9029-1854/keywords/12596" display-index="1">
|
||||
<common:created-date>2013-05-30T10:55:45.614Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.508Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content> JAVA</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="381655" visibility="public" path="/0000-0002-9029-1854/keywords/381655" display-index="0">
|
||||
<common:created-date>2016-03-01T11:03:22.491Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.491Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content>CERIF</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="381656" visibility="public" path="/0000-0002-9029-1854/keywords/381656" display-index="0">
|
||||
<common:created-date>2016-03-01T11:03:22.502Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.502Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content>CRIS</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="381657" visibility="public" path="/0000-0002-9029-1854/keywords/381657" display-index="0">
|
||||
<common:created-date>2016-03-01T11:03:22.503Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.503Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content>RIMS</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="381658" visibility="public" path="/0000-0002-9029-1854/keywords/381658" display-index="0">
|
||||
<common:created-date>2016-03-01T11:03:22.504Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.504Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content>Open Standards</keyword:content>
|
||||
</keyword:keyword>
|
||||
<keyword:keyword put-code="381659" visibility="public" path="/0000-0002-9029-1854/keywords/381659" display-index="0">
|
||||
<common:created-date>2016-03-01T11:03:22.505Z</common:created-date>
|
||||
<common:last-modified-date>2016-03-01T11:03:22.505Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-orcid>
|
||||
<common:source-name>Andrea Bollini</common:source-name>
|
||||
</common:source>
|
||||
<keyword:content>OAI-PMH</keyword:content>
|
||||
</keyword:keyword>
|
||||
</keyword:keywords>
|
||||
<external-identifier:external-identifiers path="/0000-0002-9029-1854/external-identifiers">
|
||||
<common:last-modified-date>2018-02-05T23:27:36.636Z</common:last-modified-date>
|
||||
<external-identifier:external-identifier put-code="153301" visibility="public" path="/0000-0002-9029-1854/external-identifiers/153301" display-index="0">
|
||||
<common:created-date>2013-05-30T10:55:45.614Z</common:created-date>
|
||||
<common:last-modified-date>2018-02-05T23:27:36.636Z</common:last-modified-date>
|
||||
<common:source>
|
||||
<common:source-client-id>
|
||||
<common:uri>https://orcid.org/client/0000-0002-5982-8983</common:uri>
|
||||
<common:path>0000-0002-5982-8983</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:source-client-id>
|
||||
<common:source-name>Scopus - Elsevier</common:source-name>
|
||||
<common:assertion-origin-orcid>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:assertion-origin-orcid>
|
||||
<common:assertion-origin-name>Andrea Bollini</common:assertion-origin-name>
|
||||
</common:source>
|
||||
<common:external-id-type>Scopus Author ID</common:external-id-type>
|
||||
<common:external-id-value>55484808800</common:external-id-value>
|
||||
<common:external-id-url>http://www.scopus.com/inward/authorDetails.url?authorID=55484808800&partnerID=MN8TOARS</common:external-id-url>
|
||||
<common:external-id-relationship>self</common:external-id-relationship>
|
||||
</external-identifier:external-identifier>
|
||||
</external-identifier:external-identifiers>
|
||||
</person:person>
|
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<search:search num-found="1" xmlns:search="http://www.orcid.org/ns/search" xmlns:common="http://www.orcid.org/ns/common">
|
||||
<search:result>
|
||||
<common:orcid-identifier>
|
||||
<common:uri>https://orcid.org/0000-0002-9029-1854</common:uri>
|
||||
<common:path>0000-0002-9029-1854</common:path>
|
||||
<common:host>orcid.org</common:host>
|
||||
</common:orcid-identifier>
|
||||
</search:result>
|
||||
</search:search>
|
@@ -1473,10 +1473,20 @@ sherpa.romeo.apikey =
|
||||
# org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
|
||||
|
||||
# URL of ORCID API
|
||||
# Defaults to using the Public API (pub.orcid.org)
|
||||
orcid.api.url = https://pub.orcid.org/v2.1
|
||||
# Defaults to using the Public API V3 (pub.orcid.org)
|
||||
orcid.api.url = https://pub.orcid.org/v3.0
|
||||
orcid.url = https://orcid.org/
|
||||
|
||||
# ORCID Credentials
|
||||
# Your public or member API Credentials, see
|
||||
# https://orcid.org/content/register-client-application-0
|
||||
orcid.clientid =
|
||||
orcid.clientsecret =
|
||||
|
||||
#ORCID JWT Endpoint
|
||||
orcid.oauth.url = https://orcid.org/oauth/token
|
||||
|
||||
|
||||
## The DCInputAuthority plugin is automatically configured with every
|
||||
## value-pairs element in input-forms.xml, namely:
|
||||
## common_identifiers, common_types, common_iso_languages
|
||||
|
@@ -20,10 +20,17 @@
|
||||
<property name="apiKey" value="${sherpa.romeo.apikey}"/>
|
||||
|
||||
</bean>
|
||||
<bean class="org.dspace.external.provider.impl.OrcidV2AuthorDataProvider" init-method="init">
|
||||
<constructor-arg value="${orcid.api.url}"/>
|
||||
<property name="sourceIdentifier" value="orcidV2"/>
|
||||
<bean class="org.dspace.external.provider.impl.OrcidV3AuthorDataProvider" init-method="init">
|
||||
<property name="sourceIdentifier" value="orcid"/>
|
||||
<property name="orcidUrl" value="${orcid.url}" />
|
||||
<property name="clientId" value="${orcid.clientid}" />
|
||||
<property name="clientSecret" value="${orcid.clientsecret}" />
|
||||
<property name="OAUTHUrl" value="${orcid.oauth.url}" />
|
||||
<property name="orcidRestConnector" ref="orcidRestConnector"/>
|
||||
</bean>
|
||||
|
||||
<bean id="orcidRestConnector" class="org.dspace.external.OrcidRestConnector">
|
||||
<constructor-arg value="${orcid.api.url}"/>
|
||||
</bean>
|
||||
|
||||
<bean class="org.dspace.external.provider.impl.LCNameDataProvider">
|
||||
|
Reference in New Issue
Block a user