Implement fixes/tweaks and add javadocs

This commit is contained in:
Jelle Pelgrims
2019-08-09 09:19:00 +02:00
parent 234ef08eac
commit 38679befd8
14 changed files with 446 additions and 134 deletions

View File

@@ -460,7 +460,7 @@ public class Harvest {
List<String> errors;
System.out.print("Testing basic PMH access: ");
errors = OAIHarvester.verifyOAIharvester(server, set,
errors = harvestedCollectionService.verifyOAIharvester(server, set,
(null != metadataFormat) ? metadataFormat : "dc", false);
if (errors.isEmpty()) {
System.out.println("OK");
@@ -471,7 +471,7 @@ public class Harvest {
}
System.out.print("Testing ORE support: ");
errors = OAIHarvester.verifyOAIharvester(server, set,
errors = harvestedCollectionService.verifyOAIharvester(server, set,
(null != metadataFormat) ? metadataFormat : "dc", true);
if (errors.isEmpty()) {
System.out.println("OK");

View File

@@ -7,16 +7,28 @@
*/
package org.dspace.harvest;
import static org.dspace.harvest.OAIHarvester.OAI_ADDRESS_ERROR;
import static org.dspace.harvest.OAIHarvester.OAI_DMD_ERROR;
import static org.dspace.harvest.OAIHarvester.OAI_ORE_ERROR;
import static org.dspace.harvest.OAIHarvester.OAI_SET_ERROR;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import ORG.oclc.oai.harvester2.verb.Identify;
import ORG.oclc.oai.harvester2.verb.ListIdentifiers;
import org.dspace.content.Collection;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.harvest.dao.HarvestedCollectionDAO;
import org.dspace.harvest.service.HarvestedCollectionService;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.DOMBuilder;
import org.springframework.beans.factory.annotation.Autowired;
/**
@@ -27,6 +39,10 @@ import org.springframework.beans.factory.annotation.Autowired;
* @author kevinvandevelde at atmire.com
*/
public class HarvestedCollectionServiceImpl implements HarvestedCollectionService {
private static final Namespace ORE_NS = Namespace.getNamespace("http://www.openarchives.org/ore/terms/");
private static final Namespace OAI_NS = Namespace.getNamespace("http://www.openarchives.org/OAI/2.0/");
@Autowired(required = true)
protected HarvestedCollectionDAO harvestedCollectionDAO;
@@ -156,5 +172,94 @@ public class HarvestedCollectionServiceImpl implements HarvestedCollectionServic
return 0 < harvestedCollectionDAO.count(context);
}
/**
* Verify the existence of an OAI server with the specified set and
* supporting the provided metadata formats.
*
* @param oaiSource the address of the OAI-PMH provider
* @param oaiSetId OAI set identifier
* @param metaPrefix OAI metadataPrefix
* @param testORE whether the method should also check the PMH provider for ORE support
* @return list of errors encountered during verification. Empty list indicates a "success" condition.
*/
public List<String> verifyOAIharvester(String oaiSource,
String oaiSetId, String metaPrefix, boolean testORE) {
List<String> errorSet = new ArrayList<String>();
// First, see if we can contact the target server at all.
try {
new Identify(oaiSource);
} catch (Exception ex) {
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached.");
return errorSet;
}
// Next, make sure the metadata we need is supported by the target server
Namespace DMD_NS = OAIHarvester.getDMDNamespace(metaPrefix);
if (null == DMD_NS) {
errorSet.add(OAI_DMD_ERROR + ": " + metaPrefix);
return errorSet;
}
String OREOAIPrefix = null;
String DMDOAIPrefix = null;
try {
OREOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, OAIHarvester.getORENamespace().getURI());
DMDOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, DMD_NS.getURI());
} catch (Exception ex) {
errorSet.add(OAI_ADDRESS_ERROR
+ ": OAI did not respond to ListMetadataFormats query ("
+ ORE_NS.getPrefix() + ":" + OREOAIPrefix + " ; "
+ DMD_NS.getPrefix() + ":" + DMDOAIPrefix + "): "
+ ex.getMessage());
return errorSet;
}
if (testORE && OREOAIPrefix == null) {
errorSet.add(OAI_ORE_ERROR + ": The OAI server does not support ORE dissemination");
}
if (DMDOAIPrefix == null) {
errorSet.add(OAI_DMD_ERROR + ": The OAI server does not support dissemination in this format");
}
// Now scan the sets and make sure the one supplied is in the list
boolean foundSet = false;
try {
//If we do not want to harvest from one set, then skip this.
if (!"all".equals(oaiSetId)) {
ListIdentifiers ls = new ListIdentifiers(oaiSource, null, null, oaiSetId, DMDOAIPrefix);
// The only error we can really get here is "noSetHierarchy"
if (ls.getErrors() != null && ls.getErrors().getLength() > 0) {
for (int i = 0; i < ls.getErrors().getLength(); i++) {
String errorCode = ls.getErrors().item(i).getAttributes().getNamedItem("code").getTextContent();
errorSet.add(
OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec (" +
errorCode + ")");
}
} else {
// Drilling down to /OAI-PMH/ListSets/set
DOMBuilder db = new DOMBuilder();
Document reply = db.build(ls.getDocument());
Element root = reply.getRootElement();
//Check if we can find items, if so this indicates that we have children and our sets exist
foundSet = 0 < root.getChild("ListIdentifiers", OAI_NS).getChildren().size();
if (!foundSet) {
errorSet.add(OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec");
}
}
}
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached");
return errorSet;
}
return errorSet;
}
}

View File

@@ -32,7 +32,6 @@ import javax.xml.transform.TransformerException;
import ORG.oclc.oai.harvester2.verb.GetRecord;
import ORG.oclc.oai.harvester2.verb.Identify;
import ORG.oclc.oai.harvester2.verb.ListIdentifiers;
import ORG.oclc.oai.harvester2.verb.ListMetadataFormats;
import ORG.oclc.oai.harvester2.verb.ListRecords;
import org.apache.commons.lang3.StringUtils;
@@ -106,7 +105,7 @@ public class OAIHarvester {
protected BitstreamFormatService bitstreamFormatService;
protected BundleService bundleService;
protected CollectionService collectionService;
protected HarvestedCollectionService harvestedCollection;
protected HarvestedCollectionService harvestedCollectionService;
protected InstallItemService installItemService;
protected ItemService itemService;
protected HandleService handleService;
@@ -144,7 +143,7 @@ public class OAIHarvester {
bundleService = ContentServiceFactory.getInstance().getBundleService();
collectionService = ContentServiceFactory.getInstance().getCollectionService();
handleService = HandleServiceFactory.getInstance().getHandleService();
harvestedCollection = HarvestServiceFactory.getInstance().getHarvestedCollectionService();
harvestedCollectionService = HarvestServiceFactory.getInstance().getHarvestedCollectionService();
harvestedItemService = HarvestServiceFactory.getInstance().getHarvestedItemService();
itemService = ContentServiceFactory.getInstance().getItemService();
installItemService = ContentServiceFactory.getInstance().getInstallItemService();
@@ -154,7 +153,6 @@ public class OAIHarvester {
configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
if (dso.getType() != Constants.COLLECTION) {
throw new HarvestingException("OAIHarvester can only harvest collections");
}
@@ -163,7 +161,7 @@ public class OAIHarvester {
targetCollection = (Collection) dso;
harvestRow = hc;
if (harvestRow == null || !harvestedCollection.isHarvestable(harvestRow)) {
if (harvestRow == null || !harvestedCollectionService.isHarvestable(harvestRow)) {
throw new HarvestingException("Provided collection is not set up for harvesting");
}
@@ -192,7 +190,7 @@ public class OAIHarvester {
*
* @return Namespace of the supported ORE format. Returns null if not found.
*/
private static Namespace getORENamespace() {
public static Namespace getORENamespace() {
String ORESerializationString = null;
String ORESeialKey = null;
String oreString = "oai.harvester.oreSerializationFormat";
@@ -217,7 +215,7 @@ public class OAIHarvester {
* @param metadataKey
* @return Namespace of the designated metadata format. Returns null of not found.
*/
private static Namespace getDMDNamespace(String metadataKey) {
public static Namespace getDMDNamespace(String metadataKey) {
String metadataString = null;
String metaString = "oai.harvester.metadataformats";
@@ -317,7 +315,7 @@ public class OAIHarvester {
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_BUSY);
harvestRow.setHarvestMessage("Collection harvesting is initializing...");
harvestRow.setHarvestStartTime(startTime);
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
intermediateCommit();
// expiration timer starts
@@ -358,7 +356,7 @@ public class OAIHarvester {
harvestRow.setHarvestStartTime(new Date());
harvestRow.setHarvestMessage("OAI server did not contain any updates");
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_READY);
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
return;
} else {
throw new HarvestingException(errorSet.toString());
@@ -415,7 +413,7 @@ public class OAIHarvester {
harvestRow.setHarvestMessage(String
.format("Collection is currently being harvested (item %d of %d)",
currentRecord, totalListSize));
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
} finally {
//In case of an exception, make sure to restore our authentication state to the previous state
ourContext.restoreAuthSystemState();
@@ -433,19 +431,19 @@ public class OAIHarvester {
alertAdmin(HarvestedCollection.STATUS_OAI_ERROR, hex);
}
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_OAI_ERROR);
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
ourContext.complete();
return;
} catch (Exception ex) {
harvestRow.setHarvestMessage("Unknown error occurred while generating an OAI response");
harvestRow.setHarvestStatus(HarvestedCollection.STATUS_UNKNOWN_ERROR);
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
alertAdmin(HarvestedCollection.STATUS_UNKNOWN_ERROR, ex);
log.error("Error occurred while generating an OAI response: " + ex.getMessage() + " " + ex.getCause(), ex);
ourContext.complete();
return;
} finally {
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
ourContext.turnOffAuthorisationSystem();
collectionService.update(ourContext, targetCollection);
ourContext.restoreAuthSystemState();
@@ -460,7 +458,7 @@ public class OAIHarvester {
log.info(
"Harvest from " + oaiSource + " successful. The process took " + timeTaken + " milliseconds. Harvested "
+ currentRecord + " items.");
harvestedCollection.update(ourContext, harvestRow);
harvestedCollectionService.update(ourContext, harvestRow);
ourContext.setMode(originalMode);
}
@@ -904,97 +902,14 @@ public class OAIHarvester {
String oaiSetId = harvestRow.getOaiSetId();
String metaPrefix = harvestRow.getHarvestMetadataConfig();
return verifyOAIharvester(oaiSource, oaiSetId, metaPrefix, true);
return harvestedCollectionService.verifyOAIharvester(oaiSource, oaiSetId, metaPrefix, true);
}
/**
* Verify the existence of an OAI server with the specified set and
* supporting the provided metadata formats.
* Return all available metadata formats
*
* @param oaiSource the address of the OAI-PMH provider
* @param oaiSetId OAI set identifier
* @param metaPrefix OAI metadataPrefix
* @param testORE whether the method should also check the PMH provider for ORE support
* @return list of errors encountered during verification. Empty list indicates a "success" condition.
* @return a list containing a map for each supported metadata format
*/
public static List<String> verifyOAIharvester(String oaiSource,
String oaiSetId, String metaPrefix, boolean testORE) {
List<String> errorSet = new ArrayList<String>();
// First, see if we can contact the target server at all.
try {
new Identify(oaiSource);
} catch (Exception ex) {
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached.");
return errorSet;
}
// Next, make sure the metadata we need is supported by the target server
Namespace DMD_NS = OAIHarvester.getDMDNamespace(metaPrefix);
if (null == DMD_NS) {
errorSet.add(OAI_DMD_ERROR + ": " + metaPrefix);
return errorSet;
}
String OREOAIPrefix = null;
String DMDOAIPrefix = null;
try {
OREOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, getORENamespace().getURI());
DMDOAIPrefix = OAIHarvester.oaiResolveNamespaceToPrefix(oaiSource, DMD_NS.getURI());
} catch (Exception ex) {
errorSet.add(OAI_ADDRESS_ERROR
+ ": OAI did not respond to ListMetadataFormats query ("
+ ORE_NS.getPrefix() + ":" + OREOAIPrefix + " ; "
+ DMD_NS.getPrefix() + ":" + DMDOAIPrefix + "): "
+ ex.getMessage());
return errorSet;
}
if (testORE && OREOAIPrefix == null) {
errorSet.add(OAI_ORE_ERROR + ": The OAI server does not support ORE dissemination");
}
if (DMDOAIPrefix == null) {
errorSet.add(OAI_DMD_ERROR + ": The OAI server does not support dissemination in this format");
}
// Now scan the sets and make sure the one supplied is in the list
boolean foundSet = false;
try {
//If we do not want to harvest from one set, then skip this.
if (!"all".equals(oaiSetId)) {
ListIdentifiers ls = new ListIdentifiers(oaiSource, null, null, oaiSetId, DMDOAIPrefix);
// The only error we can really get here is "noSetHierarchy"
if (ls.getErrors() != null && ls.getErrors().getLength() > 0) {
for (int i = 0; i < ls.getErrors().getLength(); i++) {
String errorCode = ls.getErrors().item(i).getAttributes().getNamedItem("code").getTextContent();
errorSet.add(
OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec (" +
errorCode + ")");
}
} else {
// Drilling down to /OAI-PMH/ListSets/set
Document reply = db.build(ls.getDocument());
Element root = reply.getRootElement();
//Check if we can find items, if so this indicates that we have children and our sets exist
foundSet = 0 < root.getChild("ListIdentifiers", OAI_NS).getChildren().size();
if (!foundSet) {
errorSet.add(OAI_SET_ERROR + ": The OAI server does not have a set with the specified setSpec");
}
}
}
} catch (RuntimeException re) {
throw re;
} catch (Exception e) {
errorSet.add(OAI_ADDRESS_ERROR + ": OAI server could not be reached");
return errorSet;
}
return errorSet;
}
public static List<Map<String,String>> getAvailableMetadataFormats() {
List<Map<String,String>> configs = new ArrayList<>();
String metaString = "oai.harvester.metadataformats.";

View File

@@ -137,4 +137,15 @@ public interface HarvestedCollectionService {
public void update(Context context, HarvestedCollection harvestedCollection) throws SQLException;
public boolean exists(Context context) throws SQLException;
/**
* Test the given harvest settings
* @param oaiSource the address of the OAI-PMH provider
* @param oaiSetId OAI set identifier
* @param metaPrefix OAI metadataPrefix
* @param testORE whether the method should also check the PMH provider for ORE support
* @return list of errors encountered during verification. An empty list indicates a "success" condition.
*/
public List<String> verifyOAIharvester(String oaiSource,
String oaiSetId, String metaPrefix, boolean testORE);
}

View File

@@ -0,0 +1,30 @@
/**
* 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.harvest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A mock for the HarvestedCollectionService
* @author Jelle Pelgrims (jelle.atmire at gmail.com)
*/
public class MockHarvestedCollectionServiceImpl extends HarvestedCollectionServiceImpl {
@Override
public List<String> verifyOAIharvester(String oaiSource,
String oaiSetId, String metaPrefix, boolean testORE) {
if (metaPrefix.equals("dc")) {
return new ArrayList<>();
} else {
return Arrays.asList("(Mock error) Incorrect metadataConfigID");
}
}
}

View File

@@ -9,7 +9,10 @@ package org.dspace.app.rest;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
@@ -34,8 +37,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* Rest controller that handles the changing of harvest settings for collections
*
* @author Jelle Pelgrims
*/
@RestController
@RequestMapping("/api/core/collections/" +
"{collectionUuid:[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" +
@@ -48,6 +54,14 @@ public class CollectionHarvestSettingsController {
@Autowired
HarvestedCollectionService harvestedCollectionService;
/**
* GET Endpoint for updating the settings of a collection.
*
* @param collectionUuid The collection whose settings should be changed
* @param response The response object
* @param request The request object
* @throws SQLException
*/
@RequestMapping(method = RequestMethod.PUT, consumes = {"application/json"})
@PreAuthorize("hasAuthority('ADMIN')")
public void updateHarvestSettingsEndpoint(@PathVariable UUID collectionUuid,
@@ -72,37 +86,82 @@ public class CollectionHarvestSettingsController {
throw new UnprocessableEntityException("Error parsing request body: " + e.toString(), e);
}
// Create a new harvestedCollection object if there isn't one yet
HarvestedCollection harvestedCollection = harvestedCollectionService.find(context, collection);
if (harvestedCollection == null) {
harvestedCollection = harvestedCollectionService.create(context, collection);
}
// Delete harvestedCollection object if harvest type is not set
if (harvestedCollectionRest.getHarvestType() == HarvestTypeEnum.NONE.getValue()) {
// Delete harvestedCollectionService object if harvest type is not set
if (harvestedCollectionRest.getHarvestType() == HarvestTypeEnum.NONE.getValue()
&& harvestedCollection != null) {
harvestedCollectionService.delete(context, harvestedCollection);
} else if (testHarvestSettings(context, collection, harvestedCollectionRest)) {
updateCollectionHarvestSettings(context, harvestedCollection, harvestedCollectionRest);
} else {
throw new UnprocessableEntityException("Incorrect harvest settings in request");
} else if (harvestedCollectionRest.getHarvestType() != HarvestTypeEnum.NONE.getValue()) {
List<String> errors = testHarvestSettings(collection, harvestedCollectionRest);
if (errors.size() == 0) {
if (harvestedCollection == null) {
harvestedCollection = harvestedCollectionService.create(context, collection);
}
updateCollectionHarvestSettings(context, harvestedCollection, harvestedCollectionRest);
} else {
throw new UnprocessableEntityException(
"Incorrect harvest settings in request. The following errors were found: " + errors.toString()
);
}
}
context.complete();
}
private boolean testHarvestSettings(Context context,
Collection collection,
HarvestedCollectionRest harvestedCollectionRest) throws SQLException {
List<String> errors = OAIHarvester.verifyOAIharvester(
harvestedCollectionRest.getOaiSource(),
harvestedCollectionRest.getOaiSetId(),
harvestedCollectionRest.getMetadataConfigId(),
true
);
return errors.size() == 0;
/**
* Function used to verify that the harvest settings work
* @param collection The collection to which the harvest settings should be aplied
* @param harvestedCollectionRest A object containg the harvest settings to be tested
* @return
*/
private List<String> testHarvestSettings(Collection collection,
HarvestedCollectionRest harvestedCollectionRest) {
int harvestType = harvestedCollectionRest.getHarvestType();
String metadataConfigId = harvestedCollectionRest.getMetadataConfigId();
List<String> errors = new ArrayList<>();
// See if metadata config identifier appears in available metadata formats
List<Map<String,String>> metadataFormats = OAIHarvester.getAvailableMetadataFormats();
boolean inAvailableMetadataFormats = metadataFormats.stream()
.filter(x -> x.get("id").equals(metadataConfigId))
.count() >= 1;
if (inAvailableMetadataFormats) {
boolean testORE = Arrays.asList(
HarvestTypeEnum.METADATA_AND_REF.getValue(),
HarvestTypeEnum.METADATA_AND_BITSTREAMS.getValue()
).contains(harvestType);
// Actually verify the harvest settings
List<String> verificationErrors = harvestedCollectionService.verifyOAIharvester(
harvestedCollectionRest.getOaiSource(),
harvestedCollectionRest.getOaiSetId(),
metadataConfigId,
testORE
);
errors = verificationErrors;
} else {
errors.add(
"The metadata format with identifier '" + metadataConfigId + "' is not an available metadata format."
);
}
return errors;
}
/**
* Function to update the harvest settings of a collection
* @param context The context object
* @param harvestedCollection The harvestedCollection whose settings should be updated
* @param harvestedCollectionRest An object containing the new harvest settings
* @throws SQLException
*/
private void updateCollectionHarvestSettings(Context context, HarvestedCollection harvestedCollection,
HarvestedCollectionRest harvestedCollectionRest) throws SQLException {
int harvestType = harvestedCollectionRest.getHarvestType();

View File

@@ -23,8 +23,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* Rest controller that handles the harvesting metadata formats
*
* @author Jelle Pelgrims
*/
@RestController
@RequestMapping("/api/config/harvestermetadata")
public class HarvesterMetadataController {
@@ -35,6 +38,12 @@ public class HarvesterMetadataController {
@Autowired
private HalLinkService halLinkService;
/**
* GET endpoint that returns all available metadata formats
* @param request The request object
* @param response The response object
* @return a HarvesterMetadataResource containing all available metadata formats
*/
@RequestMapping(method = RequestMethod.GET)
public HarvesterMetadataResource get(HttpServletRequest request,
HttpServletResponse response) {

View File

@@ -1,5 +1,18 @@
/**
* 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;
/**
* An enum containing all the possible harvest types
*
* @author Jelle Pelgrims (jelle.atmire @ gmail.com)
*/
public enum HarvestTypeEnum {
NONE(0),
METADATA_ONLY(1),

View File

@@ -13,6 +13,11 @@ import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.dspace.app.rest.HarvesterMetadataController;
/**
* The rest resource used for harvester metadata
*
* @author Jelle Pelgrims
*/
public class HarvesterMetadataRest extends BaseObjectRest<String> {
public static final String NAME = "harvestermetadata";

View File

@@ -10,6 +10,12 @@ package org.dspace.app.rest.model.hateoas;
import org.dspace.app.rest.model.HarvesterMetadataRest;
import org.dspace.app.rest.utils.Utils;
/**
* Harvester metadata rest HAL Resource. The HAL Resource wraps the REST Resource
* adding support for the links.
*
* @author Jelle Pelgrims (jelle.pelgrims at gmail.com)
*/
public class HarvesterMetadataResource extends DSpaceResource<HarvesterMetadataRest> {
public HarvesterMetadataResource(HarvesterMetadataRest data, Utils utils, String... rels) {

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
default-lazy-init="true">
<!-- ******************** -->
<!-- Service declarations -->
<!-- ******************** -->
<bean class="org.dspace.app.requestitem.RequestItemServiceImpl"/>
<bean class="org.dspace.app.itemexport.ItemExportServiceImpl"/>
<!--Ensure that bean remains prototype ! Uses setters to set certain properties such as should is pass through workflow-->
<bean class="org.dspace.app.itemimport.ItemImportServiceImpl" scope="prototype"/>
<!--Ensure that bean remains prototype ! -->
<bean class="org.dspace.app.mediafilter.MediaFilterServiceImpl" scope="prototype"/>
<bean class="org.dspace.app.sfx.SFXFileReaderServiceImpl" scope="prototype"/>
<bean class="org.dspace.app.util.MetadataExposureServiceImpl"/>
<bean class="org.dspace.app.util.OpenSearchServiceImpl"/>
<bean class="org.dspace.app.util.WebAppServiceImpl"/>
<bean class="org.dspace.authenticate.AuthenticationServiceImpl"/>
<bean class="org.dspace.authorize.AuthorizeServiceImpl"/>
<bean class="org.dspace.authorize.ResourcePolicyServiceImpl"/>
<bean class="org.dspace.authority.AuthorityValueServiceImpl"/>
<bean class="org.dspace.authority.AuthorityServiceImpl"/>
<bean class="org.dspace.checker.ChecksumHistoryServiceImpl"/>
<bean class="org.dspace.checker.ChecksumResultServiceImpl"/>
<bean class="org.dspace.checker.MostRecentChecksumServiceImpl"/>
<bean class="org.dspace.checker.SimpleReporterServiceImpl"/>
<bean class="org.dspace.content.CollectionServiceImpl"/>
<bean class="org.dspace.content.BitstreamFormatServiceImpl"/>
<bean class="org.dspace.content.BitstreamServiceImpl"/>
<bean class="org.dspace.content.BundleServiceImpl"/>
<bean class="org.dspace.content.CommunityServiceImpl"/>
<bean class="org.dspace.content.InstallItemServiceImpl"/>
<bean class="org.dspace.content.ItemServiceImpl"/>
<bean class="org.dspace.content.MetadataFieldServiceImpl"/>
<bean class="org.dspace.content.MetadataSchemaServiceImpl"/>
<bean class="org.dspace.content.MetadataValueServiceImpl"/>
<bean class="org.dspace.content.SiteServiceImpl"/>
<bean class="org.dspace.content.SupervisedItemServiceImpl"/>
<bean class="org.dspace.content.WorkspaceItemServiceImpl"/>
<bean class="org.dspace.content.RelationshipServiceImpl"/>
<bean class="org.dspace.content.EntityTypeServiceImpl"/>
<bean class="org.dspace.content.EntityServiceImpl"/>
<bean class="org.dspace.content.RelationshipTypeServiceImpl"/>
<bean class="org.dspace.content.authority.ChoiceAuthorityServiceImpl"/>
<bean class="org.dspace.content.authority.MetadataAuthorityServiceImpl" lazy-init="true"/>
<!-- Ensure PluginService is initialized properly via init() method -->
<bean class="org.dspace.core.LegacyPluginServiceImpl" init-method="init"/>
<bean class="org.dspace.core.LicenseServiceImpl"/>
<bean class="org.dspace.core.NewsServiceImpl">
<property name="acceptableFilenames">
<list>
<value>news-top.html</value>
<value>news-side.html</value>
</list>
</property>
</bean>
<!-- Ensure WorkflowCuratorService is initialized properly via init() method -->
<bean class="org.dspace.curate.WorkflowCuratorServiceImpl" init-method="init"/>
<bean class="org.dspace.disseminate.CitationDocumentServiceImpl"/>
<!-- Ensure EmbargoService is initialized properly via init() method -->
<bean class="org.dspace.embargo.EmbargoServiceImpl" init-method="init"/>
<bean class="org.dspace.eperson.AccountServiceImpl"/>
<bean class="org.dspace.eperson.EPersonServiceImpl"/>
<bean class="org.dspace.eperson.GroupServiceImpl"/>
<bean class="org.dspace.eperson.RegistrationDataServiceImpl"/>
<bean class="org.dspace.eperson.SubscribeServiceImpl"/>
<bean class="org.dspace.eperson.SupervisorServiceImpl"/>
<bean class="org.dspace.event.EventServiceImpl"/>
<bean class="org.dspace.handle.HandleServiceImpl"/>
<!-- Replace harvestCollectionService with a mocked service -->
<bean class="org.dspace.harvest.MockHarvestedCollectionServiceImpl" id="org.dspace.harvest.service.HarvestedCollectionService"/>
<bean class="org.dspace.harvest.HarvestedItemServiceImpl"/>
<bean class="org.dspace.harvest.HarvestSchedulingServiceImpl"/>
<bean class="org.dspace.identifier.DOIServiceImpl"/>
<bean class="org.dspace.license.CreativeCommonsServiceImpl"/>
<bean id="spiderDetectorService" class="org.dspace.statistics.util.SpiderDetectorServiceImpl"/>
<bean id="clientInfoService" class="org.dspace.service.impl.ClientInfoServiceImpl"/>
<bean class="org.dspace.versioning.VersionHistoryServiceImpl"/>
<!-- Configurable workflow services -->
<bean class="org.dspace.xmlworkflow.storedcomponents.ClaimedTaskServiceImpl"/>
<bean class="org.dspace.xmlworkflow.storedcomponents.CollectionRoleServiceImpl"/>
<bean class="org.dspace.xmlworkflow.storedcomponents.InProgressUserServiceImpl"/>
<bean class="org.dspace.xmlworkflow.storedcomponents.PoolTaskServiceImpl"/>
<bean class="org.dspace.xmlworkflow.storedcomponents.WorkflowItemRoleServiceImpl"/>
<bean class="org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItemServiceImpl"/>
<bean class="org.dspace.xmlworkflow.XmlWorkflowServiceImpl"/>
<bean class="org.dspace.xmlworkflow.WorkflowRequirementsServiceImpl"/>
<bean class="org.dspace.xmlworkflow.XmlWorkflowFactoryImpl"/>
</beans>

View File

@@ -25,6 +25,11 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Integration test for collection harvest settings controller
*
* @author Jelle Pelgrims (jelle.atmire at gmail.com)
*/
public class CollectionHarvestSettingsControllerIT extends AbstractControllerIntegrationTest {
Collection collection;
@@ -44,11 +49,17 @@ public class CollectionHarvestSettingsControllerIT extends AbstractControllerInt
.build();
collection = CollectionBuilder.createCollection(context, community).withName("Collection 1").build();
context.restoreAuthSystemState();
}
/**
* Function to create a JSONObject containing the harvest settings
* @param harvestType The harvest type
* @param oaiSource The OAI source
* @param oaiSetId The OAI set id
* @param metadataConfigId The metadata config id
* @return A JSONObject containing the given harvest settings
*/
public JSONObject createHarvestSettingsJson(String harvestType,
String oaiSource, String oaiSetId, String metadataConfigId) {
JSONObject json = new JSONObject();
@@ -59,13 +70,11 @@ public class CollectionHarvestSettingsControllerIT extends AbstractControllerInt
return json;
}
// This test might fail if the oai_source ("https://dspace.mit.edu/oai/request") is down
@Test
public void EndpointWorksWithStandardSettings() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.mit.edu/oai/request", "col_1721.1_114174", "dc");
JSONObject json = createHarvestSettingsJson("METADATA_ONLY", "https://dspace.org/oai/request", "col_1721.1_114174", "dc");
getClient(token).perform(
put("/api/core/collections/" + collection.getID() + "/harvester")
@@ -99,7 +108,7 @@ public class CollectionHarvestSettingsControllerIT extends AbstractControllerInt
public void HarvestSettingsDeletedIfHarvestTypeIsNone() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
JSONObject json = createHarvestSettingsJson("NONE", "", "", "");
JSONObject json = createHarvestSettingsJson("NONE", "", "", "dc");
getClient(token).perform(
put("/api/core/collections/" + collection.getID() + "/harvester")

View File

@@ -15,7 +15,11 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.harvest.OAIHarvester;
import org.junit.Test;
/**
* Integration test for harvester metadata controller
*
* @author Jelle Pelgrims (jelle.atmire at gmail.com)
*/
public class HarvesterMetadataControllerIT extends AbstractControllerIntegrationTest {
@Test

View File

@@ -0,0 +1,30 @@
/**
* 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.harvest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A mock for the HarvestedCollectionService
* @author Jelle Pelgrims (jelle.atmire at gmail.com)
*/
public class MockHarvestedCollectionServiceImpl extends HarvestedCollectionServiceImpl {
@Override
public List<String> verifyOAIharvester(String oaiSource,
String oaiSetId, String metaPrefix, boolean testORE) {
if (metaPrefix.equals("dc")) {
return new ArrayList<>();
} else {
return Arrays.asList("(Mock error) Incorrect metadataConfigID");
}
}
}