diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/ResourceUtils.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/ResourceUtils.java index 9840535989a7c..948bc69da9481 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/ResourceUtils.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/ResourceUtils.java @@ -7,12 +7,15 @@ package org.elasticsearch.xpack.core.template; +import org.elasticsearch.xpack.core.template.resources.TemplateResources; + import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Map; public class ResourceUtils { + static byte[] loadVersionedResourceUTF8(Class clazz, String name, int version, String versionProperty) { return loadVersionedResourceUTF8(clazz, name, version, versionProperty, Map.of()); } @@ -25,7 +28,7 @@ static byte[] loadVersionedResourceUTF8( Map variables ) { try { - String content = loadResource(clazz, name); + String content = loadResourceWithFallback(clazz, name); content = TemplateUtils.replaceVariables(content, String.valueOf(version), versionProperty, variables); return content.getBytes(StandardCharsets.UTF_8); } catch (IOException e) { @@ -33,8 +36,25 @@ static byte[] loadVersionedResourceUTF8( } } - public static String loadResource(Class clazz, String name) throws IOException { - InputStream is = clazz.getResourceAsStream(name); + /** + * loadResourceWithFallback loads template resources from TemplateResource class. It expects + * the loader to be a named Java module and the template resources to contain required templates + * with a folder named with the module name. If the specified resource name is not found in + * template resource then the plugin's resources is used as a fallback. + * + * @param clazz the runtime class of the source plugin + * @param name the relative path of the resource with leading `/` + * @return the loaded resource as string + * @throws IOException + */ + static String loadResourceWithFallback(Class clazz, String name) throws IOException { + InputStream is = null; + if (clazz.getModule().isNamed()) { + is = TemplateResources.class.getResourceAsStream("/" + clazz.getModule().getName() + name); + } + if (is == null) { + is = clazz.getResourceAsStream(name); + } if (is == null) { throw new IOException("Resource [" + name + "] not found in classpath."); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java index a4e5d7cdc4b44..596917aa1b95c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/template/YamlTemplateRegistry.java @@ -31,7 +31,7 @@ import java.util.Optional; import java.util.stream.Collectors; -import static org.elasticsearch.xpack.core.template.ResourceUtils.loadResource; +import static org.elasticsearch.xpack.core.template.ResourceUtils.loadResourceWithFallback; import static org.elasticsearch.xpack.core.template.ResourceUtils.loadVersionedResourceUTF8; /** @@ -64,7 +64,7 @@ public YamlTemplateRegistry( try { final Map resources = XContentHelper.convertToMap( YamlXContent.yamlXContent, - loadResource(this.getClass(), "/resources.yaml"), + loadResourceWithFallback(this.getClass(), "/resources.yaml"), false ); version = (((Number) resources.get("version")).intValue());