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 f748894fe9..8f36141a2d 100644 --- a/dspace-api/src/main/java/org/dspace/external/OpenAIRERestConnector.java +++ b/dspace-api/src/main/java/org/dspace/external/OpenAIRERestConnector.java @@ -53,22 +53,26 @@ public class OpenAIRERestConnector { 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; + private String url = "https://api.openaire.eu"; /** * Boolean with token usage definition true if we want to use a token + * and can be configured with: openaire.token.enabled */ - boolean tokenEnabled; + boolean tokenEnabled = false; /** * OpenAIRE Authorization and Authentication Token Service URL + * and can be configured with: openaire.token.url */ private String tokenServiceUrl; /** * OpenAIRE clientId + * and can be configured with: openaire.token.clientId */ private String clientId; @@ -79,13 +83,16 @@ public class OpenAIRERestConnector { /** * OpenAIRE clientSecret + * and can be configured with: openaire.token.clientSecret */ private String clientSecret; + public OpenAIRERestConnector(String url) { this.url = url; } + /** * This method grabs an accessToken an sets the expiration time Based.
* Based on https://develop.openaire.eu/basic.html 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 index e424e08966..429275cea0 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 @@ -18,6 +18,13 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +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.model.ExternalDataObject; +import org.dspace.external.provider.ExternalDataProvider; +import org.springframework.beans.factory.annotation.Autowired; import eu.openaire.jaxb.helper.FundingHelper; import eu.openaire.jaxb.helper.ProjectHelper; import eu.openaire.jaxb.model.Response; @@ -26,13 +33,6 @@ import eu.openaire.oaf.model.base.FunderType; import eu.openaire.oaf.model.base.FundingTreeType; import eu.openaire.oaf.model.base.FundingType; 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.model.ExternalDataObject; -import org.dspace.external.provider.ExternalDataProvider; -import org.springframework.beans.factory.annotation.Autowired; /** * This class is the implementation of the ExternalDataProvider interface that @@ -81,7 +81,7 @@ public class OpenAIREFundingDataProvider implements ExternalDataProvider { @Override public Optional getExternalDataObject(String id) { - + // we use base64 encoding in order to use slashes / and other // characters that must be escaped for the <:entry-id> String decodedId = new String(Base64.getDecoder().decode(id)); @@ -90,10 +90,8 @@ public class OpenAIREFundingDataProvider implements ExternalDataProvider { 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.ExternalDataObjectBuilder(project) - .setId(generateProjectURI(project)) - .setSource(sourceIdentifier) - .build(); + ExternalDataObject externalDataObject = new OpenAIREFundingDataProvider.ExternalDataObjectBuilder( + project).setId(generateProjectURI(project)).setSource(sourceIdentifier).build(); return Optional.of(externalDataObject); } } catch (NumberFormatException e) { @@ -137,9 +135,7 @@ public class OpenAIREFundingDataProvider implements ExternalDataProvider { if (projects.size() > 0) { return projects.stream() .map(project -> new OpenAIREFundingDataProvider.ExternalDataObjectBuilder(project) - .setId(generateProjectURI(project)) - .setSource(sourceIdentifier) - .build()) + .setId(generateProjectURI(project)).setSource(sourceIdentifier).build()) .collect(Collectors.toList()); } return Collections.emptyList(); 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 new file mode 100644 index 0000000000..7698b50f8e --- /dev/null +++ b/dspace-server-webapp/src/test/data/dspaceFolder/config/spring/api/external-openaire.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + \ No newline at end of file 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 new file mode 100644 index 0000000000..d734f08c7a --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/OpenAIREFundingExternalSourcesIT.java @@ -0,0 +1,95 @@ +package org.dspace.app.rest; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +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.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.dspace.app.rest.matcher.ExternalSourceEntryMatcher; +import org.dspace.app.rest.matcher.ExternalSourceMatcher; +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.hamcrest.Matchers; +import org.junit.Test; + +public class OpenAIREFundingExternalSourcesIT extends AbstractControllerIntegrationTest { + + /** + * Test openaire funding external source + * + * @throws Exception + */ + @Test + 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)))); + } + + /** + * Test openaire funding entries for a query returning no results + * + * @throws Exception + */ + @Test + public void findOneOpenAIREFundingExternalSourceEntriesEmptyWithQueryTest() throws Exception { + + getClient().perform(get("/api/integration/externalsources/openAIREFunding/entries").param("query", "empty")) + .andExpect(status().isOk()).andExpect(jsonPath("$.page.number", is(0))); + } + + /** + * Test openaire funding entries with multiple keywords for a query returning no + * results + * + * @throws Exception + */ + @Test + public void findOneOpenAIREFundingExternalSourceEntriesWithQueryMultipleKeywordsTest() throws Exception { + + getClient() + .perform( + get("/api/integration/externalsources/openAIREFunding/entries").param("query", "empty+results")) + .andExpect(status().isOk()).andExpect(jsonPath("$.page.number", is(0))); + } + + /** + * Test openaire funding entries for a query using ?query=mock + * + * @throws Exception + */ + @Test + 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")))); + + } + + /** + * Test openaire funding entry value + * + * @throws Exception + */ + @Test + 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)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", + Matchers.allOf(hasJsonPath("$.id", is(projectID)), hasJsonPath("$.display", is(projectName)), + hasJsonPath("$.value", is(projectName)), + hasJsonPath("$.externalSource", is("openAIREFunding")), + hasJsonPath("$.type", is("externalSourceEntry"))))); + + } +} 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 new file mode 100644 index 0000000000..baf1041ab5 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/external/provider/impl/MockOpenAIREFundingDataProvider.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.external.provider.impl; + +import static org.mockito.Mockito.when; + +import java.io.IOException; +import javax.xml.bind.JAXBException; + +import eu.openaire.jaxb.helper.OpenAIREHandler; +import eu.openaire.jaxb.model.Response; +import org.dspace.external.OpenAIRERestConnector; +import org.mockito.AdditionalMatchers; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +/** + * 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 { + @Override + public void init() throws IOException { + OpenAIRERestConnector restConnector = Mockito.mock(OpenAIRERestConnector.class); + + when(restConnector.searchProjectByKeywords(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt(), + ArgumentMatchers.startsWith("mushroom"))).thenAnswer(new Answer() { + public Response answer(InvocationOnMock invocation) { + try { + return OpenAIREHandler + .unmarshal(this.getClass().getResourceAsStream("openaire-projects.xml")); + } catch (JAXBException e) { + e.printStackTrace(); + } + return null; + } + }); + + when(restConnector.searchProjectByKeywords(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt(), + AdditionalMatchers.not(ArgumentMatchers.startsWith("mushroom")))).thenAnswer(new Answer() { + public Response answer(InvocationOnMock invocation) { + try { + return OpenAIREHandler + .unmarshal(this.getClass().getResourceAsStream("openaire-no-projects.xml")); + } catch (JAXBException e) { + e.printStackTrace(); + } + return null; + } + }); + + when(restConnector.searchProjectByIDAndFunder(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), + ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())).thenAnswer(new Answer() { + public Response answer(InvocationOnMock invocation) { + try { + return OpenAIREHandler + .unmarshal(this.getClass().getResourceAsStream("openaire-project.xml")); + } catch (JAXBException e) { + e.printStackTrace(); + } + return null; + } + }); + + setConnector(restConnector); + } +} diff --git a/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-no-projects.xml b/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-no-projects.xml new file mode 100644 index 0000000000..481f2e14ec --- /dev/null +++ b/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-no-projects.xml @@ -0,0 +1,16 @@ + + +
+ (oaftype exact project) and ( mushroomss) + en_US + 10 + 1 + 0 + + +
+ + + + +
\ No newline at end of file diff --git a/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-project.xml b/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-project.xml new file mode 100644 index 0000000000..2b7c489442 --- /dev/null +++ b/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-project.xml @@ -0,0 +1,74 @@ + + +
+ (oaftype exact project) and (projectcode_nt exact "110062") and (fundershortname exact "FCT") + en_US + 10 + 1 + 1 + + +
+ + +
+ fct_________::59523e9f4736c2cab70a470f088b53dd + 2021-08-06 + 2021-08-06 +
+ + + + + fct_________::110062 + http://www.fct.pt/apoios/projectos/consulta/vglobal_projecto.phtml.en?idProjecto=110062&idElemConcurso=3734 + 110062 + PTDC/AGR-ALI/110062/2009 + Portuguese Wild Mushrooms: Chemical characterization and functional study of antiproliferative and proapoptotic properties in cancer cell lines + 2010-12-24 + 2013-12-23 + PTDC/2009 + Agricultural and Forestry Sciences - Food Science and Technology + 0 + false + false + false + 0.0 + 0.0 + + + fct_________::FCT + FCT + Fundao para a Cincia e a Tecnologia, I.P. + PT + + + fct_________::FCT::5876-PPCDTI + 5876-PPCDTI + 5876-PPCDTI + + fct:program + + + + false + false + 0.900 + null + + + + + + + +
+
+ + +
\ No newline at end of file diff --git a/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-projects.xml b/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-projects.xml new file mode 100644 index 0000000000..225055eb92 --- /dev/null +++ b/dspace-server-webapp/src/test/resources/org/dspace/external/provider/impl/openaire-projects.xml @@ -0,0 +1,610 @@ + + +
+ (oaftype exact project) and ( mushroom) + en_US + 10 + 1 + 77 + + +
+ + +
+ rcuk________::98b50e6e0715fad40627833c7030d3c3 + 2018-02-06 + 2021-02-20 +
+ + + + + rcuk________::103679 + 103679 + Mushroom Robo-Pic - Development of an autonomous robotic mushroom picking system + 2017-10-01 + 2019-06-30 + 0 + false + false + false + 0.0 + 0.0 + + + rcuk________::RCUK + UKRI + UK Research and Innovation + GB + + + rcuk________::RCUK::Innovate UK + Innovate UK + Innovate UK + + rcuk:fundingStream + + + + false + false + 0.900 + null + + + + + rcuk________::ebafcf5f45afa2e9807f981e668db66b + Littleport Mushroom Farms Llp + + + + + + + +
+ +
+ rcuk________::6ac77c83ee0d98c433f91f3dc83074b2 + 2017-11-04 + 2021-02-20 +
+ + + + + rcuk________::752540 + 752540 + Exending Shelf Life of Mushroom Growing Kits + 2015-05-01 + 2015-10-31 + 0 + false + false + false + 0.0 + 0.0 + + + rcuk________::RCUK + UKRI + UK Research and Innovation + GB + + + rcuk________::RCUK::Innovate UK + Innovate UK + Innovate UK + + rcuk:fundingStream + + + + false + false + 0.900 + null + + + + + rcuk________::f2a533e22408279c50f647779633cf69 + Espresso Mushroom Company Ltd + + + + + + + +
+ +
+ arc_________::e1da9b244237847b24379fb1b11fb151 + 2015-08-24 + 2018-11-20 +
+ + + + arc_________::LP0220040 + http://purl.org/au-research/grants/arc/LP0220040 + LP0220040 + Use of Organic Residues in Edible Mushroom Production + 2002-01-01 + 2003-12-31 + compost,exotic mushrooms,mushroom production,organic wastes,peat,wood processing wastes + 0 + false + false + false + 0.0 + 0.0 + + + arc_________::ARC + ARC + Australian Research Council (ARC) + AU + + + arc_________::ARC::Linkage Projects + Linkage Projects + Linkage Projects + + arc:fundingStream + + + + false + false + 0.900 + null + + + + + + + +
+ +
+ rcuk________::c137d9bfad46b1ebcc9b3f06e6eb5683 + 2018-08-01 + 2021-02-20 +
+ + + + + rcuk________::133611 + 133611 + The development of a mushroom harvesting machine to increase yield and production while reducing waste and labour shortage risk + 2018-07-01 + 2019-06-30 + 0 + false + false + false + 0.0 + 0.0 + + + rcuk________::RCUK + UKRI + UK Research and Innovation + GB + + + rcuk________::RCUK::Innovate UK + Innovate UK + Innovate UK + + rcuk:fundingStream + + + + false + false + 0.900 + null + + + + + rcuk________::560dfc3b58d1ab0d8a8957a943a76962 + + Mushroom Machine Company Limited + + + + + + +
+ +
+ corda__h2020::c97f7d6f1ff338991c0ec20b33ddb1e0 + 2018-07-21 + 2021-07-19 +
+ + + + + corda__h2020::820352 + 820352 + Smartmushroom + Smart MAnagement of spent mushRoom subsTrate to lead the MUSHROOM sector towards a circular economy + 2018-08-01 + 2021-01-31 + H2020-EIC-FTI-2018-2020 + 0 + false + Fast Track to Innovation (FTI) + true + false + Waste from animal breeding and agriculture, specifically horse and chicken manure and wheat straw, are the raw materials of the growing substrate of mushroom. To grow 1 tonne of mushroom, 3 to 4 tonnes of substrate are needed. However, when mushroom production is completed the substrate cannot be used for another growing cycle due to the depletion of nutrients needed for mushroom growing and it is called Spent Mushroom Substrate (SMS) and becomes a waste that should be managed according to regulations. In Europe, c.a. 3.65 million tons of SMS are generated each year. SMS is a high-moisture content bulk material rich in organic matter and nutrients and it could be reused in agriculture by adding it to the soils as amendment or mulch or weathered to be reused as casing soil. However, nitrates directive set a disposal limit that makes that large quantities of SMS cannot be simply spread in soils next to growers’ facilities, as there is a high risk of leachates and water pollution. Due to its low bulk density and high water content, transportation costs are high and therefore storage is becoming a sound problem. SmartMUSHROOM aims to increase mushroom growers’ waste management efficiency by using a new technology which allow them to obtain enough biogas from fresh SMS to dry a mixture of digestate and additional fresh SMS and pelletize it targeting to obtain a marketable high-quality organic fertilizer rich in organic matter and in nutrients, easy to handle, store and transport to any farming region in Europe. A perfect example of biobased circular economy. The aim of the project is to build a pilot plant to demonstrate the technology and find the best commercial formulation for the pellets to enter organic farming market. After the end of project we aim to build at least 18 treatment plants that will place in market 153,000 tonnes of SMS-pellets, generating a total Turnover of 54M€ in the period 2021-2025 and up to 105 related new jobs. + EUR + 2977940.0 + 2264140.0 + + + ec__________::EC + EC + European Commission + EU + + + ec__________::EC::H2020::IA + Innovation action + IA + ec:h2020toas + + + ec__________::EC::H2020 + H2020 + Horizon 2020 Framework Programme + + ec:h2020fundings + + + + + + false + false + 0.900 + null + + + + + pending_org_::39d5641e14f7cfe56e3e836199e33eba + ECOBELIEVE DOO + + ECOBELIEVE DOO GRKINJA + + + pending_org_::3c128a988f1404fed53e1cd8a61df51b + Asociacion Profesional de Productores de Compost y Hongos, de la Rioja, Navarra y Aragón + + ASOCHAMP + + + pending_org_::7555b3c59a033e789ce6190a6c9f39aa + INVESTIGACION Y DESARROLLO CASTILLA Y LEON S.A + + IDECAL S.A. + + + pending_org_::4193497542c7b30e3f50f52414905579 + NOVIS GMBH + + NOVIS GMBH + + + + + + +
+ +
+ nwo_________::c091653b5930a5a11c748720167b04d7 + 2016-06-23 + 2018-08-07 +
+ + + + + nwo_________::2300148817 + 2300148817 + Production of therapeutic proteins in mushroom + 2007-09-01 + 2012-04-30 + 0 + false + false + false + 0.0 + 0.0 + + + nwo_________::NWO + NWO + Netherlands Organisation for Scientific Research (NWO) + NL + + + + false + false + 0.900 + null + + + + + + + +
+ +
+ nwo_________::5ee5a31d8c77215faef3bd35bd9696ff + 2016-06-23 + 2018-08-07 +
+ + + + + nwo_________::2300148209 + 2300148209 + Control of Verticillium fungicola on mushroom + 2006-10-01 + 2012-08-10 + 0 + false + false + false + 0.0 + 0.0 + + + nwo_________::NWO + NWO + Netherlands Organisation for Scientific Research (NWO) + NL + + + + false + false + 0.900 + null + + + + + + + +
+ +
+ nwo_________::98df9c76cbd6537553284af850398659 + 2016-06-23 + 2018-08-07 +
+ + + + + nwo_________::2300147728 + 2300147728 + Master switches of initiation of mushroom formation + 2005-11-01 + 2012-09-12 + 0 + false + false + false + 0.0 + 0.0 + + + nwo_________::NWO + NWO + Netherlands Organisation for Scientific Research (NWO) + NL + + + + false + false + 0.900 + null + + + + + + + +
+ +
+ nwo_________::7ddc7f2f259735f312a27c54f6b2ee5d + 2016-06-23 + 2018-08-07 +
+ + + + + nwo_________::2300164658 + 2300164658 + Push the white button; controlling mushroom formation + 2011-09-01 + 0 + false + false + false + 0.0 + 0.0 + + + nwo_________::NWO + NWO + Netherlands Organisation for Scientific Research (NWO) + NL + + + + false + false + 0.900 + null + + + + + + + +
+ +
+ nsf_________::c5fa29db776dc4f21919e12cbaea37eb + 2016-03-11 + 2018-08-07 +
+ + + + + nsf_________::6112554 + 6112554 + Respiratory Mechanisms in Cultivated Mushroom + 1961-01-01 + 1963-01-01 + 0 + false + false + false + 0.0 + 0.0 + + + nsf_________::NSF + NSF + National Science Foundation + US + + + + false + false + 0.900 + null + + + + + openorgs____::2f4b2e4dcb319a5f66e887d2fd555734 + + University of Delaware + UD + + + + + + +
+ +
+ + +
\ No newline at end of file