diff --git a/.gitignore b/.gitignore index 41a151f160cfa..8b2a7335ade9d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,10 +20,8 @@ nbactions.xml .gradle/ build/ -# maven stuff (to be removed when trunk becomes 4.x) -*-execution-hints.log -target/ -dependency-reduced-pom.xml +# vscode stuff +.vscode/ # testing stuff **/.local* @@ -43,4 +41,3 @@ html_docs # random old stuff that we should look at the necessity of... /tmp/ eclipse-build - diff --git a/build.gradle b/build.gradle index bfbc06d5d0455..196c5fde49c96 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,7 @@ import org.apache.tools.ant.taskdefs.condition.Os import org.elasticsearch.gradle.BuildPlugin +import org.elasticsearch.gradle.LoggedExec import org.elasticsearch.gradle.Version import org.elasticsearch.gradle.VersionCollection import org.elasticsearch.gradle.VersionProperties @@ -30,6 +31,7 @@ import org.gradle.api.tasks.wrapper.Wrapper.DistributionType import org.gradle.util.GradleVersion import org.gradle.util.DistributionLocator +import java.nio.file.Files import java.nio.file.Path import java.security.MessageDigest @@ -463,6 +465,59 @@ gradle.projectsEvaluated { } +static void assertLinesInFile(final Path path, final List expectedLines) { + final List actualLines = Files.readAllLines(path) + int line = 0 + for (final String expectedLine : expectedLines) { + final String actualLine = actualLines.get(line) + if (expectedLine != actualLine) { + throw new GradleException("expected line [${line + 1}] in [${path}] to be [${expectedLine}] but was [${actualLine}]") + } + line++ + } +} + +/* + * Check that all generated JARs have our NOTICE.txt and an appropriate + * LICENSE.txt in them. We configurate this in gradle but we'd like to + * be extra paranoid. + */ +subprojects { project -> + project.tasks.withType(Jar).whenTaskAdded { jarTask -> + final Task extract = project.task("extract${jarTask.name.capitalize()}", type: LoggedExec) { + dependsOn jarTask + ext.destination = project.buildDir.toPath().resolve("jar-extracted/${jarTask.name}") + commandLine "${->new File(rootProject.compilerJavaHome, 'bin/jar')}", + 'xf', "${-> jarTask.outputs.files.singleFile}", 'META-INF/LICENSE.txt', 'META-INF/NOTICE.txt' + workingDir destination + doFirst { + project.delete(destination) + Files.createDirectories(destination) + } + } + + final Task checkNotice = project.task("verify${jarTask.name.capitalize()}Notice") { + dependsOn extract + doLast { + final List noticeLines = Files.readAllLines(project.noticeFile.toPath()) + final Path noticePath = extract.destination.resolve('META-INF/NOTICE.txt') + assertLinesInFile(noticePath, noticeLines) + } + } + project.check.dependsOn checkNotice + + final Task checkLicense = project.task("verify${jarTask.name.capitalize()}License") { + dependsOn extract + doLast { + final List licenseLines = Files.readAllLines(project.licenseFile.toPath()) + final Path licensePath = extract.destination.resolve('META-INF/LICENSE.txt') + assertLinesInFile(licensePath, licenseLines) + } + } + project.check.dependsOn checkLicense + } +} + /* Remove assemble on all qa projects because we don't need to publish * artifacts for them. */ gradle.projectsEvaluated { diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy index ceb4eae863aee..966b5801cc800 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy @@ -567,16 +567,17 @@ class ClusterFormationTasks { /** Adds a task to execute a command to help setup the cluster */ static Task configureExecTask(String name, Project project, Task setup, NodeInfo node, Object[] execArgs) { - return project.tasks.create(name: name, type: LoggedExec, dependsOn: setup) { - workingDir node.cwd + return project.tasks.create(name: name, type: LoggedExec, dependsOn: setup) { Exec exec -> + exec.workingDir node.cwd + exec.environment 'JAVA_HOME', node.getJavaHome() if (Os.isFamily(Os.FAMILY_WINDOWS)) { - executable 'cmd' - args '/C', 'call' + exec.executable 'cmd' + exec.args '/C', 'call' // On Windows the comma character is considered a parameter separator: // argument are wrapped in an ExecArgWrapper that escapes commas - args execArgs.collect { a -> new EscapeCommaWrapper(arg: a) } + exec.args execArgs.collect { a -> new EscapeCommaWrapper(arg: a) } } else { - commandLine execArgs + exec.commandLine execArgs } } } diff --git a/client/rest/build.gradle b/client/rest/build.gradle index 8e0f179634a27..bcb928495c5d2 100644 --- a/client/rest/build.gradle +++ b/client/rest/build.gradle @@ -20,7 +20,6 @@ import org.elasticsearch.gradle.precommit.PrecommitTasks apply plugin: 'elasticsearch.build' -apply plugin: 'ru.vyarus.animalsniffer' apply plugin: 'nebula.maven-base-publish' apply plugin: 'nebula.maven-scm' @@ -52,8 +51,6 @@ dependencies { testCompile "org.hamcrest:hamcrest-all:${versions.hamcrest}" testCompile "org.elasticsearch:securemock:${versions.securemock}" testCompile "org.elasticsearch:mocksocket:${versions.mocksocket}" - testCompile "org.codehaus.mojo:animal-sniffer-annotations:1.15" - signature "org.codehaus.mojo.signature:java17:1.0@signature" } forbiddenApisMain { diff --git a/client/rest/src/test/java/org/elasticsearch/client/RestClientBuilderIntegTests.java b/client/rest/src/test/java/org/elasticsearch/client/RestClientBuilderIntegTests.java index 8142fea6d259b..199b7542e62a2 100644 --- a/client/rest/src/test/java/org/elasticsearch/client/RestClientBuilderIntegTests.java +++ b/client/rest/src/test/java/org/elasticsearch/client/RestClientBuilderIntegTests.java @@ -24,7 +24,6 @@ import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; import org.apache.http.HttpHost; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; import org.elasticsearch.mocksocket.MockHttpServer; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -46,8 +45,6 @@ /** * Integration test to validate the builder builds a client with the correct configuration */ -//animal-sniffer doesn't like our usage of com.sun.net.httpserver.* classes -@IgnoreJRERequirement public class RestClientBuilderIntegTests extends RestClientTestCase { private static HttpsServer httpsServer; @@ -60,8 +57,6 @@ public static void startHttpServer() throws Exception { httpsServer.start(); } - //animal-sniffer doesn't like our usage of com.sun.net.httpserver.* classes - @IgnoreJRERequirement private static class ResponseHandler implements HttpHandler { @Override public void handle(HttpExchange httpExchange) throws IOException { diff --git a/client/rest/src/test/java/org/elasticsearch/client/RestClientMultipleHostsIntegTests.java b/client/rest/src/test/java/org/elasticsearch/client/RestClientMultipleHostsIntegTests.java index da5a960c2e84c..16c192b3977a8 100644 --- a/client/rest/src/test/java/org/elasticsearch/client/RestClientMultipleHostsIntegTests.java +++ b/client/rest/src/test/java/org/elasticsearch/client/RestClientMultipleHostsIntegTests.java @@ -23,7 +23,6 @@ import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import org.apache.http.HttpHost; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; import org.elasticsearch.mocksocket.MockHttpServer; import org.junit.AfterClass; import org.junit.Before; @@ -48,8 +47,6 @@ * Integration test to check interaction between {@link RestClient} and {@link org.apache.http.client.HttpClient}. * Works against real http servers, multiple hosts. Also tests failover by randomly shutting down hosts. */ -//animal-sniffer doesn't like our usage of com.sun.net.httpserver.* classes -@IgnoreJRERequirement public class RestClientMultipleHostsIntegTests extends RestClientTestCase { private static HttpServer[] httpServers; @@ -90,8 +87,6 @@ private static HttpServer createHttpServer() throws Exception { return httpServer; } - //animal-sniffer doesn't like our usage of com.sun.net.httpserver.* classes - @IgnoreJRERequirement private static class ResponseHandler implements HttpHandler { private final int statusCode; diff --git a/client/rest/src/test/java/org/elasticsearch/client/RestClientSingleHostIntegTests.java b/client/rest/src/test/java/org/elasticsearch/client/RestClientSingleHostIntegTests.java index 59aa2baab9672..dd23dbe454fa4 100644 --- a/client/rest/src/test/java/org/elasticsearch/client/RestClientSingleHostIntegTests.java +++ b/client/rest/src/test/java/org/elasticsearch/client/RestClientSingleHostIntegTests.java @@ -33,7 +33,6 @@ import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; import org.apache.http.util.EntityUtils; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; import org.elasticsearch.mocksocket.MockHttpServer; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -64,8 +63,6 @@ * Integration test to check interaction between {@link RestClient} and {@link org.apache.http.client.HttpClient}. * Works against a real http server, one single host. */ -//animal-sniffer doesn't like our usage of com.sun.net.httpserver.* classes -@IgnoreJRERequirement public class RestClientSingleHostIntegTests extends RestClientTestCase { private static HttpServer httpServer; @@ -91,8 +88,6 @@ private static HttpServer createHttpServer() throws Exception { return httpServer; } - //animal-sniffer doesn't like our usage of com.sun.net.httpserver.* classes - @IgnoreJRERequirement private static class ResponseHandler implements HttpHandler { private final int statusCode; diff --git a/distribution/archives/build.gradle b/distribution/archives/build.gradle index af9d5f362451f..f2fc297a9e4c8 100644 --- a/distribution/archives/build.gradle +++ b/distribution/archives/build.gradle @@ -201,8 +201,7 @@ subprojects { } final List licenseLines = Files.readAllLines(rootDir.toPath().resolve("licenses/" + licenseFilename)) final Path licensePath = archiveExtractionDir.toPath().resolve("elasticsearch-${VersionProperties.elasticsearch}/LICENSE.txt") - final List actualLines = Files.readAllLines(licensePath) - assertLinesInFile(licensePath, actualLines, licenseLines) + assertLinesInFile(licensePath, licenseLines) } } check.dependsOn checkLicense @@ -213,8 +212,7 @@ subprojects { doLast { final List noticeLines = Arrays.asList("Elasticsearch", "Copyright 2009-2018 Elasticsearch") final Path noticePath = archiveExtractionDir.toPath().resolve("elasticsearch-${VersionProperties.elasticsearch}/NOTICE.txt") - final List actualLines = Files.readAllLines(noticePath) - assertLinesInFile(noticePath, actualLines, noticeLines) + assertLinesInFile(noticePath, noticeLines) } } check.dependsOn checkNotice @@ -304,4 +302,3 @@ configure(subprojects.findAll { it.name.contains('zip') }) { } } } - diff --git a/distribution/build.gradle b/distribution/build.gradle index 23d1d7b66ad43..c1ab5b76148b3 100644 --- a/distribution/build.gradle +++ b/distribution/build.gradle @@ -460,14 +460,3 @@ subprojects { return result } } - -static void assertLinesInFile(final Path path, final List actualLines, final List expectedLines) { - int line = 0 - for (final String expectedLine : expectedLines) { - final String actualLine = actualLines.get(line) - if (expectedLine != actualLine) { - throw new GradleException("expected line [${line + 1}] in [${path}] to be [${expectedLine}] but was [${actualLine}]") - } - line++ - } -} diff --git a/distribution/packages/build.gradle b/distribution/packages/build.gradle index 863f6a3613d73..6e5b69a66f7df 100644 --- a/distribution/packages/build.gradle +++ b/distribution/packages/build.gradle @@ -415,8 +415,7 @@ subprojects { "License: " + expectedLicense) final List licenseLines = Files.readAllLines(rootDir.toPath().resolve("licenses/" + licenseFilename)) final List expectedLines = header + licenseLines.collect { " " + it } - final List actualLines = Files.readAllLines(copyrightPath) - assertLinesInFile(copyrightPath, actualLines, expectedLines) + assertLinesInFile(copyrightPath, expectedLines) } } } else { @@ -432,8 +431,7 @@ subprojects { } final List licenseLines = Files.readAllLines(rootDir.toPath().resolve("licenses/" + licenseFilename)) final Path licensePath = packageExtractionDir.toPath().resolve("usr/share/elasticsearch/LICENSE.txt") - final List actualLines = Files.readAllLines(licensePath) - assertLinesInFile(licensePath, actualLines, licenseLines) + assertLinesInFile(licensePath, licenseLines) } } } @@ -444,8 +442,7 @@ subprojects { doLast { final List noticeLines = Arrays.asList("Elasticsearch", "Copyright 2009-2018 Elasticsearch") final Path noticePath = packageExtractionDir.toPath().resolve("usr/share/elasticsearch/NOTICE.txt") - final List actualLines = Files.readAllLines(noticePath) - assertLinesInFile(noticePath, actualLines, noticeLines) + assertLinesInFile(noticePath, noticeLines) } } check.dependsOn checkNotice diff --git a/docs/painless/painless-comments.asciidoc b/docs/painless/painless-comments.asciidoc index d1d2e47a143a6..588e464d97f78 100644 --- a/docs/painless/painless-comments.asciidoc +++ b/docs/painless/painless-comments.asciidoc @@ -1,12 +1,12 @@ [[painless-comments]] === Comments -Painless supports both single-line and multi-line comments. Comments can be -included anywhere within a script. Use the `//` token anywhere on a line to -specify a single-line comment. All characters from the `//` token to the end -of the line are ignored. Use an opening `/*` token and a closing `*/` token -to specify a multi-line comment. Multi-line comments can start anywhere on a -line, and all characters in between the `/*` token and `*/` token are ignored. +Use the `//` token anywhere on a line to specify a single-line comment. All +characters from the `//` token to the end of the line are ignored. Use an +opening `/*` token and a closing `*/` token to specify a multi-line comment. +Multi-line comments can start anywhere on a line, and all characters in between +the `/*` token and `*/` token are ignored. Comments can be included anywhere +within a script. *Grammar* [source,ANTLR4] @@ -17,17 +17,17 @@ MULTI_LINE_COMMENT: '/*' .*? '*/'; *Examples* -Single-line comments. - +* Single-line comments. ++ [source,Painless] ---- // single-line comment int value; // single-line comment ---- - -Multi-line comments. - ++ +* Multi-line comments. ++ [source,Painless] ---- /* multi- diff --git a/docs/painless/painless-identifiers.asciidoc b/docs/painless/painless-identifiers.asciidoc new file mode 100644 index 0000000000000..17073e3d4c415 --- /dev/null +++ b/docs/painless/painless-identifiers.asciidoc @@ -0,0 +1,29 @@ +[[painless-identifiers]] +=== Identifiers + +Specify identifiers to <>, <>, and +<> variables, <>, and +<>. <> and +<> cannot be used as identifiers. + +*Grammar* +[source,ANTLR4] +---- +ID: [_a-zA-Z] [_a-zA-Z-0-9]*; +---- + +*Examples* + +* Variations of identifiers. ++ +[source,Painless] +---- +a +Z +id +list +list0 +MAP25 +_map25 +Map_25 +---- diff --git a/docs/painless/painless-keywords.asciidoc b/docs/painless/painless-keywords.asciidoc index 99b5b4060d24e..cb3bafbd20f13 100644 --- a/docs/painless/painless-keywords.asciidoc +++ b/docs/painless/painless-keywords.asciidoc @@ -2,8 +2,8 @@ === Keywords The keywords in the table below are reserved for built-in language -features. These keywords cannot be used as <> or -<>. +features. These keywords cannot be used as +<> or <>. [cols="^1,^1,^1,^1,^1"] |==== diff --git a/docs/painless/painless-lang-spec.asciidoc b/docs/painless/painless-lang-spec.asciidoc index b324ad301141c..ba6595000ae2f 100644 --- a/docs/painless/painless-lang-spec.asciidoc +++ b/docs/painless/painless-lang-spec.asciidoc @@ -23,6 +23,8 @@ include::painless-keywords.asciidoc[] include::painless-literals.asciidoc[] +include::painless-identifiers.asciidoc[] + include::painless-variables.asciidoc[] include::painless-types.asciidoc[] diff --git a/docs/painless/painless-literals.asciidoc b/docs/painless/painless-literals.asciidoc index 3f91c9299c0ad..441cb264f1e15 100644 --- a/docs/painless/painless-literals.asciidoc +++ b/docs/painless/painless-literals.asciidoc @@ -24,18 +24,18 @@ HEX: '-'? '0' [xX] [0-9a-fA-F]+ [lL]?; *Examples* -Integer literals. - +* Integer literals. ++ [source,Painless] ---- -0 <1> -0D <2> -1234L <3> --90f <4> --022 <5> -0xF2A <6> +<1> 0 +<2> 0D +<3> 1234L +<4> -90f +<5> -022 +<6> 0xF2A ---- - ++ <1> `int 0` <2> `double 0.0` <3> `long 1234` @@ -61,17 +61,17 @@ EXPONENT: ( [eE] [+\-]? [0-9]+ ); *Examples* -Floating point literals. - +* Floating point literals. ++ [source,Painless] ---- -0.0 <1> -1E6 <2> -0.977777 <3> --126.34 <4> -89.9F <5> +<1> 0.0 +<2> 1E6 +<3> 0.977777 +<4> -126.34 +<5> 89.9F ---- - ++ <1> `double 0.0` <2> `double 1000000.0` in exponent notation <3> `double 0.977777` @@ -81,12 +81,11 @@ Floating point literals. [[strings]] ==== Strings -Use string literals to specify string values of the -<> with either single-quotes or double-quotes. -Use a `\"` token to include a double-quote as part of a double-quoted string -literal. Use a `\'` token to include a single-quote as part of a single-quoted -string literal. Use a `\\` token to include a backslash as part of any string -literal. +Use string literals to specify <> values with +either single-quotes or double-quotes. Use a `\"` token to include a +double-quote as part of a double-quoted string literal. Use a `\'` token to +include a single-quote as part of a single-quoted string literal. Use a `\\` +token to include a backslash as part of any string literal. *Grammar* [source,ANTLR4] @@ -97,22 +96,22 @@ STRING: ( '"' ( '\\"' | '\\\\' | ~[\\"] )*? '"' ) *Examples* -String literals using single-quotes. - +* String literals using single-quotes. ++ [source,Painless] ---- 'single-quoted string literal' -'\'single-quoted string with escaped single-quotes\' and backslash \\' -'single-quoted string with non-escaped "double-quotes"' +'\'single-quoted with escaped single-quotes\' and backslash \\' +'single-quoted with non-escaped "double-quotes"' ---- - -String literals using double-quotes. - ++ +* String literals using double-quotes. ++ [source,Painless] ---- "double-quoted string literal" -"\"double-quoted string with escaped double-quotes\" and backslash: \\" -"double-quoted string with non-escaped 'single-quotes'" +"\"double-quoted with escaped double-quotes\" and backslash: \\" +"double-quoted with non-escaped 'single-quotes'" ---- [[characters]] @@ -126,16 +125,16 @@ or an error will occur. *Examples* -Casting string literals into <> values. - +* Casting string literals into <> values. ++ [source,Painless] ---- (char)"C" (char)'c' ---- - -Casting a <> value into a <> value. - ++ +* Casting a <> value into a <> value. ++ [source,Painless] ---- String s = "s"; diff --git a/docs/painless/painless-operators.asciidoc b/docs/painless/painless-operators.asciidoc index b2dab60796d55..a9e96bbf22509 100644 --- a/docs/painless/painless-operators.asciidoc +++ b/docs/painless/painless-operators.asciidoc @@ -704,6 +704,7 @@ e = ~d; // sets e the negation of d The cast operator can be used to explicitly convert one type to another. See casting [MARK] for more information. +[[constructor-call]] ==== Constructor Call A constructor call is a special type of method call [MARK] used to allocate a reference type instance using the new operator. The format is the new operator followed by a type, an opening parenthesis, arguments if any, and a closing parenthesis. Arguments are a series of zero-to-many expressions delimited by commas. Auto-boxing and auto-unboxing will be applied automatically for arguments passed into a constructor call. See boxing and unboxing [MARK] for more information on this topic. Constructor argument types can always be resolved at run-time; if appropriate type conversions (casting) cannot be applied an error will occur. Once a reference type instance has been allocated, its members may be used as part of other expressions. diff --git a/docs/painless/painless-variables.asciidoc b/docs/painless/painless-variables.asciidoc index 08725b328a3c2..9756676a08b5b 100644 --- a/docs/painless/painless-variables.asciidoc +++ b/docs/painless/painless-variables.asciidoc @@ -1,122 +1,130 @@ [[painless-variables]] === Variables -Variables in Painless must be declared and can be -statically or <>. - -[[identifiers]] -==== Identifiers - -Specify variable identifiers using the following grammar. Variable identifiers -must start with a letter or underscore. You cannot use -<> or <> as identifiers. - -*Grammar:* -[source,ANTLR4] ----- -ID: [_a-zA-Z] [_a-zA-Z-0-9]*; ----- - -*Examples:* -[source,Java] ----- -a -Z -id -list -list0 -MAP25 -_map25 ----- +<> variables to <> values for +<> in expressions. Specify variables as a +<>, <>, or +<>. Variable operations follow the structure of a +standard JVM in relation to instruction execution and memory usage. [[declaration]] ==== Declaration -Variables must be declared before you use them. The format is `type-name -identifier-name`. To declare multiple variables of the same type, specify a -comma-separated list of identifier names. You can immediately assign a value to -a variable when you declare it. +Declare variables before use with the format of <> +<>. Specify a comma-separated list of +<> following the <> +to declare multiple variables in a single statement. Use an +<> statement combined with a declaration statement to +immediately assign a value to a variable. Variables not immediately assigned a +value will have a default value assigned implicitly based on the +<>. -*Grammar:* +*Grammar* [source,ANTLR4] ---- +declaration : type ID assignment? (',' ID assignment?)*; type: ID ('[' ']')*; -declaration : type ID (',' ID)*; +assignment: '=' expression; ---- -*Examples:* -[source,Java] +*Examples* + +* Different variations of variable declaration. ++ +[source,Painless] ---- -int x; // Declare a variable with type int and id x -List y; // Declare a variable with type List and id y -int x, y, z; // Declare variables with type int and ids x, y, and z -def[] d; // Declare the variable d with type def[] -int i = 10; // Declare the int variable i and set it to the int literal 10 +<1> int x; +<2> List y; +<3> int x, y, z; +<4> def[] d; +<5> int i = 10; ---- ++ +<1> declare a variable of type `int` and identifier `x` +<2> declare a variable of type `List` and identifier `y` +<3> declare three variables of type `int` and identifiers `x`, `y`, `z` +<4> declare a variable of type `def[]` and identifier `d` +<5> declare a variable of type `int` and identifier `i`; + assign the integer literal `10` to `i` -[[variable-assignment]] +[[assignment]] ==== Assignment -Use the equals operator (`=`) to assign a value to a variable. The format is -`identifier-name = value`. Any value expression can be assigned to any variable -as long as the types match or the expression's type can be implicitly cast to -the variable's type. An error occurs if the types do not match. +Use the `equals` operator (`=`) to assign a value to a variable. Any expression +that produces a value can be assigned to any variable as long as the +<> are the same or the resultant +<> can be implicitly <> to +the variable <>. Otherwise, an error will occur. +<> values are shallow-copied when assigned. -*Grammar:* +*Grammar* [source,ANTLR4] ---- assignment: ID '=' expression ---- - -*Examples:* - -Assigning a literal of the appropriate type directly to a declared variable. - -[source,Java] ----- -int i;   // Declare an int i -i = 10;  // Set the int i to the int literal 10 ----- - -Immediately assigning a value when declaring a variable. - -[source,Java] ----- -int i = 10; // Declare the int variable i and set it the int literal 1 -double j = 2.0; // Declare the double variable j and set it to the double - // literal 2.0 ----- - -Assigning a variable of one primitive type to another variable of the same -type. - -[source,Java] ----- -int i = 10; // Declare the int variable i and set it to the int literal 10 -int j = i;  // Declare the int variable j and set it to the int variable i ----- - -Assigning a reference type to a new heap allocation with the `new` operator. - -[source,Java] ----- -ArrayList l = new ArrayList();  // Declare an ArrayList variable l and set it - // to a newly allocated ArrayList -Map m = new HashMap(); // Declare a Map variable m and set it - // to a newly allocated HashMap ----- - -Assigning a variable of one reference type to another variable of the same type. - -[source,Java] ----- -List l = new ArrayList(); // Declare List variable l and set it a newly - // allocated ArrayList -List k = l;  // Declare List variable k and set it to the - // value of the List variable l -List m;                   // Declare List variable m and set it the - // default value null -m = k;                    // Set the value of List variable m to the value - // of List variable k ----- +*Examples* + +* Variable assignment with an <>. ++ +[source,Painless] +---- +<1> int i; +<2> i = 10; +---- ++ +<1> declare `int i` +<2> assign `10` to `i` ++ +* <> combined with immediate variable assignment. ++ +[source,Painless] +---- +<1> int i = 10; +<2> double j = 2.0; +---- ++ +<1> declare `int i`; assign `10` to `i` +<2> declare `double j`; assign `2.0` to `j` ++ +* Assignment of one variable to another using +<>. ++ +[source,Painless] +---- +<1> int i = 10; +<2> int j = i; +---- ++ +<1> declare `int i`; assign `10` to `i` +<2> declare `int j`; assign `j` to `i` ++ +* Assignment with <> using the +<>. ++ +[source,Painless] +---- +<1> ArrayList l = new ArrayList(); +<2> Map m = new HashMap(); +---- ++ +<1> declare `ArrayList l`; assign a newly-allocated `Arraylist` to `l` +<2> declare `Map m`; assign a newly-allocated `HashMap` to `m` + with an implicit cast to `Map` ++ +* Assignment of one variable to another using +<>. ++ +[source,Painless] +---- +<1> List l = new ArrayList(); +<2> List k = l; +<3> List m; +<4> m = k; +---- ++ +<1> declare `List l`; assign a newly-allocated `Arraylist` to `l` + with an implicit cast to `List` +<2> declare `List k`; assign a shallow-copy of `l` to `k` +<3> declare `List m`; +<4> assign a shallow-copy of `k` to `m` diff --git a/docs/plugins/analysis.asciidoc b/docs/plugins/analysis.asciidoc index 3c3df021de5cb..c09c48640ea3d 100644 --- a/docs/plugins/analysis.asciidoc +++ b/docs/plugins/analysis.asciidoc @@ -53,6 +53,7 @@ A number of analysis plugins have been contributed by our community: * https://github.com/duydo/elasticsearch-analysis-vietnamese[Vietnamese Analysis Plugin] (by Duy Do) * https://github.com/ofir123/elasticsearch-network-analysis[Network Addresses Analysis Plugin] (by Ofir123) * https://github.com/medcl/elasticsearch-analysis-string2int[String2Integer Analysis Plugin] (by Medcl) +* https://github.com/ZarHenry96/elasticsearch-dandelion-plugin[Dandelion Analysis Plugin] (by ZarHenry96) include::analysis-icu.asciidoc[] diff --git a/docs/reference/aggregations/metrics/cardinality-aggregation.asciidoc b/docs/reference/aggregations/metrics/cardinality-aggregation.asciidoc index 938d42a70abd5..d458d377a6077 100644 --- a/docs/reference/aggregations/metrics/cardinality-aggregation.asciidoc +++ b/docs/reference/aggregations/metrics/cardinality-aggregation.asciidoc @@ -5,8 +5,7 @@ A `single-value` metrics aggregation that calculates an approximate count of distinct values. Values can be extracted either from specific fields in the document or generated by a script. -Assume you are indexing books and would like to count the unique authors that -match a query: +Assume you are indexing store sales and would like to count the unique number of sold products that match a query: [source,js] -------------------------------------------------- diff --git a/docs/reference/mapping/types/token-count.asciidoc b/docs/reference/mapping/types/token-count.asciidoc index da4220f4bb401..6f3295fab5ebb 100644 --- a/docs/reference/mapping/types/token-count.asciidoc +++ b/docs/reference/mapping/types/token-count.asciidoc @@ -81,7 +81,7 @@ Defaults to `true`. <>:: - Should the field be searchable? Accepts `not_analyzed` (default) and `no`. + Should the field be searchable? Accepts `true` (default) and `false`. <>:: diff --git a/docs/reference/migration/index.asciidoc b/docs/reference/migration/index.asciidoc index b60dff09974b0..6c654a4564531 100644 --- a/docs/reference/migration/index.asciidoc +++ b/docs/reference/migration/index.asciidoc @@ -26,3 +26,5 @@ include::migrate_6_1.asciidoc[] include::migrate_6_2.asciidoc[] include::migrate_6_3.asciidoc[] + +include::migrate_6_4.asciidoc[] diff --git a/docs/reference/migration/migrate_6_4.asciidoc b/docs/reference/migration/migrate_6_4.asciidoc new file mode 100644 index 0000000000000..a761509597fd2 --- /dev/null +++ b/docs/reference/migration/migrate_6_4.asciidoc @@ -0,0 +1,12 @@ +[[breaking-changes-6.4]] +== Breaking changes in 6.4 + +[[breaking_64_api_changes]] +=== API changes + +==== Field capabilities request format + +In the past, `fields` could be provided either as a parameter, or as part of the request +body. Specifying `fields` in the request body is now deprecated, and instead they should +always be supplied through a request parameter. In 7.0.0, the field capabilities API will +not accept `fields` supplied in the request body. diff --git a/docs/reference/modules/transport.asciidoc b/docs/reference/modules/transport.asciidoc index 50c35a4a73634..b7a65d98592cc 100644 --- a/docs/reference/modules/transport.asciidoc +++ b/docs/reference/modules/transport.asciidoc @@ -41,7 +41,7 @@ addressable from the outside. Defaults to the actual port assigned via |`transport.tcp.connect_timeout` |The socket connect timeout setting (in time setting format). Defaults to `30s`. -|`transport.tcp.compress` |Set to `true` to enable compression (LZF) +|`transport.tcp.compress` |Set to `true` to enable compression (`DEFLATE`) between all nodes. Defaults to `false`. |`transport.ping_schedule` | Schedule a regular ping message to ensure that connections are kept alive. Defaults to `5s` in the transport client and `-1` (disabled) elsewhere. diff --git a/docs/reference/search/field-caps.asciidoc b/docs/reference/search/field-caps.asciidoc index 8329d96131dff..6cb483e7a256e 100644 --- a/docs/reference/search/field-caps.asciidoc +++ b/docs/reference/search/field-caps.asciidoc @@ -20,7 +20,7 @@ GET twitter/_field_caps?fields=rating // CONSOLE // TEST[setup:twitter] -Alternatively the `fields` option can also be defined in the request body: +Alternatively the `fields` option can also be defined in the request body. deprecated[6.4.0, Please use a request parameter instead.] [source,js] -------------------------------------------------- @@ -30,6 +30,7 @@ POST _field_caps } -------------------------------------------------- // CONSOLE +// TEST[warning:Specifying a request body is deprecated -- the [fields] request parameter should be used instead.] This is equivalent to the previous request. diff --git a/qa/vagrant/src/test/resources/packaging/tests/30_deb_package.bats b/qa/vagrant/src/test/resources/packaging/tests/30_deb_package.bats index e4a56ccb14151..59aaa3e8a072f 100644 --- a/qa/vagrant/src/test/resources/packaging/tests/30_deb_package.bats +++ b/qa/vagrant/src/test/resources/packaging/tests/30_deb_package.bats @@ -191,8 +191,8 @@ setup() { assert_file_not_exist "/usr/share/elasticsearch" - assert_file_not_exist "/usr/share/doc/elasticsearch" - assert_file_not_exist "/usr/share/doc/elasticsearch/copyright" + assert_file_not_exist "/usr/share/doc/elasticsearch-oss" + assert_file_not_exist "/usr/share/doc/elasticsearch-oss/copyright" } @test "[DEB] package has been completly removed" { diff --git a/qa/vagrant/src/test/resources/packaging/utils/packages.bash b/qa/vagrant/src/test/resources/packaging/utils/packages.bash index cd8b25fad7940..a214cd6940f63 100644 --- a/qa/vagrant/src/test/resources/packaging/utils/packages.bash +++ b/qa/vagrant/src/test/resources/packaging/utils/packages.bash @@ -116,9 +116,10 @@ verify_package_installation() { # Env file assert_file "/etc/default/elasticsearch" f root elasticsearch 660 - # Doc files - assert_file "/usr/share/doc/elasticsearch" d root root 755 - assert_file "/usr/share/doc/elasticsearch/copyright" f root root 644 + # Machine-readable debian/copyright file + local copyrightDir=$(readlink -f /usr/share/doc/$PACKAGE_NAME) + assert_file $copyrightDir d root root 755 + assert_file "$copyrightDir/copyright" f root root 644 fi if is_rpm; then diff --git a/qa/vagrant/src/test/resources/packaging/utils/utils.bash b/qa/vagrant/src/test/resources/packaging/utils/utils.bash index 98cad111de54b..8421fe571a5b9 100644 --- a/qa/vagrant/src/test/resources/packaging/utils/utils.bash +++ b/qa/vagrant/src/test/resources/packaging/utils/utils.bash @@ -249,6 +249,7 @@ clean_before_test() { "/etc/sysconfig/elasticsearch" \ "/var/run/elasticsearch" \ "/usr/share/doc/elasticsearch" \ + "/usr/share/doc/elasticsearch-oss" \ "/tmp/elasticsearch" \ "/usr/lib/systemd/system/elasticsearch.conf" \ "/usr/lib/tmpfiles.d/elasticsearch.conf" \ diff --git a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java index 30b7c912f32f2..4baa09a1422de 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java +++ b/server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java @@ -1336,8 +1336,10 @@ private NoOpResult innerNoOp(final NoOp noOp) throws IOException { final long seqNo = noOp.seqNo(); try { final NoOpResult noOpResult = new NoOpResult(noOp.seqNo()); - final Translog.Location location = translog.add(new Translog.NoOp(noOp.seqNo(), noOp.primaryTerm(), noOp.reason())); - noOpResult.setTranslogLocation(location); + if (noOp.origin() != Operation.Origin.LOCAL_TRANSLOG_RECOVERY) { + final Translog.Location location = translog.add(new Translog.NoOp(noOp.seqNo(), noOp.primaryTerm(), noOp.reason())); + noOpResult.setTranslogLocation(location); + } noOpResult.setTook(System.nanoTime() - noOp.startTime()); noOpResult.freeze(); return noOpResult; diff --git a/server/src/main/java/org/elasticsearch/rest/action/RestFieldCapabilitiesAction.java b/server/src/main/java/org/elasticsearch/rest/action/RestFieldCapabilitiesAction.java index 470f98a1e639a..b2aac8d50ea08 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/RestFieldCapabilitiesAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/RestFieldCapabilitiesAction.java @@ -57,11 +57,16 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - if (request.hasContentOrSourceParam() && request.hasParam("fields")) { - throw new IllegalArgumentException("can't specify a request body and [fields]" + - " request parameter, either specify a request body or the" + - " [fields] request parameter"); + if (request.hasContentOrSourceParam()) { + deprecationLogger.deprecated("Specifying a request body is deprecated -- the" + + " [fields] request parameter should be used instead."); + if (request.hasParam("fields")) { + throw new IllegalArgumentException("can't specify a request body and [fields]" + + " request parameter, either specify a request body or the" + + " [fields] request parameter"); + } } + final String[] indices = Strings.splitStringByCommaToArray(request.param("index")); final FieldCapabilitiesRequest fieldRequest; if (request.hasContentOrSourceParam()) { diff --git a/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java b/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java index 618e11fdf7a3c..b75297f518325 100644 --- a/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java +++ b/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java @@ -3621,15 +3621,13 @@ protected long doGenerateSeqNoForOperation(Operation operation) { noOpEngine.recoverFromTranslog(); final int gapsFilled = noOpEngine.fillSeqNoGaps(primaryTerm.get()); final String reason = randomAlphaOfLength(16); - noOpEngine.noOp( - new Engine.NoOp( - maxSeqNo + 1, - primaryTerm.get(), - randomFrom(PRIMARY, REPLICA, PEER_RECOVERY, LOCAL_TRANSLOG_RECOVERY), - System.nanoTime(), - reason)); + noOpEngine.noOp(new Engine.NoOp(maxSeqNo + 1, primaryTerm.get(), LOCAL_TRANSLOG_RECOVERY, System.nanoTime(), reason)); assertThat(noOpEngine.getLocalCheckpointTracker().getCheckpoint(), equalTo((long) (maxSeqNo + 1))); - assertThat(noOpEngine.getTranslog().stats().getUncommittedOperations(), equalTo(1 + gapsFilled)); + assertThat(noOpEngine.getTranslog().stats().getUncommittedOperations(), equalTo(gapsFilled)); + noOpEngine.noOp( + new Engine.NoOp(maxSeqNo + 2, primaryTerm.get(), randomFrom(PRIMARY, REPLICA, PEER_RECOVERY), System.nanoTime(), reason)); + assertThat(noOpEngine.getLocalCheckpointTracker().getCheckpoint(), equalTo((long) (maxSeqNo + 2))); + assertThat(noOpEngine.getTranslog().stats().getUncommittedOperations(), equalTo(gapsFilled + 1)); // skip to the op that we added to the translog Translog.Operation op; Translog.Operation last = null; @@ -3641,7 +3639,7 @@ protected long doGenerateSeqNoForOperation(Operation operation) { assertNotNull(last); assertThat(last, instanceOf(Translog.NoOp.class)); final Translog.NoOp noOp = (Translog.NoOp) last; - assertThat(noOp.seqNo(), equalTo((long) (maxSeqNo + 1))); + assertThat(noOp.seqNo(), equalTo((long) (maxSeqNo + 2))); assertThat(noOp.primaryTerm(), equalTo(primaryTerm.get())); assertThat(noOp.reason(), equalTo(reason)); } finally { diff --git a/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java b/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java index 7208c002d7b15..1bdc54b982e7c 100644 --- a/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java +++ b/server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java @@ -1661,6 +1661,16 @@ public void testRecoverFromStoreWithNoOps() throws IOException { IndexShardTestCase.updateRoutingEntry(newShard, newShard.routingEntry().moveToStarted()); assertDocCount(newShard, 1); assertDocCount(shard, 2); + + for (int i = 0; i < 2; i++) { + newShard = reinitShard(newShard, ShardRoutingHelper.initWithSameId(primaryShardRouting, + RecoverySource.StoreRecoverySource.EXISTING_STORE_INSTANCE)); + newShard.markAsRecovering("store", new RecoveryState(newShard.routingEntry(), localNode, null)); + assertTrue(newShard.recoverFromStore()); + try (Translog.Snapshot snapshot = getTranslog(newShard).newSnapshot()) { + assertThat(snapshot.totalOperations(), equalTo(2)); + } + } closeShards(newShard, shard); } diff --git a/server/src/test/java/org/elasticsearch/rest/action/RestFieldCapabilitiesActionTests.java b/server/src/test/java/org/elasticsearch/rest/action/RestFieldCapabilitiesActionTests.java new file mode 100644 index 0000000000000..b8dd007f56729 --- /dev/null +++ b/server/src/test/java/org/elasticsearch/rest/action/RestFieldCapabilitiesActionTests.java @@ -0,0 +1,59 @@ +/* + * 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.rest.action; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestFieldCapabilitiesAction; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.rest.FakeRestRequest; +import org.elasticsearch.usage.UsageService; +import org.junit.Before; + +import java.io.IOException; +import java.util.Collections; + +import static org.mockito.Mockito.mock; + +public class RestFieldCapabilitiesActionTests extends ESTestCase { + + private RestFieldCapabilitiesAction action; + + @Before + public void setUpAction() { + action = new RestFieldCapabilitiesAction(Settings.EMPTY, mock(RestController.class)); + } + + public void testRequestBodyIsDeprecated() throws IOException { + String content = "{ \"fields\": [\"title\"] }"; + RestRequest request = new FakeRestRequest.Builder(xContentRegistry()) + .withPath("/_field_caps") + .withContent(new BytesArray(content), XContentType.JSON) + .build(); + action.prepareRequest(request, mock(NodeClient.class)); + + assertWarnings("Specifying a request body is deprecated -- the" + + " [fields] request parameter should be used instead."); + } +} diff --git a/test/framework/src/test/java/org/elasticsearch/test/VersionUtilsTests.java b/test/framework/src/test/java/org/elasticsearch/test/VersionUtilsTests.java index 113e945afad00..f6ddb48aaaf2c 100644 --- a/test/framework/src/test/java/org/elasticsearch/test/VersionUtilsTests.java +++ b/test/framework/src/test/java/org/elasticsearch/test/VersionUtilsTests.java @@ -302,6 +302,7 @@ public void testResolveReleasedVersionsAtNewMinorBranchIn6x() { * Tests that {@link Version#minimumCompatibilityVersion()} and {@link VersionUtils#allReleasedVersions()} * agree with the list of wire and index compatible versions we build in gradle. */ + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/30133") public void testGradleVersionsMatchVersionUtils() { // First check the index compatible versions VersionsFromProperty indexCompatible = new VersionsFromProperty("tests.gradle_index_compat_versions"); diff --git a/x-pack/build.gradle b/x-pack/build.gradle index 44653e7f8452f..ea7ea86887b06 100644 --- a/x-pack/build.gradle +++ b/x-pack/build.gradle @@ -23,10 +23,8 @@ subprojects { ext.licenseName = 'Elastic License' ext.licenseUrl = "https://raw.githubusercontent.com/elastic/elasticsearch/${licenseCommit}/licenses/ELASTIC-LICENSE.txt" - plugins.withType(BuildPlugin).whenPluginAdded { - project.licenseFile = rootProject.file('licenses/ELASTIC-LICENSE.txt') - project.noticeFile = xpackRootProject.file('NOTICE.txt') - } + project.ext.licenseFile = rootProject.file('licenses/ELASTIC-LICENSE.txt') + project.ext.noticeFile = xpackRootProject.file('NOTICE.txt') plugins.withType(PluginBuildPlugin).whenPluginAdded { project.esplugin.licenseFile = rootProject.file('licenses/ELASTIC-LICENSE.txt') diff --git a/x-pack/plugin/build.gradle b/x-pack/plugin/build.gradle index a4e0e672cd5bd..a27d9ac386e82 100644 --- a/x-pack/plugin/build.gradle +++ b/x-pack/plugin/build.gradle @@ -31,6 +31,20 @@ configurations { task testJar(type: Jar) { appendix 'test' from sourceSets.test.output + /* + * Stick the license and notice file in the jar. This isn't strictly + * needed because we don't publish it but it makes our super-paranoid + * tests happy. + */ + metaInf { + from(project.licenseFile.parent) { + include project.licenseFile.name + rename { 'LICENSE.txt' } + } + from(project.noticeFile.parent) { + include project.noticeFile.name + } + } } artifacts { testArtifacts testJar diff --git a/x-pack/plugin/sql/sql-cli/build.gradle b/x-pack/plugin/sql/sql-cli/build.gradle index 9eae21fb18a23..06eb24c743ad8 100644 --- a/x-pack/plugin/sql/sql-cli/build.gradle +++ b/x-pack/plugin/sql/sql-cli/build.gradle @@ -45,9 +45,12 @@ dependencyLicenses { * can be easilly shipped around and used. */ jar { - from { + from({ configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } + }) { + // We don't need the META-INF from the things we bundle. For now. + exclude 'META-INF/*' } manifest { attributes 'Main-Class': 'org.elasticsearch.xpack.sql.cli.Cli'