From ab58e1662c31d65ca2952cac469e05d20b47882d Mon Sep 17 00:00:00 2001 From: "Stefan E. Funk" <funk@sub.uni-goettingen.de> Date: Mon, 25 Oct 2021 17:23:29 +0200 Subject: [PATCH] Fix restok bug Add tests for restok bug Increase version --- oaipmh-core/pom.xml | 2 +- .../IdentifierListDelivererAbstract.java | 87 +-------- .../IdentifierListDelivererDATACITE.java | 75 ++++++- .../middleware/IdentifierListDelivererDC.java | 75 ++++++- .../IdentifierListDelivererIDIOM.java | 12 +- .../IdentifierListDelivererInterface.java | 6 +- .../info/textgrid/middleware/OAIPMHImpl.java | 59 +++--- .../textgrid/middleware/OAIPMHUtilities.java | 5 - .../RecordListDelivererAbstract.java | 184 +----------------- .../RecordListDelivererDATACITE.java | 117 ++++++++++- .../middleware/RecordListDelivererDC.java | 3 + .../middleware/RecordListDelivererIDIOM.java | 16 +- .../middleware/OaiPmhTextgridOnlineTests.java | 84 ++++++-- oaipmh-webapp/pom.xml | 2 +- pom.xml | 2 +- 15 files changed, 407 insertions(+), 322 deletions(-) diff --git a/oaipmh-core/pom.xml b/oaipmh-core/pom.xml index ec1fecad..6c9ab177 100644 --- a/oaipmh-core/pom.xml +++ b/oaipmh-core/pom.xml @@ -5,7 +5,7 @@ <parent> <artifactId>oaipmh</artifactId> <groupId>info.textgrid.middleware</groupId> - <version>4.0.5-SNAPSHOT</version> + <version>4.0.6-SNAPSHOT</version> </parent> <groupId>info.textgrid.middleware</groupId> <artifactId>oaipmh-core</artifactId> diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java index 0bcf0fc0..a3229fe4 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererAbstract.java @@ -1,24 +1,15 @@ package info.textgrid.middleware; -import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; -import java.util.Hashtable; import java.util.List; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import org.apache.commons.logging.LogFactory; -import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.search.SearchScrollRequest; -import org.elasticsearch.action.search.SearchType; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.common.Strings; -import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.builder.SearchSourceBuilder; import org.json.JSONObject; import info.textgrid.middleware.oaipmh.HeaderType; import info.textgrid.middleware.oaipmh.ListIdentifiersType; @@ -42,7 +33,6 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD private static org.apache.commons.logging.Log log = LogFactory.getLog(RecordListDelivererAbstract.class); - protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); // ** // CLASS @@ -92,6 +82,7 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD if (request.getMetadataPrefix() != null && request.getResumptionToken() != null) { result.setError(OAIPMHConstants.OAI_BAD_ARGUMENT, "The resumptionToken is an exclusive argument, please remove metadataPrefix!"); + return result; } // Check if metadata prefix is existing and valid. @@ -103,23 +94,10 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD "The value of the metadataPrefix " + request.getMetadataPrefix() + " is not supported by the item identified by the value of: " + request.getIdentifier()); + return result; } - // Check for invalid resumptionToken. - if (request.getResumptionToken() != null) { - boolean restokDCExisting = IdentifierListDelivererDC.cursorCollector != null - && IdentifierListDelivererDC.cursorCollector.containsKey(request.getResumptionToken()); - boolean restokIDIOMExisting = IdentifierListDelivererIDIOM.cursorCollector != null - && IdentifierListDelivererDC.cursorCollector.containsKey(request.getResumptionToken()); - boolean restok = cursorCollector != null - && cursorCollector.containsKey(request.getResumptionToken()); - if (!restokDCExisting && !restokIDIOMExisting && !restok) { - result.setError(OAIPMHConstants.OAI_BAD_RESUMPTION_TOKEN, "The value of the " - + request.getResumptionToken() + " argument is invalid or expired."); - } - } - - // Check more errors. + // Check params in general. List<String> errorValues = new ArrayList<String>(); if (request.getResumptionToken() == null && request.getMetadataPrefix() == null) { @@ -137,71 +115,16 @@ public abstract class IdentifierListDelivererAbstract implements IdentifierListD return result; } - /** - * <p> - * To get the required values for the ListIdentifiers request this function will ask ElasticSearch - * for a specific textgridUri the values "created" and "textgridUri". - * </p> - * - * <p> - * Since the ListIdentifiers request enables the possibility the limit the request in a specific - * time interval, it is necessary to perform a range query on the ElasticSearch index.</p - * - * @param from : start value for the range query - * @param to : end value to the range query - * @return after calling the function "setListIdentifierHeader" the return value is the whole - * ListIdentifiers element - * @throws IOException - */ - public ListIdentifiersType processIdentifierList(String from, String to, String set, - String resumptionToken) throws IOException, ParseException { - - // FIXME combine it with with getIdentifierListWithSet and check for empty set - - ListIdentifiersType lit = new ListIdentifiersType(); - QueryBuilder query = setOrNot(set, from, to); - SearchResponse listListIdentiferValues; - - String[] includes = this.identifierListFields; - String[] excludes = Strings.EMPTY_ARRAY; - // TODO: necessary? - // FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); - - SearchRequest searchRequest = - new SearchRequest(OAI_ESClient.getEsIndex()).searchType(SearchType.QUERY_THEN_FETCH); - - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - searchSourceBuilder.query(query); - searchSourceBuilder.size(this.searchResponseSize); - searchSourceBuilder.fetchSource(includes, excludes); - - if (resumptionToken != null) { - SearchScrollRequest scrollRequest = new SearchScrollRequest(resumptionToken); - scrollRequest.scroll(TimeValue.timeValueSeconds(lifeTimeResToken)); - listListIdentiferValues = - OAI_ESClient.getEsClient().scroll(scrollRequest, RequestOptions.DEFAULT); - } else { - searchRequest.source(searchSourceBuilder); - searchRequest.scroll(TimeValue.timeValueMinutes(lifeTimeResToken)); - listListIdentiferValues = - OAI_ESClient.getEsClient().search(searchRequest, RequestOptions.DEFAULT); - } - - listListIdentiferValues = - hitHandling(listListIdentiferValues, lit, set, listListIdentiferValues.getScrollId()); - - return lit; - } - /** * @param listFurtherValues * @param lit * @param set * @param resumptionToken + * @param cursorCollector * @return */ public SearchResponse hitHandling(SearchResponse listFurtherValues, ListIdentifiersType lit, - String set, String resumptionToken) { + String set, String resumptionToken, Map<String, Integer> cursorCollector) { int i = 0; long size = listFurtherValues.getHits().totalHits; diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDATACITE.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDATACITE.java index ea7a7535..c19b2162 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDATACITE.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDATACITE.java @@ -1,17 +1,34 @@ package info.textgrid.middleware; +import java.io.IOException; +import java.text.ParseException; +import java.util.Hashtable; +import java.util.Map; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchScrollRequest; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import info.textgrid.middleware.oaipmh.ListIdentifiersType; + /** * <p> * Class to build the Element for a ListIdentifiers request. * </p> * * @author Stefan E. Funk, SUB Göttingen - * @version 2021-07-06 + * @version 2021-10-25 * @since 2014-02-20 */ public class IdentifierListDelivererDATACITE extends IdentifierListDelivererAbstract { + protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); + /** * @param datestamp taken from the elasticSearch index (created element) * @param identifier taken from the elasticSearch index (textgridUri) @@ -21,4 +38,60 @@ public class IdentifierListDelivererDATACITE extends IdentifierListDelivererAbst super(textgrid, dariah); } + /* + * (non-Javadoc) + * + * @see info.textgrid.middleware.IdentifierListDelivererInterface#processIdentifierList(java.lang. + * String, java.lang.String, java.lang.String, java.lang.String) + */ + public ListIdentifiersType processIdentifierList(String from, String to, String set, + String resumptionToken) throws IOException, ParseException { + + /* + * To get the required values for the ListIdentifiers request this function will ask + * ElasticSearc for a specific textgridUri the values "created" and "textgridUri". + */ + + /* + * Since the ListIdentifiers request enables the possibility the limit the request in a specific + * time interval, it is necessary to perform a range query on the ElasticSearch index. + */ + + // FIXME combine it with with getIdentifierListWithSet and check for empty set + + ListIdentifiersType lit = new ListIdentifiersType(); + QueryBuilder query = setOrNot(set, from, to); + SearchResponse listListIdentiferValues; + + String[] includes = this.identifierListFields; + String[] excludes = Strings.EMPTY_ARRAY; + // TODO: necessary? + // FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); + + SearchRequest searchRequest = + new SearchRequest(OAI_ESClient.getEsIndex()).searchType(SearchType.QUERY_THEN_FETCH); + + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + searchSourceBuilder.query(query); + searchSourceBuilder.size(this.searchResponseSize); + searchSourceBuilder.fetchSource(includes, excludes); + + if (resumptionToken != null) { + SearchScrollRequest scrollRequest = new SearchScrollRequest(resumptionToken); + scrollRequest.scroll(TimeValue.timeValueSeconds(lifeTimeResToken)); + listListIdentiferValues = + OAI_ESClient.getEsClient().scroll(scrollRequest, RequestOptions.DEFAULT); + } else { + searchRequest.source(searchSourceBuilder); + searchRequest.scroll(TimeValue.timeValueMinutes(lifeTimeResToken)); + listListIdentiferValues = + OAI_ESClient.getEsClient().search(searchRequest, RequestOptions.DEFAULT); + } + + listListIdentiferValues = hitHandling(listListIdentiferValues, lit, set, + listListIdentiferValues.getScrollId(), cursorCollector); + + return lit; + } + } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDC.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDC.java index 6aad6aaa..483bdef8 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDC.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererDC.java @@ -1,5 +1,20 @@ package info.textgrid.middleware; +import java.io.IOException; +import java.text.ParseException; +import java.util.Hashtable; +import java.util.Map; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchScrollRequest; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import info.textgrid.middleware.oaipmh.ListIdentifiersType; + /** * <p> * Class to build the Element for a ListIdentifiers request. @@ -7,12 +22,14 @@ package info.textgrid.middleware; * * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2021-07-06 + * @version 2021-10-25 * @since 2014-02-20 */ public class IdentifierListDelivererDC extends IdentifierListDelivererAbstract { + protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); + /** * <p> * In OAIPMH a ListIdentifiers request is answered by responding the datestamp and the identifier @@ -28,4 +45,60 @@ public class IdentifierListDelivererDC extends IdentifierListDelivererAbstract { super(textgrid, dariah); } + /* + * (non-Javadoc) + * + * @see info.textgrid.middleware.IdentifierListDelivererInterface#processIdentifierList(java.lang. + * String, java.lang.String, java.lang.String, java.lang.String) + */ + public ListIdentifiersType processIdentifierList(String from, String to, String set, + String resumptionToken) throws IOException, ParseException { + + /* + * To get the required values for the ListIdentifiers request this function will ask + * ElasticSearc for a specific textgridUri the values "created" and "textgridUri". + */ + + /* + * Since the ListIdentifiers request enables the possibility the limit the request in a specific + * time interval, it is necessary to perform a range query on the ElasticSearch index. + */ + + // FIXME combine it with with getIdentifierListWithSet and check for empty set + + ListIdentifiersType lit = new ListIdentifiersType(); + QueryBuilder query = setOrNot(set, from, to); + SearchResponse listListIdentiferValues; + + String[] includes = this.identifierListFields; + String[] excludes = Strings.EMPTY_ARRAY; + // TODO: necessary? + // FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); + + SearchRequest searchRequest = + new SearchRequest(OAI_ESClient.getEsIndex()).searchType(SearchType.QUERY_THEN_FETCH); + + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + searchSourceBuilder.query(query); + searchSourceBuilder.size(this.searchResponseSize); + searchSourceBuilder.fetchSource(includes, excludes); + + if (resumptionToken != null) { + SearchScrollRequest scrollRequest = new SearchScrollRequest(resumptionToken); + scrollRequest.scroll(TimeValue.timeValueSeconds(lifeTimeResToken)); + listListIdentiferValues = + OAI_ESClient.getEsClient().scroll(scrollRequest, RequestOptions.DEFAULT); + } else { + searchRequest.source(searchSourceBuilder); + searchRequest.scroll(TimeValue.timeValueMinutes(lifeTimeResToken)); + listListIdentiferValues = + OAI_ESClient.getEsClient().search(searchRequest, RequestOptions.DEFAULT); + } + + listListIdentiferValues = hitHandling(listListIdentiferValues, lit, set, + listListIdentiferValues.getScrollId(), cursorCollector); + + return lit; + } + } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIDIOM.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIDIOM.java index 2da5475f..e7256c83 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIDIOM.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererIDIOM.java @@ -2,6 +2,8 @@ package info.textgrid.middleware; import java.io.IOException; import java.text.ParseException; +import java.util.Hashtable; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.elasticsearch.action.search.SearchRequest; @@ -23,7 +25,16 @@ import info.textgrid.middleware.oaipmh.ResumptionTokenType; */ public class IdentifierListDelivererIDIOM extends IdentifierListDelivererAbstract { + // ** + // STATICS + // ** + private static Log log = LogFactory.getLog(IdentifierListDelivererIDIOM.class); + protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); + + // ** + // CLASS + // ** // Set default to 30, can be changed in oaipmh.properties. private int idiomResponseSize = 30; @@ -60,7 +71,6 @@ public class IdentifierListDelivererIDIOM extends IdentifierListDelivererAbstrac .must(QueryBuilders.matchPhraseQuery("format", "text/tg.inputform+rdf+xml")) .must(QueryBuilders.matchPhraseQuery("notes", "ARTEFACT")); - // List<String> artefactURIs = new ArrayList<String>(); // Queries queries = new Queries(); diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererInterface.java b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererInterface.java index 81068740..3c0a2020 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererInterface.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/IdentifierListDelivererInterface.java @@ -10,13 +10,13 @@ import info.textgrid.middleware.oaipmh.ListIdentifiersType; public interface IdentifierListDelivererInterface { /** - * @param from - * @param to + * @param from Start value for the range query + * @param to End value to the range query * @param set * @param resumptionToken * @return * @throws ParseException - * @throws IOException + * @throws IOException */ public ListIdentifiersType processIdentifierList(String from, String to, String set, String resumptionToken) throws ParseException, IOException; diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHImpl.java b/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHImpl.java index aa3a0a98..28e4e5b8 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHImpl.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHImpl.java @@ -32,7 +32,7 @@ import info.textgrid.middleware.oaipmh.VerbType; * * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2021-10-21 + * @version 2021-10-25 * @since 2014-01-29 */ public class OAIPMHImpl implements OAIPMHProducer { @@ -347,8 +347,7 @@ public class OAIPMHImpl implements OAIPMHProducer { IdentifierListDelivererInterface idListDeliv = null; - // If metadataFormat IS SET, set recordListDeliverer accordingly (requestChecker checks for - // BOTH resumption token and metadata format params!). + // If metadataFormat IS SET, set recordListDeliverer accordingly. if (request.getMetadataPrefix() != null) { if (request.getMetadataPrefix().equals(OAIPMHUtilities.OAIDC_PREFIX)) { idListDeliv = this.identifierListDC; @@ -359,25 +358,33 @@ public class OAIPMHImpl implements OAIPMHProducer { } } - // If resumption token IS SET, check resumption token hash maps to decide which metadata + // If metadata prefix is NOT set, check resumption token hash maps to decide which metadata // format we shall use. else { - boolean restokDCExisting = IdentifierListDelivererDC.cursorCollector != null - && IdentifierListDelivererDC.cursorCollector.containsKey(request.getResumptionToken()); - boolean restokIDIOMExisting = IdentifierListDelivererIDIOM.cursorCollector != null - && IdentifierListDelivererIDIOM.cursorCollector - .containsKey(request.getResumptionToken()); - // FIXME KWAKK!! - boolean restokOpenAireExisting = OAIPMHUtilities.cursorCollector != null - && IdentifierListDelivererAbstract.cursorCollector + boolean restokDCExisting = RecordListDelivererDC.cursorCollector != null + && RecordListDelivererDC.cursorCollector.containsKey(request.getResumptionToken()); + boolean restokIDIOMExisting = RecordListDelivererIDIOM.cursorCollector != null + && RecordListDelivererIDIOM.cursorCollector.containsKey(request.getResumptionToken()); + boolean restokOpenAireExisting = RecordListDelivererDATACITE.cursorCollector != null + && RecordListDelivererDATACITE.cursorCollector .containsKey(request.getResumptionToken()); + this.log.info("restokDCExisting " + restokDCExisting); + this.log.info("restokIDIOMExisting " + restokIDIOMExisting); + this.log.info("restokOpenAireExisting " + restokOpenAireExisting); + if (restokDCExisting) { idListDeliv = this.identifierListDC; } else if (restokIDIOMExisting) { idListDeliv = this.identifierListIDIOM; } else if (restokOpenAireExisting) { idListDeliv = this.identifierListDATACITE; + } else { + // We have got an invalid resumptionToken here! + ErrorHandler e = new ErrorHandler(); + e.setError(OAIPMHConstants.OAI_BAD_RESUMPTION_TOKEN, "The value of the " + + request.getResumptionToken() + " argument is invalid or expired."); + oaipmhRoot.getError().add(e.getError()); } } @@ -527,8 +534,7 @@ public class OAIPMHImpl implements OAIPMHProducer { RecordListDelivererInterface recListDeliv = null; - // If metadataFormat IS SET, set recordListDeliverer accordingly (requestChecker checks for - // BOTH resumption token and metadata format params!). + // If metadataFormat IS SET, set recordListDeliverer accordingly. if (request.getMetadataPrefix() != null) { if (request.getMetadataPrefix().equals(OAIPMHUtilities.OAIDC_PREFIX)) { recListDeliv = this.recordListDC; @@ -541,28 +547,17 @@ public class OAIPMHImpl implements OAIPMHProducer { } } - // If resumption token IS SET, check resumption token hash maps to decide which metadata + // If metadata prefix is NOT set, check resumption token hash maps to decide which metadata // format we shall use. else { boolean restokDCExisting = RecordListDelivererDC.cursorCollector != null && RecordListDelivererDC.cursorCollector.containsKey(request.getResumptionToken()); - - this.log.info("restok DC: " + request.getResumptionToken()); - this.log.info(RecordListDelivererDC.cursorCollector.entrySet()); - boolean restokIDIOMExisting = RecordListDelivererIDIOM.cursorCollector != null && RecordListDelivererIDIOM.cursorCollector.containsKey(request.getResumptionToken()); - - this.log.info("restok IDIOM: " + request.getResumptionToken()); - this.log.info(RecordListDelivererIDIOM.cursorCollector.entrySet()); - boolean restokOpenAireExisting = RecordListDelivererDATACITE.cursorCollector != null && RecordListDelivererDATACITE.cursorCollector .containsKey(request.getResumptionToken()); - this.log.info("restok DATACITE: " + request.getResumptionToken()); - this.log.info(RecordListDelivererDATACITE.cursorCollector.entrySet()); - this.log.info("restokDCExisting " + restokDCExisting); this.log.info("restokIDIOMExisting " + restokIDIOMExisting); this.log.info("restokOpenAireExisting " + restokOpenAireExisting); @@ -573,6 +568,12 @@ public class OAIPMHImpl implements OAIPMHProducer { recListDeliv = this.recordListIDIOM; } else if (restokOpenAireExisting) { recListDeliv = this.recordListDATACITE; + } else { + // We have got an invalid resumptionToken here! + ErrorHandler e = new ErrorHandler(); + e.setError(OAIPMHConstants.OAI_BAD_RESUMPTION_TOKEN, "The value of the " + + request.getResumptionToken() + " argument is invalid or expired."); + oaipmhRoot.getError().add(e.getError()); } } @@ -583,13 +584,7 @@ public class OAIPMHImpl implements OAIPMHProducer { request.getResumptionToken()); if (listRecords != null) { - /* - * if (this.recordListDC.getResultSize() == 0) { requestErrors.setError("RecordMatchError", - * "The combination of the values of the from, until, set and metadataPrefix arguments results in an empty list." - * ); oaipmhRoot.getError().add(requestErrors.getError()); } else { - */ oaipmhRoot.setListRecords(listRecords); - // } } } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHUtilities.java b/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHUtilities.java index 58b3b273..16daea53 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHUtilities.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/OAIPMHUtilities.java @@ -10,7 +10,6 @@ import java.util.Arrays; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashSet; -import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Properties; @@ -112,10 +111,6 @@ public class OAIPMHUtilities { // STATICS // ** - protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); - - // private static org.apache.commons.logging.Log log = LogFactory.getLog(OAIPMHImpl.class); - /** * @param verb * @return diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java index 87f51047..ed10a015 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererAbstract.java @@ -1,26 +1,15 @@ package info.textgrid.middleware; -import java.io.IOException; import java.util.ArrayList; -import java.util.Hashtable; import java.util.List; -import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.search.SearchScrollRequest; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.builder.SearchSourceBuilder; import info.textgrid.middleware.oaipmh.RequestType; import info.textgrid.middleware.oaipmh.ResumptionTokenType; /** - * + * @author Maximilian Brodhun, SUB Göttingen + * @author Stefan E. Funk, SUB Göttingen + * @version 2021-10-25 + * @since */ public abstract class RecordListDelivererAbstract implements RecordListDelivererInterface { @@ -50,11 +39,6 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer public ResumptionTokenType resTokenForResponse; - // private static final int LIFETIME_RES_TOKEN = 600; - protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); - - private static Log log = LogFactory.getLog(RecordListDelivererAbstract.class); - /** * @param textgrid * @param dariah @@ -64,108 +48,6 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer this.dariah = dariah; } - /** - * @param query - * @param resumptionToken - * @param set - * @return - */ - protected List<String> getFieldsFromESIndex(QueryBuilder query, String resumptionToken, - String set) { - - List<String> uriList = new ArrayList<String>(); - - QueryBuilder recordFilter; - if (this.textgrid) { - // We filter out all editions here! - recordFilter = QueryBuilders.boolQuery().must(query) - .must(QueryBuilders.matchPhraseQuery("format", this.formatToFilter)); - } else { - // Do not filter at all in DH. We need every ID! - recordFilter = QueryBuilders.boolQuery().must(query); - } - - SearchRequest searchRequest = new SearchRequest(OAI_ESClient.getEsIndex()); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - - searchSourceBuilder.query(recordFilter); - searchSourceBuilder.size(this.searchResponseSize); - searchRequest.source(searchSourceBuilder); - - SearchResponse scrollResp = new SearchResponse(); - - if (resumptionToken != null) { - SearchScrollRequest scrollRequest = new SearchScrollRequest(resumptionToken); - scrollRequest.scroll(TimeValue.timeValueHours(24L)); - - try { - scrollResp = OAI_ESClient.getEsClient().scroll(scrollRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } else { - searchRequest.source(searchSourceBuilder); - searchRequest.scroll(TimeValue.timeValueHours(24L)); - try { - scrollResp = OAI_ESClient.getEsClient().search(searchRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - String scrollID = scrollResp.getScrollId(); - long completeListSize = scrollResp.getHits().totalHits; - setResultSize(completeListSize); - - if (completeListSize > 0) { - - setFoundItems(true); - int i = 0; - - for (SearchHit hit : scrollResp.getHits().getHits()) { - i++; - if (hit != null && hit.getFields() != null) { - String id2add; - // FIXME Could we not use hit.getId() also for TG hits? Where is the difference? - if (this.textgrid) { - id2add = hit.getSourceAsMap().get(TGConstants.URI).toString(); - } else { - id2add = hit.getId(); - } - uriList.add(id2add); - } - } - if (resumptionToken != null - && this.resTokenForResponse.getCursor().intValue() >= completeListSize) { - try { - cursorCollector.remove(resumptionToken); - } catch (NullPointerException couldNotRemove) { - log.info("Could not remove hash value: " + resumptionToken + " from hash map"); - } - this.resTokenForResponse.setValue(""); - } else { - this.resTokenForResponse = OAIPMHUtilities.getResumptionToken( - completeListSize, resumptionToken, cursorCollector, scrollID, this.searchResponseSize, - i); - } - - log.debug("cursorCollector: " + cursorCollector); - - } else { - log.info("HALLO"); - setFoundItems(false); - } - - if (this.resTokenForResponse != null) { - log.debug("restok value: " + this.resTokenForResponse.getValue()); - log.debug("restok cursor: " + this.resTokenForResponse.getCursor()); - } - - return uriList; - } - /** * @param request * @return @@ -175,10 +57,10 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer ErrorHandler result = new ErrorHandler(); // Check for metadata prefix AND resumption token. - // FIXME Doesn't work yet!! if (request.getMetadataPrefix() != null && request.getResumptionToken() != null) { result.setError(OAIPMHConstants.OAI_BAD_ARGUMENT, "The resumptionToken is an exclusive argument, please remove metadataPrefix!"); + return result; } // Check if metadata prefix is existing and valid. @@ -190,20 +72,7 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer "The value of the metadataPrefix " + request.getMetadataPrefix() + " is not supported by the item identified by the value of: " + request.getIdentifier()); - } - - // Check for invalid resumptionToken. - if (request.getResumptionToken() != null) { - boolean restokIDIOMExisting = RecordListDelivererIDIOM.cursorCollector != null - && RecordListDelivererIDIOM.cursorCollector.containsKey(request.getResumptionToken()); - boolean restokDCExisting = RecordListDelivererDC.cursorCollector != null - && RecordListDelivererDC.cursorCollector.containsKey(request.getResumptionToken()); - boolean restok = cursorCollector != null - && cursorCollector.containsKey(request.getResumptionToken()); - if (!restokDCExisting && !restokIDIOMExisting && !restok) { - result.setError(OAIPMHConstants.OAI_BAD_RESUMPTION_TOKEN, "The value of the " - + request.getResumptionToken() + " argument is invalid or expired."); - } + return result; } // Check params in general. @@ -233,47 +102,6 @@ public abstract class RecordListDelivererAbstract implements RecordListDeliverer return result; } - // /* - // * (non-Javadoc) - // * - // * @see info.textgrid.middleware.RecordListDelivererInterface#setHeader(java.lang.String, - // * java.lang.String, java.lang.String) - // */ - // public HeaderType setHeader(final String set, final String headerIdentifier, - // String modifiedDate) { - // - // HeaderType header = new HeaderType(); - // String identifierForHeader = headerIdentifier; - // - // System.out.println("header identifier: " + headerIdentifier); - // System.out.println("modified value: " + modifiedDate); - // - // // Set date in XML format. - // try { - // header.setDatestamp(OAIPMHUtilities.convertDateFormat(modifiedDate).toXMLFormat()); - // } catch (ParseException e) { - // // TODO Auto-generated catch block - // e.printStackTrace(); - // } catch (DatatypeConfigurationException e) { - // // TODO Auto-generated catch block - // e.printStackTrace(); - // } - // - // // Set header specific for TextGrid objects (remove URL). - // if (this.textgrid == true) { - // identifierForHeader = identifierForHeader.replaceFirst("https://textgridrep.org/", ""); - // } - // - // header.setIdentifier(identifierForHeader); - // - // // Set set :-) - // if (set != null) { - // header.getSetSpec().add(this.specFieldPrefix + set); - // } - // - // return header; - // } - // ** // GETTER AND SETTER // ** diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDATACITE.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDATACITE.java index e1b396a1..b9978d43 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDATACITE.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDATACITE.java @@ -3,12 +3,21 @@ package info.textgrid.middleware; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; +import java.util.Hashtable; import java.util.List; +import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchScrollRequest; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.builder.SearchSourceBuilder; import info.textgrid.middleware.oaipmh.GetRecordType; import info.textgrid.middleware.oaipmh.ListRecordsType; import info.textgrid.middleware.oaipmh.RecordType; @@ -16,12 +25,17 @@ import info.textgrid.middleware.oaipmh.RecordType; /** * @author Maximilian Brodhun, SUB Göttingen * @author Stefan E. Funk, SUB Göttingen - * @version 2021-09-10 + * @version 2021-10-25 * @since 2020-06-13 */ public class RecordListDelivererDATACITE extends RecordListDelivererAbstract { + // ** + // STATICS + // ** + private static Log log = LogFactory.getLog(RecordListDelivererDATACITE.class); + protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); /** * @param textgrid @@ -159,4 +173,105 @@ public class RecordListDelivererDATACITE extends RecordListDelivererAbstract { return result; } + /** + * @param query + * @param resumptionToken + * @param set + * @return + */ + private List<String> getFieldsFromESIndex(QueryBuilder query, String resumptionToken, + String set) { + + List<String> uriList = new ArrayList<String>(); + + QueryBuilder recordFilter; + if (this.textgrid) { + // We filter out all editions here! + recordFilter = QueryBuilders.boolQuery().must(query) + .must(QueryBuilders.matchPhraseQuery("format", this.formatToFilter)); + } else { + // Do not filter at all in DH. We need every ID! + recordFilter = QueryBuilders.boolQuery().must(query); + } + + SearchRequest searchRequest = new SearchRequest(OAI_ESClient.getEsIndex()); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + + searchSourceBuilder.query(recordFilter); + searchSourceBuilder.size(this.searchResponseSize); + searchRequest.source(searchSourceBuilder); + + SearchResponse scrollResp = new SearchResponse(); + + if (resumptionToken != null) { + SearchScrollRequest scrollRequest = new SearchScrollRequest(resumptionToken); + scrollRequest.scroll(TimeValue.timeValueHours(24L)); + + try { + scrollResp = OAI_ESClient.getEsClient().scroll(scrollRequest, RequestOptions.DEFAULT); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + searchRequest.source(searchSourceBuilder); + searchRequest.scroll(TimeValue.timeValueHours(24L)); + try { + scrollResp = OAI_ESClient.getEsClient().search(searchRequest, RequestOptions.DEFAULT); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + String scrollID = scrollResp.getScrollId(); + long completeListSize = scrollResp.getHits().totalHits; + setResultSize(completeListSize); + + if (completeListSize > 0) { + + setFoundItems(true); + int i = 0; + + for (SearchHit hit : scrollResp.getHits().getHits()) { + i++; + if (hit != null && hit.getFields() != null) { + String id2add; + // FIXME Could we not use hit.getId() also for TG hits? Where is the difference? + if (this.textgrid) { + id2add = hit.getSourceAsMap().get(TGConstants.URI).toString(); + } else { + id2add = hit.getId(); + } + uriList.add(id2add); + } + } + if (resumptionToken != null + && this.resTokenForResponse.getCursor().intValue() >= completeListSize) { + try { + cursorCollector.remove(resumptionToken); + } catch (NullPointerException couldNotRemove) { + log.info("Could not remove hash value: " + resumptionToken + " from hash map"); + } + this.resTokenForResponse.setValue(""); + } else { + this.resTokenForResponse = OAIPMHUtilities.getResumptionToken(completeListSize, + resumptionToken, cursorCollector, scrollID, this.searchResponseSize, i); + } + + log.debug("cursorCollector: " + cursorCollector); + + } else { + log.info("HALLO"); + setFoundItems(false); + } + + if (this.resTokenForResponse != null) { + log.debug("restok value: " + this.resTokenForResponse.getValue()); + log.debug("restok cursor: " + this.resTokenForResponse.getCursor()); + } + + return uriList; + } + } diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java index ac8c7330..9a808fa5 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererDC.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.ParseException; +import java.util.Hashtable; +import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -44,6 +46,7 @@ public class RecordListDelivererDC extends RecordListDelivererAbstract { // ** private static Log log = LogFactory.getLog(RecordListDelivererDC.class); + protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); // ** // DC-Field Lists diff --git a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIDIOM.java b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIDIOM.java index 2625b6df..c854bffa 100644 --- a/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIDIOM.java +++ b/oaipmh-core/src/main/java/info/textgrid/middleware/RecordListDelivererIDIOM.java @@ -2,6 +2,8 @@ package info.textgrid.middleware; import java.io.IOException; import java.text.ParseException; +import java.util.Hashtable; +import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.elasticsearch.action.search.SearchRequest; @@ -19,11 +21,19 @@ import info.textgrid.middleware.oaipmh.ListRecordsType; import info.textgrid.middleware.oaipmh.ResumptionTokenType; /** - * + * @author Maximilian Brodhun, SUB Göttingen + * @author Stefan E. Funk, SUB Göttingen + * @version 2021-10-25 + * @since */ public class RecordListDelivererIDIOM extends RecordListDelivererAbstract { + // ** + // STATICS + // ** + private static Log log = LogFactory.getLog(RecordListDelivererIDIOM.class); + protected static Map<String, Integer> cursorCollector = new Hashtable<String, Integer>(); // Set default to 30, can be changed in oaipmh.properties. private int idiomResponseSize = 30; @@ -136,6 +146,10 @@ public class RecordListDelivererIDIOM extends RecordListDelivererAbstract { return recordList; } + // ** + // GETTERA & SETTERS + // ** + /** * @return */ diff --git a/oaipmh-core/src/test/java/info/textgrid/middleware/OaiPmhTextgridOnlineTests.java b/oaipmh-core/src/test/java/info/textgrid/middleware/OaiPmhTextgridOnlineTests.java index 443807aa..08997e3b 100644 --- a/oaipmh-core/src/test/java/info/textgrid/middleware/OaiPmhTextgridOnlineTests.java +++ b/oaipmh-core/src/test/java/info/textgrid/middleware/OaiPmhTextgridOnlineTests.java @@ -30,7 +30,7 @@ import org.junit.Test; * * @author Stefan E. Funk, SUB Göttingen */ -//@Ignore +// @Ignore public class OaiPmhTextgridOnlineTests { // TODO Configure config files for all the different OAI-PMH service instances! @@ -51,6 +51,17 @@ public class OaiPmhTextgridOnlineTests { // NOTE Use "mvn tomcat:run" here! // private static String host = "http://localhost:8080/oaipmh-webapp/"; + // ** + // FINALS + // ** + + private static final String OAIDC_SCHEMA_FORMAT = "oai_dc"; + private static final String IDIOMMETS_SCHEMA_FORMAT = "oai_idiom_mets"; + private static final String DATACITE_SCHEMA_FORMAT = "oai_datacite"; + private static final String EXPECTED_OAIDC_FORMAT_CONTENT = "<oai_dc:dc>"; + private static final String EXPECTED_IDIOMMETS_FORMAT_CONTENT = "<mets "; + private static final String EXPECTED_DATACITE_FORMAT_CONTENT = "<datacite:resource>"; + // ** // STATICS // ** @@ -1276,8 +1287,15 @@ public class OaiPmhTextgridOnlineTests { System.out.println("\t" + theThreadName + "time: " + OaiPmhTestUtilities.getDurationInSecs(timeRunning) + " (loop " + loopCount + (maxNumberOfPagesToTest != 0 ? "/" + maxNumberOfPagesToTest : "") + ")"); - String restok = examineResumptionTokenTag(httpResponse, testOccurance, "", - recordsExpectedPerRequest, loopCount, theThreadName); + + String responseString = IOUtils.readStringFromStream((InputStream) httpResponse.getEntity()); + + // Test resumption token tags. + String restok = examineResumptionTokenTag(responseString, testOccurance, + OaiPmhTestUtilities.NO_TOKEN, recordsExpectedPerRequest, loopCount, theThreadName); + + // Test general metadata content, must go conform with the metadata prefix setting. + examineContent(responseString, theMetadataPrefix); while (status == HttpStatus.SC_OK && !restok.equals(OaiPmhTestUtilities.NO_TOKEN)) { loopCount += 1; @@ -1296,8 +1314,14 @@ public class OaiPmhTextgridOnlineTests { System.out.println("\t" + theThreadName + "time: " + OaiPmhTestUtilities.getDurationInSecs(timeRunning) + " (loop " + loopCount + (maxNumberOfPagesToTest != 0 ? "/" + maxNumberOfPagesToTest : "") + ")"); - restok = examineResumptionTokenTag(httpResponse, testOccurance, restok, + + // Test resumption token tags. + responseString = IOUtils.readStringFromStream((InputStream) httpResponse.getEntity()); + restok = examineResumptionTokenTag(responseString, testOccurance, restok, recordsExpectedPerRequest, loopCount, theThreadName); + + // Test general metadata content, must go conform with the metadata prefix setting. + examineContent(responseString, theMetadataPrefix); } } // Only check for max loops, if we do have less loops and no resumption token, it will be fine, @@ -1331,33 +1355,32 @@ public class OaiPmhTextgridOnlineTests { * existing, tag is existing and has no token value. * @throws IOException */ - public static String examineResumptionTokenTag(final Response theResponse, + public static String examineResumptionTokenTag(final String theResponseString, final String recordOrHeader, final String oldtok, final int recordsExpectedPerRequest, final int loopCount, final String theThreadName) throws IOException { - String res = IOUtils.readStringFromStream((InputStream) theResponse.getEntity()); - // Test for OAIPMH errors. - if (res.contains("<error code=\"badArgument\">")) { - String message = theThreadName + OaiPmhTestUtilities.ERROR + " IN OAIPMH RESPONSE: " + res; + if (theResponseString.contains("<error code=\"badArgument\">")) { + String message = + theThreadName + OaiPmhTestUtilities.ERROR + " IN OAIPMH RESPONSE: " + theResponseString; System.out.println(message); throw new IOException(message); } // Count response objects at first. int recordCount = 0; - int i = res.indexOf("<" + recordOrHeader + ">", 0); + int i = theResponseString.indexOf("<" + recordOrHeader + ">", 0); while (i != -1) { recordCount++; i++; - i = res.indexOf("<" + recordOrHeader + ">", i); + i = theResponseString.indexOf("<" + recordOrHeader + ">", i); } System.out.println("\t" + theThreadName + recordOrHeader + "s: " + recordCount); // Check if token tag is existing. - int tokStart = res.indexOf("<resumptionToken"); - int tokEnd = res.indexOf("</resumptionToken"); + int tokStart = theResponseString.indexOf("<resumptionToken"); + int tokEnd = theResponseString.indexOf("</resumptionToken"); if (tokStart == -1 && tokEnd == -1) { System.out.println("\t" + theThreadName + "token: no token"); @@ -1365,7 +1388,7 @@ public class OaiPmhTextgridOnlineTests { return OaiPmhTestUtilities.NO_TOKEN; } - String restokTmp = res.substring(tokStart, tokEnd); + String restokTmp = theResponseString.substring(tokStart, tokEnd); // Get token tag. String toktag = restokTmp.substring(0, restokTmp.indexOf(">") + 1).trim(); System.out.println("\t" + theThreadName + "tokentag: " + toktag); @@ -1442,4 +1465,37 @@ public class OaiPmhTextgridOnlineTests { return result; } + /** + * @param theResponseString + * @param theMetadataFormat + */ + private static void examineContent(String theResponseString, String theMetadataFormat) { + + System.out.println(theResponseString); + + // Check for correct metadata content according to metadata prefix. + if (theMetadataFormat.equals(OAIDC_SCHEMA_FORMAT) + && !theResponseString.contains("metadataPrefix=\"" + OAIDC_SCHEMA_FORMAT + "\"") + && !theResponseString.contains(EXPECTED_OAIDC_FORMAT_CONTENT)) { + System.out + .println(OAIDC_SCHEMA_FORMAT + " needs to deliver content with schema: " + + EXPECTED_OAIDC_FORMAT_CONTENT + "!"); + assertTrue(false); + } else if (theMetadataFormat.equals(IDIOMMETS_SCHEMA_FORMAT) + && !theResponseString.contains("metadataPrefix=\"" + IDIOMMETS_SCHEMA_FORMAT + "\"") + && !theResponseString.contains(EXPECTED_IDIOMMETS_FORMAT_CONTENT)) { + System.out + .println(IDIOMMETS_SCHEMA_FORMAT + " needs to deliver content with schema: " + + EXPECTED_IDIOMMETS_FORMAT_CONTENT + "!"); + assertTrue(false); + } else if (theMetadataFormat.equals(DATACITE_SCHEMA_FORMAT) + && !theResponseString.contains("metadataPrefix=\"" + DATACITE_SCHEMA_FORMAT + "\"") + && !theResponseString.contains(EXPECTED_DATACITE_FORMAT_CONTENT)) { + System.out + .println(DATACITE_SCHEMA_FORMAT + " needs to deliver content with schema: " + + EXPECTED_DATACITE_FORMAT_CONTENT + "!"); + assertTrue(false); + } + } + } diff --git a/oaipmh-webapp/pom.xml b/oaipmh-webapp/pom.xml index ba387c57..57f2511f 100644 --- a/oaipmh-webapp/pom.xml +++ b/oaipmh-webapp/pom.xml @@ -5,7 +5,7 @@ <parent> <artifactId>oaipmh</artifactId> <groupId>info.textgrid.middleware</groupId> - <version>4.0.5-SNAPSHOT</version> + <version>4.0.6-SNAPSHOT</version> </parent> <groupId>info.textgrid.middleware</groupId> <artifactId>oaipmh-webapp</artifactId> diff --git a/pom.xml b/pom.xml index 63729178..95f65ba0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>info.textgrid.middleware</groupId> <artifactId>oaipmh</artifactId> - <version>4.0.5-SNAPSHOT</version> + <version>4.0.6-SNAPSHOT</version> <packaging>pom</packaging> <name>DARIAHDE :: OAI-PMH DataProvider</name> <properties> -- GitLab