From 15f4dc3dc18d77e255ffb130209b9c91beb3bdf6 Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Fri, 9 Feb 2024 14:51:46 +0100 Subject: [PATCH 001/114] Provide ability to store the id of a controlled vocabulary node / offer localized labels using cv.xml files per locale --- .../authority/DSpaceControlledVocabulary.java | 54 +++++++++---- .../controlled-vocabularies/countries.xml | 10 +++ .../controlled-vocabularies/countries_de.xml | 10 +++ .../test/data/dspaceFolder/config/local.cfg | 4 + .../DSpaceControlledVocabularyTest.java | 79 +++++++++++++++++++ 5 files changed, 141 insertions(+), 16 deletions(-) create mode 100644 dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml create mode 100644 dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index 16632ee5466b..11f7009cfaa5 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -8,6 +8,7 @@ package org.dspace.content.authority; import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -59,20 +60,26 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements HierarchicalAuthority { private static Logger log = org.apache.logging.log4j.LogManager.getLogger(DSpaceControlledVocabulary.class); - protected static String xpathTemplate = "//node[contains(translate(@label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + + protected static String xpathIdTemplate = "//node[contains(translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + + "'abcdefghijklmnopqrstuvwxyz'),'%s')]"; + protected static String xpathLabelTemplate = "//node[contains(translate(@label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + "'abcdefghijklmnopqrstuvwxyz'),'%s')]"; protected static String idTemplate = "//node[@id = '%s']"; protected static String labelTemplate = "//node[@label = '%s']"; protected static String idParentTemplate = "//node[@id = '%s']/parent::isComposedBy/parent::node"; protected static String rootTemplate = "/node"; + protected static String idAttribute = "id"; + protected static String labelAttribute = "label"; protected static String pluginNames[] = null; - protected String vocabularyName = null; protected InputSource vocabulary = null; protected Boolean suggestHierarchy = false; protected Boolean storeHierarchy = true; protected String hierarchyDelimiter = "::"; protected Integer preloadLevel = 1; + protected String valueAttribute = labelAttribute; + protected String valueTemplate = labelTemplate; + protected String xpathValueTemplate = xpathLabelTemplate; public DSpaceControlledVocabulary() { super(); @@ -114,7 +121,7 @@ public boolean accept(File dir, String name) { } } - protected void init() { + protected void init(String locale) { if (vocabulary == null) { ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService(); @@ -123,13 +130,26 @@ protected void init() { String vocabulariesPath = config.getProperty("dspace.dir") + "/config/controlled-vocabularies/"; String configurationPrefix = "vocabulary.plugin." + vocabularyName; storeHierarchy = config.getBooleanProperty(configurationPrefix + ".hierarchy.store", storeHierarchy); + boolean storeIDs = config.getBooleanProperty(configurationPrefix + ".storeIDs", false); suggestHierarchy = config.getBooleanProperty(configurationPrefix + ".hierarchy.suggest", suggestHierarchy); preloadLevel = config.getIntProperty(configurationPrefix + ".hierarchy.preloadLevel", preloadLevel); String configuredDelimiter = config.getProperty(configurationPrefix + ".delimiter"); if (configuredDelimiter != null) { hierarchyDelimiter = configuredDelimiter.replaceAll("(^\"|\"$)", ""); } + if (storeIDs) { + valueAttribute = idAttribute; + valueTemplate = idTemplate; + xpathValueTemplate = xpathIdTemplate; + } + String filename = vocabulariesPath + vocabularyName + ".xml"; + if (StringUtils.isNotEmpty(locale)) { + String localizedFilename = vocabulariesPath + vocabularyName + "_" + locale + ".xml"; + if (Paths.get(localizedFilename).toFile().exists()) { + filename = localizedFilename; + } + } log.info("Loading " + filename); vocabulary = new InputSource(filename); } @@ -142,9 +162,9 @@ protected String buildString(Node node) { return (""); } else { String parentValue = buildString(node.getParentNode()); - Node currentLabel = node.getAttributes().getNamedItem("label"); - if (currentLabel != null) { - String currentValue = currentLabel.getNodeValue(); + Node currentNodeValue = node.getAttributes().getNamedItem(valueAttribute); + if (currentNodeValue != null) { + String currentValue = currentNodeValue.getNodeValue(); if (parentValue.equals("")) { return currentValue; } else { @@ -158,12 +178,13 @@ protected String buildString(Node node) { @Override public Choices getMatches(String text, int start, int limit, String locale) { - init(); + init(locale); log.debug("Getting matches for '" + text + "'"); String xpathExpression = ""; String[] textHierarchy = text.split(hierarchyDelimiter, -1); for (int i = 0; i < textHierarchy.length; i++) { - xpathExpression += String.format(xpathTemplate, textHierarchy[i].replaceAll("'", "'").toLowerCase()); + xpathExpression += + String.format(xpathValueTemplate, textHierarchy[i].replaceAll("'", "'").toLowerCase()); } XPath xpath = XPathFactory.newInstance().newXPath(); int total = 0; @@ -182,12 +203,13 @@ public Choices getMatches(String text, int start, int limit, String locale) { @Override public Choices getBestMatch(String text, String locale) { - init(); + init(locale); log.debug("Getting best matches for '" + text + "'"); String xpathExpression = ""; String[] textHierarchy = text.split(hierarchyDelimiter, -1); for (int i = 0; i < textHierarchy.length; i++) { - xpathExpression += String.format(labelTemplate, textHierarchy[i].replaceAll("'", "'")); + xpathExpression += + String.format(valueTemplate, textHierarchy[i].replaceAll("'", "'")); } XPath xpath = XPathFactory.newInstance().newXPath(); List choices = new ArrayList(); @@ -229,21 +251,21 @@ public boolean isHierarchical() { @Override public Choices getTopChoices(String authorityName, int start, int limit, String locale) { - init(); + init(locale); String xpathExpression = rootTemplate; return getChoicesByXpath(xpathExpression, start, limit); } @Override public Choices getChoicesByParent(String authorityName, String parentId, int start, int limit, String locale) { - init(); + init(locale); String xpathExpression = String.format(idTemplate, parentId); return getChoicesByXpath(xpathExpression, start, limit); } @Override public Choice getParentChoice(String authorityName, String childId, String locale) { - init(); + init(locale); try { String xpathExpression = String.format(idParentTemplate, childId); Choice choice = createChoiceFromNode(getNodeFromXPath(xpathExpression)); @@ -267,7 +289,7 @@ private boolean isRootElement(Node node) { } private Node getNode(String key) throws XPathExpressionException { - init(); + init(null); String xpathExpression = String.format(idTemplate, key); Node node = getNodeFromXPath(xpathExpression); return node; @@ -324,7 +346,7 @@ private String getNodeLabel(String key, boolean useHierarchy) { if (useHierarchy) { return this.buildString(node); } else { - return node.getAttributes().getNamedItem("label").getNodeValue(); + return node.getAttributes().getNamedItem("id").getNodeValue(); } } catch (XPathExpressionException e) { return (""); @@ -345,7 +367,7 @@ private String getValue(Node node) { if (this.storeHierarchy) { return hierarchy; } else { - return node.getAttributes().getNamedItem("label").getNodeValue(); + return node.getAttributes().getNamedItem(valueAttribute).getNodeValue(); } } diff --git a/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml new file mode 100644 index 000000000000..45ad97d0e158 --- /dev/null +++ b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml new file mode 100644 index 000000000000..820ebac81d8a --- /dev/null +++ b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 05a4cc5add01..175e125d8146 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -174,3 +174,7 @@ authority.controlled.dspace.object.owner = true # Configuration required for thorough testing of browse links webui.browse.link.1 = author:dc.contributor.* webui.browse.link.2 = subject:dc.subject.* + +# Configuration required for testing the controlled vocabulary functionality, which is configured using properties +vocabulary.plugin.countries.hierarchy.store=false +vocabulary.plugin.countries.storeIDs=true \ No newline at end of file diff --git a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java index 255b070e5eac..e7d67600a5fa 100644 --- a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java +++ b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java @@ -89,6 +89,85 @@ public void testGetMatches() throws IOException, ClassNotFoundException { assertEquals("north 40", result.values[0].value); } + /** + * Test of getMatches method of class + * DSpaceControlledVocabulary using a controlled vocabulary with configured storage of node id. + * @throws java.lang.ClassNotFoundException passed through. + */ + @Test + public void testGetMatchesIdValue() throws ClassNotFoundException { + System.out.println("getMatchesIdValue"); + + final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; + + String idValue = "DZA"; + int start = 0; + int limit = 10; + String locale = null; + // This "countries" Controlled Vocab is included in TestEnvironment data + // (under /src/test/data/dspaceFolder/) and it should be auto-loaded + // by test configs in /src/test/data/dspaceFolder/config/local.cfg + DSpaceControlledVocabulary instance = (DSpaceControlledVocabulary) + CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), + "countries"); + assertNotNull(instance); + Choices result = instance.getMatches(idValue, start, limit, locale); + assertEquals(idValue, result.values[0].value); + } + + /** + * Test of getMatches method of class + * DSpaceControlledVocabulary using a localized controlled vocabulary with no locale (fallback to default) + * @throws java.lang.ClassNotFoundException passed through. + */ + + @Test + public void testGetMatchesNoLocale() throws ClassNotFoundException { + System.out.println("getMatchesNoLocale"); + + final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; + + String idValue = "DZA"; + int start = 0; + int limit = 10; + String locale = null; + // This "countries" Controlled Vocab is included in TestEnvironment data + // (under /src/test/data/dspaceFolder/) and it should be auto-loaded + // by test configs in /src/test/data/dspaceFolder/config/local.cfg + DSpaceControlledVocabulary instance = (DSpaceControlledVocabulary) + CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), + "countries"); + assertNotNull(instance); + Choices result = instance.getMatches(idValue, start, limit, locale); + assertEquals("Algeria", result.values[0].label); + } + + /** + * Test of getMatches method of class + * DSpaceControlledVocabulary using a localized controlled vocabulary with valid locale parameter (localized + * label returned) + */ + @Test + public void testGetMatchesGermanLocale() throws ClassNotFoundException { + System.out.println("getMatchesNoLocale"); + + final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; + + String idValue = "DZA"; + int start = 0; + int limit = 10; + String locale = "de"; + // This "countries" Controlled Vocab is included in TestEnvironment data + // (under /src/test/data/dspaceFolder/) and it should be auto-loaded + // by test configs in /src/test/data/dspaceFolder/config/local.cfg + DSpaceControlledVocabulary instance = (DSpaceControlledVocabulary) + CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), + "countries"); + assertNotNull(instance); + Choices result = instance.getMatches(idValue, start, limit, locale); + assertEquals("Algerien", result.values[0].label); + } + /** * Test of getBestMatch method, of class DSpaceControlledVocabulary. */ From 5c3902486e3d80a5bf2bc4059679296b9741762c Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Fri, 9 Feb 2024 15:12:03 +0100 Subject: [PATCH 002/114] added line endings --- .../dspaceFolder/config/controlled-vocabularies/countries.xml | 2 +- .../config/controlled-vocabularies/countries_de.xml | 2 +- dspace-api/src/test/data/dspaceFolder/config/local.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml index 45ad97d0e158..078e8bfa3865 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries.xml @@ -7,4 +7,4 @@ - \ No newline at end of file + diff --git a/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml index 820ebac81d8a..b4bbf0b1e03c 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml +++ b/dspace-api/src/test/data/dspaceFolder/config/controlled-vocabularies/countries_de.xml @@ -7,4 +7,4 @@ - \ No newline at end of file + diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 175e125d8146..9873f24920f1 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -177,4 +177,4 @@ webui.browse.link.2 = subject:dc.subject.* # Configuration required for testing the controlled vocabulary functionality, which is configured using properties vocabulary.plugin.countries.hierarchy.store=false -vocabulary.plugin.countries.storeIDs=true \ No newline at end of file +vocabulary.plugin.countries.storeIDs=true From 0d6836720c4f4c55415093f285f4d94348763536 Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Fri, 9 Feb 2024 16:02:23 +0100 Subject: [PATCH 003/114] Bugfix after IT --- .../content/authority/DSpaceControlledVocabulary.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index 11f7009cfaa5..8169f9bf1a00 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -225,12 +225,12 @@ public Choices getBestMatch(String text, String locale) { @Override public String getLabel(String key, String locale) { - return getNodeLabel(key, this.suggestHierarchy); + return getNodeValue(key, this.suggestHierarchy); } @Override public String getValue(String key, String locale) { - return getNodeLabel(key, this.storeHierarchy); + return getNodeValue(key, this.storeHierarchy); } @Override @@ -337,7 +337,7 @@ private Map addOtherInformation(String parentCurr, String noteCu return extras; } - private String getNodeLabel(String key, boolean useHierarchy) { + private String getNodeValue(String key, boolean useHierarchy) { try { Node node = getNode(key); if (Objects.isNull(node)) { @@ -346,7 +346,7 @@ private String getNodeLabel(String key, boolean useHierarchy) { if (useHierarchy) { return this.buildString(node); } else { - return node.getAttributes().getNamedItem("id").getNodeValue(); + return node.getAttributes().getNamedItem(valueAttribute).getNodeValue(); } } catch (XPathExpressionException e) { return (""); From 5d9649a9016fa7c647b1d87eff52625054f7b713 Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Tue, 19 Mar 2024 11:08:58 +0100 Subject: [PATCH 004/114] Bugfix getMatches: only use label query xPathTemplate (getMatches purpose is to find choices by label) --- .../authority/DSpaceControlledVocabulary.java | 8 +-- .../DSpaceControlledVocabularyTest.java | 59 +++++++++++++------ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index 8169f9bf1a00..1d3760ba0c0f 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -60,9 +60,7 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements HierarchicalAuthority { private static Logger log = org.apache.logging.log4j.LogManager.getLogger(DSpaceControlledVocabulary.class); - protected static String xpathIdTemplate = "//node[contains(translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + - "'abcdefghijklmnopqrstuvwxyz'),'%s')]"; - protected static String xpathLabelTemplate = "//node[contains(translate(@label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + + protected static String xpathTemplate = "//node[contains(translate(@label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ'," + "'abcdefghijklmnopqrstuvwxyz'),'%s')]"; protected static String idTemplate = "//node[@id = '%s']"; protected static String labelTemplate = "//node[@label = '%s']"; @@ -79,7 +77,6 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Hiera protected Integer preloadLevel = 1; protected String valueAttribute = labelAttribute; protected String valueTemplate = labelTemplate; - protected String xpathValueTemplate = xpathLabelTemplate; public DSpaceControlledVocabulary() { super(); @@ -140,7 +137,6 @@ protected void init(String locale) { if (storeIDs) { valueAttribute = idAttribute; valueTemplate = idTemplate; - xpathValueTemplate = xpathIdTemplate; } String filename = vocabulariesPath + vocabularyName + ".xml"; @@ -184,7 +180,7 @@ public Choices getMatches(String text, int start, int limit, String locale) { String[] textHierarchy = text.split(hierarchyDelimiter, -1); for (int i = 0; i < textHierarchy.length; i++) { xpathExpression += - String.format(xpathValueTemplate, textHierarchy[i].replaceAll("'", "'").toLowerCase()); + String.format(xpathTemplate, textHierarchy[i].replaceAll("'", "'").toLowerCase()); } XPath xpath = XPathFactory.newInstance().newXPath(); int total = 0; diff --git a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java index e7d67600a5fa..a148863ae33e 100644 --- a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java +++ b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java @@ -95,15 +95,23 @@ public void testGetMatches() throws IOException, ClassNotFoundException { * @throws java.lang.ClassNotFoundException passed through. */ @Test - public void testGetMatchesIdValue() throws ClassNotFoundException { - System.out.println("getMatchesIdValue"); + public void testGetMatchesIdValueForLabel() throws ClassNotFoundException { + } + + /** + * Test of getMatches method of class + * DSpaceControlledVocabulary using a localized controlled vocabulary with no locale (fallback to default) + * @throws java.lang.ClassNotFoundException passed through. + */ + @Test + public void testGetMatchesNoLocale() throws ClassNotFoundException { final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; String idValue = "DZA"; + String labelPart = "Alge"; int start = 0; int limit = 10; - String locale = null; // This "countries" Controlled Vocab is included in TestEnvironment data // (under /src/test/data/dspaceFolder/) and it should be auto-loaded // by test configs in /src/test/data/dspaceFolder/config/local.cfg @@ -111,26 +119,21 @@ public void testGetMatchesIdValue() throws ClassNotFoundException { CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), "countries"); assertNotNull(instance); - Choices result = instance.getMatches(idValue, start, limit, locale); + Choices result = instance.getMatches(labelPart, start, limit, null); assertEquals(idValue, result.values[0].value); + assertEquals("Algeria", result.values[0].label); } /** - * Test of getMatches method of class + * Test of getBestMatch method of class * DSpaceControlledVocabulary using a localized controlled vocabulary with no locale (fallback to default) * @throws java.lang.ClassNotFoundException passed through. */ - @Test - public void testGetMatchesNoLocale() throws ClassNotFoundException { - System.out.println("getMatchesNoLocale"); - + public void testGetBestMatchIdValueNoLocale() throws ClassNotFoundException { final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; String idValue = "DZA"; - int start = 0; - int limit = 10; - String locale = null; // This "countries" Controlled Vocab is included in TestEnvironment data // (under /src/test/data/dspaceFolder/) and it should be auto-loaded // by test configs in /src/test/data/dspaceFolder/config/local.cfg @@ -138,7 +141,8 @@ public void testGetMatchesNoLocale() throws ClassNotFoundException { CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), "countries"); assertNotNull(instance); - Choices result = instance.getMatches(idValue, start, limit, locale); + Choices result = instance.getBestMatch(idValue, null); + assertEquals(idValue, result.values[0].value); assertEquals("Algeria", result.values[0].label); } @@ -149,14 +153,12 @@ public void testGetMatchesNoLocale() throws ClassNotFoundException { */ @Test public void testGetMatchesGermanLocale() throws ClassNotFoundException { - System.out.println("getMatchesNoLocale"); - final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; String idValue = "DZA"; + String labelPart = "Alge"; int start = 0; int limit = 10; - String locale = "de"; // This "countries" Controlled Vocab is included in TestEnvironment data // (under /src/test/data/dspaceFolder/) and it should be auto-loaded // by test configs in /src/test/data/dspaceFolder/config/local.cfg @@ -164,7 +166,30 @@ public void testGetMatchesGermanLocale() throws ClassNotFoundException { CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), "countries"); assertNotNull(instance); - Choices result = instance.getMatches(idValue, start, limit, locale); + Choices result = instance.getMatches(labelPart, start, limit, "de"); + assertEquals(idValue, result.values[0].value); + assertEquals("Algerien", result.values[0].label); + } + + /** + * Test of getBestMatch method of class + * DSpaceControlledVocabulary using a localized controlled vocabulary with valid locale parameter (localized + * label returned) + */ + @Test + public void testGetBestMatchIdValueGermanLocale() throws ClassNotFoundException { + final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; + + String idValue = "DZA"; + // This "countries" Controlled Vocab is included in TestEnvironment data + // (under /src/test/data/dspaceFolder/) and it should be auto-loaded + // by test configs in /src/test/data/dspaceFolder/config/local.cfg + DSpaceControlledVocabulary instance = (DSpaceControlledVocabulary) + CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), + "countries"); + assertNotNull(instance); + Choices result = instance.getBestMatch(idValue, "de"); + assertEquals(idValue, result.values[0].value); assertEquals("Algerien", result.values[0].label); } From 4426bef317058075a8c1c9754f9ec362dd408da0 Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Tue, 19 Mar 2024 14:48:42 +0100 Subject: [PATCH 005/114] Removed empty unused test case --- .../authority/DSpaceControlledVocabularyTest.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java index a148863ae33e..0ddcfbd18476 100644 --- a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java +++ b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java @@ -89,16 +89,6 @@ public void testGetMatches() throws IOException, ClassNotFoundException { assertEquals("north 40", result.values[0].value); } - /** - * Test of getMatches method of class - * DSpaceControlledVocabulary using a controlled vocabulary with configured storage of node id. - * @throws java.lang.ClassNotFoundException passed through. - */ - @Test - public void testGetMatchesIdValueForLabel() throws ClassNotFoundException { - - } - /** * Test of getMatches method of class * DSpaceControlledVocabulary using a localized controlled vocabulary with no locale (fallback to default) From bcf5adc2bf253915f703d4da5bed426e8d124291 Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Wed, 27 Mar 2024 11:21:44 +0100 Subject: [PATCH 006/114] always pass the locale to init, ensuring getChoice works as expected --- .../authority/DSpaceControlledVocabulary.java | 14 +++--- .../DSpaceControlledVocabularyTest.java | 45 +++++++++++++++++++ 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index 1d3760ba0c0f..3271f440d779 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -221,19 +221,19 @@ public Choices getBestMatch(String text, String locale) { @Override public String getLabel(String key, String locale) { - return getNodeValue(key, this.suggestHierarchy); + return getNodeValue(key, locale, this.suggestHierarchy); } @Override public String getValue(String key, String locale) { - return getNodeValue(key, this.storeHierarchy); + return getNodeValue(key, locale, this.storeHierarchy); } @Override public Choice getChoice(String authKey, String locale) { Node node; try { - node = getNode(authKey); + node = getNode(authKey, locale); } catch (XPathExpressionException e) { return null; } @@ -284,8 +284,8 @@ private boolean isRootElement(Node node) { return false; } - private Node getNode(String key) throws XPathExpressionException { - init(null); + private Node getNode(String key, String locale) throws XPathExpressionException { + init(locale); String xpathExpression = String.format(idTemplate, key); Node node = getNodeFromXPath(xpathExpression); return node; @@ -333,9 +333,9 @@ private Map addOtherInformation(String parentCurr, String noteCu return extras; } - private String getNodeValue(String key, boolean useHierarchy) { + private String getNodeValue(String key, String locale, boolean useHierarchy) { try { - Node node = getNode(key); + Node node = getNode(key, locale); if (Objects.isNull(node)) { return null; } diff --git a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java index 0ddcfbd18476..43bd20cc1553 100644 --- a/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java +++ b/dspace-api/src/test/java/org/dspace/content/authority/DSpaceControlledVocabularyTest.java @@ -183,6 +183,51 @@ public void testGetBestMatchIdValueGermanLocale() throws ClassNotFoundException assertEquals("Algerien", result.values[0].label); } + /** + * Test of getChoice method of class + * DSpaceControlledVocabulary using a localized controlled vocabulary with no locale (fallback to default) + * @throws java.lang.ClassNotFoundException passed through. + */ + @Test + public void testGetChoiceNoLocale() throws ClassNotFoundException { + final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; + + String idValue = "DZA"; + // This "countries" Controlled Vocab is included in TestEnvironment data + // (under /src/test/data/dspaceFolder/) and it should be auto-loaded + // by test configs in /src/test/data/dspaceFolder/config/local.cfg + DSpaceControlledVocabulary instance = (DSpaceControlledVocabulary) + CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), + "countries"); + assertNotNull(instance); + Choice result = instance.getChoice(idValue, null); + assertEquals(idValue, result.value); + assertEquals("Algeria", result.label); + } + + /** + * Test of getChoice method of class + * DSpaceControlledVocabulary using a localized controlled vocabulary with valid locale parameter (localized + * label returned) + * @throws java.lang.ClassNotFoundException passed through. + */ + @Test + public void testGetChoiceGermanLocale() throws ClassNotFoundException { + final String PLUGIN_INTERFACE = "org.dspace.content.authority.ChoiceAuthority"; + + String idValue = "DZA"; + // This "countries" Controlled Vocab is included in TestEnvironment data + // (under /src/test/data/dspaceFolder/) and it should be auto-loaded + // by test configs in /src/test/data/dspaceFolder/config/local.cfg + DSpaceControlledVocabulary instance = (DSpaceControlledVocabulary) + CoreServiceFactory.getInstance().getPluginService().getNamedPlugin(Class.forName(PLUGIN_INTERFACE), + "countries"); + assertNotNull(instance); + Choice result = instance.getChoice(idValue, "de"); + assertEquals(idValue, result.value); + assertEquals("Algerien", result.label); + } + /** * Test of getBestMatch method, of class DSpaceControlledVocabulary. */ From 4e541dad5d3f0616b348a82189d2e3d70f48257e Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Fri, 24 May 2024 11:52:32 +0200 Subject: [PATCH 007/114] fixed init call to cover new 'locale' parameter --- .../dspace/content/authority/DSpaceControlledVocabulary.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java index 80ab0b5231b5..4e30559e1c92 100644 --- a/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java +++ b/dspace-api/src/main/java/org/dspace/content/authority/DSpaceControlledVocabulary.java @@ -244,7 +244,7 @@ public Choice getChoice(String authKey, String locale) { @Override public boolean isHierarchical() { - init(); + init(null); return true; } @@ -277,7 +277,7 @@ public Choice getParentChoice(String authorityName, String childId, String local @Override public Integer getPreloadLevel() { - init(); + init(null); return preloadLevel; } From 3dab2a7cea812420422af160d86371a59b48374f Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Tue, 4 Jun 2024 16:02:53 -0400 Subject: [PATCH 008/114] 110719: Port fix to checkLinks that works on redirects --- .../ctask/general/BasicLinkChecker.java | 14 +++++-- .../impl/TestDSpaceRunnableHandler.java | 39 +++++++++++++++++ .../org/dspace/curate/CurationScriptIT.java | 42 +++++++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java b/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java index fbc6eebdb5b8..388036bd6744 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java @@ -132,10 +132,18 @@ protected int getResponseStatus(String url) { try { URL theURL = new URL(url); HttpURLConnection connection = (HttpURLConnection) theURL.openConnection(); - int code = connection.getResponseCode(); - connection.disconnect(); + connection.setInstanceFollowRedirects(true); + int statusCode = connection.getResponseCode(); + if ((statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM || + statusCode == HttpURLConnection.HTTP_SEE_OTHER)) { + connection.disconnect(); + String newUrl = connection.getHeaderField("Location"); + if (newUrl != null) { + return getResponseStatus(newUrl); + } - return code; + } + return statusCode; } catch (IOException ioe) { // Must be a bad URL diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java b/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java index 1b5b3fa7ac1a..aced81cbdfdb 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/scripts/handler/impl/TestDSpaceRunnableHandler.java @@ -7,6 +7,9 @@ */ package org.dspace.app.scripts.handler.impl; +import java.util.ArrayList; +import java.util.List; + import org.dspace.scripts.handler.impl.CommandLineDSpaceRunnableHandler; /** @@ -17,6 +20,12 @@ public class TestDSpaceRunnableHandler extends CommandLineDSpaceRunnableHandler private Exception exception = null; + private final List infoMessages = new ArrayList<>(); + + private final List errorMessages = new ArrayList<>(); + + private final List warningMessages = new ArrayList<>(); + /** * We're overriding this method so that we can stop the script from doing the System.exit() if * an exception within the script is thrown @@ -33,4 +42,34 @@ public void handleException(String message, Exception e) { public Exception getException() { return exception; } + + @Override + public void logInfo(String message) { + super.logInfo(message); + infoMessages.add(message); + } + + @Override + public void logWarning(String message) { + super.logWarning(message); + warningMessages.add(message); + } + + @Override + public void logError(String message) { + super.logError(message); + errorMessages.add(message); + } + + public List getInfoMessages() { + return infoMessages; + } + + public List getErrorMessages() { + return errorMessages; + } + + public List getWarningMessages() { + return warningMessages; + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java b/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java index 3e40a8559482..6bb9acb92482 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java @@ -9,6 +9,7 @@ import static com.jayway.jsonpath.JsonPath.read; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -21,6 +22,7 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.databind.ObjectMapper; +import org.dspace.app.launcher.ScriptLauncher; import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter; import org.dspace.app.rest.matcher.ProcessMatcher; import org.dspace.app.rest.model.ParameterValueRest; @@ -28,6 +30,7 @@ import org.dspace.app.rest.model.ScriptRest; import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; @@ -41,7 +44,9 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.eperson.EPerson; import org.dspace.scripts.DSpaceCommandLineParameter; +import org.dspace.scripts.DSpaceRunnable; import org.dspace.scripts.configuration.ScriptConfiguration; +import org.dspace.scripts.factory.ScriptServiceFactory; import org.dspace.scripts.service.ScriptService; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -640,4 +645,41 @@ public void securityCurateTest() throws Exception { ProcessBuilder.deleteProcess(idItemRef.get()); } } + + @Test + public void testURLRedirectCurateTest() throws Exception { + context.turnOffAuthorisationSystem(); + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + Item publicItem1 = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald").withAuthor("Doe, John") + .withMetadata("dc", "identifier", "uri", "https://tinyurl.com/2rxpte5s") + .withSubject("ExtraEntry") + .build(); + + String[] args = new String[] {"curate", "-t", "checklinks", "-i", publicItem1.getHandle()}; + TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); + + ScriptService scriptService = ScriptServiceFactory.getInstance().getScriptService(); + ScriptConfiguration scriptConfiguration = scriptService.getScriptConfiguration(args[0]); + + DSpaceRunnable script = null; + if (scriptConfiguration != null) { + script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration); + } + if (script != null) { + script.initialize(args, testDSpaceRunnableHandler, admin); + script.run(); + } + + assertTrue(testDSpaceRunnableHandler.getInfoMessages().contains("200 - OK")); + } } From e826660cb0bd926de390e04e466d54ceedb67a1e Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Thu, 13 Jun 2024 20:48:31 +0200 Subject: [PATCH 009/114] 110719: IT checking redirect links accepted by checklinks curate task --- .../org/dspace/curate/CurationScriptIT.java | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java b/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java index 6bb9acb92482..8c0744a09cce 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/curate/CurationScriptIT.java @@ -9,6 +9,7 @@ import static com.jayway.jsonpath.JsonPath.read; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -22,7 +23,7 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.launcher.ScriptLauncher; +import org.apache.commons.lang3.StringUtils; import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter; import org.dspace.app.rest.matcher.ProcessMatcher; import org.dspace.app.rest.model.ParameterValueRest; @@ -661,12 +662,19 @@ public void testURLRedirectCurateTest() throws Exception { .withTitle("Public item 1") .withIssueDate("2017-10-17") .withAuthor("Smith, Donald").withAuthor("Doe, John") - .withMetadata("dc", "identifier", "uri", "https://tinyurl.com/2rxpte5s") + // Value not starting with http or https + .withMetadata("dc", "identifier", "uri", "demo.dspace.org/home") + // MetadataValueLinkChecker uri field with regular link + .withMetadata("dc", "description", null, "https://google.com") + // MetadataValueLinkChecker uri field with redirect link + .withMetadata("dc", "description", "uri", "https://demo7.dspace.org/handle/123456789/1") + // MetadataValueLinkChecker uri field with non resolving link + .withMetadata("dc", "description", "uri", "https://www.atmire.com/broken-link") .withSubject("ExtraEntry") .build(); String[] args = new String[] {"curate", "-t", "checklinks", "-i", publicItem1.getHandle()}; - TestDSpaceRunnableHandler testDSpaceRunnableHandler = new TestDSpaceRunnableHandler(); + TestDSpaceRunnableHandler handler = new TestDSpaceRunnableHandler(); ScriptService scriptService = ScriptServiceFactory.getInstance().getScriptService(); ScriptConfiguration scriptConfiguration = scriptService.getScriptConfiguration(args[0]); @@ -676,10 +684,27 @@ public void testURLRedirectCurateTest() throws Exception { script = scriptService.createDSpaceRunnableForScriptConfiguration(scriptConfiguration); } if (script != null) { - script.initialize(args, testDSpaceRunnableHandler, admin); + script.initialize(args, handler, admin); script.run(); } - assertTrue(testDSpaceRunnableHandler.getInfoMessages().contains("200 - OK")); + // field that should be ignored + assertFalse(checkIfInfoTextLoggedByHandler(handler, "demo.dspace.org/home")); + // redirect links in field that should not be ignored (https) => expect OK + assertTrue(checkIfInfoTextLoggedByHandler(handler, "https://demo7.dspace.org/handle/123456789/1 = 200 - OK")); + // regular link in field that should not be ignored (http) => expect OK + assertTrue(checkIfInfoTextLoggedByHandler(handler, "https://google.com = 200 - OK")); + // nonexistent link in field that should not be ignored => expect 404 + assertTrue(checkIfInfoTextLoggedByHandler(handler, "https://www.atmire.com/broken-link = 404 - FAILED")); } + + boolean checkIfInfoTextLoggedByHandler(TestDSpaceRunnableHandler handler, String text) { + for (String message: handler.getInfoMessages()) { + if (StringUtils.containsIgnoreCase(message, text)) { + return true; + } + } + return false; + } + } From d80f49e0238981c22703abbb1423aa2896eca694 Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Tue, 23 Jul 2024 18:28:43 +0200 Subject: [PATCH 010/114] 116609: Improve running process observability - keep temp process log files in [dspace]/log/processes/ instead of temp dir - reformat file names of process logs - ensure that running and scheduled processes are cleaned up during startup --- .../dspace/scripts/ProcessServiceImpl.java | 56 +++++++++++++++---- .../app/rest/ProcessRestRepositoryIT.java | 8 +-- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java b/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java index 2e14aeaa36c0..63751d87e92a 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java @@ -45,14 +45,15 @@ import org.dspace.core.LogHelper; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.eperson.service.EPersonService; import org.dspace.scripts.service.ProcessService; +import org.dspace.services.ConfigurationService; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; /** * The implementation for the {@link ProcessService} class */ -public class ProcessServiceImpl implements ProcessService { +public class ProcessServiceImpl implements ProcessService, InitializingBean { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(ProcessService.class); @@ -72,7 +73,26 @@ public class ProcessServiceImpl implements ProcessService { private MetadataFieldService metadataFieldService; @Autowired - private EPersonService ePersonService; + private ConfigurationService configurationService; + + @Override + public void afterPropertiesSet() throws Exception { + Context context = new Context(); + + // Processes that were running or scheduled when tomcat crashed, should be cleaned up during startup. + List processesToBeFailed = findByStatusAndCreationTimeOlderThan( + context, List.of(ProcessStatus.RUNNING, ProcessStatus.SCHEDULED), new Date()); + for (Process process : processesToBeFailed) { + context.setCurrentUser(process.getEPerson()); + // Fail the process. + log.info("Process with ID {} did not complete before tomcat shutdown, failing it now.", process.getID()); + fail(context, process); + // But still attach its log to the process. + createLogBitstream(context, process); + } + + context.complete(); + } @Override public Process create(Context context, EPerson ePerson, String scriptName, @@ -286,8 +306,8 @@ public int countSearch(Context context, ProcessQueryParameterContainer processQu @Override public void appendLog(int processId, String scriptName, String output, ProcessLogLevel processLogLevel) throws IOException { - File tmpDir = FileUtils.getTempDirectory(); - File tempFile = new File(tmpDir, scriptName + processId + ".log"); + File logsDir = getLogsDirectory(); + File tempFile = new File(logsDir, processId + "-" + scriptName + ".log"); FileWriter out = new FileWriter(tempFile, true); try { try (BufferedWriter writer = new BufferedWriter(out)) { @@ -302,12 +322,15 @@ public void appendLog(int processId, String scriptName, String output, ProcessLo @Override public void createLogBitstream(Context context, Process process) throws IOException, SQLException, AuthorizeException { - File tmpDir = FileUtils.getTempDirectory(); - File tempFile = new File(tmpDir, process.getName() + process.getID() + ".log"); - FileInputStream inputStream = FileUtils.openInputStream(tempFile); - appendFile(context, process, inputStream, Process.OUTPUT_TYPE, process.getName() + process.getID() + ".log"); - inputStream.close(); - tempFile.delete(); + File logsDir = getLogsDirectory(); + File tempFile = new File(logsDir, process.getID() + "-" + process.getName() + ".log"); + if (tempFile.exists()) { + FileInputStream inputStream = FileUtils.openInputStream(tempFile); + appendFile(context, process, inputStream, Process.OUTPUT_TYPE, + process.getID() + "-" + process.getName() + ".log"); + inputStream.close(); + tempFile.delete(); + } } @Override @@ -336,4 +359,15 @@ private String formatLogLine(int processId, String scriptName, String output, Pr return sb.toString(); } + private File getLogsDirectory() { + String pathStr = configurationService.getProperty("dspace.dir") + + File.separator + "log" + File.separator + "processes"; + File logsDir = new File(pathStr); + if (!logsDir.exists()) { + if (!logsDir.mkdirs()) { + throw new RuntimeException("Couldn't create [dspace.dir]/log/processes/ directory."); + } + } + return logsDir; + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ProcessRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ProcessRestRepositoryIT.java index 670d8e2f35b0..6c018df6d070 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ProcessRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ProcessRestRepositoryIT.java @@ -856,10 +856,10 @@ public void getProcessOutput() throws Exception { getClient(token).perform(get("/api/system/processes/" + process1.getID() + "/output")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name", - is(process1.getName() + process1.getID() + ".log"))) + is(process1.getID() + "-" + process1.getName() + ".log"))) .andExpect(jsonPath("$.type", is("bitstream"))) .andExpect(jsonPath("$.metadata['dc.title'][0].value", - is(process1.getName() + process1.getID() + ".log"))) + is(process1.getID() + "-" + process1.getName() + ".log"))) .andExpect(jsonPath("$.metadata['dspace.process.filetype'][0].value", is("script_output"))); @@ -869,10 +869,10 @@ public void getProcessOutput() throws Exception { .perform(get("/api/system/processes/" + process1.getID() + "/output")) .andExpect(status().isOk()) .andExpect(jsonPath("$.name", - is(process1.getName() + process1.getID() + ".log"))) + is(process1.getID() + "-" + process1.getName() + ".log"))) .andExpect(jsonPath("$.type", is("bitstream"))) .andExpect(jsonPath("$.metadata['dc.title'][0].value", - is(process1.getName() + process1.getID() + ".log"))) + is(process1.getID() + "-" + process1.getName() + ".log"))) .andExpect(jsonPath("$.metadata['dspace.process.filetype'][0].value", is("script_output"))); From 156ad471b575dfc1c2b643ec4b2f677d6f89a314 Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Thu, 25 Jul 2024 09:33:50 +0200 Subject: [PATCH 011/114] 116609: Add tomcat shutdown line to process log --- .../src/main/java/org/dspace/scripts/ProcessServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java b/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java index 63751d87e92a..2f34fac65833 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java @@ -88,6 +88,9 @@ public void afterPropertiesSet() throws Exception { log.info("Process with ID {} did not complete before tomcat shutdown, failing it now.", process.getID()); fail(context, process); // But still attach its log to the process. + appendLog(process.getID(), process.getName(), + "Process did not complete before tomcat shutdown.", + ProcessLogLevel.ERROR); createLogBitstream(context, process); } From bdf7069cb752782a4f8df62885c9ae6116be9dde Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Thu, 25 Jul 2024 14:13:16 +0200 Subject: [PATCH 012/114] 116687: Never handle exception with null message --- .../rest/scripts/handler/impl/RestDSpaceRunnableHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java index 596ab4429093..ee67baa8ab38 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/scripts/handler/impl/RestDSpaceRunnableHandler.java @@ -130,7 +130,7 @@ public void handleCompletion() { @Override public void handleException(Exception e) { - handleException(null, e); + handleException(e.getMessage(), e); } @Override From 070fe689d70d8dbfcde63899d377f2524f38d6db Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Mon, 29 Jul 2024 13:48:32 +0200 Subject: [PATCH 013/114] 116609: Add try catch to init method in ProcessServiceImpl --- .../dspace/scripts/ProcessServiceImpl.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java b/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java index c34705a64d5d..ab5147221cfc 100644 --- a/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/scripts/ProcessServiceImpl.java @@ -77,24 +77,29 @@ public class ProcessServiceImpl implements ProcessService, InitializingBean { @Override public void afterPropertiesSet() throws Exception { - Context context = new Context(); - - // Processes that were running or scheduled when tomcat crashed, should be cleaned up during startup. - List processesToBeFailed = findByStatusAndCreationTimeOlderThan( - context, List.of(ProcessStatus.RUNNING, ProcessStatus.SCHEDULED), new Date()); - for (Process process : processesToBeFailed) { - context.setCurrentUser(process.getEPerson()); - // Fail the process. - log.info("Process with ID {} did not complete before tomcat shutdown, failing it now.", process.getID()); - fail(context, process); - // But still attach its log to the process. - appendLog(process.getID(), process.getName(), - "Process did not complete before tomcat shutdown.", - ProcessLogLevel.ERROR); - createLogBitstream(context, process); - } + try { + Context context = new Context(); + + // Processes that were running or scheduled when tomcat crashed, should be cleaned up during startup. + List processesToBeFailed = findByStatusAndCreationTimeOlderThan( + context, List.of(ProcessStatus.RUNNING, ProcessStatus.SCHEDULED), new Date()); + for (Process process : processesToBeFailed) { + context.setCurrentUser(process.getEPerson()); + // Fail the process. + log.info("Process with ID {} did not complete before tomcat shutdown, failing it now.", + process.getID()); + fail(context, process); + // But still attach its log to the process. + appendLog(process.getID(), process.getName(), + "Process did not complete before tomcat shutdown.", + ProcessLogLevel.ERROR); + createLogBitstream(context, process); + } - context.complete(); + context.complete(); + } catch (Exception e) { + log.error("Unable to clean up Processes: ", e); + } } @Override From e8ec0c1b1d20dd5e812f38593a24718fff1d8c6e Mon Sep 17 00:00:00 2001 From: Agustina Martinez Date: Mon, 5 Aug 2024 11:06:06 +0200 Subject: [PATCH 014/114] Fix 9734: Check configured workflow.reviewer.file-edit to show item edit functionality in workflow UI --- .../processingaction/ScoreReviewAction.java | 15 ++++++++++++++- .../processingaction/SingleUserReviewAction.java | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java index a8ed4fd3dae9..50f338499282 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java @@ -8,6 +8,7 @@ package org.dspace.xmlworkflow.state.actions.processingaction; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -20,6 +21,8 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.MetadataFieldName; import org.dspace.core.Context; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionAdvancedInfo; @@ -34,6 +37,9 @@ public class ScoreReviewAction extends ProcessingAction { private static final Logger log = LogManager.getLogger(ScoreReviewAction.class); + private final ConfigurationService configurationService + = DSpaceServicesFactory.getInstance().getConfigurationService(); + // Option(s) public static final String SUBMIT_SCORE = "submit_score"; @@ -114,7 +120,14 @@ private boolean checkRequestValid(int score, String review) { @Override public List getOptions() { - return List.of(SUBMIT_SCORE, RETURN_TO_POOL); + List options = new ArrayList<>(); + options.add(SUBMIT_SCORE); + if (configurationService.getBooleanProperty("workflow.reviewer.file-edit", false)) { + options.add(SUBMIT_EDIT_METADATA); + } + options.add(RETURN_TO_POOL); + + return options; } @Override diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java index 64e0957b65b7..c46fa851e4f1 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java @@ -21,6 +21,8 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; @@ -40,6 +42,9 @@ public class SingleUserReviewAction extends ProcessingAction { private static final Logger log = LogManager.getLogger(SingleUserReviewAction.class); + private final ConfigurationService configurationService + = DSpaceServicesFactory.getInstance().getConfigurationService(); + public static final int OUTCOME_REJECT = 1; protected static final String SUBMIT_DECLINE_TASK = "submit_decline_task"; @@ -95,6 +100,9 @@ public ActionResult processAccept(Context c, XmlWorkflowItem wfi) throws SQLExce public List getOptions() { List options = new ArrayList<>(); options.add(SUBMIT_APPROVE); + if (configurationService.getBooleanProperty("workflow.reviewer.file-edit", false)) { + options.add(SUBMIT_EDIT_METADATA); + } options.add(SUBMIT_REJECT); options.add(SUBMIT_DECLINE_TASK); return options; From 7477c4311c93a214dcb7225874d872ccdda7f14a Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 11:40:35 +0200 Subject: [PATCH 015/114] refactoring OpenSearchController: remove SyndicationFeed dependency --- .../dspace/app/rest/OpenSearchController.java | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/OpenSearchController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/OpenSearchController.java index baf45c14b6eb..6bc7034b5b09 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/OpenSearchController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/OpenSearchController.java @@ -9,9 +9,7 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; @@ -24,7 +22,6 @@ import org.apache.logging.log4j.Logger; import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ScopeResolver; -import org.dspace.app.util.SyndicationFeed; import org.dspace.app.util.factory.UtilServiceFactory; import org.dspace.app.util.service.OpenSearchService; import org.dspace.authorize.factory.AuthorizeServiceFactory; @@ -200,12 +197,10 @@ public void search(HttpServletRequest request, log.info("opensearch done, query=\"" + query + "\",results=" + qResults.getTotalSearchResults()); - // format and return results - Map labelMap = getLabels(request); List dsoResults = qResults.getIndexableObjects(); Document resultsDoc = openSearchService.getResultsDoc(context, format, query, (int) qResults.getTotalSearchResults(), qResults.getStart(), - qResults.getMaxResults(), container, dsoResults, labelMap); + qResults.getMaxResults(), container, dsoResults); try { Transformer xf = TransformerFactory.newInstance().newTransformer(); response.setContentType(openSearchService.getContentType(format)); @@ -274,20 +269,4 @@ private void init() { public void setOpenSearchService(OpenSearchService oSS) { openSearchService = oSS; } - - - /** - * Internal method to get labels for the returned document - */ - private Map getLabels(HttpServletRequest request) { - // TODO: get strings from translation file or configuration - Map labelMap = new HashMap(); - labelMap.put(SyndicationFeed.MSG_UNTITLED, "notitle"); - labelMap.put(SyndicationFeed.MSG_LOGO_TITLE, "logo.title"); - labelMap.put(SyndicationFeed.MSG_FEED_DESCRIPTION, "general-feed.description"); - for (String selector : SyndicationFeed.getDescriptionSelectors()) { - labelMap.put("metadata." + selector, selector); - } - return labelMap; - } } From 4374505cc9c3e2e520f3405cb33845b40b8db5ed Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 11:44:10 +0200 Subject: [PATCH 016/114] refactoring of OpenSearchService interface: remove label method parameter --- .../app/util/service/OpenSearchService.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java b/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java index 03f41e535c53..74bdd5bc7a6c 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java +++ b/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.sql.SQLException; import java.util.List; -import java.util.Map; import org.dspace.content.DSpaceObject; import org.dspace.core.Context; @@ -85,15 +84,13 @@ public interface OpenSearchService { * @param start - start result index * @param pageSize - page size * @param scope - search scope, null or the community/collection - * @param results the retreived DSpace objects satisfying search - * @param labels labels to apply - format specific + * @param results the retrieved DSpace objects satisfying search * @return formatted search results * @throws IOException if IO error */ public String getResultsString(Context context, String format, String query, int totalResults, int start, - int pageSize, - IndexableObject scope, List results, - Map labels) throws IOException; + int pageSize, IndexableObject scope, List results,) + throws IOException; /** * Returns a formatted set of search results as a document @@ -105,14 +102,12 @@ public String getResultsString(Context context, String format, String query, int * @param start - start result index * @param pageSize - page size * @param scope - search scope, null or the community/collection - * @param results the retreived DSpace objects satisfying search - * @param labels labels to apply - format specific + * @param results the retrieved DSpace objects satisfying search * @return formatted search results * @throws IOException if IO error */ public Document getResultsDoc(Context context, String format, String query, int totalResults, int start, - int pageSize, - IndexableObject scope, List results, Map labels) + int pageSize, IndexableObject scope, List results) throws IOException; public DSpaceObject resolveScope(Context context, String scope) throws SQLException; From 7b525e183a184e16ff0e389dd1c3603b7dc8fab4 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 11:47:46 +0200 Subject: [PATCH 017/114] refactoring of OpenSearchServiceImpl: adapt to changes made in interface --- .../app/util/OpenSearchServiceImpl.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/util/OpenSearchServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/util/OpenSearchServiceImpl.java index bff741b5ca42..2800ae6d10a2 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/OpenSearchServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/util/OpenSearchServiceImpl.java @@ -14,7 +14,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; import com.rometools.modules.opensearch.OpenSearchModule; import com.rometools.modules.opensearch.entity.OSQuery; @@ -58,12 +57,12 @@ public class OpenSearchServiceImpl implements OpenSearchService { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(OpenSearchServiceImpl.class); // Namespaces used - protected final String osNs = "http://a9.com/-/spec/opensearch/1.1/"; + protected final static String osNs = "http://a9.com/-/spec/opensearch/1.1/"; - @Autowired(required = true) + @Autowired protected ConfigurationService configurationService; - @Autowired(required = true) + @Autowired protected HandleService handleService; protected OpenSearchServiceImpl() { @@ -119,11 +118,10 @@ public String getDescription(String scope) { @Override public String getResultsString(Context context, String format, String query, int totalResults, int start, - int pageSize, - IndexableObject scope, List results, - Map labels) throws IOException { + int pageSize, IndexableObject scope, List results) + throws IOException { try { - return getResults(context, format, query, totalResults, start, pageSize, scope, results, labels) + return getResults(context, format, query, totalResults, start, pageSize, scope, results) .outputString(); } catch (FeedException e) { log.error(e.toString(), e); @@ -133,11 +131,10 @@ public String getResultsString(Context context, String format, String query, int @Override public Document getResultsDoc(Context context, String format, String query, int totalResults, int start, - int pageSize, - IndexableObject scope, List results, Map labels) + int pageSize, IndexableObject scope, List results) throws IOException { try { - return getResults(context, format, query, totalResults, start, pageSize, scope, results, labels) + return getResults(context, format, query, totalResults, start, pageSize, scope, results) .outputW3CDom(); } catch (FeedException e) { log.error(e.toString(), e); @@ -146,8 +143,7 @@ public Document getResultsDoc(Context context, String format, String query, int } protected SyndicationFeed getResults(Context context, String format, String query, int totalResults, int start, - int pageSize, IndexableObject scope, - List results, Map labels) { + int pageSize, IndexableObject scope, List results) { // Encode results in requested format if ("rss".equals(format)) { format = "rss_2.0"; @@ -156,7 +152,7 @@ protected SyndicationFeed getResults(Context context, String format, String quer } SyndicationFeed feed = new SyndicationFeed(); - feed.populate(null, context, scope, results, labels); + feed.populate(null, context, scope, results); feed.setType(format); feed.addModule(openSearchMarkup(query, totalResults, start, pageSize)); return feed; From 70dde2db0b1161a1891da2726171d01122042cf2 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 11:54:58 +0200 Subject: [PATCH 018/114] refactoring of SyndicationFeed: move method getLabels from OpenSearchController --- .../org/dspace/app/util/SyndicationFeed.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java index 654036963572..d736ab5a06a7 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java @@ -11,6 +11,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -135,8 +136,6 @@ public class SyndicationFeed { protected String[] podcastableMIMETypes = configurationService.getArrayProperty("webui.feed.podcast.mimetypes", new String[] {"audio/x-mpeg"}); - // -------- Instance variables: - // the feed object we are building protected SyndFeed feed = null; @@ -146,9 +145,6 @@ public class SyndicationFeed { protected CommunityService communityService; protected ItemService itemService; - /** - * Constructor. - */ public SyndicationFeed() { feed = new SyndFeedImpl(); ContentServiceFactory contentServiceFactory = ContentServiceFactory.getInstance(); @@ -157,16 +153,6 @@ public SyndicationFeed() { communityService = contentServiceFactory.getCommunityService(); } - /** - * Returns list of metadata selectors used to compose the description element - * - * @return selector list - format 'schema.element[.qualifier]' - */ - public static String[] getDescriptionSelectors() { - return (String[]) ArrayUtils.clone(descriptionFields); - } - - /** * Fills in the feed and entry-level metadata from DSpace objects. * @@ -174,10 +160,9 @@ public static String[] getDescriptionSelectors() { * @param context context * @param dso the scope * @param items array of objects - * @param labels label map */ public void populate(HttpServletRequest request, Context context, IndexableObject dso, - List items, Map labels) { + List items) { String logoURL = null; String objectURL = null; String defaultTitle = null; @@ -553,5 +538,19 @@ protected String getOneDC(Item item, String field) { List dcv = itemService.getMetadataByMetadataString(item, field); return (dcv.size() > 0) ? dcv.get(0).getValue() : null; } -} + /** + * Internal method to get labels for the returned document + */ + private Map getLabels() { + // TODO: get strings from translation file or configuration + Map labelMap = new HashMap<>(); + labelMap.put(SyndicationFeed.MSG_UNTITLED, "notitle"); + labelMap.put(SyndicationFeed.MSG_LOGO_TITLE, "logo.title"); + labelMap.put(SyndicationFeed.MSG_FEED_DESCRIPTION, "general-feed.description"); + for (String selector : descriptionFields) { + labelMap.put("metadata." + selector, selector); + } + return labelMap; + } +} From c533a5754ac1fca02ff8a7f1800f456f66a86c87 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 12:06:02 +0200 Subject: [PATCH 019/114] call private method getLabels() directly --- .../src/main/java/org/dspace/app/util/SyndicationFeed.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java index d736ab5a06a7..bcd4067c8daa 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java @@ -168,6 +168,9 @@ public void populate(HttpServletRequest request, Context context, IndexableObjec String defaultTitle = null; boolean podcastFeed = false; this.request = request; + + Map labels = getLabels(); + // dso is null for the whole site, or a search without scope if (dso == null) { defaultTitle = configurationService.getProperty("dspace.name"); From 7bb76d8523949b4da35badda979eb9f51f3ca760 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 12:10:17 +0200 Subject: [PATCH 020/114] fixed compilation error (obsolete comma) --- .../java/org/dspace/app/util/service/OpenSearchService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java b/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java index 74bdd5bc7a6c..78b208faa2bc 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java +++ b/dspace-api/src/main/java/org/dspace/app/util/service/OpenSearchService.java @@ -89,7 +89,7 @@ public interface OpenSearchService { * @throws IOException if IO error */ public String getResultsString(Context context, String format, String query, int totalResults, int start, - int pageSize, IndexableObject scope, List results,) + int pageSize, IndexableObject scope, List results) throws IOException; /** From fa9f9457f77a9b882322054ce180bf8e12ba07a5 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 5 Aug 2024 12:22:27 +0200 Subject: [PATCH 021/114] resolve lint warnings: remove trailing whitespaces --- .../src/main/java/org/dspace/app/util/SyndicationFeed.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java index bcd4067c8daa..e6220cd220de 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java +++ b/dspace-api/src/main/java/org/dspace/app/util/SyndicationFeed.java @@ -168,9 +168,9 @@ public void populate(HttpServletRequest request, Context context, IndexableObjec String defaultTitle = null; boolean podcastFeed = false; this.request = request; - + Map labels = getLabels(); - + // dso is null for the whole site, or a search without scope if (dso == null) { defaultTitle = configurationService.getProperty("dspace.name"); @@ -555,5 +555,5 @@ private Map getLabels() { labelMap.put("metadata." + selector, selector); } return labelMap; - } + } } From 4b32fa216caede8b0ac4922bbfc3d7fd0d006750 Mon Sep 17 00:00:00 2001 From: Yury Bondarenko Date: Tue, 6 Aug 2024 15:38:55 +0200 Subject: [PATCH 022/114] Make submissiondefinition pagination test more flexible --- .../SubmissionDefinitionsControllerIT.java | 45 +++++++++++-------- .../matcher/SubmissionDefinitionsMatcher.java | 15 +++++-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java index babb1fac2326..6ad6aff7e9b0 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java @@ -8,6 +8,7 @@ package org.dspace.app.rest; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.dspace.app.rest.matcher.SubmissionDefinitionsMatcher.matchSubmissionConfig; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.hasSize; @@ -17,8 +18,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.List; + import org.dspace.app.rest.matcher.SubmissionDefinitionsMatcher; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.app.util.SubmissionConfig; +import org.dspace.app.util.SubmissionConfigReader; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.content.Collection; @@ -239,13 +244,17 @@ public void findSections() throws Exception { @Test public void findAllPaginationTest() throws Exception { + List definitions = new SubmissionConfigReader().getAllSubmissionConfigs(100, 0); + int totalCount = definitions.size(); + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") .param("size", "1") .param("page", "0")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("traditional"))) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0]", matchSubmissionConfig(definitions.get(0)))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=0"), Matchers.containsString("size=1")))) @@ -259,8 +268,8 @@ public void findAllPaginationTest() throws Exception { Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=6"), Matchers.containsString("size=1")))) .andExpect(jsonPath("$.page.size", is(1))) - .andExpect(jsonPath("$.page.totalElements", is(7))) - .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(totalCount))) + .andExpect(jsonPath("$.page.totalPages", is(totalCount))) .andExpect(jsonPath("$.page.number", is(0))); getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") @@ -268,7 +277,7 @@ public void findAllPaginationTest() throws Exception { .param("page", "1")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("test-hidden"))) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0]", matchSubmissionConfig(definitions.get(1)))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=0"), Matchers.containsString("size=1")))) @@ -285,8 +294,8 @@ public void findAllPaginationTest() throws Exception { Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page="), Matchers.containsString("size=1")))) .andExpect(jsonPath("$.page.size", is(1))) - .andExpect(jsonPath("$.page.totalElements", is(7))) - .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(totalCount))) + .andExpect(jsonPath("$.page.totalPages", is(totalCount))) .andExpect(jsonPath("$.page.number", is(1))); getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") @@ -294,7 +303,7 @@ public void findAllPaginationTest() throws Exception { .param("page", "2")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("accessConditionNotDiscoverable"))) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0]", matchSubmissionConfig(definitions.get(2)))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=0"), Matchers.containsString("size=1")))) @@ -311,8 +320,8 @@ public void findAllPaginationTest() throws Exception { Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=6"), Matchers.containsString("size=1")))) .andExpect(jsonPath("$.page.size", is(1))) - .andExpect(jsonPath("$.page.totalElements", is(7))) - .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(totalCount))) + .andExpect(jsonPath("$.page.totalPages", is(totalCount))) .andExpect(jsonPath("$.page.number", is(2))); getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") @@ -320,7 +329,7 @@ public void findAllPaginationTest() throws Exception { .param("page", "3")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("languagetestprocess"))) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0]", matchSubmissionConfig(definitions.get(3)))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=0"), Matchers.containsString("size=1")))) @@ -337,8 +346,8 @@ public void findAllPaginationTest() throws Exception { Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=6"), Matchers.containsString("size=1")))) .andExpect(jsonPath("$.page.size", is(1))) - .andExpect(jsonPath("$.page.totalElements", is(7))) - .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(totalCount))) + .andExpect(jsonPath("$.page.totalPages", is(totalCount))) .andExpect(jsonPath("$.page.number", is(3))); getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") @@ -346,7 +355,7 @@ public void findAllPaginationTest() throws Exception { .param("page", "4")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("qualdroptest"))) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0]", matchSubmissionConfig(definitions.get(4)))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=0"), Matchers.containsString("size=1")))) @@ -363,8 +372,8 @@ public void findAllPaginationTest() throws Exception { Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=6"), Matchers.containsString("size=1")))) .andExpect(jsonPath("$.page.size", is(1))) - .andExpect(jsonPath("$.page.totalElements", is(7))) - .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(totalCount))) + .andExpect(jsonPath("$.page.totalPages", is(totalCount))) .andExpect(jsonPath("$.page.number", is(4))); getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions") @@ -372,7 +381,7 @@ public void findAllPaginationTest() throws Exception { .param("page", "5")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("extractiontestprocess"))) + .andExpect(jsonPath("$._embedded.submissiondefinitions[0]", matchSubmissionConfig(definitions.get(5)))) .andExpect(jsonPath("$._links.first.href", Matchers.allOf( Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=0"), Matchers.containsString("size=1")))) @@ -389,8 +398,8 @@ public void findAllPaginationTest() throws Exception { Matchers.containsString("/api/config/submissiondefinitions?"), Matchers.containsString("page=6"), Matchers.containsString("size=1")))) .andExpect(jsonPath("$.page.size", is(1))) - .andExpect(jsonPath("$.page.totalElements", is(7))) - .andExpect(jsonPath("$.page.totalPages", is(7))) + .andExpect(jsonPath("$.page.totalElements", is(totalCount))) + .andExpect(jsonPath("$.page.totalPages", is(totalCount))) .andExpect(jsonPath("$.page.number", is(5))); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionDefinitionsMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionDefinitionsMatcher.java index 398097db6fba..86f1c7830a0a 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionDefinitionsMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubmissionDefinitionsMatcher.java @@ -13,6 +13,7 @@ import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; +import org.dspace.app.util.SubmissionConfig; import org.hamcrest.Matcher; /** @@ -25,7 +26,7 @@ private SubmissionDefinitionsMatcher() { } public static Matcher matchSubmissionDefinition(boolean isDefault, String name, String id) { return allOf( matchProperties(isDefault, name, id), - matchLinks() + matchLinks(id) ); } @@ -42,8 +43,8 @@ public static Matcher matchFullEmbeds() { /** * Gets a matcher for all expected links. */ - public static Matcher matchLinks() { - return HalMatcher.matchLinks(REST_SERVER_URL + "config/submissiondefinitions/traditional", + public static Matcher matchLinks(String id) { + return HalMatcher.matchLinks(REST_SERVER_URL + "config/submissiondefinitions/" + id, "collections", "sections", "self" @@ -61,4 +62,12 @@ public static Matcher matchProperties(boolean isDefault, String is(REST_SERVER_URL + "config/submissiondefinitions/" + id + "/sections")) ); } + + public static Matcher matchSubmissionConfig(SubmissionConfig config) { + return matchSubmissionDefinition( + config.isDefaultConf(), + config.getSubmissionName(), + config.getSubmissionName() + ); + } } From 6baf93dc07add4ceafd34ba0e5ad08e4d89ce17d Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 31 Jul 2024 14:26:02 -0400 Subject: [PATCH 023/114] Make POI record buffer size adjustable. 'bin/dspace filter-media' was giving us RecordFormatException on OOXML files with enormous records. --- .../dspace/app/mediafilter/TikaTextExtractionFilter.java | 9 ++++++--- dspace/config/dspace.cfg | 7 +++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java index e83bf706ed02..a51e45c68f7b 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java @@ -18,6 +18,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.poi.util.IOUtils; import org.apache.tika.Tika; import org.apache.tika.exception.TikaException; import org.apache.tika.metadata.Metadata; @@ -72,21 +73,23 @@ public InputStream getDestinationStream(Item currentItem, InputStream source, bo // Not using temporary file. We'll use Tika's default in-memory parsing. // Get maximum characters to extract. Default is 100,000 chars, which is also Tika's default setting. String extractedText; - int maxChars = configurationService.getIntProperty("textextractor.max-chars", 100000); + int maxChars = configurationService.getIntProperty("textextractor.max-chars", 100_000); try { // Use Tika to extract text from input. Tika will automatically detect the file type. Tika tika = new Tika(); tika.setMaxStringLength(maxChars); // Tell Tika the maximum number of characters to extract + IOUtils.setByteArrayMaxOverride( + configurationService.getIntProperty("textextractor.max-array", 1_000_000)); extractedText = tika.parseToString(source); } catch (IOException e) { System.err.format("Unable to extract text from bitstream in Item %s%n", currentItem.getID().toString()); - e.printStackTrace(); + e.printStackTrace(System.err); log.error("Unable to extract text from bitstream in Item {}", currentItem.getID().toString(), e); throw e; } catch (OutOfMemoryError oe) { System.err.format("OutOfMemoryError occurred when extracting text from bitstream in Item %s. " + "You may wish to enable 'textextractor.use-temp-file'.%n", currentItem.getID().toString()); - oe.printStackTrace(); + oe.printStackTrace(System.err); log.error("OutOfMemoryError occurred when extracting text from bitstream in Item {}. " + "You may wish to enable 'textextractor.use-temp-file'.", currentItem.getID().toString(), oe); throw oe; diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 55c472c68702..3a5d9890761b 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -519,6 +519,13 @@ filter.org.dspace.app.mediafilter.PDFBoxThumbnail.inputFormats = Adobe PDF # text ("filter-media -f" ) and then reindex your site ("index-discovery -b"). #textextractor.use-temp-file = false +# Maximum size of a record buffer for text extraction. Set this if you are +# seeing RecordFormatException calling out excessive array length from +# 'dspace filter-media'. It is likely that you will need to increase the +# size of the Java heap if you greatly increase this value -- see JAVA_OPTS +# in 'bin/dspace' or 'bin/dspace/bat'. +#textextractor.max-array = 1000000 + # Custom settings for ImageMagick Thumbnail Filters # ImageMagick and GhostScript must be installed on the server, set the path to ImageMagick and GhostScript executable # http://www.imagemagick.org/ From 9d1d4c819d80f1fa1cf5f79c9b5bac8b7d1cf3e9 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Wed, 31 Jul 2024 15:02:15 -0400 Subject: [PATCH 024/114] Get the stock default value right. --- .../org/dspace/app/mediafilter/TikaTextExtractionFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java index a51e45c68f7b..17e7b85e9bfc 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/TikaTextExtractionFilter.java @@ -79,7 +79,7 @@ public InputStream getDestinationStream(Item currentItem, InputStream source, bo Tika tika = new Tika(); tika.setMaxStringLength(maxChars); // Tell Tika the maximum number of characters to extract IOUtils.setByteArrayMaxOverride( - configurationService.getIntProperty("textextractor.max-array", 1_000_000)); + configurationService.getIntProperty("textextractor.max-array", 100_000_000)); extractedText = tika.parseToString(source); } catch (IOException e) { System.err.format("Unable to extract text from bitstream in Item %s%n", currentItem.getID().toString()); From 2bcea0f860db9a3dc915119a5e111d057d2b2936 Mon Sep 17 00:00:00 2001 From: autavares-dev Date: Wed, 7 Aug 2024 16:34:38 -0300 Subject: [PATCH 025/114] Changes Group2GroupCache computation --- .../org/dspace/eperson/Group2GroupCache.java | 3 +- .../org/dspace/eperson/GroupServiceImpl.java | 72 +++++++++--------- .../eperson/dao/Group2GroupCacheDAO.java | 74 +++++++++++++++++-- .../dao/impl/Group2GroupCacheDAOImpl.java | 34 +++++++++ 4 files changed, 143 insertions(+), 40 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/Group2GroupCache.java b/dspace-api/src/main/java/org/dspace/eperson/Group2GroupCache.java index a1c12371f5ff..0c6ea58b1977 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/Group2GroupCache.java +++ b/dspace-api/src/main/java/org/dspace/eperson/Group2GroupCache.java @@ -15,6 +15,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import org.dspace.core.HibernateProxyHelper; /** @@ -23,7 +24,7 @@ * @author kevinvandevelde at atmire.com */ @Entity -@Table(name = "group2groupcache") +@Table(name = "group2groupcache", uniqueConstraints = { @UniqueConstraint(columnNames = {"parent_id", "child_id"}) }) public class Group2GroupCache implements Serializable { @Id diff --git a/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java index 3fb20e2f1e6f..b52f17a5c692 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java @@ -20,6 +20,7 @@ import java.util.UUID; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.SetUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; @@ -673,15 +674,14 @@ protected boolean isEPersonInGroup(Context context, Group group, EPerson ePerson /** - * Regenerate the group cache AKA the group2groupcache table in the database - - * meant to be called when a group is added or removed from another group + * Returns a set with pairs of parent and child group UUIDs, representing the new cache table rows. * - * @param context The relevant DSpace Context. - * @param flushQueries flushQueries Flush all pending queries + * @param context The relevant DSpace Context. + * @param flushQueries flushQueries Flush all pending queries + * @return Pairs of parent and child group UUID of the new cache. * @throws SQLException An exception that provides information on a database access error or other errors. */ - protected void rethinkGroupCache(Context context, boolean flushQueries) throws SQLException { - + private Set> computeNewCache(Context context, boolean flushQueries) throws SQLException { Map> parents = new HashMap<>(); List> group2groupResults = groupDAO.getGroup2GroupResults(context, flushQueries); @@ -689,19 +689,8 @@ protected void rethinkGroupCache(Context context, boolean flushQueries) throws S UUID parent = group2groupResult.getLeft(); UUID child = group2groupResult.getRight(); - // if parent doesn't have an entry, create one - if (!parents.containsKey(parent)) { - Set children = new HashSet<>(); - - // add child id to the list - children.add(child); - parents.put(parent, children); - } else { - // parent has an entry, now add the child to the parent's record - // of children - Set children = parents.get(parent); - children.add(child); - } + parents.putIfAbsent(parent, new HashSet<>()); + parents.get(parent).add(child); } // now parents is a hash of all of the IDs of groups that are parents @@ -714,27 +703,42 @@ protected void rethinkGroupCache(Context context, boolean flushQueries) throws S parent.getValue().addAll(myChildren); } - // empty out group2groupcache table - group2GroupCacheDAO.deleteAll(context); - - // write out new one + // write out new cache IN MEMORY ONLY and returns it + Set> newCache = new HashSet<>(); for (Map.Entry> parent : parents.entrySet()) { UUID key = parent.getKey(); - for (UUID child : parent.getValue()) { + newCache.add(Pair.of(key, child)); + } + } + return newCache; + } - Group parentGroup = find(context, key); - Group childGroup = find(context, child); + /** + * Regenerate the group cache AKA the group2groupcache table in the database - + * meant to be called when a group is added or removed from another group + * + * @param context The relevant DSpace Context. + * @param flushQueries flushQueries Flush all pending queries + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + protected void rethinkGroupCache(Context context, boolean flushQueries) throws SQLException { + // current cache in the database + var oldCache = group2GroupCacheDAO.getCache(context); - if (parentGroup != null && childGroup != null && group2GroupCacheDAO - .find(context, parentGroup, childGroup) == null) { - Group2GroupCache group2GroupCache = group2GroupCacheDAO.create(context, new Group2GroupCache()); - group2GroupCache.setParent(parentGroup); - group2GroupCache.setChild(childGroup); - group2GroupCacheDAO.save(context, group2GroupCache); - } - } + // correct cache, computed from the Group table + var newCache = computeNewCache(context, flushQueries); + + var toDelete = SetUtils.difference(oldCache, newCache); + var toCreate = SetUtils.difference(newCache, oldCache); + + for (var pair : toDelete ) { + group2GroupCacheDAO.deleteFromCache(context, pair.getLeft(), pair.getRight()); + } + + for (var pair : toCreate ) { + group2GroupCacheDAO.addToCache(context, pair.getLeft(), pair.getRight()); } } diff --git a/dspace-api/src/main/java/org/dspace/eperson/dao/Group2GroupCacheDAO.java b/dspace-api/src/main/java/org/dspace/eperson/dao/Group2GroupCacheDAO.java index 7db569a59e2b..d41d52c7e618 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/dao/Group2GroupCacheDAO.java +++ b/dspace-api/src/main/java/org/dspace/eperson/dao/Group2GroupCacheDAO.java @@ -9,7 +9,10 @@ import java.sql.SQLException; import java.util.List; +import java.util.Set; +import java.util.UUID; +import org.apache.commons.lang3.tuple.Pair; import org.dspace.core.Context; import org.dspace.core.GenericDAO; import org.dspace.eperson.Group; @@ -25,13 +28,74 @@ */ public interface Group2GroupCacheDAO extends GenericDAO { - public List findByParent(Context context, Group group) throws SQLException; + /** + * Returns the current cache table as a set of UUID pairs. + * @param context The relevant DSpace Context. + * @return Set of UUID pairs, where the first element is the parent UUID and the second one is the child UUID. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + Set> getCache(Context context) throws SQLException; - public List findByChildren(Context context, Iterable groups) throws SQLException; + /** + * Returns all cache entities that are children of a given parent Group entity. + * @param context The relevant DSpace Context. + * @param group Parent group to perform the search. + * @return List of cached groups that are children of the parent group. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + List findByParent(Context context, Group group) throws SQLException; - public Group2GroupCache findByParentAndChild(Context context, Group parent, Group child) throws SQLException; + /** + * Returns all cache entities that are parents of at least one group from a children groups list. + * @param context The relevant DSpace Context. + * @param groups Children groups to perform the search. + * @return List of cached groups that are parents of at least one group from the children groups list. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + List findByChildren(Context context, Iterable groups) throws SQLException; - public Group2GroupCache find(Context context, Group parent, Group child) throws SQLException; + /** + * Returns the cache entity given specific parent and child groups. + * @param context The relevant DSpace Context. + * @param parent Parent group. + * @param child Child gruoup. + * @return Cached group. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + Group2GroupCache findByParentAndChild(Context context, Group parent, Group child) throws SQLException; - public void deleteAll(Context context) throws SQLException; + /** + * Returns the cache entity given specific parent and child groups. + * @param context The relevant DSpace Context. + * @param parent Parent group. + * @param child Child gruoup. + * @return Cached group. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + Group2GroupCache find(Context context, Group parent, Group child) throws SQLException; + + /** + * Completely deletes the current cache table. + * @param context The relevant DSpace Context. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + void deleteAll(Context context) throws SQLException; + + /** + * Deletes a specific cache row given parent and child groups UUIDs. + * @param context The relevant DSpace Context. + * @param parent Parent group UUID. + * @param child Child group UUID. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + void deleteFromCache(Context context, UUID parent, UUID child) throws SQLException; + + /** + * Adds a single row to the cache table given parent and child groups UUIDs. + * @param context The relevant DSpace Context. + * @param parent Parent group UUID. + * @param child Child group UUID. + * @throws SQLException An exception that provides information on a database access error or other errors. + */ + void addToCache(Context context, UUID parent, UUID child) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/eperson/dao/impl/Group2GroupCacheDAOImpl.java b/dspace-api/src/main/java/org/dspace/eperson/dao/impl/Group2GroupCacheDAOImpl.java index 1cd359188ca3..adbd776ffab6 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/dao/impl/Group2GroupCacheDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/dao/impl/Group2GroupCacheDAOImpl.java @@ -8,14 +8,18 @@ package org.dspace.eperson.dao.impl; import java.sql.SQLException; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; +import java.util.UUID; import jakarta.persistence.Query; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import org.apache.commons.lang3.tuple.Pair; import org.dspace.core.AbstractHibernateDAO; import org.dspace.core.Context; import org.dspace.eperson.Group; @@ -35,6 +39,16 @@ protected Group2GroupCacheDAOImpl() { super(); } + @Override + public Set> getCache(Context context) throws SQLException { + Query query = createQuery( + context, + "SELECT new org.apache.commons.lang3.tuple.ImmutablePair(g.parent.id, g.child.id) FROM Group2GroupCache g" + ); + List> results = query.getResultList(); + return new HashSet>(results); + } + @Override public List findByParent(Context context, Group group) throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); @@ -90,4 +104,24 @@ public Group2GroupCache find(Context context, Group parent, Group child) throws public void deleteAll(Context context) throws SQLException { createQuery(context, "delete from Group2GroupCache").executeUpdate(); } + + @Override + public void deleteFromCache(Context context, UUID parent, UUID child) throws SQLException { + Query query = getHibernateSession(context).createNativeQuery( + "delete from group2groupcache g WHERE g.parent_id = :parent AND g.child_id = :child" + ); + query.setParameter("parent", parent); + query.setParameter("child", child); + query.executeUpdate(); + } + + @Override + public void addToCache(Context context, UUID parent, UUID child) throws SQLException { + Query query = getHibernateSession(context).createNativeQuery( + "insert into group2groupcache (parent_id, child_id) VALUES (:parent, :child)" + ); + query.setParameter("parent", parent); + query.setParameter("child", child); + query.executeUpdate(); + } } From 743b7049cfeeabfd414c38526bcdbf2e52426739 Mon Sep 17 00:00:00 2001 From: autavares-dev Date: Thu, 8 Aug 2024 15:52:03 -0300 Subject: [PATCH 026/114] Refactor 'var' variables to explicit types --- .../java/org/dspace/eperson/GroupServiceImpl.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java index b52f17a5c692..4cec4c9c0d93 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java @@ -725,19 +725,19 @@ private Set> computeNewCache(Context context, boolean flushQuer */ protected void rethinkGroupCache(Context context, boolean flushQueries) throws SQLException { // current cache in the database - var oldCache = group2GroupCacheDAO.getCache(context); + Set> oldCache = group2GroupCacheDAO.getCache(context); // correct cache, computed from the Group table - var newCache = computeNewCache(context, flushQueries); + Set> newCache = computeNewCache(context, flushQueries); - var toDelete = SetUtils.difference(oldCache, newCache); - var toCreate = SetUtils.difference(newCache, oldCache); + SetUtils.SetView> toDelete = SetUtils.difference(oldCache, newCache); + SetUtils.SetView> toCreate = SetUtils.difference(newCache, oldCache); - for (var pair : toDelete ) { + for (Pair pair : toDelete ) { group2GroupCacheDAO.deleteFromCache(context, pair.getLeft(), pair.getRight()); } - for (var pair : toCreate ) { + for (Pair pair : toCreate ) { group2GroupCacheDAO.addToCache(context, pair.getLeft(), pair.getRight()); } } From b8f4ab0eb3e90b080eaae057fb5ee673d3477dc2 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 17 Sep 2024 08:47:54 -0400 Subject: [PATCH 027/114] More information about failed DOI registrations. --- .../dspace/identifier/doi/DOIOrganiser.java | 3 ++- .../identifier/doi/DataCiteConnector.java | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java index b03af68b42ab..0ee64f94b799 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java @@ -577,7 +577,8 @@ public void update(DOI doiRow) { } } catch (IdentifierException ex) { if (!(ex instanceof DOIIdentifierException)) { - LOG.error("It wasn't possible to register the identifier online. ", ex); + LOG.error("Registering DOI {} for object {}: the registrar returned an error.", + doiRow.getDoi(), dso.getID(), ex); } DOIIdentifierException doiIdentifierException = (DOIIdentifierException) ex; diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java index 23af904f2c71..e56a82942369 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java @@ -461,6 +461,10 @@ public void reserveDOI(Context context, DSpaceObject dso, String doi) log.warn("While reserving the DOI {}, we got a http status code " + "{} and the message \"{}\".", doi, Integer.toString(resp.statusCode), resp.getContent()); + Format format = Format.getCompactFormat(); + format.setEncoding("UTF-8"); + XMLOutputter xout = new XMLOutputter(format); + log.info("We send the following XML:\n{}", xout.outputString(root)); throw new DOIIdentifierException("Unable to parse an answer from " + "DataCite API. Please have a look into DSpace logs.", DOIIdentifierException.BAD_ANSWER); @@ -632,6 +636,14 @@ protected DataCiteResponse sendGetRequest(String doi, String path) return sendHttpRequest(httpget, doi); } + /** + * Send a DataCite metadata document to the registrar. + * + * @param doi identify the object. + * @param metadataRoot describe the object. The root element of the document. + * @return the registrar's response. + * @throws DOIIdentifierException passed through. + */ protected DataCiteResponse sendMetadataPostRequest(String doi, Element metadataRoot) throws DOIIdentifierException { Format format = Format.getCompactFormat(); @@ -640,6 +652,14 @@ protected DataCiteResponse sendMetadataPostRequest(String doi, Element metadataR return sendMetadataPostRequest(doi, xout.outputString(new Document(metadataRoot))); } + /** + * Send a DataCite metadata document to the registrar. + * + * @param doi identify the object. + * @param metadata describe the object. + * @return the registrar's response. + * @throws DOIIdentifierException passed through. + */ protected DataCiteResponse sendMetadataPostRequest(String doi, String metadata) throws DOIIdentifierException { // post mds/metadata/ @@ -687,7 +707,7 @@ protected DataCiteResponse sendMetadataPostRequest(String doi, String metadata) * properties such as request URI and method type. * @param doi DOI string to operate on * @return response from DataCite - * @throws DOIIdentifierException if DOI error + * @throws DOIIdentifierException if registrar returns an error. */ protected DataCiteResponse sendHttpRequest(HttpUriRequest req, String doi) throws DOIIdentifierException { From 02f52c7d5c245eaae09dbd636fc8c7935d7cc242 Mon Sep 17 00:00:00 2001 From: Jukka Lipka <3710455+jlipka@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:11:08 +0200 Subject: [PATCH 028/114] fix(submission): Submission scope naming fixed According to the documentation, the value for the property is 'submission' in the 'submission-forms.xml'. Without this change, an empty input field will never be marked as an error, even if the field is marked as 'required'. --- dspace-api/src/main/java/org/dspace/app/util/DCInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/util/DCInput.java b/dspace-api/src/main/java/org/dspace/app/util/DCInput.java index dd88390cb856..846a74cad5d5 100644 --- a/dspace-api/src/main/java/org/dspace/app/util/DCInput.java +++ b/dspace-api/src/main/java/org/dspace/app/util/DCInput.java @@ -163,7 +163,7 @@ public class DCInput { * The scope of the input sets, this restricts hidden metadata fields from * view by the end user during submission. */ - public static final String SUBMISSION_SCOPE = "submit"; + public static final String SUBMISSION_SCOPE = "submission"; /** * Class constructor for creating a DCInput object based on the contents of From dd8b1d91cb74c5afadc1e545b2192b5ebb8848b1 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Wed, 30 Oct 2024 13:37:53 +0100 Subject: [PATCH 029/114] 119960: Fixed NPE when retrieving a DSpace object with the api/dso/find endpoint without the required permissions --- .../app/rest/UUIDLookupRestController.java | 10 ++++- .../app/rest/UUIDLookupRestControllerIT.java | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java index 40c0a79b97be..21631a6737a9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java @@ -24,9 +24,11 @@ import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.DSpaceObjectUtils; import org.dspace.app.rest.utils.Utils; +import org.dspace.authorize.AuthorizeException; +import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.DSpaceObject; +import org.dspace.core.Constants; import org.dspace.core.Context; -import org.dspace.discovery.SearchServiceException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.Link; @@ -65,6 +67,9 @@ public class UUIDLookupRestController implements InitializingBean { @Autowired private DiscoverableEndpointsService discoverableEndpointsService; + @Autowired + private AuthorizeService authorizeService; + @Autowired private ConverterService converter; @@ -85,13 +90,14 @@ public void afterPropertiesSet() throws Exception { public void getDSObyIdentifier(HttpServletRequest request, HttpServletResponse response, @RequestParam(PARAM) UUID uuid) - throws IOException, SQLException, SearchServiceException { + throws IOException, SQLException, AuthorizeException { Context context = null; try { context = ContextUtil.obtainContext(request); DSpaceObject dso = dspaceObjectUtil.findDSpaceObject(context, uuid); if (dso != null) { + authorizeService.authorizeAction(context, dso, Constants.READ); DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection()); URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()).slash(dsor.getId()) .toUri(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/UUIDLookupRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/UUIDLookupRestControllerIT.java index 8a6debce3ec7..3b0821645861 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/UUIDLookupRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/UUIDLookupRestControllerIT.java @@ -17,6 +17,8 @@ import org.apache.commons.codec.CharEncoding; import org.apache.commons.io.IOUtils; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.dspace.authorize.ResourcePolicy; +import org.dspace.authorize.service.ResourcePolicyService; import org.dspace.builder.BitstreamBuilder; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; @@ -31,6 +33,7 @@ import org.dspace.eperson.Group; import org.junit.Ignore; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; /** * Integration test for the UUIDLookup endpoint @@ -39,6 +42,9 @@ */ public class UUIDLookupRestControllerIT extends AbstractControllerIntegrationTest { + @Autowired + ResourcePolicyService resourcePolicyService; + @Test /** * Test the proper redirection of a site's uuid @@ -307,4 +313,35 @@ public void testMissingIdentifierParameter() throws Exception { .andExpect(status().isUnprocessableEntity()); } + @Test + public void testUnauthorized() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context) + .build(); + for (ResourcePolicy rp : resourcePolicyService.find(context, community)) { + resourcePolicyService.delete(context, rp); + } + context.restoreAuthSystemState(); + + getClient().perform(get("/api/dso/find") + .param("uuid", community.getID().toString())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void testForbidden() throws Exception { + context.turnOffAuthorisationSystem(); + Community community = CommunityBuilder.createCommunity(context) + .build(); + for (ResourcePolicy rp : resourcePolicyService.find(context, community)) { + resourcePolicyService.delete(context, rp); + } + context.restoreAuthSystemState(); + + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform(get("/api/dso/find") + .param("uuid", community.getID().toString())) + .andExpect(status().isForbidden()); + } + } From f1d12ef4560bdf7dffea29c5545d8d51d596cd17 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 11 Nov 2024 10:26:29 -0600 Subject: [PATCH 030/114] Add a job to test Docker deployment with the built images --- .github/workflows/docker.yml | 43 +++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a9ff8760e763..12d49689b319 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -147,4 +147,45 @@ jobs: tags_flavor: suffix=-loadsql secrets: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }} \ No newline at end of file + DOCKER_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }} + + ######################################################################## + # Test Deployment via Docker to ensure images are working properly + ######################################################################## + docker-deploy: + # Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace' + if: github.repository == 'dspace/dspace' + runs-on: ubuntu-latest + # Must run after all major images are built + needs: [dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] + steps: + - name: Checkout codebase + uses: actions/checkout@v4 + # Start backend using our compose script in the codebase. + - name: Start backend in Docker + env: + # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 + dspace__P__server__P__url: http://127.0.0.1:8080/server + run: | + docker compose -f docker-compose.yml up -d + sleep 10 + docker container ls + # Create a test admin account. Load test data from a simple set of AIPs as defined in cli.ingest.yml + - name: Load test data into Backend + run: | + docker compose -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en + docker compose -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli + # Verify backend started successfully. + # 1. Make sure root endpoint is responding (check for dspace.name defined in docker-compose.yml) + # 2. Also check /collections endpoint to ensure the test data loaded properly (check for a collection name in AIPs) + - name: Verify backend is responding properly + run: | + result=$(wget -O- -q http://127.0.0.1:8080/server/api) + echo "$result" + echo "$result" | grep -oE "\"DSpace Started with Docker Compose\"," + result=$(wget -O- -q http://127.0.0.1:8080/server/api/core/collections) + echo "$result" + echo "$result" | grep -oE "\"Dog in Yard\"," + - name: Shutdown Docker containers + run: | + docker compose -f docker-compose.yml down From 1cfcb0eee27d54ec604888173221da8525b9b6a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 22:18:52 +0000 Subject: [PATCH 031/114] Bump com.puppycrawl.tools:checkstyle in the build-tools group Bumps the build-tools group with 1 update: [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle). Updates `com.puppycrawl.tools:checkstyle` from 10.19.0 to 10.20.1 - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.19.0...checkstyle-10.20.1) --- updated-dependencies: - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fa401be71b8c..bab2c19e1328 100644 --- a/pom.xml +++ b/pom.xml @@ -295,7 +295,7 @@ com.puppycrawl.tools checkstyle - 10.19.0 + 10.20.1 From ef381aa1516df0d45227cd6c752b32658a69509b Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Tue, 12 Nov 2024 15:59:17 -0500 Subject: [PATCH 032/114] 115778: Adjust redirect check to only follow a limited amount defined in curate.cfg --- .../dspace/ctask/general/BasicLinkChecker.java | 16 ++++++++++++---- dspace/config/modules/curate.cfg | 3 +++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java b/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java index 388036bd6744..a302159ea9a4 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/BasicLinkChecker.java @@ -19,6 +19,8 @@ import org.dspace.content.MetadataValue; import org.dspace.curate.AbstractCurationTask; import org.dspace.curate.Curator; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; /** * A basic link checker that is designed to be extended. By default this link checker @@ -42,6 +44,9 @@ public class BasicLinkChecker extends AbstractCurationTask { // The log4j logger for this class private static Logger log = org.apache.logging.log4j.LogManager.getLogger(BasicLinkChecker.class); + protected static final ConfigurationService configurationService + = DSpaceServicesFactory.getInstance().getConfigurationService(); + /** * Perform the link checking. @@ -110,7 +115,8 @@ protected List getURLs(Item item) { */ protected boolean checkURL(String url, StringBuilder results) { // Link check the URL - int httpStatus = getResponseStatus(url); + int redirects = 0; + int httpStatus = getResponseStatus(url, redirects); if ((httpStatus >= 200) && (httpStatus < 300)) { results.append(" - " + url + " = " + httpStatus + " - OK\n"); @@ -128,18 +134,20 @@ protected boolean checkURL(String url, StringBuilder results) { * @param url The url to open * @return The HTTP response code (e.g. 200 / 301 / 404 / 500) */ - protected int getResponseStatus(String url) { + protected int getResponseStatus(String url, int redirects) { try { URL theURL = new URL(url); HttpURLConnection connection = (HttpURLConnection) theURL.openConnection(); connection.setInstanceFollowRedirects(true); int statusCode = connection.getResponseCode(); + int maxRedirect = configurationService.getIntProperty("curate.checklinks.max-redirect", 0); if ((statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM || statusCode == HttpURLConnection.HTTP_SEE_OTHER)) { connection.disconnect(); String newUrl = connection.getHeaderField("Location"); - if (newUrl != null) { - return getResponseStatus(newUrl); + if (newUrl != null && (maxRedirect >= redirects || maxRedirect == -1)) { + redirects++; + return getResponseStatus(newUrl, redirects); } } diff --git a/dspace/config/modules/curate.cfg b/dspace/config/modules/curate.cfg index 1d7b87960df1..6e75738de543 100644 --- a/dspace/config/modules/curate.cfg +++ b/dspace/config/modules/curate.cfg @@ -26,3 +26,6 @@ curate.taskqueue.dir = ${dspace.dir}/ctqueues # (optional) directory location of scripted (non-java) tasks # curate.script.dir = ${dspace.dir}/ctscripts + +# Maximum amount of redirects set to 0 for none and -1 for unlimited +curate.checklinks.max-redirect = 0 From c96b5316d5b4af9e479c814fd0048dac002cbffa Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 11 Nov 2024 14:10:44 -0600 Subject: [PATCH 033/114] Add a check that the Handle Server can be started & works properly --- .github/workflows/docker.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 12d49689b319..660c9eb817a6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -186,6 +186,25 @@ jobs: result=$(wget -O- -q http://127.0.0.1:8080/server/api/core/collections) echo "$result" echo "$result" | grep -oE "\"Dog in Yard\"," + # Verify Handle Server can be stared and is working properly + # 1. First generate the "[dspace]/handle-server" folder with the sitebndl.zip + # 2. Start the Handle Server (and wait 20 seconds to let it start up) + # 3. Verify logs do NOT include "Exception" in the text (as that means an error occurred) + # 4. Check that Handle Proxy HTML page is responding on default port (8000) + - name: Verify Handle Server is working properly + run: | + docker exec -i dspace /dspace/bin/make-handle-config + docker exec -i dspace /dspace/bin/start-handle-server + sleep 20 + echo "Checking for errors in handle-server.log..." + result=$(docker exec -i dspace cat /dspace/log/handle-server.log) + echo "$result" + echo "$result" | grep -vqz "Exception" + echo "Checking to see if Handle Proxy webpage is available..." + result=$(wget -O- -q http://127.0.0.1:8000/) + echo "$result" + echo "$result" | grep -oE "Handle Proxy" + # Shutdown our containers - name: Shutdown Docker containers run: | docker compose -f docker-compose.yml down From eb766c7cdf1d92898cc8c2a1ba067ba8dac2abad Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 12 Nov 2024 13:50:57 -0600 Subject: [PATCH 034/114] Ensure Docker images built from PRs are stored as artifacts. This allows us to use those new images when testing deployment (in docker-deploy) --- .github/workflows/docker.yml | 34 +++++++++--- .github/workflows/reusable-docker-build.yml | 58 +++++++++++++++++++-- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 660c9eb817a6..eed8de5a8722 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -157,27 +157,47 @@ jobs: if: github.repository == 'dspace/dspace' runs-on: ubuntu-latest # Must run after all major images are built - needs: [dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] + needs: [dspace, dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] steps: + # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase uses: actions/checkout@v4 - # Start backend using our compose script in the codebase. + # For PRs, download Docker image artifacts (built by reusable-docker-build.yml for all PRs) + - name: Download Docker image artifacts (for PRs) + if: github.event_name == 'pull_request' + uses: actions/download-artifact@v4 + with: + # Download all Docker images (TAR files) into the /tmp/docker directory + pattern: docker-image-* + path: /tmp/docker + merge-multiple: true + # For PRs, load each of the images into Docker by calling "docker image load" for each. + # This ensures we are using the images built from this PR & not the prior versions on DockerHub + - name: Load all downloaded Docker images (for PRs) + if: github.event_name == 'pull_request' + run: | + find /tmp/docker -type f -name "*.tar" -exec docker image load --input "{}" \; + docker image ls -a + # Start backend using our compose script in the codebase. - name: Start backend in Docker env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server + # Force using "pr-testing" version of Docker images. The "pr-testing" tag is a temporary tag that we assign to + # all PR-built docker images in reusabe-docker-build.yml + DSPACE_VER: pr-testing run: | docker compose -f docker-compose.yml up -d sleep 10 docker container ls - # Create a test admin account. Load test data from a simple set of AIPs as defined in cli.ingest.yml + # Create a test admin account. Load test data from a simple set of AIPs as defined in cli.ingest.yml - name: Load test data into Backend run: | docker compose -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en docker compose -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli - # Verify backend started successfully. - # 1. Make sure root endpoint is responding (check for dspace.name defined in docker-compose.yml) - # 2. Also check /collections endpoint to ensure the test data loaded properly (check for a collection name in AIPs) + # Verify backend started successfully. + # 1. Make sure root endpoint is responding (check for dspace.name defined in docker-compose.yml) + # 2. Also check /collections endpoint to ensure the test data loaded properly (check for a collection name in AIPs) - name: Verify backend is responding properly run: | result=$(wget -O- -q http://127.0.0.1:8080/server/api) @@ -204,7 +224,7 @@ jobs: result=$(wget -O- -q http://127.0.0.1:8000/) echo "$result" echo "$result" | grep -oE "Handle Proxy" - # Shutdown our containers + # Shutdown our containers - name: Shutdown Docker containers run: | docker compose -f docker-compose.yml down diff --git a/.github/workflows/reusable-docker-build.yml b/.github/workflows/reusable-docker-build.yml index 7a8de661fa68..91aa93c54ab2 100644 --- a/.github/workflows/reusable-docker-build.yml +++ b/.github/workflows/reusable-docker-build.yml @@ -113,6 +113,12 @@ jobs: - name: Set up QEMU emulation to build for multiple architectures uses: docker/setup-qemu-action@v3 + #------------------------------------------------------------ + # Build & deploy steps for new commits to a branch (non-PRs) + # + # These steps build the images, push to DockerHub, and + # (if necessary) redeploy demo/sandbox sites. + #------------------------------------------------------------ # https://github.com/docker/login-action - name: Login to DockerHub # Only login if not a PR, as PRs only trigger a Docker build and not a push @@ -125,6 +131,7 @@ jobs: # https://github.com/docker/metadata-action # Get Metadata for docker_build_deps step below - name: Sync metadata (tags, labels) from GitHub to Docker for image + if: ${{ ! matrix.isPr }} id: meta_build uses: docker/metadata-action@v5 with: @@ -133,7 +140,9 @@ jobs: flavor: ${{ env.TAGS_FLAVOR }} # https://github.com/docker/build-push-action - - name: Build and push image + - name: Build and push image to DockerHub + # Only build & push if not a PR + if: ${{ ! matrix.isPr }} id: docker_build uses: docker/build-push-action@v5 with: @@ -142,9 +151,7 @@ jobs: context: ${{ inputs.dockerfile_context }} file: ${{ inputs.dockerfile_path }} platforms: ${{ matrix.arch }} - # For pull requests, we run the Docker build (to ensure no PR changes break the build), - # but we ONLY do an image push to DockerHub if it's NOT a PR - push: ${{ ! matrix.isPr }} + push: true # Use tags / labels provided by 'docker/metadata-action' above tags: ${{ steps.meta_build.outputs.tags }} labels: ${{ steps.meta_build.outputs.labels }} @@ -189,11 +196,54 @@ jobs: run: | curl -X POST $REDEPLOY_DEMO_URL + #------------------------------------------------------------- + # Build steps for PRs only + # + # These steps build the images and store as a build artifact. + # These artifacts can then be used by later jobs to run the + # brand-new images for automated testing. + #-------------------------------------------------------------- + # Get Metadata for docker_build_deps step below + - name: Create metadata (tags, labels) for local Docker image + if: matrix.isPr + id: meta_build_pr + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_NAME }} + # Hardcode to use custom "pr-testing" tag because that will allow us to spin up this PR + # for testing in docker.yml + tags: pr-testing + flavor: ${{ env.TAGS_FLAVOR }} + # Build local image and stores in a TAR file in /tmp directory + - name: Build and push image to local image + if: matrix.isPr + uses: docker/build-push-action@v5 + with: + build-contexts: | + ${{ inputs.dockerfile_additional_contexts }} + context: ${{ inputs.dockerfile_context }} + file: ${{ inputs.dockerfile_path }} + platforms: ${{ matrix.arch }} + tags: ${{ steps.meta_build_pr.outputs.tags }} + labels: ${{ steps.meta_build_pr.outputs.labels }} + # Export image to a local TAR file + outputs: type=docker,dest=/tmp/${{ inputs.build_id }}.tar + # Upload the local docker image (in TAR file) to a build Artifact + - name: Upload local image to artifact + if: matrix.isPr + uses: actions/upload-artifact@v4 + with: + name: docker-image-${{ inputs.build_id }} + path: /tmp/${{ inputs.build_id }}.tar + if-no-files-found: error + retention-days: 1 + # Merge Docker digests (from various architectures) into a manifest. # This runs after all Docker builds complete above, and it tells hub.docker.com # that these builds should be all included in the manifest for this tag. # (e.g. AMD64 and ARM64 should be listed as options under the same tagged Docker image) docker-build_manifest: + # Only run if this is NOT a PR if: ${{ github.event_name != 'pull_request' }} runs-on: ubuntu-latest needs: From 31312b800a6bed795d5ca31bf2dfb445fc709c4d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 11 Nov 2024 16:45:59 -0600 Subject: [PATCH 035/114] Fix error in running Handle Server in GitHub Actions. Must exclude "spring-jcl" from dependencies as it conflicts with "commons-logging" (used by more of our dependencies) --- dspace-api/pom.xml | 7 +++++++ dspace-iiif/pom.xml | 5 +++++ dspace-oai/pom.xml | 5 +++++ dspace-rdf/pom.xml | 5 +++++ dspace-server-webapp/pom.xml | 5 +++++ dspace-services/pom.xml | 7 +++++++ dspace-sword/pom.xml | 5 +++++ dspace-swordv2/pom.xml | 5 +++++ pom.xml | 7 +++++++ 9 files changed, 51 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index a80f27bc22be..1c883b8ead0b 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -388,6 +388,13 @@ org.springframework spring-orm + + + + org.springframework + spring-jcl + + diff --git a/dspace-iiif/pom.xml b/dspace-iiif/pom.xml index 98683cdc9f76..d0de321b039e 100644 --- a/dspace-iiif/pom.xml +++ b/dspace-iiif/pom.xml @@ -44,6 +44,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index dbfaee3f692a..45205d9ec2ce 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -80,6 +80,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index 45ab69b4834e..3f58d4b28181 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -67,6 +67,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index b437b07869af..8d2bb9ff97a1 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -468,6 +468,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index 52e975b5af18..58673127fe99 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -90,6 +90,13 @@ spring-context-support ${spring.version} compile + + + + org.springframework + spring-jcl + + org.apache.commons diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index 60f7a5327462..82d0fdde98c0 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -55,6 +55,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index 2ed6aa168001..c7aba4b1cc69 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -78,6 +78,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/pom.xml b/pom.xml index 25d1b83609d7..c5953054694a 100644 --- a/pom.xml +++ b/pom.xml @@ -1155,6 +1155,13 @@ org.springframework spring-orm ${spring.version} + + + + org.springframework + spring-jcl + + org.swordapp From a2172b37c3bb57a55e5a82ac2003ef20918c8984 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 09:17:30 -0600 Subject: [PATCH 036/114] Ensure "host" command is installed in images, so "bin/make-handle-config" will work. --- Dockerfile | 5 +++++ Dockerfile.test | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/Dockerfile b/Dockerfile index 75817980379c..fdf2808c1c9a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,6 +58,11 @@ ENV DSPACE_INSTALL=/dspace # Copy the /dspace directory from 'ant_build' container to /dspace in this container COPY --from=ant_build /dspace $DSPACE_INSTALL WORKDIR $DSPACE_INSTALL +# Need host command for "[dspace]/bin/make-handle-config" +RUN apt-get update \ + && apt-get install -y --no-install-recommends host \ + && apt-get purge -y --auto-remove \ + && rm -rf /var/lib/apt/lists/* # Expose Tomcat port EXPOSE 8080 # Give java extra memory (2GB) diff --git a/Dockerfile.test b/Dockerfile.test index f3acef00e825..218126b17aab 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -57,6 +57,11 @@ ENV DSPACE_INSTALL=/dspace # Copy the /dspace directory from 'ant_build' container to /dspace in this container COPY --from=ant_build /dspace $DSPACE_INSTALL WORKDIR $DSPACE_INSTALL +# Need host command for "[dspace]/bin/make-handle-config" +RUN apt-get update \ + && apt-get install -y --no-install-recommends host \ + && apt-get purge -y --auto-remove \ + && rm -rf /var/lib/apt/lists/* # Expose Tomcat port and debugging port EXPOSE 8080 8000 # Give java extra memory (2GB) From daa4abba62d500bb4a9f26dd9f62c156780ee22a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 10:37:53 -0600 Subject: [PATCH 037/114] Bug fixes. Ensure all steps of docker-deploy use the same environment variables. Ensure Handle Server HTTP port is open --- .github/workflows/docker.yml | 13 +++++++------ Dockerfile | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index eed8de5a8722..5197ed3bfe39 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -158,6 +158,12 @@ jobs: runs-on: ubuntu-latest # Must run after all major images are built needs: [dspace, dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] + env: + # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 + dspace__P__server__P__url: http://127.0.0.1:8080/server + # Force using "pr-testing" version of all Docker images. The "pr-testing" tag is a temporary tag that we + # assign to all PR-built docker images in reusabe-docker-build.yml + DSPACE_VER: pr-testing steps: # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase @@ -180,12 +186,6 @@ jobs: docker image ls -a # Start backend using our compose script in the codebase. - name: Start backend in Docker - env: - # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 - dspace__P__server__P__url: http://127.0.0.1:8080/server - # Force using "pr-testing" version of Docker images. The "pr-testing" tag is a temporary tag that we assign to - # all PR-built docker images in reusabe-docker-build.yml - DSPACE_VER: pr-testing run: | docker compose -f docker-compose.yml up -d sleep 10 @@ -214,6 +214,7 @@ jobs: - name: Verify Handle Server is working properly run: | docker exec -i dspace /dspace/bin/make-handle-config + echo "Starting Handle Server..." docker exec -i dspace /dspace/bin/start-handle-server sleep 20 echo "Checking for errors in handle-server.log..." diff --git a/Dockerfile b/Dockerfile index fdf2808c1c9a..d3f85a5bd641 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,8 +63,8 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends host \ && apt-get purge -y --auto-remove \ && rm -rf /var/lib/apt/lists/* -# Expose Tomcat port -EXPOSE 8080 +# Expose Tomcat port (8080) & Handle Server HTTP port (8000) +EXPOSE 8080 8000 # Give java extra memory (2GB) ENV JAVA_OPTS=-Xmx2000m # On startup, run DSpace Runnable JAR From 53d24606431fcd3bd9a7c1a54298190842836e1c Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 11:45:03 -0600 Subject: [PATCH 038/114] Add check for Handle Server error.log --- .github/workflows/docker.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5197ed3bfe39..1e839e89fceb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -217,6 +217,10 @@ jobs: echo "Starting Handle Server..." docker exec -i dspace /dspace/bin/start-handle-server sleep 20 + echo "Checking for errors in error.log" + result=$(docker exec -i dspace sh -c "cat /dspace/handle-server/logs/error.log* || echo ''") + echo "$result" + echo "$result" | grep -vqz "Exception" echo "Checking for errors in handle-server.log..." result=$(docker exec -i dspace cat /dspace/log/handle-server.log) echo "$result" From 6076afec5f9a2bf53ace35abe384dc67dc5c1aef Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 14:27:28 -0600 Subject: [PATCH 039/114] Fix error in Handle Server startup caused by having multiple versions of BouncyCastle in our classpath. Exclude the old version brought in by cnri-servlet-container --- dspace-api/pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 1c883b8ead0b..846c9720200a 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -413,6 +413,16 @@ org.mortbay.jasper apache-jsp + + + org.bouncycastle + bcpkix-jdk15on + + + org.bouncycastle + bcprov-jdk15on + From b6be2818caee0b66b7b4c634b507a3af6e16786c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:15:28 +0000 Subject: [PATCH 040/114] Bump com.google.guava:guava from 32.0.0-jre to 32.1.3-jre Bumps [com.google.guava:guava](https://github.com/google/guava) from 32.0.0-jre to 32.1.3-jre. - [Release notes](https://github.com/google/guava/releases) - [Commits](https://github.com/google/guava/commits) --- updated-dependencies: - dependency-name: com.google.guava:guava dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f41ec26a1328..98f7f0c3929e 100644 --- a/pom.xml +++ b/pom.xml @@ -1815,7 +1815,7 @@ com.google.guava guava - 32.0.0-jre + 32.1.3-jre From 79ae15003dc946992cec8217c01662ed143ed6a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:15:54 +0000 Subject: [PATCH 041/114] Bump org.antlr:antlr4-runtime from 4.13.1 to 4.13.2 Bumps [org.antlr:antlr4-runtime](https://github.com/antlr/antlr4) from 4.13.1 to 4.13.2. - [Release notes](https://github.com/antlr/antlr4/releases) - [Changelog](https://github.com/antlr/antlr4/blob/dev/CHANGES.txt) - [Commits](https://github.com/antlr/antlr4/compare/4.13.1...4.13.2) --- updated-dependencies: - dependency-name: org.antlr:antlr4-runtime dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f41ec26a1328..e52e5ecd5feb 100644 --- a/pom.xml +++ b/pom.xml @@ -1131,7 +1131,7 @@ org.antlr antlr4-runtime - 4.13.1 + 4.13.2 From 2cfedfafadcee9ef91c7516e860acb7e5fd37217 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:16:07 +0000 Subject: [PATCH 042/114] Bump jersey.version from 3.1.5 to 3.1.9 Bumps `jersey.version` from 3.1.5 to 3.1.9. Updates `org.glassfish.jersey.core:jersey-client` from 3.1.5 to 3.1.9 Updates `org.glassfish.jersey.inject:jersey-hk2` from 3.1.5 to 3.1.9 --- updated-dependencies: - dependency-name: org.glassfish.jersey.core:jersey-client dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.glassfish.jersey.inject:jersey-hk2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f41ec26a1328..5a93938c8d06 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ 1.78.1 8.0.1 - 3.1.5 + 3.1.9 2.9.0 From 4148e15ae917072b30387060b9e0d2ebacd18ce9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:16:21 +0000 Subject: [PATCH 043/114] Bump org.apache.ant:ant from 1.10.14 to 1.10.15 Bumps org.apache.ant:ant from 1.10.14 to 1.10.15. --- updated-dependencies: - dependency-name: org.apache.ant:ant dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f41ec26a1328..86577c24caf6 100644 --- a/pom.xml +++ b/pom.xml @@ -1377,7 +1377,7 @@ org.apache.ant ant - 1.10.14 + 1.10.15 org.apache.jena From bcc41a953ec96d3e6b5526c4da9c7ee4c4e90780 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 21:16:58 +0000 Subject: [PATCH 044/114] Bump slf4j.version from 2.0.11 to 2.0.16 Bumps `slf4j.version` from 2.0.11 to 2.0.16. Updates `org.slf4j:jul-to-slf4j` from 2.0.11 to 2.0.16 Updates `org.slf4j:jcl-over-slf4j` from 2.0.11 to 2.0.16 Updates `org.slf4j:slf4j-api` from 2.0.11 to 2.0.16 Updates `org.slf4j:slf4j-jdk14` from 2.0.11 to 2.0.16 Updates `org.slf4j:log4j-over-slf4j` from 2.0.11 to 2.0.16 --- updated-dependencies: - dependency-name: org.slf4j:jul-to-slf4j dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.slf4j:jcl-over-slf4j dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.slf4j:slf4j-jdk14 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.slf4j:log4j-over-slf4j dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f41ec26a1328..6249b5cb0829 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,7 @@ 2.23.1 2.0.31 1.19.0 - 2.0.11 + 2.0.16 2.9.2 1.78.1 From d70a8fccc881cf8f89b95f3036b5180cf4d67f86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Nov 2024 23:03:52 +0000 Subject: [PATCH 045/114] Bump joda-time:joda-time from 2.12.5 to 2.13.0 Bumps [joda-time:joda-time](https://github.com/JodaOrg/joda-time) from 2.12.5 to 2.13.0. - [Release notes](https://github.com/JodaOrg/joda-time/releases) - [Changelog](https://github.com/JodaOrg/joda-time/blob/main/RELEASE-NOTES.txt) - [Commits](https://github.com/JodaOrg/joda-time/compare/v2.12.5...v2.13.0) --- updated-dependencies: - dependency-name: joda-time:joda-time dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f9b53c9ca115..08e532d607e6 100644 --- a/pom.xml +++ b/pom.xml @@ -1546,7 +1546,7 @@ joda-time joda-time - 2.12.5 + 2.13.0 jakarta.activation From a5a7af98d9c954766f59c6909bbc9a02b16b4ca2 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Thu, 14 Nov 2024 10:58:00 -0500 Subject: [PATCH 046/114] Document correct default max-array. --- dspace/config/dspace.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 3a5d9890761b..f28d6d3e497e 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -524,7 +524,7 @@ filter.org.dspace.app.mediafilter.PDFBoxThumbnail.inputFormats = Adobe PDF # 'dspace filter-media'. It is likely that you will need to increase the # size of the Java heap if you greatly increase this value -- see JAVA_OPTS # in 'bin/dspace' or 'bin/dspace/bat'. -#textextractor.max-array = 1000000 +#textextractor.max-array = 100000000 # Custom settings for ImageMagick Thumbnail Filters # ImageMagick and GhostScript must be installed on the server, set the path to ImageMagick and GhostScript executable From 87a1cf80ece83bdedf6e3cad26bca1cdae003d70 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Nov 2024 14:46:31 -0600 Subject: [PATCH 047/114] Remove unnecessary dependencyManagement section from dspace-api. No longer needed for dependency convergence --- dspace-api/pom.xml | 73 ++-------------------------------------------- 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 846c9720200a..1d2a444c6502 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -793,11 +793,13 @@ org.apache.velocity velocity-engine-core + 2.3 org.xmlunit xmlunit-core + 2.10.0 test @@ -873,75 +875,4 @@ - - - - - - - io.netty - netty-buffer - 4.1.114.Final - - - io.netty - netty-transport - 4.1.114.Final - - - io.netty - netty-transport-native-unix-common - 4.1.114.Final - - - io.netty - netty-common - 4.1.114.Final - - - io.netty - netty-handler - 4.1.114.Final - - - io.netty - netty-codec - 4.1.114.Final - - - org.apache.velocity - velocity-engine-core - 2.3 - - - org.xmlunit - xmlunit-core - 2.10.0 - test - - - com.github.java-json-tools - json-schema-validator - 2.2.14 - - - jakarta.validation - jakarta.validation-api - 3.1.0 - - - io.swagger - swagger-core - 1.6.2 - - - org.scala-lang - scala-library - 2.13.11 - test - - - - From 9cc078aa3382adedb9bbd39769b7502e5d47e94a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Nov 2024 14:58:49 -0600 Subject: [PATCH 048/114] Fix multiple declarations of maven-dependency-plugin. Combine two tasks into one declaration --- dspace/modules/server/pom.xml | 36 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index f9b1006e7453..d1b97a15fcfa 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -27,7 +27,7 @@ maven-dependency-plugin - unpack + unpack-additions prepare-package unpack-dependencies @@ -42,6 +42,20 @@ META-INF/** + + unpack-server + prepare-package + + unpack-dependencies + + + runtime + org.dspace + dspace-server-webapp + **/static/**,**/*.properties + ${project.build.directory}/additions + + @@ -68,26 +82,6 @@ - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - prepare-package - - unpack-dependencies - - - runtime - org.dspace - dspace-server-webapp - **/static/**,**/*.properties - ${project.build.directory}/additions - - - - 2.0.16 2.9.2 @@ -1619,11 +1620,6 @@ log4j-jul ${log4j.version} - - org.slf4j - jul-to-slf4j - ${slf4j.version} - org.apache.pdfbox @@ -1685,16 +1681,6 @@ slf4j-api ${slf4j.version} - - org.slf4j - slf4j-jdk14 - ${slf4j.version} - - - org.slf4j - log4j-over-slf4j - ${slf4j.version} - com.google.errorprone From c512ff429ffb505571c134997c40436553f1e8ff Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Nov 2024 15:27:19 -0600 Subject: [PATCH 050/114] Remove deprecated GoogleRecorderEventListener and unused GoogleQueryManager and GoogleAccount --- .../org/dspace/app/statistics/package.html | 2 - .../java/org/dspace/google/GoogleAccount.java | 144 ------------- .../org/dspace/google/GoogleQueryManager.java | 49 ----- .../google/GoogleRecorderEventListener.java | 201 ------------------ .../java/org/dspace/usage/package-info.java | 2 +- 5 files changed, 1 insertion(+), 397 deletions(-) delete mode 100644 dspace-api/src/main/java/org/dspace/google/GoogleAccount.java delete mode 100644 dspace-api/src/main/java/org/dspace/google/GoogleQueryManager.java delete mode 100644 dspace-api/src/main/java/org/dspace/google/GoogleRecorderEventListener.java diff --git a/dspace-api/src/main/java/org/dspace/app/statistics/package.html b/dspace-api/src/main/java/org/dspace/app/statistics/package.html index a6d8d8699cf7..931a7039080d 100644 --- a/dspace-api/src/main/java/org/dspace/app/statistics/package.html +++ b/dspace-api/src/main/java/org/dspace/app/statistics/package.html @@ -46,8 +46,6 @@
writes event records to the Java logger.
{@link org.dspace.statistics.SolrLoggerUsageEventListener SolrLoggerUsageEventListener}
writes event records to Solr.
-
{@link org.dspace.google.GoogleRecorderEventListener GoogleRecorderEventListener}<.dt> -
writes event records to Google Analytics.
diff --git a/dspace-api/src/main/java/org/dspace/google/GoogleAccount.java b/dspace-api/src/main/java/org/dspace/google/GoogleAccount.java deleted file mode 100644 index a24c02a2e1c3..000000000000 --- a/dspace-api/src/main/java/org/dspace/google/GoogleAccount.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ - -package org.dspace.google; - -import java.io.File; -import java.util.HashSet; -import java.util.Set; - -import com.google.api.client.auth.oauth2.Credential; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.api.services.analytics.Analytics; -import com.google.api.services.analytics.AnalyticsScopes; -import org.apache.logging.log4j.Logger; -import org.dspace.services.factory.DSpaceServicesFactory; - -/** - * User: Robin Taylor - * Date: 11/07/2014 - * Time: 13:23 - */ - -public class GoogleAccount { - - // Read from config - private String applicationName; - private String tableId; - private String emailAddress; - private String certificateLocation; - - // Created from factories - private JsonFactory jsonFactory; - private HttpTransport httpTransport; - - // The Google stuff - private Credential credential; - private Analytics client; - - private volatile static GoogleAccount uniqueInstance; - - private static Logger log = org.apache.logging.log4j.LogManager.getLogger(GoogleAccount.class); - - - private GoogleAccount() { - applicationName = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("google-analytics.application.name"); - tableId = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("google-analytics.table.id"); - emailAddress = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("google-analytics.account.email"); - certificateLocation = DSpaceServicesFactory.getInstance().getConfigurationService() - .getProperty("google-analytics.certificate.location"); - - jsonFactory = JacksonFactory.getDefaultInstance(); - - try { - httpTransport = GoogleNetHttpTransport.newTrustedTransport(); - credential = authorize(); - } catch (Exception e) { - throw new RuntimeException("Error initialising Google Analytics client", e); - } - - // Create an Analytics instance - client = new Analytics.Builder(httpTransport, jsonFactory, credential).setApplicationName(applicationName) - .build(); - - log.info("Google Analytics client successfully initialised"); - } - - public static GoogleAccount getInstance() { - if (uniqueInstance == null) { - synchronized (GoogleAccount.class) { - if (uniqueInstance == null) { - uniqueInstance = new GoogleAccount(); - } - } - } - - return uniqueInstance; - } - - private Credential authorize() throws Exception { - Set scopes = new HashSet(); - scopes.add(AnalyticsScopes.ANALYTICS); - scopes.add(AnalyticsScopes.ANALYTICS_EDIT); - scopes.add(AnalyticsScopes.ANALYTICS_MANAGE_USERS); - scopes.add(AnalyticsScopes.ANALYTICS_PROVISION); - scopes.add(AnalyticsScopes.ANALYTICS_READONLY); - - credential = new GoogleCredential.Builder() - .setTransport(httpTransport) - .setJsonFactory(jsonFactory) - .setServiceAccountId(emailAddress) - .setServiceAccountScopes(scopes) - .setServiceAccountPrivateKeyFromP12File(new File(certificateLocation)) - .build(); - - return credential; - } - - - public String getApplicationName() { - return applicationName; - } - - public String getTableId() { - return tableId; - } - - public String getEmailAddress() { - return emailAddress; - } - - public String getCertificateLocation() { - return certificateLocation; - } - - public JsonFactory getJsonFactory() { - return jsonFactory; - } - - public HttpTransport getHttpTransport() { - return httpTransport; - } - - public Credential getCredential() { - return credential; - } - - public Analytics getClient() { - return client; - } - -} - diff --git a/dspace-api/src/main/java/org/dspace/google/GoogleQueryManager.java b/dspace-api/src/main/java/org/dspace/google/GoogleQueryManager.java deleted file mode 100644 index 2719aef04da4..000000000000 --- a/dspace-api/src/main/java/org/dspace/google/GoogleQueryManager.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ - -package org.dspace.google; - -import java.io.IOException; - -import com.google.api.services.analytics.model.GaData; - - -/** - * User: Robin Taylor - * Date: 20/08/2014 - * Time: 09:26 - */ -public class GoogleQueryManager { - - public GaData getPageViews(String startDate, String endDate, String handle) throws IOException { - return GoogleAccount.getInstance().getClient().data().ga().get( - GoogleAccount.getInstance().getTableId(), - startDate, - endDate, - "ga:pageviews") // Metrics. - .setDimensions("ga:year,ga:month") - .setSort("-ga:year,-ga:month") - .setFilters("ga:pagePath=~/handle/" + handle + "$") - .execute(); - } - - public GaData getBitstreamDownloads(String startDate, String endDate, String handle) throws IOException { - return GoogleAccount.getInstance().getClient().data().ga().get( - GoogleAccount.getInstance().getTableId(), - startDate, - endDate, - "ga:totalEvents") // Metrics. - .setDimensions("ga:year,ga:month") - .setSort("-ga:year,-ga:month") - .setFilters( - "ga:eventCategory==bitstream;ga:eventAction==download;ga:pagePath=~" + handle + "/") - .execute(); - } - -} - diff --git a/dspace-api/src/main/java/org/dspace/google/GoogleRecorderEventListener.java b/dspace-api/src/main/java/org/dspace/google/GoogleRecorderEventListener.java deleted file mode 100644 index fb4e9c04de5b..000000000000 --- a/dspace-api/src/main/java/org/dspace/google/GoogleRecorderEventListener.java +++ /dev/null @@ -1,201 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ - -package org.dspace.google; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import jakarta.servlet.http.HttpServletRequest; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.logging.log4j.Logger; -import org.dspace.content.factory.ContentServiceFactory; -import org.dspace.core.Constants; -import org.dspace.service.ClientInfoService; -import org.dspace.services.ConfigurationService; -import org.dspace.services.model.Event; -import org.dspace.usage.AbstractUsageEventListener; -import org.dspace.usage.UsageEvent; -import org.springframework.beans.factory.annotation.Autowired; - - -/** - * User: Robin Taylor - * Date: 14/08/2014 - * Time: 10:05 - * - * Notify Google Analytics of... well anything we want really. - * @deprecated Use org.dspace.google.GoogleAsyncEventListener instead - */ -@Deprecated -public class GoogleRecorderEventListener extends AbstractUsageEventListener { - - private String analyticsKey; - private CloseableHttpClient httpclient; - private String GoogleURL = "https://www.google-analytics.com/collect"; - private static Logger log = org.apache.logging.log4j.LogManager.getLogger(GoogleRecorderEventListener.class); - - protected ContentServiceFactory contentServiceFactory; - protected ConfigurationService configurationService; - protected ClientInfoService clientInfoService; - - public GoogleRecorderEventListener() { - // httpclient is threadsafe so we only need one. - httpclient = HttpClients.createDefault(); - } - - @Autowired - public void setContentServiceFactory(ContentServiceFactory contentServiceFactory) { - this.contentServiceFactory = contentServiceFactory; - } - - @Autowired - public void setConfigurationService(ConfigurationService configurationService) { - this.configurationService = configurationService; - } - - @Autowired - public void setClientInfoService(ClientInfoService clientInfoService) { - this.clientInfoService = clientInfoService; - } - - @Override - public void receiveEvent(Event event) { - if ((event instanceof UsageEvent)) { - log.debug("Usage event received " + event.getName()); - - // This is a wee bit messy but these keys should be combined in future. - analyticsKey = configurationService.getProperty("google.analytics.key"); - - if (StringUtils.isNotBlank(analyticsKey)) { - try { - UsageEvent ue = (UsageEvent) event; - - if (ue.getAction() == UsageEvent.Action.VIEW) { - if (ue.getObject().getType() == Constants.BITSTREAM) { - logEvent(ue, "bitstream", "download"); - - // Note: I've left this commented out code here to show how we could record page views - // as events, - // but since they are already taken care of by the Google Analytics Javascript there is - // not much point. - - //} else if (ue.getObject().getType() == Constants.ITEM) { - // logEvent(ue, "item", "view"); - //} else if (ue.getObject().getType() == Constants.COLLECTION) { - // logEvent(ue, "collection", "view"); - //} else if (ue.getObject().getType() == Constants.COMMUNITY) { - // logEvent(ue, "community", "view"); - } - } - } catch (Exception e) { - log.error(e.getMessage()); - } - } - } - } - - private void logEvent(UsageEvent ue, String category, String action) throws IOException, SQLException { - HttpPost httpPost = new HttpPost(GoogleURL); - - List nvps = new ArrayList(); - nvps.add(new BasicNameValuePair("v", "1")); - nvps.add(new BasicNameValuePair("tid", analyticsKey)); - - // Client Id, should uniquely identify the user or device. If we have a session id for the user - // then lets use it, else generate a UUID. - if (ue.getRequest().getSession(false) != null) { - nvps.add(new BasicNameValuePair("cid", ue.getRequest().getSession().getId())); - } else { - nvps.add(new BasicNameValuePair("cid", UUID.randomUUID().toString())); - } - - nvps.add(new BasicNameValuePair("t", "event")); - nvps.add(new BasicNameValuePair("uip", getIPAddress(ue.getRequest()))); - nvps.add(new BasicNameValuePair("ua", ue.getRequest().getHeader("USER-AGENT"))); - nvps.add(new BasicNameValuePair("dr", ue.getRequest().getHeader("referer"))); - nvps.add(new BasicNameValuePair("dp", ue.getRequest().getRequestURI())); - nvps.add(new BasicNameValuePair("dt", getObjectName(ue))); - nvps.add(new BasicNameValuePair("ec", category)); - nvps.add(new BasicNameValuePair("ea", action)); - - if (ue.getObject().getType() == Constants.BITSTREAM) { - // Bitstream downloads may occasionally be for collection or community images, so we need to label them - // with the parent object type. - nvps.add(new BasicNameValuePair("el", getParentType(ue))); - } - - httpPost.setEntity(new UrlEncodedFormEntity(nvps)); - - try (CloseableHttpResponse response2 = httpclient.execute(httpPost)) { - // I can't find a list of what are acceptable responses, so I log the response but take no action. - log.debug("Google Analytics response is " + response2.getStatusLine()); - } - - log.debug("Posted to Google Analytics - " + ue.getRequest().getRequestURI()); - } - - private String getParentType(UsageEvent ue) { - try { - int parentType = contentServiceFactory.getDSpaceObjectService(ue.getObject()) - .getParentObject(ue.getContext(), ue.getObject()).getType(); - if (parentType == Constants.ITEM) { - return "item"; - } else if (parentType == Constants.COLLECTION) { - return "collection"; - } else if (parentType == Constants.COMMUNITY) { - return "community"; - } - } catch (SQLException e) { - // This shouldn't merit interrupting the user's transaction so log the error and continue. - log.error( - "Error in Google Analytics recording - can't determine ParentObjectType for bitstream " + ue.getObject() - .getID()); - e.printStackTrace(); - } - - return null; - } - - private String getObjectName(UsageEvent ue) { - try { - if (ue.getObject().getType() == Constants.BITSTREAM) { - // For a bitstream download we really want to know the title of the owning item rather than the - // bitstream name. - return contentServiceFactory.getDSpaceObjectService(ue.getObject()) - .getParentObject(ue.getContext(), ue.getObject()).getName(); - } else { - return ue.getObject().getName(); - } - } catch (SQLException e) { - // This shouldn't merit interrupting the user's transaction so log the error and continue. - log.error( - "Error in Google Analytics recording - can't determine ParentObjectName for bitstream " + ue.getObject() - .getID()); - e.printStackTrace(); - } - - return null; - - } - - private String getIPAddress(HttpServletRequest request) { - return clientInfoService.getClientIp(request); - } - -} diff --git a/dspace-api/src/main/java/org/dspace/usage/package-info.java b/dspace-api/src/main/java/org/dspace/usage/package-info.java index 5883bcf358f4..26984ae0caa0 100644 --- a/dspace-api/src/main/java/org/dspace/usage/package-info.java +++ b/dspace-api/src/main/java/org/dspace/usage/package-info.java @@ -25,7 +25,7 @@ * {@code EventService}, as with the stock listeners. *

* - * @see org.dspace.google.GoogleRecorderEventListener + * @see org.dspace.google.GoogleAsyncEventListener * @see org.dspace.statistics.SolrLoggerUsageEventListener */ From 69ce3368c6aa428fa71d83566790d81bbcf8034c Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Nov 2024 15:28:01 -0600 Subject: [PATCH 051/114] Remove unused google dependencies from POMs --- dspace-api/pom.xml | 16 ---------------- pom.xml | 30 ------------------------------ 2 files changed, 46 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 846c9720200a..aa16077bac5e 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -689,22 +689,6 @@ com.google.apis google-api-services-analytics
- - com.google.api-client - google-api-client - - - com.google.http-client - google-http-client - - - com.google.http-client - google-http-client-jackson2 - - - com.google.oauth-client - google-oauth-client - diff --git a/pom.xml b/pom.xml index 0f3c006603e6..e1fc4cc0798c 100644 --- a/pom.xml +++ b/pom.xml @@ -1746,36 +1746,6 @@ google-api-services-analytics v3-rev145-1.23.0 - - com.google.api-client - google-api-client - 1.23.0 - - - com.google.http-client - google-http-client - 1.23.0 - - - com.google.http-client - google-http-client-jackson2 - 1.23.0 - - - jackson-core - com.fasterxml.jackson.core - - - jackson-databind - com.fasterxml.jackson.core - - - - - com.google.oauth-client - google-oauth-client - 1.33.3 - From a73a6ba3f638af1f2ed861c87e04df211f0a1011 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:56:15 +0000 Subject: [PATCH 052/114] Bump the spring group with 12 updates Bumps the spring group with 12 updates: | Package | From | To | | --- | --- | --- | | [org.springframework:spring-orm](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-core](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-beans](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-aop](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-context](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-context-support](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-tx](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-jdbc](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-web](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-webmvc](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-expression](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | | [org.springframework:spring-test](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.0` | Updates `org.springframework:spring-orm` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-core` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-beans` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-aop` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-context` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-context-support` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-tx` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-jdbc` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-web` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-webmvc` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-expression` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-test` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-core` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-beans` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-aop` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-context` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-context-support` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-tx` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-jdbc` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-web` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-webmvc` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-expression` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) Updates `org.springframework:spring-test` from 6.1.14 to 6.2.0 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.0) --- updated-dependencies: - dependency-name: org.springframework:spring-orm dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-beans dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-aop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context-support dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-tx dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-jdbc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-web dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-webmvc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-expression dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-beans dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-aop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context-support dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-tx dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-jdbc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-web dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-webmvc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-expression dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d7646769c18..ee14de0ad9c8 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 17 - 6.1.14 + 6.2.0 3.3.5 6.3.4 6.4.8.Final From b8cb0008833f765787206e18140d5645c393b197 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:56:32 +0000 Subject: [PATCH 053/114] Bump net.minidev:json-smart from 2.5.0 to 2.5.1 Bumps [net.minidev:json-smart](https://github.com/netplex/json-smart-v2) from 2.5.0 to 2.5.1. - [Release notes](https://github.com/netplex/json-smart-v2/releases) - [Commits](https://github.com/netplex/json-smart-v2/compare/2.5.0...2.5.1) --- updated-dependencies: - dependency-name: net.minidev:json-smart dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dspace-server-webapp/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index 8d2bb9ff97a1..b44fa0ab0727 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -299,7 +299,7 @@ @@ -560,7 +560,7 @@ net.minidev json-smart - 2.5.0 + 2.5.1 From 9aa3f5a7ceeb13be622718da9eebf45e3b0b752f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:56:40 +0000 Subject: [PATCH 054/114] Bump dnsjava:dnsjava from 3.6.0 to 3.6.2 Bumps [dnsjava:dnsjava](https://github.com/dnsjava/dnsjava) from 3.6.0 to 3.6.2. - [Release notes](https://github.com/dnsjava/dnsjava/releases) - [Changelog](https://github.com/dnsjava/dnsjava/blob/master/Changelog) - [Commits](https://github.com/dnsjava/dnsjava/compare/v3.6.0...v3.6.2) --- updated-dependencies: - dependency-name: dnsjava:dnsjava dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 1d2a444c6502..0de9a1cd6fda 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -640,7 +640,7 @@ dnsjava dnsjava - 3.6.0 + 3.6.2 From 342c0c83bbdb332acbbffc5661c6ec9d6eca5cab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:56:53 +0000 Subject: [PATCH 055/114] Bump bouncycastle.version from 1.78.1 to 1.79 Bumps `bouncycastle.version` from 1.78.1 to 1.79. Updates `org.bouncycastle:bcpkix-jdk18on` from 1.78.1 to 1.79 - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) Updates `org.bouncycastle:bcprov-jdk18on` from 1.78.1 to 1.79 - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) Updates `org.bouncycastle:bcutil-jdk18on` from 1.78.1 to 1.79 - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcpkix-jdk18on dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.bouncycastle:bcprov-jdk18on dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.bouncycastle:bcutil-jdk18on dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d7646769c18..9dd9cbf4bf2a 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 2.0.16 2.9.2 - 1.78.1 + 1.79 8.0.1 3.1.9 From 66ae4287615945dbf136dd9c2d08748a0ba84a58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:57:00 +0000 Subject: [PATCH 056/114] Bump com.nimbusds:nimbus-jose-jwt from 9.45 to 9.47 Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 9.45 to 9.47. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/9.47..9.45) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d7646769c18..a6b7f7918262 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 2.9.0 - 9.45 + 9.47 From 484262d98042a58d5244afc71794271c83538290 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:57:15 +0000 Subject: [PATCH 057/114] Bump log4j.version from 2.23.1 to 2.24.1 Bumps `log4j.version` from 2.23.1 to 2.24.1. Updates `org.apache.logging.log4j:log4j-api` from 2.23.1 to 2.24.1 Updates `org.apache.logging.log4j:log4j-1.2-api` from 2.23.1 to 2.24.1 Updates `org.apache.logging.log4j:log4j-core` from 2.23.1 to 2.24.1 Updates `org.apache.logging.log4j:log4j-web` from 2.23.1 to 2.24.1 Updates `org.apache.logging.log4j:log4j-slf4j-impl` from 2.23.1 to 2.24.1 Updates `org.apache.logging.log4j:log4j-jul` from 2.23.1 to 2.24.1 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-1.2-api dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-web dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-slf4j-impl dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-jul dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9d7646769c18..ff3e3e29a24a 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 1.1.1 9.4.56.v20240826 - 2.23.1 + 2.24.1 2.0.31 1.19.0 From aa537c44902f458a684bcbb67b5ff702ded61363 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 08:59:19 -0600 Subject: [PATCH 058/114] Ensure we use "pr-testing" images for PRs, but use "latest" images for other builds (e.g. after PR is merged to a branch). --- .github/workflows/docker.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1e839e89fceb..a0aee14bea38 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -161,9 +161,10 @@ jobs: env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server - # Force using "pr-testing" version of all Docker images. The "pr-testing" tag is a temporary tag that we - # assign to all PR-built docker images in reusabe-docker-build.yml - DSPACE_VER: pr-testing + # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, for branch commits, use the + # "latest" tag. NOTE: the "pr-testing" tag is a temporary tag that we assign to all PR-built docker images in + # reusabe-docker-build.yml + DSPACE_VER: ${{ github.event_name == 'pull_request' && 'pr-testing' || 'latest' }} steps: # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase From 6183997addbbdc158bfe6a876c8f752453efeb19 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 11:30:14 -0600 Subject: [PATCH 059/114] Remove parboiled-java and minor cleanup of unused OAI dependencies --- dspace-oai/pom.xml | 23 +------------------ .../xoai/app/CCElementItemCompilePlugin.java | 2 +- .../main/java/org/dspace/xoai/app/XOAI.java | 2 +- .../tests/integration/xoai/PipelineTest.java | 9 ++++---- 4 files changed, 8 insertions(+), 28 deletions(-) diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 45205d9ec2ce..bf5a80c0f5e4 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -99,22 +99,9 @@ org.springframework.boot spring-boot-starter-web - - - org.parboiled - parboiled-java - - - - org.parboiled - parboiled-java - 1.3.1 - - org.dspace @@ -137,15 +124,7 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - - - org.apache.logging.log4j - log4j-slf4j-impl - runtime - + org.apache.logging.log4j log4j-1.2-api diff --git a/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java b/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java index 225d56a4c982..370543029d8b 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java @@ -11,7 +11,7 @@ import com.lyncode.xoai.dataprovider.xml.xoai.Element; import com.lyncode.xoai.dataprovider.xml.xoai.Metadata; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.license.factory.LicenseServiceFactory; diff --git a/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java b/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java index 25cc1ee3655f..ad138ca9f2ad 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java @@ -9,7 +9,7 @@ import static com.lyncode.xoai.dataprovider.core.Granularity.Second; import static java.util.Objects.nonNull; -import static org.apache.commons.lang.StringUtils.EMPTY; +import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_PARAM; import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_START; import static org.dspace.xoai.util.ItemUtils.retrieveMetadata; diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java index 0f48824159c2..0f7ffde0bd00 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java @@ -13,13 +13,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.io.InputStream; +import java.nio.charset.Charset; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource; import com.lyncode.xoai.util.XSLPipeline; +import org.apache.commons.io.IOUtils; import org.dspace.xoai.tests.support.XmlMatcherBuilder; import org.junit.Test; -import org.parboiled.common.FileUtils; public class PipelineTest { private static TransformerFactory factory = TransformerFactory.newInstance(); @@ -28,9 +29,9 @@ public class PipelineTest { public void pipelineTest() throws Exception { InputStream input = PipelineTest.class.getClassLoader().getResourceAsStream("item.xml"); InputStream xslt = PipelineTest.class.getClassLoader().getResourceAsStream("oai_dc.xsl"); - String output = FileUtils.readAllText(new XSLPipeline(input, true) - .apply(factory.newTemplates(new StreamSource(xslt))) - .getTransformed()); + String output = IOUtils.toString(new XSLPipeline(input, true) + .apply(factory.newTemplates(new StreamSource(xslt))) + .getTransformed(), Charset.defaultCharset()); assertThat(output, oai_dc().withXPath("/oai_dc:dc/dc:title", equalTo("Teste"))); From c23f91a3d1a294f481537d06fcc60afbb280a494 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 11:31:28 -0600 Subject: [PATCH 060/114] Fix OAI using incorrect Java Injection API. One incorrect usage found in server-webapp too --- dspace-api/pom.xml | 1 - dspace-oai/pom.xml | 5 ++--- .../app/rest/submit/step/validation/CclicenseValidator.java | 2 +- pom.xml | 6 ++++++ 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 2b4f476d5363..e850ab615885 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -703,7 +703,6 @@ jakarta.inject jakarta.inject-api - 2.0.1 diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index bf5a80c0f5e4..8853d1a308b8 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -65,9 +65,8 @@ - javax.inject - javax.inject - 1 + jakarta.inject + jakarta.inject-api diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/CclicenseValidator.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/CclicenseValidator.java index d0cfd14ec8c5..2273b377fefa 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/CclicenseValidator.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/step/validation/CclicenseValidator.java @@ -12,8 +12,8 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import javax.inject.Inject; +import jakarta.inject.Inject; import org.dspace.app.rest.model.ErrorRest; import org.dspace.app.rest.submit.SubmissionService; import org.dspace.app.util.DCInputsReaderException; diff --git a/pom.xml b/pom.xml index 8ebcdf343a96..70dfc9fcd55c 100644 --- a/pom.xml +++ b/pom.xml @@ -1554,6 +1554,12 @@ jakarta.activation-api 2.1.3 + + + jakarta.inject + jakarta.inject-api + 2.0.1 + jakarta.mail From 76b54b31b7ec6a9835d956888982fe7b68c72f2a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 12:02:20 -0600 Subject: [PATCH 061/114] Log4j cleanup. Remove last traces of log4j v1 (and remove log4j1 bridge to avoid them coming back). Create log4j2 settings for Handle Plugin. --- .../app/bulkedit/MetadataExportSearchIT.java | 5 +- .../dspace/builder/OrcidHistoryBuilder.java | 5 +- dspace-oai/pom.xml | 5 -- .../xoai/filter/ItemsWithBitstreamFilter.java | 4 +- dspace-rdf/pom.xml | 4 -- .../rest/converter/SearchEventConverter.java | 5 +- .../bitstream/BitstreamLinksetProcessor.java | 5 +- .../BitstreamParentItemProcessor.java | 5 +- .../bitstream/BitstreamTypeProcessor.java | 5 +- .../processor/item/ItemAuthorProcessor.java | 5 +- .../item/ItemContentBitstreamsProcessor.java | 5 +- .../item/ItemDescribedbyProcessor.java | 5 +- .../processor/item/ItemLicenseProcessor.java | 5 +- .../processor/item/ItemLinksetProcessor.java | 5 +- .../processor/item/ItemTypeProcessor.java | 5 +- .../service/impl/LinksetServiceImpl.java | 5 +- dspace-sword/pom.xml | 4 -- dspace-swordv2/pom.xml | 4 -- dspace/bin/start-handle-server | 2 +- dspace/bin/start-handle-server.bat | 2 +- dspace/config/log4j-handle-plugin.properties | 34 ------------- dspace/config/log4j2-handle-plugin.xml | 48 +++++++++++++++++++ pom.xml | 20 -------- 23 files changed, 91 insertions(+), 101 deletions(-) delete mode 100644 dspace/config/log4j-handle-plugin.properties create mode 100644 dspace/config/log4j2-handle-plugin.xml diff --git a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java index 3a972692efeb..63a87a48f554 100644 --- a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java +++ b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java @@ -23,7 +23,8 @@ import com.google.common.io.Files; import com.opencsv.CSVReader; import com.opencsv.exceptions.CsvException; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.app.launcher.ScriptLauncher; import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; @@ -51,7 +52,7 @@ public class MetadataExportSearchIT extends AbstractIntegrationTestWithDatabase private Item[] itemsSubject2 = new Item[numberItemsSubject2]; private String filename; private Collection collection; - private Logger logger = Logger.getLogger(MetadataExportSearchIT.class); + private Logger logger = LogManager.getLogger(MetadataExportSearchIT.class); private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); private SearchService searchService; diff --git a/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java b/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java index 199f412f8506..d811d03f5358 100644 --- a/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java @@ -11,7 +11,8 @@ import java.sql.SQLException; import java.util.Date; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.orcid.OrcidHistory; @@ -24,7 +25,7 @@ */ public class OrcidHistoryBuilder extends AbstractBuilder { - private static final Logger log = Logger.getLogger(OrcidHistoryBuilder.class); + private static final Logger log = LogManager.getLogger(OrcidHistoryBuilder.class); private OrcidHistory orcidHistory; diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 8853d1a308b8..ab04734b00c0 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -123,11 +123,6 @@ org.apache.logging.log4j log4j-core - - - org.apache.logging.log4j - log4j-1.2-api - diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java index 3599c5b9e168..9bf1c65dc9d9 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java @@ -9,8 +9,8 @@ import java.sql.SQLException; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.content.Bundle; import org.dspace.content.Item; import org.dspace.handle.factory.HandleServiceFactory; diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index 3f58d4b28181..7f77e3e8a897 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -89,10 +89,6 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - org.apache.commons diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java index e9786962e0f5..d781d255df11 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java @@ -13,7 +13,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.PageRest; import org.dspace.app.rest.model.SearchEventRest; import org.dspace.app.rest.model.SearchResultsRest; @@ -31,7 +32,7 @@ @Component public class SearchEventConverter { /* Log4j logger */ - private static final Logger log = Logger.getLogger(SearchEventConverter.class); + private static final Logger log = LogManager.getLogger(SearchEventConverter.class); @Autowired private ScopeResolver scopeResolver; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java index 97eb9f2a546d..349dde7b6dac 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -25,7 +26,7 @@ */ public class BitstreamLinksetProcessor extends BitstreamSignpostingProcessor { - private static final Logger log = Logger.getLogger(BitstreamLinksetProcessor.class); + private static final Logger log = LogManager.getLogger(BitstreamLinksetProcessor.class); private final BitstreamService bitstreamService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java index 32928dfa8892..c855f06784f7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -28,7 +29,7 @@ */ public class BitstreamParentItemProcessor extends BitstreamSignpostingProcessor { - private static final Logger log = Logger.getLogger(BitstreamParentItemProcessor.class); + private static final Logger log = LogManager.getLogger(BitstreamParentItemProcessor.class); private final BitstreamService bitstreamService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java index 8889a415d327..d0f170b4c55a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java @@ -11,7 +11,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -28,7 +29,7 @@ */ public class BitstreamTypeProcessor extends BitstreamSignpostingProcessor { - private static final Logger log = Logger.getLogger(BitstreamTypeProcessor.class); + private static final Logger log = LogManager.getLogger(BitstreamTypeProcessor.class); @Autowired private SimpleMapConverter mapConverterDSpaceToSchemaOrgUri; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java index f3a9e35198a7..ebc7c46f4d23 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java @@ -16,7 +16,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -37,7 +38,7 @@ public class ItemAuthorProcessor extends ItemSignpostingProcessor { /** * log4j category */ - private static final Logger log = Logger.getLogger(ItemAuthorProcessor.class); + private static final Logger log = LogManager.getLogger(ItemAuthorProcessor.class); private final ItemService itemService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java index 0b91e57f7b3f..65a29c2b6c98 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java @@ -11,7 +11,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -33,7 +34,7 @@ public class ItemContentBitstreamsProcessor extends ItemSignpostingProcessor { /** * log4j category */ - private static final Logger log = Logger.getLogger(ItemContentBitstreamsProcessor.class); + private static final Logger log = LogManager.getLogger(ItemContentBitstreamsProcessor.class); public ItemContentBitstreamsProcessor(FrontendUrlService frontendUrlService) { super(frontendUrlService); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java index 20091e6d0992..a86b98f2e5d0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -23,7 +24,7 @@ */ public class ItemDescribedbyProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemDescribedbyProcessor.class); + private static final Logger log = LogManager.getLogger(ItemDescribedbyProcessor.class); private final ConfigurationService configurationService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java index b60ee35d7fe4..6e26d8f1b225 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java @@ -11,7 +11,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -25,7 +26,7 @@ */ public class ItemLicenseProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemLicenseProcessor.class); + private static final Logger log = LogManager.getLogger(ItemLicenseProcessor.class); private final CreativeCommonsService creativeCommonsService = LicenseServiceFactory.getInstance().getCreativeCommonsService(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java index 2d09e5616171..4e48caf9594f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -23,7 +24,7 @@ */ public class ItemLinksetProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemLinksetProcessor.class); + private static final Logger log = LogManager.getLogger(ItemLinksetProcessor.class); private final ConfigurationService configurationService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java index 49b3612cd92c..f2533a5a9564 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java @@ -11,7 +11,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -27,7 +28,7 @@ */ public class ItemTypeProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemTypeProcessor.class); + private static final Logger log = LogManager.getLogger(ItemTypeProcessor.class); private static final String ABOUT_PAGE_URI = "https://schema.org/AboutPage"; @Autowired diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java index 5b28817c9438..42b1c8184957 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java @@ -13,7 +13,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.security.BitstreamMetadataReadPermissionEvaluatorPlugin; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.processor.bitstream.BitstreamSignpostingProcessor; @@ -37,7 +38,7 @@ @Service public class LinksetServiceImpl implements LinksetService { - private static final Logger log = Logger.getLogger(LinksetServiceImpl.class); + private static final Logger log = LogManager.getLogger(LinksetServiceImpl.class); @Autowired protected ItemService itemService; diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index 82d0fdde98c0..509ba213569a 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -91,10 +91,6 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - xom diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index c7aba4b1cc69..1fdbcc498fa0 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -95,10 +95,6 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - diff --git a/dspace/bin/start-handle-server b/dspace/bin/start-handle-server index 6d5c9a4b4406..b2af9cf759b8 100755 --- a/dspace/bin/start-handle-server +++ b/dspace/bin/start-handle-server @@ -36,6 +36,6 @@ rm -f $HANDLEDIR/txns/lock # does not support more than one JVM writing to the same rolling log. nohup java $JAVA_OPTS -classpath `$BINDIR/dspace classpath` \ -Ddspace.log.init.disable=true \ - -Dlog4j.configuration=log4j-handle-plugin.properties \ + -Dlog4j2.configurationFile=log4j2-handle-plugin.xml \ net.handle.server.Main $HANDLEDIR \ > $LOGDIR/handle-server.log 2>&1 & diff --git a/dspace/bin/start-handle-server.bat b/dspace/bin/start-handle-server.bat index caf6ff3eef12..8280e2b442f1 100644 --- a/dspace/bin/start-handle-server.bat +++ b/dspace/bin/start-handle-server.bat @@ -51,7 +51,7 @@ echo. echo NOTE: If you want to run the Handle Server as a backend process, re-execute this script echo using the Windows "start" command. For example, "start /B start-handle-server.bat" echo. -java %JAVA_OPTS% -cp "%DSPACE_CLASSPATH%" -Ddspace.log.init.disable=true -Dlog4j.configuration=log4j-handle-plugin.properties net.handle.server.Main %HANDLEDIR% >> "%LOGDIR%/handle-server.log" +java %JAVA_OPTS% -cp "%DSPACE_CLASSPATH%" -Ddspace.log.init.disable=true -Dlog4j2.configurationFile=log4j2-handle-plugin.xml net.handle.server.Main %HANDLEDIR% >> "%LOGDIR%/handle-server.log" REM Clean up DSPACE_CLASSPATH variable set DSPACE_CLASSPATH= diff --git a/dspace/config/log4j-handle-plugin.properties b/dspace/config/log4j-handle-plugin.properties deleted file mode 100644 index 44d39fb1bdf0..000000000000 --- a/dspace/config/log4j-handle-plugin.properties +++ /dev/null @@ -1,34 +0,0 @@ -########################################################################### -# log4j-handle-plugin.properties -# -# This is the log4j configuration file for the embedded DSpace Handle server, -# writing daily rolling logs. We cannot simply write to the same logs, since -# log4j does not support more than one JVM writing to the same rolling log. -########################################################################### - -# VARIABLES: -# The following variables can be used to easily tweak the default log4j settings. -# These variables are used by the log4j config / appenders later in this file. - -# log.dir -# Default log file directory for DSpace. Defaults to the 'log' subdirectory -# under [dspace.dir]. NOTE: The value of 'dspace.dir' will be replaced by -# its value in your configuration when DSpace is deployed (via Ant). -log.dir=${dspace.dir}/log - -# Set root category priority to INFO and its only appender to A1. -log4j.rootCategory=INFO, A1 - -# A1 is set to be a DailyRollingFileAppender. -log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender -log4j.appender.A1.File=${log.dir}/handle-plugin.log -log4j.appender.A1.DatePattern='.'yyyy-MM-dd - -# A1 uses PatternLayout. -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%d %-5p %c @ %m%n - - -# block passwords from being exposed in Axis logs. -# (DEBUG exposes passwords in Basic Auth) -log4j.logger.org.apache.axis.handlers.http.HTTPAuthHandler=INFO \ No newline at end of file diff --git a/dspace/config/log4j2-handle-plugin.xml b/dspace/config/log4j2-handle-plugin.xml new file mode 100644 index 000000000000..5f72e05c7303 --- /dev/null +++ b/dspace/config/log4j2-handle-plugin.xml @@ -0,0 +1,48 @@ + + + + + + + ${log4j:configParentLocation}/../log + + + + + + + + + yyyy-MM-dd + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 70dfc9fcd55c..916b8f7683eb 100644 --- a/pom.xml +++ b/pom.xml @@ -1601,31 +1601,11 @@ log4j-api ${log4j.version} - - org.apache.logging.log4j - log4j-1.2-api - ${log4j.version} - org.apache.logging.log4j log4j-core ${log4j.version} - - org.apache.logging.log4j - log4j-web - ${log4j.version} - - - org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} - - - org.apache.logging.log4j - log4j-jul - ${log4j.version} - org.apache.pdfbox From d31198b525d240b407d0a44f914cb1ab1ee71398 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 13:41:37 -0600 Subject: [PATCH 062/114] Resolve dependency convergence issue --- dspace-server-webapp/pom.xml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index b44fa0ab0727..b64829f91a41 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -293,14 +293,6 @@ spring-expression ${spring.version} - - - @@ -610,6 +602,13 @@ com.jayway.jsonpath json-path + + + + net.minidev + json-smart + + com.jayway.jsonpath From e0b7241acb167496ebc8c80c73ae69b9f6611a1c Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 16:06:10 -0600 Subject: [PATCH 063/114] Ensure only main branch uses "latest". Other branches should use the tag corresponding to the branch name --- .github/workflows/docker.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a0aee14bea38..143b69a2f9fe 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -161,10 +161,10 @@ jobs: env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server - # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, for branch commits, use the - # "latest" tag. NOTE: the "pr-testing" tag is a temporary tag that we assign to all PR-built docker images in - # reusabe-docker-build.yml - DSPACE_VER: ${{ github.event_name == 'pull_request' && 'pr-testing' || 'latest' }} + # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, if on main branch, use the + # "latest" tag. Otherwise, use the branch name. NOTE: the "pr-testing" tag is a temporary tag that we assign to + # all PR-built docker images in reusabe-docker-build.yml + DSPACE_VER: ${{ (github.event_name == 'pull_request' && 'pr-testing') || (github.ref_name == github.event.repository.default_branch && 'latest') || github.ref_name }} steps: # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase From ec73c37554e21de50d8775bacd06d93aace751bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:24:02 +0000 Subject: [PATCH 064/114] Bump org.springframework.security:spring-security-test Bumps the spring group with 1 update: [org.springframework.security:spring-security-test](https://github.com/spring-projects/spring-security). Updates `org.springframework.security:spring-security-test` from 6.3.4 to 6.4.0 - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/6.3.4...6.4.0) --- updated-dependencies: - dependency-name: org.springframework.security:spring-security-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 702ab76a9f4d..ddac9996a857 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 17 6.2.0 3.3.5 - 6.3.4 + 6.4.0 6.4.8.Final 8.0.1.Final 42.7.4 From 26be63daa65f379a65f5f23791820563f176cb17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:24:20 +0000 Subject: [PATCH 065/114] Bump org.apache.httpcomponents.client5:httpclient5 from 5.3.1 to 5.4.1 Bumps [org.apache.httpcomponents.client5:httpclient5](https://github.com/apache/httpcomponents-client) from 5.3.1 to 5.4.1. - [Changelog](https://github.com/apache/httpcomponents-client/blob/rel/v5.4.1/RELEASE_NOTES.txt) - [Commits](https://github.com/apache/httpcomponents-client/compare/rel/v5.3.1...rel/v5.4.1) --- updated-dependencies: - dependency-name: org.apache.httpcomponents.client5:httpclient5 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dspace-server-webapp/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index b64829f91a41..b115cff73417 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -590,7 +590,7 @@ org.apache.httpcomponents.client5 httpclient5 - 5.3.1 + 5.4.1 test From 81e08b620fea465759df28aa00bcb36070fa548c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:24:40 +0000 Subject: [PATCH 066/114] Bump com.amazonaws:aws-java-sdk-s3 from 1.12.261 to 1.12.778 Bumps [com.amazonaws:aws-java-sdk-s3](https://github.com/aws/aws-sdk-java) from 1.12.261 to 1.12.778. - [Changelog](https://github.com/aws/aws-sdk-java/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-java/compare/1.12.261...1.12.778) --- updated-dependencies: - dependency-name: com.amazonaws:aws-java-sdk-s3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index b1707aecdd0c..44f967516bae 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -733,7 +733,7 @@ com.amazonaws aws-java-sdk-s3 - 1.12.261 + 1.12.778 From fd656095551ed0cb80032db7a43e1786ba8e833d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:25:07 +0000 Subject: [PATCH 068/114] Bump de.digitalcollections.iiif:iiif-apis from 0.3.10 to 0.3.11 Bumps [de.digitalcollections.iiif:iiif-apis](https://github.com/dbmdz/iiif-apis) from 0.3.10 to 0.3.11. - [Release notes](https://github.com/dbmdz/iiif-apis/releases) - [Commits](https://github.com/dbmdz/iiif-apis/compare/0.3.10...0.3.11) --- updated-dependencies: - dependency-name: de.digitalcollections.iiif:iiif-apis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dspace-iiif/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-iiif/pom.xml b/dspace-iiif/pom.xml index d0de321b039e..9c4c174bf39f 100644 --- a/dspace-iiif/pom.xml +++ b/dspace-iiif/pom.xml @@ -111,7 +111,7 @@ de.digitalcollections.iiif iiif-apis - 0.3.10 + 0.3.11 org.javassist From d1fa17881a368c95f5f8cc7d74eaa757c72e700e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:25:18 +0000 Subject: [PATCH 069/114] Bump com.github.spotbugs:spotbugs-maven-plugin from 4.8.6.5 to 4.8.6.6 Bumps [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 4.8.6.5 to 4.8.6.6. - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.8.6.5...spotbugs-maven-plugin-4.8.6.6) --- updated-dependencies: - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 702ab76a9f4d..22e898cd0426 100644 --- a/pom.xml +++ b/pom.xml @@ -303,7 +303,7 @@ com.github.spotbugs spotbugs-maven-plugin - 4.8.6.5 + 4.8.6.6 Max Low From 793c4f910174855a00b3c63773e876b7dcd7b934 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:25:22 +0000 Subject: [PATCH 070/114] Bump org.apache.bcel:bcel from 6.7.0 to 6.10.0 Bumps [org.apache.bcel:bcel](https://github.com/apache/commons-bcel) from 6.7.0 to 6.10.0. - [Changelog](https://github.com/apache/commons-bcel/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-bcel/compare/rel/commons-bcel-6.7.0...rel/commons-bcel-6.10.0) --- updated-dependencies: - dependency-name: org.apache.bcel:bcel dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index b1707aecdd0c..382a4fa7c48a 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -789,7 +789,7 @@ org.apache.bcel bcel - 6.7.0 + 6.10.0 test From e27ceb57c1324b7b15931d1ed48414c0316c1d2d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 20 Nov 2024 12:45:05 -0600 Subject: [PATCH 071/114] Remove unused dependencies from several modules --- dspace-services/pom.xml | 23 ----------------------- dspace-sword/pom.xml | 18 ------------------ dspace/modules/server-boot/pom.xml | 4 ---- dspace/modules/server/pom.xml | 5 ----- pom.xml | 14 +------------- 5 files changed, 1 insertion(+), 63 deletions(-) diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index 58673127fe99..852d6a648c37 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -128,23 +128,6 @@ junit provided - - - org.mortbay.jetty - jetty - 6.1.26 - test - - - org.mortbay.jetty - jetty-servlet-tester - 6.1.26 - test - - - org.apache.commons - commons-collections4 - org.apache.commons commons-configuration2 @@ -164,11 +147,5 @@ jakarta.annotation-api - - org.springframework.boot - spring-boot-starter-log4j2 - ${spring-boot.version} - - diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index 509ba213569a..d7aa12034314 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -25,15 +25,6 @@ - - - - org.dspace dspace-api @@ -63,11 +54,6 @@ - - jaxen - jaxen - - org.apache.httpcomponents httpclient @@ -97,10 +83,6 @@ xom 1.3.9 - - commons-io - commons-io - diff --git a/dspace/modules/server-boot/pom.xml b/dspace/modules/server-boot/pom.xml index 4a8fd8f966ff..c9554109ab32 100644 --- a/dspace/modules/server-boot/pom.xml +++ b/dspace/modules/server-boot/pom.xml @@ -30,10 +30,6 @@ org.dspace dspace-server-webapp - - org.apache.solr - solr-solrj - diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index d1b97a15fcfa..a3a927576b40 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -271,11 +271,6 @@ provided ${spring-boot.version} - - org.apache.solr - solr-solrj - ${solr.client.version} - diff --git a/pom.xml b/pom.xml index ddac9996a857..da9e9e8f67aa 100644 --- a/pom.xml +++ b/pom.xml @@ -1164,11 +1164,7 @@ - - org.swordapp - sword-common - 1.1 - + spring-core @@ -1477,14 +1473,6 @@ commons-collections4 4.4 - - - commons-collections - commons-collections - 3.2.2 - org.apache.commons commons-configuration2 From 1b06816a6dc4454e94ca9533c781638ed68dff0d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 21 Nov 2024 16:21:22 -0600 Subject: [PATCH 072/114] Ensure log4j-slf4j2-impl bridge exists to forward slf4J logs to log4j. Move that and log4j-core to dspace-api so it is inherited everywhere else. --- dspace-api/pom.xml | 8 ++++++++ dspace-oai/pom.xml | 4 ---- dspace-rdf/pom.xml | 4 ---- dspace-sword/pom.xml | 4 ---- dspace-swordv2/pom.xml | 4 ---- pom.xml | 6 ++++++ 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index ec9146bdba82..43bbc0f758b5 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -341,6 +341,14 @@ org.apache.logging.log4j log4j-api + + org.apache.logging.log4j + log4j-core + + + org.apache.logging.log4j + log4j-slf4j2-impl + org.hibernate.orm hibernate-core diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index ab04734b00c0..9ba9ff3e2f71 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -119,10 +119,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index 7f77e3e8a897..7f214dc088d4 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -85,10 +85,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - org.apache.commons diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index d7aa12034314..940227a9354b 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -73,10 +73,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - xom diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index 1fdbcc498fa0..ac361b33c684 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -91,10 +91,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - diff --git a/pom.xml b/pom.xml index 5bd08d2061cf..e2638a90982f 100644 --- a/pom.xml +++ b/pom.xml @@ -1594,6 +1594,12 @@ log4j-core ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j2-impl + ${log4j.version} + org.apache.pdfbox From 98768d6f4fcc5181501d02d77ef5056641ac8cd3 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 22 Nov 2024 11:04:11 -0600 Subject: [PATCH 073/114] Enable all optional modules/controllers to test their deployment in Spring Boot --- .github/workflows/docker.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 143b69a2f9fe..816dcd228ca5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -161,6 +161,15 @@ jobs: env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server + # Enable all optional modules / controllers for this test deployment. + # This helps check for errors in deploying these modules via Spring Boot + iiif__P__enabled: true + ldn__P__enabled: true + oai__P__enabled: true + rdf__P__enabled: true + signposting__P__enabled: true + sword-server__P__enabled: true + swordv2-server__P__enabled: true # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, if on main branch, use the # "latest" tag. Otherwise, use the branch name. NOTE: the "pr-testing" tag is a temporary tag that we assign to # all PR-built docker images in reusabe-docker-build.yml From fc544a830987782d90d22c747e12a42ccf9926d7 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 22 Nov 2024 13:50:16 -0600 Subject: [PATCH 074/114] Fix syntax error in #10040. Env variables cannot have dashes or periods --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 816dcd228ca5..7e7cbc1b07ca 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -168,8 +168,8 @@ jobs: oai__P__enabled: true rdf__P__enabled: true signposting__P__enabled: true - sword-server__P__enabled: true - swordv2-server__P__enabled: true + sword__D__server__P__enabled: true + swordv2__D__server__P__enabled: true # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, if on main branch, use the # "latest" tag. Otherwise, use the branch name. NOTE: the "pr-testing" tag is a temporary tag that we assign to # all PR-built docker images in reusabe-docker-build.yml From 5bf1f26ebaacfc211d8dac3766ae9e4d7a31d4cd Mon Sep 17 00:00:00 2001 From: "David P. Steelman" Date: Mon, 25 Nov 2024 08:57:37 -0500 Subject: [PATCH 075/114] Adjustments to POM files so that the changes in "modules/server" are incorporated into the JAR generated by "server-boot". This commit adds an "attachClasses" parameter to the "maven-war-plugin" in the "dspace/modules/server/pom.xml", which generates a JAR file that can be referenced in the "dspace/modules/server-boot/pom.xml" (see ) via ``` org.dspace.modules server classes ``` The dependency must be placed *before* the "dspace-server-webapp" dependency, to ensure that it overrides the classes in the "dspace-server-webapp" module. In the "server-boot.jar", the CLASSPATH is determined by the order of JARs in the "BOOT-INF/classpath.idx", which is generated based on the order of dependencies in the POM (see https://stackoverflow.com/a/67997782). The root "pom.xml" file was modified to provide the version for "modules/server" JAR file, in keeping with how the versions of other JAR files are specified. --- dspace/modules/server-boot/pom.xml | 5 +++++ dspace/modules/server/pom.xml | 1 + pom.xml | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/dspace/modules/server-boot/pom.xml b/dspace/modules/server-boot/pom.xml index c9554109ab32..d95e8c5c595b 100644 --- a/dspace/modules/server-boot/pom.xml +++ b/dspace/modules/server-boot/pom.xml @@ -26,6 +26,11 @@ org.dspace.modules additions + + org.dspace.modules + server + classes + org.dspace dspace-server-webapp diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index a3a927576b40..6770a8f952fd 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -63,6 +63,7 @@ maven-war-plugin false + true true 9.4.56.v20240826 - 2.24.1 + 2.24.2 2.0.31 1.19.0 From cc7088b2277746f9a75d671ffdc155b8e3e8bbd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 22:52:04 +0000 Subject: [PATCH 077/114] Bump com.amazonaws:aws-java-sdk-s3 from 1.12.778 to 1.12.779 Bumps [com.amazonaws:aws-java-sdk-s3](https://github.com/aws/aws-sdk-java) from 1.12.778 to 1.12.779. - [Changelog](https://github.com/aws/aws-sdk-java/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-java/compare/1.12.778...1.12.779) --- updated-dependencies: - dependency-name: com.amazonaws:aws-java-sdk-s3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 43bbc0f758b5..9b48128fcb89 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -741,7 +741,7 @@ com.amazonaws aws-java-sdk-s3 - 1.12.778 + 1.12.779 9.4.56.v20240826 2.24.2 - 2.0.31 + 2.0.32 1.19.0 2.0.16 From 202c749e90009b791edeae107c4a1ec8f7e47d99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:34:41 +0000 Subject: [PATCH 082/114] Bump the apache-commons group across 1 directory with 2 updates Bumps the apache-commons group with 2 updates in the / directory: org.apache.commons:commons-dbcp2 and commons-io:commons-io. Updates `org.apache.commons:commons-dbcp2` from 2.12.0 to 2.13.0 Updates `commons-io:commons-io` from 2.17.0 to 2.18.0 --- updated-dependencies: - dependency-name: org.apache.commons:commons-dbcp2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons ... Signed-off-by: dependabot[bot] --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ba5c3e4771a9..b60032840499 100644 --- a/pom.xml +++ b/pom.xml @@ -1487,7 +1487,7 @@ org.apache.commons commons-dbcp2 - 2.12.0 + 2.13.0 @@ -1499,7 +1499,7 @@ commons-io commons-io - 2.17.0 + 2.18.0 org.apache.commons From 4debff7beed509c4773de559b37d286eeeec14c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:34:51 +0000 Subject: [PATCH 083/114] Bump the fasterxml group with 4 updates Bumps the fasterxml group with 4 updates: [com.fasterxml.jackson.core:jackson-annotations](https://github.com/FasterXML/jackson), [com.fasterxml.jackson.core:jackson-core](https://github.com/FasterXML/jackson-core), [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) and com.fasterxml.jackson.datatype:jackson-datatype-jsr310. Updates `com.fasterxml.jackson.core:jackson-annotations` from 2.18.1 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.core:jackson-core` from 2.18.1 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.18.1...jackson-core-2.18.2) Updates `com.fasterxml.jackson.core:jackson-core` from 2.18.1 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.18.1...jackson-core-2.18.2) Updates `com.fasterxml.jackson.core:jackson-databind` from 2.18.1 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.18.1 to 2.18.2 Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.18.1 to 2.18.2 --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-annotations dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: fasterxml ... Signed-off-by: dependabot[bot] --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ba5c3e4771a9..77bc2c0b5651 100644 --- a/pom.xml +++ b/pom.xml @@ -31,8 +31,8 @@ 3.10.8 2.35.1 - 2.18.1 - 2.18.1 + 2.18.2 + 2.18.2 2.1.1 4.0.2 4.0.5 From 05c6febdb1cb6801f4e24594e36c19a2fe1f1b0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:35:19 +0000 Subject: [PATCH 084/114] Bump the build-tools group across 1 directory with 4 updates Bumps the build-tools group with 4 updates in the / directory: [com.google.errorprone:error_prone_core](https://github.com/google/error-prone), [com.google.errorprone:error_prone_annotations](https://github.com/google/error-prone), [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) and [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin). Updates `com.google.errorprone:error_prone_core` from 2.35.1 to 2.36.0 - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.35.1...v2.36.0) Updates `com.google.errorprone:error_prone_annotations` from 2.35.1 to 2.36.0 - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.35.1...v2.36.0) Updates `com.puppycrawl.tools:checkstyle` from 10.20.1 to 10.20.2 - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-10.20.1...checkstyle-10.20.2) Updates `com.google.errorprone:error_prone_annotations` from 2.35.1 to 2.36.0 - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.35.1...v2.36.0) Updates `org.codehaus.mojo:license-maven-plugin` from 2.4.0 to 2.5.0 - [Release notes](https://github.com/mojohaus/license-maven-plugin/releases) - [Commits](https://github.com/mojohaus/license-maven-plugin/compare/2.4.0...2.5.0) --- updated-dependencies: - dependency-name: com.google.errorprone:error_prone_core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: com.google.errorprone:error_prone_annotations dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: com.google.errorprone:error_prone_annotations dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.codehaus.mojo:license-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools ... Signed-off-by: dependabot[bot] --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ba5c3e4771a9..b60a32325779 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 8.11.4 3.10.8 - 2.35.1 + 2.36.0 2.18.1 2.18.1 @@ -296,7 +296,7 @@ com.puppycrawl.tools checkstyle - 10.20.1 + 10.20.2 @@ -693,7 +693,7 @@ org.codehaus.mojo license-maven-plugin - 2.4.0 + 2.5.0 false From d728079fbe92e69876aa5bf2aa0e9aefae960496 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 23:35:20 +0000 Subject: [PATCH 085/114] Bump org.checkerframework:checker-qual from 3.48.2 to 3.48.3 Bumps [org.checkerframework:checker-qual](https://github.com/typetools/checker-framework) from 3.48.2 to 3.48.3. - [Release notes](https://github.com/typetools/checker-framework/releases) - [Changelog](https://github.com/typetools/checker-framework/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/typetools/checker-framework/compare/checker-framework-3.48.2...checker-framework-3.48.3) --- updated-dependencies: - dependency-name: org.checkerframework:checker-qual dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ba5c3e4771a9..7f02dfa3e3c6 100644 --- a/pom.xml +++ b/pom.xml @@ -1344,7 +1344,7 @@ org.checkerframework checker-qual - 3.48.2 + 3.48.3 From 5e0b22c115293be1d4584fd41e0576c558f4aca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 23:03:31 +0000 Subject: [PATCH 102/114] Bump org.apache.velocity:velocity-engine-core from 2.3 to 2.4.1 Bumps org.apache.velocity:velocity-engine-core from 2.3 to 2.4.1. --- updated-dependencies: - dependency-name: org.apache.velocity:velocity-engine-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 9b48128fcb89..599303275f9f 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -784,7 +784,7 @@ org.apache.velocity velocity-engine-core - 2.3 + 2.4.1 From b7f2f1004a9130db1163503d120e84a63d145adc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 23:03:35 +0000 Subject: [PATCH 103/114] Bump com.google.code.gson:gson from 2.10.1 to 2.11.0 Bumps [com.google.code.gson:gson](https://github.com/google/gson) from 2.10.1 to 2.11.0. - [Release notes](https://github.com/google/gson/releases) - [Changelog](https://github.com/google/gson/blob/main/CHANGELOG.md) - [Commits](https://github.com/google/gson/compare/gson-parent-2.10.1...gson-parent-2.11.0) --- updated-dependencies: - dependency-name: com.google.code.gson:gson dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d2c75fc60032..e24f11631db2 100644 --- a/pom.xml +++ b/pom.xml @@ -1353,7 +1353,7 @@ com.google.code.gson gson - 2.10.1 + 2.11.0 false From ede9f54d36d57f802f0cbb915f4c2c59ac791682 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 22:02:04 +0000 Subject: [PATCH 111/114] Bump log4j.version from 2.24.2 to 2.24.3 Bumps `log4j.version` from 2.24.2 to 2.24.3. Updates `org.apache.logging.log4j:log4j-api` from 2.24.2 to 2.24.3 Updates `org.apache.logging.log4j:log4j-core` from 2.24.2 to 2.24.3 Updates `org.apache.logging.log4j:log4j-slf4j2-impl` from 2.24.2 to 2.24.3 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-slf4j2-impl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d2c75fc60032..ba9f735aa621 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 1.1.1 9.4.56.v20240826 - 2.24.2 + 2.24.3 2.0.32 1.19.0 From e236634a4c758a6c0d81e929b2f36d49e81b0835 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 17 Dec 2024 13:11:43 -0600 Subject: [PATCH 112/114] Improve Apache Ant download process. Switch to using curl so that we can retry the request if it initially fails. --- Dockerfile | 10 ++++------ Dockerfile.cli | 10 ++++------ Dockerfile.test | 10 ++++------ 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index fe84d015b548..5aece8b7d37e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,14 +44,12 @@ WORKDIR /dspace-src ENV ANT_VERSION=1.10.13 ENV ANT_HOME=/tmp/ant-$ANT_VERSION ENV PATH=$ANT_HOME/bin:$PATH -# Need wget to install ant -RUN apt-get update \ - && apt-get install -y --no-install-recommends wget \ - && apt-get purge -y --auto-remove \ - && rm -rf /var/lib/apt/lists/* # Download and install 'ant' RUN mkdir $ANT_HOME && \ - wget -qO- "https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME + curl --silent --show-error --location --fail --retry 5 --output /tmp/apache-ant.tar.gz \ + https://archive.apache.org/dist/ant/binaries/apache-ant-${ANT_VERSION}-bin.tar.gz && \ + tar -zx --strip-components=1 -f /tmp/apache-ant.tar.gz -C $ANT_HOME && \ + rm /tmp/apache-ant.tar.gz # Run necessary 'ant' deploy scripts RUN ant init_installation update_configs update_code update_webapps diff --git a/Dockerfile.cli b/Dockerfile.cli index f13b05fc1308..e43c8eb95dd6 100644 --- a/Dockerfile.cli +++ b/Dockerfile.cli @@ -38,14 +38,12 @@ WORKDIR /dspace-src ENV ANT_VERSION=1.10.13 ENV ANT_HOME=/tmp/ant-$ANT_VERSION ENV PATH=$ANT_HOME/bin:$PATH -# Need wget to install ant -RUN apt-get update \ - && apt-get install -y --no-install-recommends wget \ - && apt-get purge -y --auto-remove \ - && rm -rf /var/lib/apt/lists/* # Download and install 'ant' RUN mkdir $ANT_HOME && \ - wget -qO- "https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME + curl --silent --show-error --location --fail --retry 5 --output /tmp/apache-ant.tar.gz \ + https://archive.apache.org/dist/ant/binaries/apache-ant-${ANT_VERSION}-bin.tar.gz && \ + tar -zx --strip-components=1 -f /tmp/apache-ant.tar.gz -C $ANT_HOME && \ + rm /tmp/apache-ant.tar.gz # Run necessary 'ant' deploy scripts RUN ant init_installation update_configs update_code diff --git a/Dockerfile.test b/Dockerfile.test index 2205c1d5605f..90266101dbf0 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -43,14 +43,12 @@ WORKDIR /dspace-src ENV ANT_VERSION=1.10.12 ENV ANT_HOME=/tmp/ant-$ANT_VERSION ENV PATH=$ANT_HOME/bin:$PATH -# Need wget to install ant -RUN apt-get update \ - && apt-get install -y --no-install-recommends wget \ - && apt-get purge -y --auto-remove \ - && rm -rf /var/lib/apt/lists/* # Download and install 'ant' RUN mkdir $ANT_HOME && \ - wget -qO- "https://archive.apache.org/dist/ant/binaries/apache-ant-$ANT_VERSION-bin.tar.gz" | tar -zx --strip-components=1 -C $ANT_HOME + curl --silent --show-error --location --fail --retry 5 --output /tmp/apache-ant.tar.gz \ + https://archive.apache.org/dist/ant/binaries/apache-ant-${ANT_VERSION}-bin.tar.gz && \ + tar -zx --strip-components=1 -f /tmp/apache-ant.tar.gz -C $ANT_HOME && \ + rm /tmp/apache-ant.tar.gz # Run necessary 'ant' deploy scripts RUN ant init_installation update_configs update_code update_webapps From 6d7a3fcb725bbb5e42790ba5c57292477f2f3f01 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 17 Dec 2024 14:13:21 -0600 Subject: [PATCH 113/114] Significantly speed up build of dspace-dependencies by only copying over POM files --- Dockerfile.dependencies | 58 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/Dockerfile.dependencies b/Dockerfile.dependencies index 34bfbc3b8c78..04233cd415fa 100644 --- a/Dockerfile.dependencies +++ b/Dockerfile.dependencies @@ -6,7 +6,7 @@ # To build with other versions, use "--build-arg JDK_VERSION=[value]" ARG JDK_VERSION=17 -# Step 1 - Run Maven Build +# Step 1 - Download all Dependencies FROM docker.io/maven:3-eclipse-temurin-${JDK_VERSION} AS build ARG TARGET_DIR=dspace-installer WORKDIR /app @@ -19,16 +19,60 @@ RUN chown -Rv dspace: /app # Switch to dspace user & run below commands as that user USER dspace -# Copy the DSpace source code (from local machine) into the workdir (excluding .dockerignore contents) -ADD --chown=dspace . /app/ +# This next part may look odd, but it speeds up the build of this image *significantly*. +# Copy ONLY the POMs to this image (from local machine). This will allow us to download all dependencies *without* +# performing any code compilation steps. + +# Parent POM +ADD --chown=dspace pom.xml /app/ +RUN mkdir -p /app/dspace + +# 'dspace' module POM. Includes 'additions' ONLY, as it's the only submodule that is required to exist. +ADD --chown=dspace dspace/pom.xml /app/dspace/ +RUN mkdir -p /app/dspace/modules/ +ADD --chown=dspace dspace/modules/pom.xml /app/dspace/modules/ +RUN mkdir -p /app/dspace/modules/additions +ADD --chown=dspace dspace/modules/additions/pom.xml /app/dspace/modules/additions/ + +# 'dspace-api' module POM +RUN mkdir -p /app/dspace-api +ADD --chown=dspace dspace-api/pom.xml /app/dspace-api/ + +# 'dspace-iiif' module POM +RUN mkdir -p /app/dspace-iiif +ADD --chown=dspace dspace-iiif/pom.xml /app/dspace-iiif/ + +# 'dspace-oai' module POM +RUN mkdir -p /app/dspace-oai +ADD --chown=dspace dspace-oai/pom.xml /app/dspace-oai/ + +# 'dspace-rdf' module POM +RUN mkdir -p /app/dspace-rdf +ADD --chown=dspace dspace-rdf/pom.xml /app/dspace-rdf/ + +# 'dspace-server-webapp' module POM +RUN mkdir -p /app/dspace-server-webapp +ADD --chown=dspace dspace-server-webapp/pom.xml /app/dspace-server-webapp/ + +# 'dspace-services' module POM +RUN mkdir -p /app/dspace-services +ADD --chown=dspace dspace-services/pom.xml /app/dspace-services/ + +# 'dspace-sword' module POM +RUN mkdir -p /app/dspace-sword +ADD --chown=dspace dspace-sword/pom.xml /app/dspace-sword/ + +# 'dspace-swordv2' module POM +RUN mkdir -p /app/dspace-swordv2 +ADD --chown=dspace dspace-swordv2/pom.xml /app/dspace-swordv2/ # Trigger the installation of all maven dependencies (hide download progress messages) # Maven flags here ensure that we skip final assembly, skip building test environment and skip all code verification checks. -# These flags speed up this installation as much as reasonably possible. -ENV MAVEN_FLAGS="-P-assembly -P-test-environment -Denforcer.skip=true -Dcheckstyle.skip=true -Dlicense.skip=true -Dxml.skip=true" -RUN mvn --no-transfer-progress install ${MAVEN_FLAGS} +# These flags speed up this installation and skip tasks we cannot perform as we don't have the full source code. +ENV MAVEN_FLAGS="-P-assembly -P-test-environment -Denforcer.skip=true -Dcheckstyle.skip=true -Dlicense.skip=true -Dxjc.skip=true -Dxml.skip=true" +RUN mvn --no-transfer-progress verify ${MAVEN_FLAGS} -# Clear the contents of the /app directory (including all maven builds), so no artifacts remain. +# Clear the contents of the /app directory (including all maven target folders), so no artifacts remain. # This ensures when dspace:dspace is built, it will use the Maven local cache (~/.m2) for dependencies USER root RUN rm -rf /app/* From 13517d7373b72ccb9ccb3dff5877cb6e59264ac0 Mon Sep 17 00:00:00 2001 From: Giuseppe Date: Wed, 18 Dec 2024 21:14:05 +0100 Subject: [PATCH 114/114] Fix issue with submission sections visibility (#9783) * README.md: v8 is the current release, not v7 (cherry picked from commit 2b698eff609d510c487ad2331d4e11cd28f64e9a) * Update README.md (cherry picked from commit 671234b08f909810d798dd950f87d1818b098363) * [DURACOM-291] Expose section scope attribute * README.md: v8 is the current release, not v7 (cherry picked from commit 2b698eff609d510c487ad2331d4e11cd28f64e9a) * Update README.md (cherry picked from commit 671234b08f909810d798dd950f87d1818b098363) --------- Co-authored-by: Christian Clauss --- .../dspace/app/rest/converter/SubmissionSectionConverter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java index 0391cbce7a2d..3cd263493b5d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SubmissionSectionConverter.java @@ -10,6 +10,7 @@ import java.sql.SQLException; import org.apache.logging.log4j.Logger; +import org.dspace.app.rest.model.ScopeEnum; import org.dspace.app.rest.model.SubmissionSectionRest; import org.dspace.app.rest.model.SubmissionVisibilityRest; import org.dspace.app.rest.model.VisibilityEnum; @@ -41,6 +42,7 @@ public SubmissionSectionRest convert(SubmissionStepConfig step, Projection proje sp.setHeader(step.getHeading()); sp.setSectionType(step.getType()); sp.setId(step.getId()); + sp.setScope(ScopeEnum.fromString(step.getScope())); sp.setVisibility(new SubmissionVisibilityRest(VisibilityEnum.fromString(step.getVisibility()), VisibilityEnum.fromString(step.getVisibilityOutside()))); return sp;