diff options
author | Ryan Ernst <ryan@iernst.net> | 2016-01-16 21:54:05 -0800 |
---|---|---|
committer | Ryan Ernst <ryan@iernst.net> | 2016-01-16 22:45:37 -0800 |
commit | 3b78267c7154d69a40d18acdab971a205acb2f22 (patch) | |
tree | b4c00ac9dfeb7f3ddb32092b6c93256f646b8b7c /core | |
parent | b4538a56761cc13e11bd359ea850346aeac2513d (diff) |
Plugins: Remove site plugins
Site plugins used to be used for things like kibana and marvel, but
there is no longer a need since kibana (and marvel as a kibana plugin)
uses node.js. This change removes site plugins, as well as the flag for
jvm plugins. Now all plugins are jvm plugins.
Diffstat (limited to 'core')
10 files changed, 58 insertions, 623 deletions
diff --git a/core/src/main/java/org/elasticsearch/http/HttpServer.java b/core/src/main/java/org/elasticsearch/http/HttpServer.java index 9971ce7722..35c46f4f79 100644 --- a/core/src/main/java/org/elasticsearch/http/HttpServer.java +++ b/core/src/main/java/org/elasticsearch/http/HttpServer.java @@ -51,7 +51,7 @@ import static org.elasticsearch.rest.RestStatus.NOT_FOUND; import static org.elasticsearch.rest.RestStatus.OK; /** - * + * A component to serve http requests, backed by rest handlers. */ public class HttpServer extends AbstractLifecycleComponent<HttpServer> { @@ -63,10 +63,6 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> { private final NodeService nodeService; - private final boolean disableSites; - - private final PluginSiteFilter pluginSiteFilter = new PluginSiteFilter(); - @Inject public HttpServer(Settings settings, Environment environment, HttpServerTransport transport, RestController restController, @@ -77,9 +73,6 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> { this.restController = restController; this.nodeService = nodeService; nodeService.setHttpServer(this); - - this.disableSites = this.settings.getAsBoolean("http.disable_sites", false); - transport.httpServerAdapter(new Dispatcher(this)); } @@ -126,27 +119,13 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> { } public void internalDispatchRequest(final HttpRequest request, final HttpChannel channel) { - String rawPath = request.rawPath(); - if (rawPath.startsWith("/_plugin/")) { - RestFilterChain filterChain = restController.filterChain(pluginSiteFilter); - filterChain.continueProcessing(request, channel); - return; - } else if (rawPath.equals("/favicon.ico")) { + if (request.rawPath().equals("/favicon.ico")) { handleFavicon(request, channel); return; } restController.dispatchRequest(request, channel); } - - class PluginSiteFilter extends RestFilter { - - @Override - public void process(RestRequest request, RestChannel channel, RestFilterChain filterChain) throws IOException { - handlePluginSite((HttpRequest) request, (HttpChannel) channel); - } - } - void handleFavicon(HttpRequest request, HttpChannel channel) { if (request.method() == RestRequest.Method.GET) { try { @@ -163,129 +142,4 @@ public class HttpServer extends AbstractLifecycleComponent<HttpServer> { channel.sendResponse(new BytesRestResponse(FORBIDDEN)); } } - - void handlePluginSite(HttpRequest request, HttpChannel channel) throws IOException { - if (disableSites) { - channel.sendResponse(new BytesRestResponse(FORBIDDEN)); - return; - } - if (request.method() == RestRequest.Method.OPTIONS) { - // when we have OPTIONS request, simply send OK by default (with the Access Control Origin header which gets automatically added) - channel.sendResponse(new BytesRestResponse(OK)); - return; - } - if (request.method() != RestRequest.Method.GET) { - channel.sendResponse(new BytesRestResponse(FORBIDDEN)); - return; - } - // TODO for a "/_plugin" endpoint, we should have a page that lists all the plugins? - - String path = request.rawPath().substring("/_plugin/".length()); - int i1 = path.indexOf('/'); - String pluginName; - String sitePath; - if (i1 == -1) { - pluginName = path; - sitePath = null; - // If a trailing / is missing, we redirect to the right page #2654 - String redirectUrl = request.rawPath() + "/"; - BytesRestResponse restResponse = new BytesRestResponse(RestStatus.MOVED_PERMANENTLY, "text/html", "<head><meta http-equiv=\"refresh\" content=\"0; URL=" + redirectUrl + "\"></head>"); - restResponse.addHeader("Location", redirectUrl); - channel.sendResponse(restResponse); - return; - } else { - pluginName = path.substring(0, i1); - sitePath = path.substring(i1 + 1); - } - - // we default to index.html, or what the plugin provides (as a unix-style path) - // this is a relative path under _site configured by the plugin. - if (sitePath.length() == 0) { - sitePath = "index.html"; - } else { - // remove extraneous leading slashes, its not an absolute path. - while (sitePath.length() > 0 && sitePath.charAt(0) == '/') { - sitePath = sitePath.substring(1); - } - } - final Path siteFile = environment.pluginsFile().resolve(pluginName).resolve("_site"); - - final String separator = siteFile.getFileSystem().getSeparator(); - // Convert file separators. - sitePath = sitePath.replace("/", separator); - - Path file = siteFile.resolve(sitePath); - - // return not found instead of forbidden to prevent malicious requests to find out if files exist or dont exist - if (!Files.exists(file) || FileSystemUtils.isHidden(file) || !file.toAbsolutePath().normalize().startsWith(siteFile.toAbsolutePath().normalize())) { - channel.sendResponse(new BytesRestResponse(NOT_FOUND)); - return; - } - - BasicFileAttributes attributes = Files.readAttributes(file, BasicFileAttributes.class); - if (!attributes.isRegularFile()) { - // If it's not a dir, we send a 403 - if (!attributes.isDirectory()) { - channel.sendResponse(new BytesRestResponse(FORBIDDEN)); - return; - } - // We don't serve dir but if index.html exists in dir we should serve it - file = file.resolve("index.html"); - if (!Files.exists(file) || FileSystemUtils.isHidden(file) || !Files.isRegularFile(file)) { - channel.sendResponse(new BytesRestResponse(FORBIDDEN)); - return; - } - } - - try { - byte[] data = Files.readAllBytes(file); - channel.sendResponse(new BytesRestResponse(OK, guessMimeType(sitePath), data)); - } catch (IOException e) { - channel.sendResponse(new BytesRestResponse(INTERNAL_SERVER_ERROR)); - } - } - - - // TODO: Don't respond with a mime type that violates the request's Accept header - private String guessMimeType(String path) { - int lastDot = path.lastIndexOf('.'); - if (lastDot == -1) { - return ""; - } - String extension = path.substring(lastDot + 1).toLowerCase(Locale.ROOT); - String mimeType = DEFAULT_MIME_TYPES.get(extension); - if (mimeType == null) { - return ""; - } - return mimeType; - } - - static { - // This is not an exhaustive list, just the most common types. Call registerMimeType() to add more. - Map<String, String> mimeTypes = new HashMap<>(); - mimeTypes.put("txt", "text/plain"); - mimeTypes.put("css", "text/css"); - mimeTypes.put("csv", "text/csv"); - mimeTypes.put("htm", "text/html"); - mimeTypes.put("html", "text/html"); - mimeTypes.put("xml", "text/xml"); - mimeTypes.put("js", "text/javascript"); // Technically it should be application/javascript (RFC 4329), but IE8 struggles with that - mimeTypes.put("xhtml", "application/xhtml+xml"); - mimeTypes.put("json", "application/json"); - mimeTypes.put("pdf", "application/pdf"); - mimeTypes.put("zip", "application/zip"); - mimeTypes.put("tar", "application/x-tar"); - mimeTypes.put("gif", "image/gif"); - mimeTypes.put("jpeg", "image/jpeg"); - mimeTypes.put("jpg", "image/jpeg"); - mimeTypes.put("tiff", "image/tiff"); - mimeTypes.put("tif", "image/tiff"); - mimeTypes.put("png", "image/png"); - mimeTypes.put("svg", "image/svg+xml"); - mimeTypes.put("ico", "image/vnd.microsoft.icon"); - mimeTypes.put("mp3", "audio/mpeg"); - DEFAULT_MIME_TYPES = unmodifiableMap(mimeTypes); - } - - public static final Map<String, String> DEFAULT_MIME_TYPES; } diff --git a/core/src/main/java/org/elasticsearch/plugins/DummyPluginInfo.java b/core/src/main/java/org/elasticsearch/plugins/DummyPluginInfo.java index a57a96c631..a7d088ce21 100644 --- a/core/src/main/java/org/elasticsearch/plugins/DummyPluginInfo.java +++ b/core/src/main/java/org/elasticsearch/plugins/DummyPluginInfo.java @@ -20,9 +20,9 @@ package org.elasticsearch.plugins; public class DummyPluginInfo extends PluginInfo { - private DummyPluginInfo(String name, String description, boolean site, String version, boolean jvm, String classname, boolean isolated) { - super(name, description, site, version, jvm, classname, isolated); + private DummyPluginInfo(String name, String description, String version, String classname, boolean isolated) { + super(name, description, version, classname, isolated); } - public static final DummyPluginInfo INSTANCE = new DummyPluginInfo("dummy_plugin_name", "dummy plugin description", true, "dummy_plugin_version", true, "DummyPluginName", true); + public static final DummyPluginInfo INSTANCE = new DummyPluginInfo("dummy_plugin_name", "dummy plugin description", "dummy_plugin_version", "DummyPluginName", true); } diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginInfo.java b/core/src/main/java/org/elasticsearch/plugins/PluginInfo.java index 3062f01697..76af7833f0 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginInfo.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginInfo.java @@ -42,19 +42,14 @@ public class PluginInfo implements Streamable, ToXContent { static final XContentBuilderString NAME = new XContentBuilderString("name"); static final XContentBuilderString DESCRIPTION = new XContentBuilderString("description"); static final XContentBuilderString URL = new XContentBuilderString("url"); - static final XContentBuilderString SITE = new XContentBuilderString("site"); static final XContentBuilderString VERSION = new XContentBuilderString("version"); - static final XContentBuilderString JVM = new XContentBuilderString("jvm"); static final XContentBuilderString CLASSNAME = new XContentBuilderString("classname"); static final XContentBuilderString ISOLATED = new XContentBuilderString("isolated"); } private String name; private String description; - private boolean site; private String version; - - private boolean jvm; private String classname; private boolean isolated; @@ -66,15 +61,11 @@ public class PluginInfo implements Streamable, ToXContent { * * @param name Its name * @param description Its description - * @param site true if it's a site plugin - * @param jvm true if it's a jvm plugin * @param version Version number */ - PluginInfo(String name, String description, boolean site, String version, boolean jvm, String classname, boolean isolated) { + PluginInfo(String name, String description, String version, String classname, boolean isolated) { this.name = name; this.description = description; - this.site = site; - this.jvm = jvm; this.version = version; this.classname = classname; this.isolated = isolated; @@ -101,43 +92,28 @@ public class PluginInfo implements Streamable, ToXContent { throw new IllegalArgumentException("Property [version] is missing for plugin [" + name + "]"); } - boolean jvm = Boolean.parseBoolean(props.getProperty("jvm")); - boolean site = Boolean.parseBoolean(props.getProperty("site")); - if (jvm == false && site == false) { - throw new IllegalArgumentException("Plugin [" + name + "] must be at least a jvm or site plugin"); + String esVersionString = props.getProperty("elasticsearch.version"); + if (esVersionString == null) { + throw new IllegalArgumentException("Property [elasticsearch.version] is missing for plugin [" + name + "]"); } - boolean isolated = true; - String classname = "NA"; - if (jvm) { - String esVersionString = props.getProperty("elasticsearch.version"); - if (esVersionString == null) { - throw new IllegalArgumentException("Property [elasticsearch.version] is missing for jvm plugin [" + name + "]"); - } - Version esVersion = Version.fromString(esVersionString); - if (esVersion.equals(Version.CURRENT) == false) { - throw new IllegalArgumentException("Plugin [" + name + "] is incompatible with Elasticsearch [" + Version.CURRENT.toString() + - "]. Was designed for version [" + esVersionString + "]"); - } - String javaVersionString = props.getProperty("java.version"); - if (javaVersionString == null) { - throw new IllegalArgumentException("Property [java.version] is missing for jvm plugin [" + name + "]"); - } - JarHell.checkVersionFormat(javaVersionString); - JarHell.checkJavaVersion(name, javaVersionString); - isolated = Boolean.parseBoolean(props.getProperty("isolated", "true")); - classname = props.getProperty("classname"); - if (classname == null) { - throw new IllegalArgumentException("Property [classname] is missing for jvm plugin [" + name + "]"); - } + Version esVersion = Version.fromString(esVersionString); + if (esVersion.equals(Version.CURRENT) == false) { + throw new IllegalArgumentException("Plugin [" + name + "] is incompatible with Elasticsearch [" + Version.CURRENT.toString() + + "]. Was designed for version [" + esVersionString + "]"); } - - if (site) { - if (!Files.exists(dir.resolve("_site"))) { - throw new IllegalArgumentException("Plugin [" + name + "] is a site plugin but has no '_site/' directory"); - } + String javaVersionString = props.getProperty("java.version"); + if (javaVersionString == null) { + throw new IllegalArgumentException("Property [java.version] is missing for plugin [" + name + "]"); + } + JarHell.checkVersionFormat(javaVersionString); + JarHell.checkJavaVersion(name, javaVersionString); + boolean isolated = Boolean.parseBoolean(props.getProperty("isolated", "true")); + String classname = props.getProperty("classname"); + if (classname == null) { + throw new IllegalArgumentException("Property [classname] is missing for plugin [" + name + "]"); } - return new PluginInfo(name, description, site, version, jvm, classname, isolated); + return new PluginInfo(name, description, version, classname, isolated); } /** @@ -155,47 +131,20 @@ public class PluginInfo implements Streamable, ToXContent { } /** - * @return true if it's a site plugin - */ - public boolean isSite() { - return site; - } - - /** - * @return true if it's a plugin running in the jvm - */ - public boolean isJvm() { - return jvm; - } - - /** - * @return true if jvm plugin has isolated classloader + * @return true if plugin has isolated classloader */ public boolean isIsolated() { return isolated; } /** - * @return jvm plugin's classname + * @return plugin's classname */ public String getClassname() { return classname; } /** - * We compute the URL for sites: "/_plugin/" + name + "/" - * - * @return relative URL for site plugin - */ - public String getUrl() { - if (site) { - return ("/_plugin/" + name + "/"); - } else { - return null; - } - } - - /** * @return Version number for the plugin */ public String getVersion() { @@ -212,8 +161,6 @@ public class PluginInfo implements Streamable, ToXContent { public void readFrom(StreamInput in) throws IOException { this.name = in.readString(); this.description = in.readString(); - this.site = in.readBoolean(); - this.jvm = in.readBoolean(); this.version = in.readString(); this.classname = in.readString(); this.isolated = in.readBoolean(); @@ -223,8 +170,6 @@ public class PluginInfo implements Streamable, ToXContent { public void writeTo(StreamOutput out) throws IOException { out.writeString(name); out.writeString(description); - out.writeBoolean(site); - out.writeBoolean(jvm); out.writeString(version); out.writeString(classname); out.writeBoolean(isolated); @@ -236,15 +181,8 @@ public class PluginInfo implements Streamable, ToXContent { builder.field(Fields.NAME, name); builder.field(Fields.VERSION, version); builder.field(Fields.DESCRIPTION, description); - if (site) { - builder.field(Fields.URL, getUrl()); - } - builder.field(Fields.JVM, jvm); - if (jvm) { - builder.field(Fields.CLASSNAME, classname); - builder.field(Fields.ISOLATED, isolated); - } - builder.field(Fields.SITE, site); + builder.field(Fields.CLASSNAME, classname); + builder.field(Fields.ISOLATED, isolated); builder.endObject(); return builder; @@ -274,14 +212,9 @@ public class PluginInfo implements Streamable, ToXContent { .append("- Plugin information:\n") .append("Name: ").append(name).append("\n") .append("Description: ").append(description).append("\n") - .append("Site: ").append(site).append("\n") .append("Version: ").append(version).append("\n") - .append("JVM: ").append(jvm).append("\n"); - - if (jvm) { - information.append(" * Classname: ").append(classname).append("\n"); - information.append(" * Isolated: ").append(isolated); - } + .append(" * Classname: ").append(classname).append("\n") + .append(" * Isolated: ").append(isolated); return information.toString(); } diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginManager.java b/core/src/main/java/org/elasticsearch/plugins/PluginManager.java index 7cd50409fb..8e6391ee0c 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginManager.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginManager.java @@ -258,9 +258,7 @@ public class PluginManager { } // check for jar hell before any copying - if (info.isJvm()) { - jarHellCheck(root, info.isIsolated()); - } + jarHellCheck(root, info.isIsolated()); // read optional security policy (extra permissions) // if it exists, confirm or warn the user diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java index 50938a1916..4e61185491 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginsService.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginsService.java @@ -98,7 +98,7 @@ public class PluginsService extends AbstractComponent { // first we load plugins that are on the classpath. this is for tests and transport clients for (Class<? extends Plugin> pluginClass : classpathPlugins) { Plugin plugin = loadPlugin(pluginClass, settings); - PluginInfo pluginInfo = new PluginInfo(plugin.name(), plugin.description(), false, "NA", true, pluginClass.getName(), false); + PluginInfo pluginInfo = new PluginInfo(plugin.name(), plugin.description(), "NA", pluginClass.getName(), false); if (logger.isTraceEnabled()) { logger.trace("plugin loaded from classpath [{}]", pluginInfo); } @@ -136,18 +136,10 @@ public class PluginsService extends AbstractComponent { plugins = Collections.unmodifiableList(pluginsLoaded); - // We need to build a List of jvm and site plugins for checking mandatory plugins - Map<String, Plugin> jvmPlugins = new HashMap<>(); - List<String> sitePlugins = new ArrayList<>(); - + // We need to build a List of plugins for checking mandatory plugins + Set<String> pluginsNames = new HashSet<>(); for (Tuple<PluginInfo, Plugin> tuple : plugins) { - PluginInfo info = tuple.v1(); - if (info.isJvm()) { - jvmPlugins.put(info.getName(), tuple.v2()); - } - if (info.isSite()) { - sitePlugins.add(info.getName()); - } + pluginsNames.add(tuple.v1().getName()); } // Checking expected plugins @@ -155,7 +147,7 @@ public class PluginsService extends AbstractComponent { if (mandatoryPlugins != null) { Set<String> missingPlugins = new HashSet<>(); for (String mandatoryPlugin : mandatoryPlugins) { - if (!jvmPlugins.containsKey(mandatoryPlugin) && !sitePlugins.contains(mandatoryPlugin) && !missingPlugins.contains(mandatoryPlugin)) { + if (!pluginsNames.contains(mandatoryPlugin) && !missingPlugins.contains(mandatoryPlugin)) { missingPlugins.add(mandatoryPlugin); } } @@ -175,10 +167,11 @@ public class PluginsService extends AbstractComponent { jvmPluginNames.add(pluginInfo.getName()); } - logger.info("modules {}, plugins {}, sites {}", moduleNames, jvmPluginNames, sitePlugins); + logger.info("modules {}, plugins {}", moduleNames, jvmPluginNames); Map<Plugin, List<OnModuleReference>> onModuleReferences = new HashMap<>(); - for (Plugin plugin : jvmPlugins.values()) { + for (Tuple<PluginInfo, Plugin> pluginEntry : plugins) { + Plugin plugin = pluginEntry.v2(); List<OnModuleReference> list = new ArrayList<>(); for (Method method : plugin.getClass().getMethods()) { if (!method.getName().equals("onModule")) { @@ -304,9 +297,6 @@ public class PluginsService extends AbstractComponent { continue; // skip over .DS_Store etc } PluginInfo info = PluginInfo.readFromProperties(module); - if (!info.isJvm()) { - throw new IllegalStateException("modules must be jvm plugins: " + info); - } if (!info.isIsolated()) { throw new IllegalStateException("modules must be isolated: " + info); } @@ -353,17 +343,14 @@ public class PluginsService extends AbstractComponent { } List<URL> urls = new ArrayList<>(); - if (info.isJvm()) { - // a jvm plugin: gather urls for jar files - try (DirectoryStream<Path> jarStream = Files.newDirectoryStream(plugin, "*.jar")) { - for (Path jar : jarStream) { - // normalize with toRealPath to get symlinks out of our hair - urls.add(jar.toRealPath().toUri().toURL()); - } + try (DirectoryStream<Path> jarStream = Files.newDirectoryStream(plugin, "*.jar")) { + for (Path jar : jarStream) { + // normalize with toRealPath to get symlinks out of our hair + urls.add(jar.toRealPath().toUri().toURL()); } } final Bundle bundle; - if (info.isJvm() && info.isIsolated() == false) { + if (info.isIsolated() == false) { bundle = bundles.get(0); // purgatory } else { bundle = new Bundle(); @@ -395,15 +382,10 @@ public class PluginsService extends AbstractComponent { // create a child to load the plugins in this bundle ClassLoader loader = URLClassLoader.newInstance(bundle.urls.toArray(new URL[0]), getClass().getClassLoader()); for (PluginInfo pluginInfo : bundle.plugins) { - final Plugin plugin; - if (pluginInfo.isJvm()) { - // reload lucene SPI with any new services from the plugin - reloadLuceneSPI(loader); - Class<? extends Plugin> pluginClass = loadPluginClass(pluginInfo.getClassname(), loader); - plugin = loadPlugin(pluginClass, settings); - } else { - plugin = new SitePlugin(pluginInfo.getName(), pluginInfo.getDescription()); - } + // reload lucene SPI with any new services from the plugin + reloadLuceneSPI(loader); + final Class<? extends Plugin> pluginClass = loadPluginClass(pluginInfo.getClassname(), loader); + final Plugin plugin = loadPlugin(pluginClass, settings); plugins.add(new Tuple<>(pluginInfo, plugin)); } } diff --git a/core/src/main/java/org/elasticsearch/plugins/SitePlugin.java b/core/src/main/java/org/elasticsearch/plugins/SitePlugin.java deleted file mode 100644 index 4c12f2095b..0000000000 --- a/core/src/main/java/org/elasticsearch/plugins/SitePlugin.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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; - -/** A site-only plugin, just serves resources */ -final class SitePlugin extends Plugin { - final String name; - final String description; - - SitePlugin(String name, String description) { - this.name = name; - this.description = description; - } - - @Override - public String name() { - return name; - } - - @Override - public String description() { - return description; - } -} diff --git a/core/src/main/java/org/elasticsearch/rest/action/cat/RestPluginsAction.java b/core/src/main/java/org/elasticsearch/rest/action/cat/RestPluginsAction.java index 34e0522365..1a37ab6da3 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/cat/RestPluginsAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/cat/RestPluginsAction.java @@ -84,8 +84,6 @@ public class RestPluginsAction extends AbstractCatAction { table.addCell("name", "alias:n;desc:node name"); table.addCell("component", "alias:c;desc:component"); table.addCell("version", "alias:v;desc:component version"); - table.addCell("type", "alias:t;desc:type (j for JVM, s for Site)"); - table.addCell("url", "alias:u;desc:url for site plugins"); table.addCell("description", "alias:d;default:false;desc:plugin details"); table.endHeaders(); return table; @@ -104,22 +102,6 @@ public class RestPluginsAction extends AbstractCatAction { table.addCell(node.name()); table.addCell(pluginInfo.getName()); table.addCell(pluginInfo.getVersion()); - String type; - if (pluginInfo.isSite()) { - if (pluginInfo.isJvm()) { - type = "j/s"; - } else { - type = "s"; - } - } else { - if (pluginInfo.isJvm()) { - type = "j"; - } else { - type = ""; - } - } - table.addCell(type); - table.addCell(pluginInfo.getUrl()); table.addCell(pluginInfo.getDescription()); table.endRow(); } diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java index deaff46f27..37a0f4e358 100644 --- a/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java +++ b/core/src/test/java/org/elasticsearch/plugins/PluginInfoTests.java @@ -40,17 +40,13 @@ public class PluginInfoTests extends ESTestCase { "version", "1.0", "elasticsearch.version", Version.CURRENT.toString(), "java.version", System.getProperty("java.specification.version"), - "jvm", "true", "classname", "FakePlugin"); PluginInfo info = PluginInfo.readFromProperties(pluginDir); assertEquals("my_plugin", info.getName()); assertEquals("fake desc", info.getDescription()); assertEquals("1.0", info.getVersion()); assertEquals("FakePlugin", info.getClassname()); - assertTrue(info.isJvm()); assertTrue(info.isIsolated()); - assertFalse(info.isSite()); - assertNull(info.getUrl()); } public void testReadFromPropertiesNameMissing() throws Exception { @@ -94,27 +90,12 @@ public class PluginInfoTests extends ESTestCase { } } - public void testReadFromPropertiesJvmAndSiteMissing() throws Exception { - Path pluginDir = createTempDir().resolve("fake-plugin"); - PluginTestUtil.writeProperties(pluginDir, - "description", "fake desc", - "version", "1.0", - "name", "my_plugin"); - try { - PluginInfo.readFromProperties(pluginDir); - fail("expected jvm or site exception"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("must be at least a jvm or site plugin")); - } - } - public void testReadFromPropertiesElasticsearchVersionMissing() throws Exception { Path pluginDir = createTempDir().resolve("fake-plugin"); PluginTestUtil.writeProperties(pluginDir, "description", "fake desc", "name", "my_plugin", - "version", "1.0", - "jvm", "true"); + "version", "1.0"); try { PluginInfo.readFromProperties(pluginDir); fail("expected missing elasticsearch version exception"); @@ -129,8 +110,7 @@ public class PluginInfoTests extends ESTestCase { "description", "fake desc", "name", "my_plugin", "elasticsearch.version", Version.CURRENT.toString(), - "version", "1.0", - "jvm", "true"); + "version", "1.0"); try { PluginInfo.readFromProperties(pluginDir); fail("expected missing java version exception"); @@ -148,8 +128,7 @@ public class PluginInfoTests extends ESTestCase { "elasticsearch.version", Version.CURRENT.toString(), "java.version", "1000000.0", "classname", "FakePlugin", - "version", "1.0", - "jvm", "true"); + "version", "1.0"); try { PluginInfo.readFromProperties(pluginDir); fail("expected incompatible java version exception"); @@ -167,8 +146,7 @@ public class PluginInfoTests extends ESTestCase { "elasticsearch.version", Version.CURRENT.toString(), "java.version", "1.7.0_80", "classname", "FakePlugin", - "version", "1.0", - "jvm", "true"); + "version", "1.0"); try { PluginInfo.readFromProperties(pluginDir); fail("expected bad java version format exception"); @@ -182,7 +160,6 @@ public class PluginInfoTests extends ESTestCase { PluginTestUtil.writeProperties(pluginDir, "description", "fake desc", "version", "1.0", - "jvm", "true", "name", "my_plugin", "elasticsearch.version", "bogus"); try { @@ -199,7 +176,6 @@ public class PluginInfoTests extends ESTestCase { "description", "fake desc", "name", "my_plugin", "version", "1.0", - "jvm", "true", "elasticsearch.version", Version.V_1_7_0.toString()); try { PluginInfo.readFromProperties(pluginDir); @@ -216,8 +192,7 @@ public class PluginInfoTests extends ESTestCase { "name", "my_plugin", "version", "1.0", "elasticsearch.version", Version.CURRENT.toString(), - "java.version", System.getProperty("java.specification.version"), - "jvm", "true"); + "java.version", System.getProperty("java.specification.version")); try { PluginInfo.readFromProperties(pluginDir); fail("expected old elasticsearch version exception"); @@ -226,42 +201,13 @@ public class PluginInfoTests extends ESTestCase { } } - public void testReadFromPropertiesSitePlugin() throws Exception { - Path pluginDir = createTempDir().resolve("fake-plugin"); - Files.createDirectories(pluginDir.resolve("_site")); - PluginTestUtil.writeProperties(pluginDir, - "description", "fake desc", - "name", "my_plugin", - "version", "1.0", - "site", "true"); - PluginInfo info = PluginInfo.readFromProperties(pluginDir); - assertTrue(info.isSite()); - assertFalse(info.isJvm()); - assertEquals("NA", info.getClassname()); - } - - public void testReadFromPropertiesSitePluginWithoutSite() throws Exception { - Path pluginDir = createTempDir().resolve("fake-plugin"); - PluginTestUtil.writeProperties(pluginDir, - "description", "fake desc", - "name", "my_plugin", - "version", "1.0", - "site", "true"); - try { - PluginInfo.readFromProperties(pluginDir); - fail("didn't get expected exception"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("site plugin but has no '_site")); - } - } - public void testPluginListSorted() { PluginsAndModules pluginsInfo = new PluginsAndModules(); - pluginsInfo.addPlugin(new PluginInfo("c", "foo", true, "dummy", true, "dummyclass", true)); - pluginsInfo.addPlugin(new PluginInfo("b", "foo", true, "dummy", true, "dummyclass", true)); - pluginsInfo.addPlugin(new PluginInfo("e", "foo", true, "dummy", true, "dummyclass", true)); - pluginsInfo.addPlugin(new PluginInfo("a", "foo", true, "dummy", true, "dummyclass", true)); - pluginsInfo.addPlugin(new PluginInfo("d", "foo", true, "dummy", true, "dummyclass", true)); + pluginsInfo.addPlugin(new PluginInfo("c", "foo", "dummy", "dummyclass", true)); + pluginsInfo.addPlugin(new PluginInfo("b", "foo", "dummy", "dummyclass", true)); + pluginsInfo.addPlugin(new PluginInfo("e", "foo", "dummy", "dummyclass", true)); + pluginsInfo.addPlugin(new PluginInfo("a", "foo", "dummy", "dummyclass", true)); + pluginsInfo.addPlugin(new PluginInfo("d", "foo", "dummy", "dummyclass", true)); final List<PluginInfo> infos = pluginsInfo.getPluginInfos(); List<String> names = infos.stream().map((input) -> input.getName()).collect(Collectors.toList()); diff --git a/core/src/test/java/org/elasticsearch/plugins/SitePluginIT.java b/core/src/test/java/org/elasticsearch/plugins/SitePluginIT.java deleted file mode 100644 index e2df2518f1..0000000000 --- a/core/src/test/java/org/elasticsearch/plugins/SitePluginIT.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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 org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.test.ESIntegTestCase.ClusterScope; -import org.elasticsearch.test.ESIntegTestCase.Scope; -import org.elasticsearch.test.rest.client.http.HttpRequestBuilder; -import org.elasticsearch.test.rest.client.http.HttpResponse; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import static org.elasticsearch.common.settings.Settings.settingsBuilder; -import static org.elasticsearch.rest.RestStatus.FORBIDDEN; -import static org.elasticsearch.rest.RestStatus.MOVED_PERMANENTLY; -import static org.elasticsearch.rest.RestStatus.NOT_FOUND; -import static org.elasticsearch.rest.RestStatus.OK; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasStatus; -import static org.hamcrest.Matchers.containsString; - -/** - * We want to test site plugins - */ -@ClusterScope(scope = Scope.SUITE, numDataNodes = 1) -public class SitePluginIT extends ESIntegTestCase { - @Override - protected Settings nodeSettings(int nodeOrdinal) { - Path pluginDir = getDataPath("/org/elasticsearch/test_plugins"); - return settingsBuilder() - .put(super.nodeSettings(nodeOrdinal)) - .put("path.plugins", pluginDir.toAbsolutePath()) - .put("force.http.enabled", true) - .build(); - } - - @Override - public HttpRequestBuilder httpClient() { - RequestConfig.Builder builder = RequestConfig.custom().setRedirectsEnabled(false); - CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(builder.build()).build(); - return new HttpRequestBuilder(httpClient).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class)); - } - - public void testRedirectSitePlugin() throws Exception { - // We use an HTTP Client to test redirection - HttpResponse response = httpClient().method("GET").path("/_plugin/dummy").execute(); - assertThat(response, hasStatus(MOVED_PERMANENTLY)); - assertThat(response.getBody(), containsString("/_plugin/dummy/")); - - // We test the real URL - response = httpClient().method("GET").path("/_plugin/dummy/").execute(); - assertThat(response, hasStatus(OK)); - assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>")); - } - - /** - * Test direct access to an existing file (index.html) - */ - public void testAnyPage() throws Exception { - HttpResponse response = httpClient().path("/_plugin/dummy/index.html").execute(); - assertThat(response, hasStatus(OK)); - assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>")); - } - - /** - * Test normalizing of path - */ - public void testThatPathsAreNormalized() throws Exception { - // more info: https://www.owasp.org/index.php/Path_Traversal - List<String> notFoundUris = new ArrayList<>(); - notFoundUris.add("/_plugin/dummy/../../../../../log4j.properties"); - notFoundUris.add("/_plugin/dummy/../../../../../%00log4j.properties"); - notFoundUris.add("/_plugin/dummy/..%c0%af..%c0%af..%c0%af..%c0%af..%c0%aflog4j.properties"); - notFoundUris.add("/_plugin/dummy/%2E%2E/%2E%2E/%2E%2E/%2E%2E/index.html"); - notFoundUris.add("/_plugin/dummy/%2e%2e/%2e%2e/%2e%2e/%2e%2e/index.html"); - notFoundUris.add("/_plugin/dummy/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2findex.html"); - notFoundUris.add("/_plugin/dummy/%2E%2E/%2E%2E/%2E%2E/%2E%2E/index.html"); - notFoundUris.add("/_plugin/dummy/..%5C..%5C..%5C..%5C..%5Clog4j.properties"); - - for (String uri : notFoundUris) { - HttpResponse response = httpClient().path(uri).execute(); - String message = String.format(Locale.ROOT, "URI [%s] expected to be not found", uri); - assertThat(message, response, hasStatus(NOT_FOUND)); - } - - // using relative path inside of the plugin should work - HttpResponse response = httpClient().path("/_plugin/dummy/dir1/../dir1/../index.html").execute(); - assertThat(response, hasStatus(OK)); - assertThat(response.getBody(), containsString("<title>Dummy Site Plugin</title>")); - } - - /** - * Test case for #4845: https://github.com/elasticsearch/elasticsearch/issues/4845 - * Serving _site plugins do not pick up on index.html for sub directories - */ - public void testWelcomePageInSubDirs() throws Exception { - HttpResponse response = httpClient().path("/_plugin/subdir/dir/").execute(); - assertThat(response, hasStatus(OK)); - assertThat(response.getBody(), containsString("<title>Dummy Site Plugin (subdir)</title>")); - - response = httpClient().path("/_plugin/subdir/dir_without_index/").execute(); - assertThat(response, hasStatus(FORBIDDEN)); - - response = httpClient().path("/_plugin/subdir/dir_without_index/page.html").execute(); - assertThat(response, hasStatus(OK)); - assertThat(response.getBody(), containsString("<title>Dummy Site Plugin (page)</title>")); - } -} diff --git a/core/src/test/java/org/elasticsearch/plugins/SitePluginRelativePathConfigIT.java b/core/src/test/java/org/elasticsearch/plugins/SitePluginRelativePathConfigIT.java deleted file mode 100644 index 1cde90d698..0000000000 --- a/core/src/test/java/org/elasticsearch/plugins/SitePluginRelativePathConfigIT.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.elasticsearch.common.io.PathUtils; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.http.HttpServerTransport; -import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.test.ESIntegTestCase.ClusterScope; -import org.elasticsearch.test.rest.client.http.HttpRequestBuilder; -import org.elasticsearch.test.rest.client.http.HttpResponse; - -import java.nio.file.Path; - -import static org.apache.lucene.util.Constants.WINDOWS; -import static org.elasticsearch.common.settings.Settings.settingsBuilder; -import static org.elasticsearch.rest.RestStatus.OK; -import static org.elasticsearch.test.ESIntegTestCase.Scope.SUITE; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasStatus; - -@ClusterScope(scope = SUITE, numDataNodes = 1) -public class SitePluginRelativePathConfigIT extends ESIntegTestCase { - private final Path root = PathUtils.get(".").toAbsolutePath().getRoot(); - - @Override - protected Settings nodeSettings(int nodeOrdinal) { - String cwdToRoot = getRelativePath(PathUtils.get(".").toAbsolutePath()); - Path pluginDir = PathUtils.get(cwdToRoot, relativizeToRootIfNecessary(getDataPath("/org/elasticsearch/test_plugins")).toString()); - - Path tempDir = createTempDir(); - boolean useRelativeInMiddleOfPath = randomBoolean(); - if (useRelativeInMiddleOfPath) { - pluginDir = PathUtils.get(tempDir.toString(), getRelativePath(tempDir), pluginDir.toString()); - } - - return settingsBuilder() - .put(super.nodeSettings(nodeOrdinal)) - .put("path.plugins", pluginDir) - .put("force.http.enabled", true) - .build(); - } - - public void testThatRelativePathsDontAffectPlugins() throws Exception { - HttpResponse response = httpClient().method("GET").path("/_plugin/dummy/").execute(); - assertThat(response, hasStatus(OK)); - } - - private Path relativizeToRootIfNecessary(Path path) { - if (WINDOWS) { - return root.relativize(path); - } - return path; - } - - private String getRelativePath(Path path) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < path.getNameCount(); i++) { - sb.append(".."); - sb.append(path.getFileSystem().getSeparator()); - } - - return sb.toString(); - } - - @Override - public HttpRequestBuilder httpClient() { - CloseableHttpClient httpClient = HttpClients.createDefault(); - return new HttpRequestBuilder(httpClient).httpTransport(internalCluster().getDataNodeInstance(HttpServerTransport.class)); - } -} |