Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.plugins;
import com.google.common.collect.*;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.cluster.node.info.PluginInfo;
import org.elasticsearch.action.admin.cluster.node.info.PluginsInfo;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.CloseableIndexComponent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
import static com.google.common.collect.Maps.newHashMap;
/**
*
*/
public class PluginsService extends AbstractComponent {
private static final String ES_PLUGIN_PROPERTIES = "es-plugin.properties";
private final Environment environment;
private final ImmutableMap plugins;
private final ImmutableMap> onModuleReferences;
private PluginsInfo cachedPluginsInfo;
private final TimeValue refreshInterval;
private long lastRefresh;
static class OnModuleReference {
public final Class moduleClass;
public final Method onModuleMethod;
OnModuleReference(Class moduleClass, Method onModuleMethod) {
this.moduleClass = moduleClass;
this.onModuleMethod = onModuleMethod;
}
}
/**
* Constructs a new PluginService
* @param settings The settings of the system
* @param environment The environment of the system
*/
public PluginsService(Settings settings, Environment environment) {
super(settings);
this.environment = environment;
Map plugins = Maps.newHashMap();
//first we load all the default plugins from the settings
String[] defaultPluginsClasses = settings.getAsArray("plugin.types");
for (String pluginClass : defaultPluginsClasses) {
Plugin plugin = loadPlugin(pluginClass, settings);
plugins.put(plugin.name(), plugin);
}
// now, find all the ones that are in the classpath
loadPluginsIntoClassLoader();
plugins.putAll(loadPluginsFromClasspath(settings));
Set sitePlugins = PluginsHelper.sitePlugins(this.environment);
String[] mandatoryPlugins = settings.getAsArray("plugin.mandatory", null);
if (mandatoryPlugins != null) {
Set missingPlugins = Sets.newHashSet();
for (String mandatoryPlugin : mandatoryPlugins) {
if (!plugins.containsKey(mandatoryPlugin) && !sitePlugins.contains(mandatoryPlugin) && !missingPlugins.contains(mandatoryPlugin)) {
missingPlugins.add(mandatoryPlugin);
}
}
if (!missingPlugins.isEmpty()) {
throw new ElasticsearchException("Missing mandatory plugins [" + Strings.collectionToDelimitedString(missingPlugins, ", ") + "]");
}
}
logger.info("loaded {}, sites {}", plugins.keySet(), sitePlugins);
this.plugins = ImmutableMap.copyOf(plugins);
MapBuilder> onModuleReferences = MapBuilder.newMapBuilder();
for (Plugin plugin : plugins.values()) {
List list = Lists.newArrayList();
for (Method method : plugin.getClass().getDeclaredMethods()) {
if (!method.getName().equals("onModule")) {
continue;
}
if (method.getParameterTypes().length == 0 || method.getParameterTypes().length > 1) {
logger.warn("Plugin: {} implementing onModule with no parameters or more than one parameter", plugin.name());
continue;
}
Class moduleClass = method.getParameterTypes()[0];
if (!Module.class.isAssignableFrom(moduleClass)) {
logger.warn("Plugin: {} implementing onModule by the type is not of Module type {}", plugin.name(), moduleClass);
continue;
}
method.setAccessible(true);
list.add(new OnModuleReference(moduleClass, method));
}
if (!list.isEmpty()) {
onModuleReferences.put(plugin, list);
}
}
this.onModuleReferences = onModuleReferences.immutableMap();
this.refreshInterval = componentSettings.getAsTime("info_refresh_interval", TimeValue.timeValueSeconds(10));
}
public ImmutableMap plugins() {
return plugins;
}
public void processModules(Iterable modules) {
for (Module module : modules) {
processModule(module);
}
}
public void processModule(Module module) {
for (Plugin plugin : plugins().values()) {
plugin.processModule(module);
// see if there are onModule references
List references = onModuleReferences.get(plugin);
if (references != null) {
for (OnModuleReference reference : references) {
if (reference.moduleClass.isAssignableFrom(module.getClass())) {
try {
reference.onModuleMethod.invoke(plugin, module);
} catch (Exception e) {
logger.warn("plugin {}, failed to invoke custom onModule method", e, plugin.name());
}
}
}
}
}
}
public Settings updatedSettings() {
ImmutableSettings.Builder builder = ImmutableSettings.settingsBuilder()
.put(this.settings);
for (Plugin plugin : plugins.values()) {
builder.put(plugin.additionalSettings());
}
return builder.build();
}
public Collection> modules() {
List> modules = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
modules.addAll(plugin.modules());
}
return modules;
}
public Collection modules(Settings settings) {
List modules = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
modules.addAll(plugin.modules(settings));
}
return modules;
}
public Collection> services() {
List> services = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
services.addAll(plugin.services());
}
return services;
}
public Collection> indexModules() {
List> modules = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
modules.addAll(plugin.indexModules());
}
return modules;
}
public Collection indexModules(Settings settings) {
List modules = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
modules.addAll(plugin.indexModules(settings));
}
return modules;
}
public Collection> indexServices() {
List> services = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
services.addAll(plugin.indexServices());
}
return services;
}
public Collection> shardModules() {
List> modules = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
modules.addAll(plugin.shardModules());
}
return modules;
}
public Collection shardModules(Settings settings) {
List modules = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
modules.addAll(plugin.shardModules(settings));
}
return modules;
}
public Collection> shardServices() {
List> services = Lists.newArrayList();
for (Plugin plugin : plugins.values()) {
services.addAll(plugin.shardServices());
}
return services;
}
/**
* Get information about plugins (jvm and site plugins).
* Information are cached for 10 seconds by default. Modify `plugins.info_refresh_interval` property if needed.
* Setting `plugins.info_refresh_interval` to `-1` will cause infinite caching.
* Setting `plugins.info_refresh_interval` to `0` will disable caching.
* @return List of plugins information
*/
synchronized public PluginsInfo info() {
if (refreshInterval.millis() != 0) {
if (cachedPluginsInfo != null &&
(refreshInterval.millis() < 0 || (System.currentTimeMillis() - lastRefresh) < refreshInterval.millis())) {
if (logger.isTraceEnabled()) logger.trace("using cache to retrieve plugins info");
return cachedPluginsInfo;
}
lastRefresh = System.currentTimeMillis();
}
if (logger.isTraceEnabled()) logger.trace("starting to fetch info on plugins");
cachedPluginsInfo = new PluginsInfo();
// We create a map to have only unique values
Set plugins = new HashSet();
for (Plugin plugin : plugins().values()) {
// We should detect if the plugin has also an embedded _site structure
File siteFile = new File(new File(environment.pluginsFile(), plugin.name()), "_site");
boolean isSite = siteFile.exists() && siteFile.isDirectory();
if (logger.isTraceEnabled()) logger.trace("found a jvm plugin [{}], [{}]{}",
plugin.name(), plugin.description(), isSite ? ": with _site structure" : "");
cachedPluginsInfo.add(new PluginInfo(plugin.name(), plugin.description(), isSite, true));
plugins.add(plugin.name());
}
File pluginsFile = environment.pluginsFile();
if (!pluginsFile.exists()) {
return cachedPluginsInfo;
}
if (!pluginsFile.isDirectory()) {
return cachedPluginsInfo;
}
File[] pluginsFiles = pluginsFile.listFiles();
if (pluginsFiles != null) {
for (File plugin : pluginsFiles) {
// We skip already known jvm plugins
if (!plugins.contains(plugin.getName())) {
File sitePluginDir = new File(plugin, "_site");
if (sitePluginDir.exists()) {
String name = plugin.getName();
String description = "No description found for " + name + ".";
// We check if es-plugin.properties exists in plugin/_site dir
File pluginPropFile = new File(sitePluginDir, ES_PLUGIN_PROPERTIES);
if (pluginPropFile.exists()) {
Properties pluginProps = new Properties();
InputStream is = null;
try {
is = new FileInputStream(pluginPropFile.getAbsolutePath());
pluginProps.load(is);
description = pluginProps.getProperty("description");
} catch (Exception e) {
logger.warn("failed to load plugin description from [" +
pluginPropFile.getAbsolutePath() + "]", e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// ignore
}
}
}
}
if (logger.isTraceEnabled()) logger.trace("found a site plugin [{}], [{}]",
name, description);
cachedPluginsInfo.add(new PluginInfo(name, description, true, false));
}
}
}
}
return cachedPluginsInfo;
}
private void loadPluginsIntoClassLoader() {
File pluginsFile = environment.pluginsFile();
if (!pluginsFile.exists()) {
return;
}
if (!pluginsFile.isDirectory()) {
return;
}
ClassLoader classLoader = settings.getClassLoader();
Class classLoaderClass = classLoader.getClass();
Method addURL = null;
while (!classLoaderClass.equals(Object.class)) {
try {
addURL = classLoaderClass.getDeclaredMethod("addURL", URL.class);
addURL.setAccessible(true);
break;
} catch (NoSuchMethodException e) {
// no method, try the parent
classLoaderClass = classLoaderClass.getSuperclass();
}
}
if (addURL == null) {
logger.debug("failed to find addURL method on classLoader [" + classLoader + "] to add methods");
return;
}
File[] pluginsFiles = pluginsFile.listFiles();
if (pluginsFile != null) {
for (File pluginFile : pluginsFiles) {
if (pluginFile.isDirectory()) {
logger.trace("--- adding plugin [" + pluginFile.getAbsolutePath() + "]");
try {
// add the root
addURL.invoke(classLoader, pluginFile.toURI().toURL());
// gather files to add
List libFiles = Lists.newArrayList();
if (pluginFile.listFiles() != null) {
libFiles.addAll(Arrays.asList(pluginFile.listFiles()));
}
File libLocation = new File(pluginFile, "lib");
if (libLocation.exists() && libLocation.isDirectory() && libLocation.listFiles() != null) {
libFiles.addAll(Arrays.asList(libLocation.listFiles()));
}
// if there are jars in it, add it as well
for (File libFile : libFiles) {
if (!(libFile.getName().endsWith(".jar") || libFile.getName().endsWith(".zip"))) {
continue;
}
addURL.invoke(classLoader, libFile.toURI().toURL());
}
} catch (Exception e) {
logger.warn("failed to add plugin [" + pluginFile + "]", e);
}
}
}
} else {
logger.debug("failed to list plugins from {}. Check your right access.", pluginsFile.getAbsolutePath());
}
}
private Map loadPluginsFromClasspath(Settings settings) {
Map plugins = newHashMap();
Enumeration pluginUrls = null;
try {
pluginUrls = settings.getClassLoader().getResources(ES_PLUGIN_PROPERTIES);
} catch (IOException e) {
logger.warn("failed to find plugins from classpath", e);
return ImmutableMap.of();
}
while (pluginUrls.hasMoreElements()) {
URL pluginUrl = pluginUrls.nextElement();
Properties pluginProps = new Properties();
InputStream is = null;
try {
is = pluginUrl.openStream();
pluginProps.load(is);
String pluginClassName = pluginProps.getProperty("plugin");
Plugin plugin = loadPlugin(pluginClassName, settings);
plugins.put(plugin.name(), plugin);
} catch (Exception e) {
logger.warn("failed to load plugin from [" + pluginUrl + "]", e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// ignore
}
}
}
}
return plugins;
}
private Plugin loadPlugin(String className, Settings settings) {
try {
Class pluginClass = (Class) settings.getClassLoader().loadClass(className);
try {
return pluginClass.getConstructor(Settings.class).newInstance(settings);
} catch (NoSuchMethodException e) {
try {
return pluginClass.getConstructor().newInstance();
} catch (NoSuchMethodException e1) {
throw new ElasticsearchException("No constructor for [" + pluginClass + "]. A plugin class must " +
"have either an empty default constructor or a single argument constructor accepting a " +
"Settings instance");
}
}
} catch (Exception e) {
throw new ElasticsearchException("Failed to load plugin class [" + className + "]", e);
}
}
}