All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.plugins.scanners.NamedComponentReader Maven / Gradle / Ivy

There is a newer version: 8.14.0
Show newest version
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

package org.elasticsearch.plugins.scanners;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.core.Strings;
import org.elasticsearch.plugins.PluginBundle;
import org.elasticsearch.xcontent.XContentParserConfiguration;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

import static java.util.Collections.emptyMap;
import static org.elasticsearch.xcontent.XContentType.JSON;

/**
 * Reads named components declared by a plugin in a cache file.
 * Cache file is expected to be present in plugin's lib directory
 * 

* The content of a cache file is a JSON representation of a map where: * keys -> name of the extensible interface (a class/interface marked with @Extensible) * values -> a map of name to implementation class name */ public class NamedComponentReader { private Logger logger = LogManager.getLogger(NamedComponentReader.class); private static final String NAMED_COMPONENTS_FILE_NAME = "named_components.json"; /** * a registry of known classes marked or indirectly marked (extending marked class) with @Extensible */ private final ExtensiblesRegistry extensiblesRegistry; public NamedComponentReader() { this(ExtensiblesRegistry.INSTANCE); } NamedComponentReader(ExtensiblesRegistry extensiblesRegistry) { this.extensiblesRegistry = extensiblesRegistry; } public Map findNamedComponents(PluginBundle bundle, ClassLoader pluginClassLoader) { Path pluginDir = bundle.getDir(); return findNamedComponents(pluginDir, pluginClassLoader); } // scope for testing Map findNamedComponents(Path pluginDir, ClassLoader pluginClassLoader) { try { Path namedComponent = findNamedComponentCacheFile(pluginDir); if (namedComponent != null) { Map namedComponents = readFromFile(namedComponent, pluginClassLoader); logger.debug(() -> Strings.format("Plugin in dir %s declared named components %s.", pluginDir, namedComponents)); return namedComponents; } logger.debug(() -> Strings.format("No named component defined in plugin dir %s", pluginDir)); } catch (IOException e) { logger.error("unable to read named components", e); } return emptyMap(); } private Path findNamedComponentCacheFile(Path pluginDir) throws IOException { try (Stream list = Files.list(pluginDir)) { return list.filter(p -> p.getFileName().toString().equals(NAMED_COMPONENTS_FILE_NAME)).findFirst().orElse(null); } } @SuppressWarnings("unchecked") Map readFromFile(Path namedComponent, ClassLoader pluginClassLoader) throws IOException { Map res = new HashMap<>(); try ( var json = new BufferedInputStream(Files.newInputStream(namedComponent)); var parser = JSON.xContent().createParser(XContentParserConfiguration.EMPTY, json) ) { Map map = parser.map(); for (Map.Entry fileAsMap : map.entrySet()) { String extensibleInterface = fileAsMap.getKey(); validateExtensible(extensibleInterface); Map components = (Map) fileAsMap.getValue(); for (Map.Entry nameToComponent : components.entrySet()) { String name = nameToComponent.getKey(); String value = (String) nameToComponent.getValue(); res.computeIfAbsent(extensibleInterface, k -> new NameToPluginInfo()) .put(name, new PluginInfo(name, value, pluginClassLoader)); } } } return res; } private void validateExtensible(String extensibleInterface) { if (extensiblesRegistry.hasExtensible(extensibleInterface) == false) { throw new IllegalStateException("Unknown extensible name " + extensibleInterface); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy