diff --git a/core/src/main/java/jeeves/server/overrides/ConfigurationOverrides.java b/core/src/main/java/jeeves/server/overrides/ConfigurationOverrides.java index 110776cf326..76e5f272cfd 100644 --- a/core/src/main/java/jeeves/server/overrides/ConfigurationOverrides.java +++ b/core/src/main/java/jeeves/server/overrides/ConfigurationOverrides.java @@ -1,6 +1,7 @@ package jeeves.server.overrides; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.apache.log4j.spi.LoggerRepository; @@ -43,6 +44,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; + import javax.servlet.ServletContext; /** @@ -512,6 +514,11 @@ String updatePropertiesInText(Properties properties, String value) { String propKey = matcher.group(1); String propValue = properties.getProperty(propKey); + // if property begins with "env:", it will be replaced later on + if (propKey.startsWith("env:")) { + continue; + } + if (propValue == null) { throw new IllegalArgumentException("Found a reference to a variable: " + propKey + " which is not a valid property. Check the spelling"); } @@ -619,6 +626,17 @@ private String lookupOverrideParamFromServlet(ServletContext context) throws IOE public static abstract class ResourceLoader { protected InputStream loadInputStream(String resource) throws IOException { + // resolves env variables before trying to resolve the actual file + Pattern p = Pattern.compile("\\$\\{env:([^\\}]*)\\}"); + Matcher m = p.matcher(resource); + while (m.find()) { + String repl = m.group(); + String subst = System.getProperty(m.group(1), ""); + if (StringUtils.isEmpty(subst)) { + Log.warning(Log.JEEVES, "Unable to resolve environmnent variable " + m.group(1) + ", replacing with empty string"); + } + resource = resource.replace((CharSequence) repl, subst); + } Path file = resolveFile(resource); if(file == null) { return fallbackInputStream(resource); diff --git a/core/src/test/java/jeeves/server/overrides/ConfigurationOverridesTest.java b/core/src/test/java/jeeves/server/overrides/ConfigurationOverridesTest.java index e66c9f679aa..c2aff3ae5d9 100644 --- a/core/src/test/java/jeeves/server/overrides/ConfigurationOverridesTest.java +++ b/core/src/test/java/jeeves/server/overrides/ConfigurationOverridesTest.java @@ -1,7 +1,24 @@ package jeeves.server.overrides; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import jeeves.config.springutil.JeevesApplicationContext; + import org.apache.log4j.Level; import org.fao.geonet.Constants; import org.fao.geonet.utils.IO; @@ -12,19 +29,6 @@ import org.springframework.security.access.ConfigAttribute; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.file.Path; -import java.util.Collection; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - public class ConfigurationOverridesTest { private static final ClassLoader classLoader; private static final Path appPath; @@ -197,7 +201,49 @@ public void noUpdateConfig() throws JDOMException, IOException { assertEquals(Xml.selectString(unchanged,"default/gui/xml[@name = 'countries']/@file"), Xml.selectString(config,"default/gui/xml[@name = 'countries']/@file")); } - + + @Test + public void resolveRessourcesWithEnvVariable() throws Exception { + // Ensures the testcase begins in correct conditions + System.clearProperty("geonetwork.datadir"); + System.clearProperty("another_one"); + + // No properties defined, it should resolve as "//test.xml" + + try { + boolean exCaught = false; + URL u = this.getClass().getResource("/"); + + try { + loader.loadXmlResource("${env:geonetwork.datadir}/${env:another_one}/test.xml"); + } catch (Throwable e) { + System.out.println(e.getMessage()); + exCaught = e.getMessage().contains("//test.xml"); + } + assertTrue( + "Expected to fail on loading //test.xml file, no exception encountered", + exCaught); + + // Same defining the previously missing env variables + + System.setProperty("geonetwork.datadir", u.toURI().getPath()); + System.setProperty("another_one", "test-spring-config.xml"); + + exCaught = false; + try { + loader.loadXmlResource("${env:geonetwork.datadir}/${env:another_one}"); + } catch (Throwable e) { + exCaught = true; + } + assertFalse("Unexepected exception caught with a legit file.", + exCaught); + } finally { + // Cleanup after testing + System.clearProperty("geonetwork.datadir"); + System.clearProperty("another_one"); + } + } + // TODO no property // no overrides // invalid appPath