Move the CLI into its own subproject (#27114)
Projects the depend on the CLI currently depend on core. This should not always be the case. The EnvironmentAwareCommand will remain in :core, but the rest of the CLI components have been moved into their own subproject of :core, :core:cli.
This commit is contained in:
parent
365dda8748
commit
cb3e8f4763
|
@ -231,6 +231,7 @@ subprojects {
|
|||
"org.elasticsearch.gradle:build-tools:${version}": ':build-tools',
|
||||
"org.elasticsearch:rest-api-spec:${version}": ':rest-api-spec',
|
||||
"org.elasticsearch:elasticsearch:${version}": ':core',
|
||||
"org.elasticsearch:elasticsearch-cli:${version}": ':core:cli',
|
||||
"org.elasticsearch.client:elasticsearch-rest-client:${version}": ':client:rest',
|
||||
"org.elasticsearch.client:elasticsearch-rest-client-sniffer:${version}": ':client:sniffer',
|
||||
"org.elasticsearch.client:elasticsearch-rest-high-level-client:${version}": ':client:rest-high-level',
|
||||
|
|
|
@ -58,7 +58,7 @@ dependencies {
|
|||
compile 'org.elasticsearch:securesm:1.1'
|
||||
|
||||
// utilities
|
||||
compile 'net.sf.jopt-simple:jopt-simple:5.0.2'
|
||||
compile "org.elasticsearch:elasticsearch-cli:${version}"
|
||||
compile 'com.carrotsearch:hppc:0.7.1'
|
||||
|
||||
// time handling, remove with java 8 time
|
||||
|
@ -265,6 +265,12 @@ if (JavaVersion.current() > JavaVersion.VERSION_1_8) {
|
|||
dependencyLicenses {
|
||||
mapping from: /lucene-.*/, to: 'lucene'
|
||||
mapping from: /jackson-.*/, to: 'jackson'
|
||||
dependencies = project.configurations.runtime.fileCollection {
|
||||
it.group.startsWith('org.elasticsearch') == false ||
|
||||
// keep the following org.elasticsearch jars in
|
||||
(it.name == 'jna' ||
|
||||
it.name == 'securesm')
|
||||
}
|
||||
}
|
||||
|
||||
if (isEclipse == false || project.path == ":core-tests") {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.elasticsearch.gradle.precommit.PrecommitTasks
|
||||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
|
||||
archivesBaseName = 'elasticsearch-cli'
|
||||
|
||||
dependencies {
|
||||
compile 'net.sf.jopt-simple:jopt-simple:5.0.2'
|
||||
}
|
||||
|
||||
test.enabled = false
|
||||
// Since CLI does not depend on :core, it cannot run the jarHell task
|
||||
jarHell.enabled = false
|
||||
|
||||
forbiddenApisMain {
|
||||
signaturesURLs = [PrecommitTasks.getResource('/forbidden/jdk-signatures.txt')]
|
||||
}
|
|
@ -23,11 +23,6 @@ import joptsimple.OptionException;
|
|||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.logging.LogConfigurator;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
@ -55,12 +50,13 @@ public abstract class Command implements Closeable {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
final SetOnce<Thread> shutdownHookThread = new SetOnce<>();
|
||||
private Thread shutdownHookThread;
|
||||
|
||||
/** Parses options for this command from args and executes it. */
|
||||
public final int main(String[] args, Terminal terminal) throws Exception {
|
||||
if (addShutdownHook()) {
|
||||
shutdownHookThread.set(new Thread(() -> {
|
||||
|
||||
shutdownHookThread = new Thread(() -> {
|
||||
try {
|
||||
this.close();
|
||||
} catch (final IOException e) {
|
||||
|
@ -75,16 +71,11 @@ public abstract class Command implements Closeable {
|
|||
throw new AssertionError(impossible);
|
||||
}
|
||||
}
|
||||
}));
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHookThread.get());
|
||||
});
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHookThread);
|
||||
}
|
||||
|
||||
if (shouldConfigureLoggingWithoutConfig()) {
|
||||
// initialize default for es.logger.level because we will not read the log4j2.properties
|
||||
final String loggerLevel = System.getProperty("es.logger.level", Level.INFO.name());
|
||||
final Settings settings = Settings.builder().put("logger.level", loggerLevel).build();
|
||||
LogConfigurator.configureWithoutConfig(settings);
|
||||
}
|
||||
beforeExecute();
|
||||
|
||||
try {
|
||||
mainWithoutErrorHandling(args, terminal);
|
||||
|
@ -103,14 +94,10 @@ public abstract class Command implements Closeable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Indicate whether or not logging should be configured without reading a log4j2.properties. Most commands should do this because we do
|
||||
* not configure logging for CLI tools. Only commands that configure logging on their own should not do this.
|
||||
*
|
||||
* @return true if logging should be configured without reading a log4j2.properties file
|
||||
* Setup method to be executed before parsing or execution of the command being run. Any exceptions thrown by the
|
||||
* method will not be cleanly caught by the parser.
|
||||
*/
|
||||
protected boolean shouldConfigureLoggingWithoutConfig() {
|
||||
return true;
|
||||
}
|
||||
protected void beforeExecute() {}
|
||||
|
||||
/**
|
||||
* Executes the command, but all errors are thrown.
|
||||
|
@ -166,6 +153,11 @@ public abstract class Command implements Closeable {
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Gets the shutdown hook thread if it exists **/
|
||||
Thread getShutdownHookThread() {
|
||||
return shutdownHookThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.cli;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation to suppress forbidden-apis errors inside a whole class, a method, or a field.
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
|
||||
public @interface SuppressForbidden {
|
||||
String reason();
|
||||
}
|
||||
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package org.elasticsearch.cli;
|
||||
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Console;
|
||||
import java.io.IOException;
|
|
@ -22,7 +22,9 @@ package org.elasticsearch.cli;
|
|||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpec;
|
||||
import joptsimple.util.KeyValuePair;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.logging.LogConfigurator;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.node.InternalSettingsPreparer;
|
||||
|
@ -102,6 +104,26 @@ public abstract class EnvironmentAwareCommand extends Command {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void beforeExecute() {
|
||||
if (shouldConfigureLoggingWithoutConfig()) {
|
||||
// initialize default for es.logger.level because we will not read the log4j2.properties
|
||||
final String loggerLevel = System.getProperty("es.logger.level", Level.INFO.name());
|
||||
final Settings settings = Settings.builder().put("logger.level", loggerLevel).build();
|
||||
LogConfigurator.configureWithoutConfig(settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether or not logging should be configured without reading a log4j2.properties. Most commands should do this because we do
|
||||
* not configure logging for CLI tools. Only commands that configure logging on their own should not do this.
|
||||
*
|
||||
* @return true if logging should be configured without reading a log4j2.properties file
|
||||
*/
|
||||
protected boolean shouldConfigureLoggingWithoutConfig() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Execute the command with the initialized {@link Environment}. */
|
||||
protected abstract void execute(Terminal terminal, OptionSet options, Environment env) throws Exception;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ apply plugin: 'elasticsearch.build'
|
|||
|
||||
dependencies {
|
||||
provided "org.elasticsearch:elasticsearch:${version}"
|
||||
provided "org.elasticsearch:elasticsearch-cli:${version}"
|
||||
testCompile "org.elasticsearch.test:framework:${version}"
|
||||
testCompile 'com.google.jimfs:jimfs:1.1'
|
||||
testCompile 'com.google.guava:guava:18.0'
|
||||
|
|
|
@ -49,11 +49,11 @@ public class EvilCommandTests extends ESTestCase {
|
|||
};
|
||||
final MockTerminal terminal = new MockTerminal();
|
||||
command.main(new String[0], terminal);
|
||||
assertNotNull(command.shutdownHookThread.get());
|
||||
assertNotNull(command.getShutdownHookThread());
|
||||
// successful removal here asserts that the runtime hook was installed in Command#main
|
||||
assertTrue(Runtime.getRuntime().removeShutdownHook(command.shutdownHookThread.get()));
|
||||
command.shutdownHookThread.get().run();
|
||||
command.shutdownHookThread.get().join();
|
||||
assertTrue(Runtime.getRuntime().removeShutdownHook(command.getShutdownHookThread()));
|
||||
command.getShutdownHookThread().run();
|
||||
command.getShutdownHookThread().join();
|
||||
assertTrue(closed.get());
|
||||
final String output = terminal.getOutput();
|
||||
if (shouldThrow) {
|
||||
|
|
|
@ -5,6 +5,7 @@ List projects = [
|
|||
'build-tools',
|
||||
'rest-api-spec',
|
||||
'core',
|
||||
'core:cli',
|
||||
'docs',
|
||||
'client:rest',
|
||||
'client:rest-high-level',
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.elasticsearch.gradle.precommit.PrecommitTasks;
|
|||
dependencies {
|
||||
compile "org.elasticsearch.client:elasticsearch-rest-client:${version}"
|
||||
compile "org.elasticsearch:elasticsearch:${version}"
|
||||
compile "org.elasticsearch:elasticsearch-cli:${version}"
|
||||
compile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${versions.randomizedrunner}"
|
||||
compile "junit:junit:${versions.junit}"
|
||||
compile "org.hamcrest:hamcrest-all:${versions.hamcrest}"
|
||||
|
|
Loading…
Reference in New Issue