From 9b2fa4582c09548d44deed147ab57284fb613d3c Mon Sep 17 00:00:00 2001 From: dshimo Date: Mon, 4 Mar 2024 15:47:09 -0600 Subject: [PATCH] bootstrap.include recursion --- .../plugins/config/ServerConfigDocument.java | 53 +++++++++++++++---- .../config/ServerConfigDocumentTest.java | 7 ++- .../servers/bootstrapOuroboros.properties | 1 + 3 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 src/test/resources/servers/bootstrapOuroboros.properties diff --git a/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java b/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java index bdb42c83..67dab44b 100644 --- a/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java +++ b/src/main/java/io/openliberty/tools/common/plugins/config/ServerConfigDocument.java @@ -223,6 +223,7 @@ private void initializeAppsLocation(CommonLoggerI log, File serverXML, File conf * 2. {server.config.dir}/configDropins/defaults/ * 3. {server.config.dir}/ * 4. {server.config.dir}/configDropins/overrides/ + * TODO: potential processing for system property tags? (-D prefixes?) * @throws FileNotFoundException * @throws Exception */ @@ -276,13 +277,16 @@ public void initializeFields(CommonLoggerI log, File serverXML, File configDir, /** * Process bootstrap.properties and boostrap.include - * @param bootstrapProp - * @param bootstrapFile - Optional specific file + * @param bootstrapProp - Populated in Maven/Gradle + * @param bootstrapFile - Optional specific file which will take precedence over config dir file * @throws Exception * @throws FileNotFoundException */ public void processBootstrapProperties(Map bootstrapProp, File bootstrapFile) throws Exception, FileNotFoundException { - File cfgDirFile = getFileFromConfigDirectory("bootstrap.properties"); + File configDirBootstrapProperties = getFileFromConfigDirectory("bootstrap.properties"); + File processedFile = null; + + // Initial bootstrap.properties processing if (bootstrapProp != null && !bootstrapProp.isEmpty()) { for (Map.Entry entry : bootstrapProp.entrySet()) { if (entry.getValue() != null) { @@ -291,18 +295,47 @@ public void processBootstrapProperties(Map bootstrapProp, File b } } else if (bootstrapFile != null && bootstrapFile.exists()) { parseProperties(new FileInputStream(bootstrapFile)); - } else if (cfgDirFile != null) { - parseProperties(new FileInputStream(cfgDirFile)); + processedFile = bootstrapFile; + } else if (configDirBootstrapProperties != null) { + parseProperties(new FileInputStream(configDirBootstrapProperties)); + processedFile = configDirBootstrapProperties; } + // Recursive processing for bootstrap.include if (props.containsKey("bootstrap.include")) { - Path bootstrapIncludePath = Paths.get(props.getProperty("bootstrap.include")).normalize(); - File bootstrapIncludeFile = bootstrapIncludePath.isAbsolute() ? - new File(bootstrapIncludePath.toString()) : new File(configDirectory, bootstrapIncludePath.toString()); - if (bootstrapIncludeFile.exists()) { - parseProperties(new FileInputStream(bootstrapIncludeFile)); + Set visited = new HashSet(); + if (processedFile != null) { + visited.add(processedFile.getAbsolutePath()); } + processBootstrapInclude(getBootstrapIncludeProperty(), visited); + } + } + + /** + * Recursive processing for a series of bootstrap.include that terminates upon revisit + * @param bootstrapIncludeLocation + * @param processedBootstrapIncludes + * @throws Exception + * @throws FileNotFoundException + */ + private void processBootstrapInclude(String bootstrapIncludeLocation, Set processedBootstrapIncludes) throws FileNotFoundException, Exception { + Path bootstrapIncludePath = Paths.get(bootstrapIncludeLocation); + File bootstrapIncludeFile = bootstrapIncludePath.isAbsolute() ? + new File(bootstrapIncludePath.toString()) : new File(configDirectory, bootstrapIncludePath.toString()); + + if (processedBootstrapIncludes.contains(bootstrapIncludeFile.getAbsolutePath())) { + return; } + + if (bootstrapIncludeFile.exists()) { + parseProperties(new FileInputStream(bootstrapIncludeFile)); + processedBootstrapIncludes.add(bootstrapIncludeFile.getAbsolutePath()); + processBootstrapInclude(getBootstrapIncludeProperty(), processedBootstrapIncludes); + } + } + + private String getBootstrapIncludeProperty() { + return props.getProperty("bootstrap.include"); } //Checks for application names in the document. Will add locations without names to a Set diff --git a/src/test/java/io/openliberty/tools/common/config/ServerConfigDocumentTest.java b/src/test/java/io/openliberty/tools/common/config/ServerConfigDocumentTest.java index c2b37574..8ff5e26e 100644 --- a/src/test/java/io/openliberty/tools/common/config/ServerConfigDocumentTest.java +++ b/src/test/java/io/openliberty/tools/common/config/ServerConfigDocumentTest.java @@ -142,7 +142,6 @@ public void environmentVariables() throws FileNotFoundException, Exception { } - // 3. bootstrap.properties @Test public void processBootstrapProperties() throws FileNotFoundException, Exception { @@ -173,10 +172,16 @@ public void processBootstrapProperties() throws FileNotFoundException, Exception configDocument.processBootstrapProperties(bootstrapPropertyMap, null); assertEquals("1000", configDocument.getProperties().getProperty("http.port")); + // bootstrap.include configDocument = new ServerConfigDocument(new TestLogger()); configDocument.initializeFields(new TestLogger(), null, serversDir, null); configDocument.processBootstrapProperties(new HashMap<>(), MOCK_SERVER_DIR.resolve("bootstrapInclude.properties").toFile()); assertEquals("extraFeatures.xml", configDocument.getProperties().getProperty("extras.filename")); + + // bootstrap.include infinite termination check + configDocument = new ServerConfigDocument(new TestLogger()); + configDocument.initializeFields(new TestLogger(), null, serversDir, null); + configDocument.processBootstrapProperties(new HashMap<>(), MOCK_SERVER_DIR.resolve("bootstrapOuroboros.properties").toFile()); } // 4. Java system properties diff --git a/src/test/resources/servers/bootstrapOuroboros.properties b/src/test/resources/servers/bootstrapOuroboros.properties new file mode 100644 index 00000000..f628030e --- /dev/null +++ b/src/test/resources/servers/bootstrapOuroboros.properties @@ -0,0 +1 @@ +bootstrap.include=bootstrapOuroboros.properties \ No newline at end of file