Skip to content

Commit ab4deef

Browse files
committed
Merge branch 'master' into ccr
* master: Security: revert to old way of merging automata (#32254) Networking: Fix test leaking buffer (#32296) Undo a debugging change that snuck in during the field aliases merge. Painless: Update More Methods to New Naming Scheme (#32305) [TEST] Fix assumeFalse -> assumeTrue in SSLReloadIntegTests Ingest: Support integer and long hex values in convert (#32213) Introduce fips_mode setting and associated checks (#32326) Add V_6_3_3 version constant [DOCS] Removed extraneous callout number. Rest HL client: Add put license action (#32214) Add ERR to ranking evaluation documentation (#32314) Introduce Application Privileges with support for Kibana RBAC (#32309) Build: Shadow x-pack:protocol into x-pack:plugin:core (#32240) [Kerberos] Add Kerberos authentication support (#32263) [ML] Extract persistent task methods from MlMetadata (#32319) Add Restore Snapshot High Level REST API Register ERR metric with NamedXContentRegistry (#32320) fixes broken build for third-party-tests (#32315) Allow Integ Tests to run in a FIPS-140 JVM (#31989) [DOCS] Rollup Caps API incorrectly mentions GET Jobs API (#32280) awaitsfix testRandomClusterStateUpdates [TEST] add version skip to weighted_avg tests Consistent encoder names (#29492) Add WeightedAvg metric aggregation (#31037) Switch monitoring to new style Requests (#32255) Rename ranking evaluation `quality_level` to `metric_score` (#32168) Fix a test bug around nested aggregations and field aliases. (#32287) Add new permission for JDK11 to load JAAS libraries (#32132) Silence SSL reload test that fails on JDK 11 [test] package pre-install java check (#32259) specify subdirs of lib, bin, modules in package (#32253) Switch x-pack:core to new style Requests (#32252) awaitsfix SSLConfigurationReloaderTests Painless: Clean up add methods in PainlessLookup (#32258) Fail shard if IndexShard#storeStats runs into an IOException (#32241) AwaitsFix RecoveryIT#testHistoryUUIDIsGenerated Remove unnecessary warning supressions (#32250) CCE when re-throwing "shard not available" exception in TransportShardMultiGetAction (#32185) Add new fields to monitoring template for Beats state (#32085)
2 parents 8819029 + e43375b commit ab4deef

File tree

455 files changed

+16922
-2818
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

455 files changed

+16922
-2818
lines changed

CONTRIBUTING.md

+35-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ If your changes affect only the documentation, run:
214214
```sh
215215
./gradlew -p docs check
216216
```
217-
For more information about testing code examples in the documentation, see
217+
For more information about testing code examples in the documentation, see
218218
https://github.com/elastic/elasticsearch/blob/master/docs/README.asciidoc
219219

220220
### Project layout
@@ -305,6 +305,39 @@ the `qa` subdirectory functions just like the top level `qa` subdirectory. The
305305
Elasticsearch process. The `transport-client` subdirectory contains extensions
306306
to Elasticsearch's standard transport client to work properly with x-pack.
307307

308+
### Gradle Build
309+
310+
We use Gradle to build Elasticsearch because it is flexible enough to not only
311+
build and package Elasticsearch, but also orchestrate all of the ways that we
312+
have to test Elasticsearch.
313+
314+
#### Configurations
315+
316+
Gradle organizes dependencies and build artifacts into "configurations" and
317+
allows you to use these configurations arbitrarilly. Here are some of the most
318+
common configurations in our build and how we use them:
319+
320+
<dl>
321+
<dt>`compile`</dt><dd>Code that is on the classpath at both compile and
322+
runtime. If the [`shadow`][shadow-plugin] plugin is applied to the project then
323+
this code is bundled into the jar produced by the project.</dd>
324+
<dt>`runtime`</dt><dd>Code that is not on the classpath at compile time but is
325+
on the classpath at runtime. We mostly use this configuration to make sure that
326+
we do not accidentally compile against dependencies of our dependencies also
327+
known as "transitive" dependencies".</dd>
328+
<dt>`compileOnly`</dt><dd>Code that is on the classpath at comile time but that
329+
should not be shipped with the project because it is "provided" by the runtime
330+
somehow. Elasticsearch plugins use this configuration to include dependencies
331+
that are bundled with Elasticsearch's server.</dd>
332+
<dt>`shadow`</dt><dd>Only available in projects with the shadow plugin. Code
333+
that is on the classpath at both compile and runtime but it *not* bundled into
334+
the jar produced by the project. If you depend on a project with the `shadow`
335+
plugin then you need to depend on this configuration because it will bring
336+
along all of the dependencies you need at runtime.</dd>
337+
<dt>`testCompile`</dt><dd>Code that is on the classpath for compiling tests
338+
that are part of this project but not production code. The canonical example
339+
of this is `junit`.</dd>
340+
</dl>
308341

309342
Contributing as part of a class
310343
-------------------------------
@@ -337,3 +370,4 @@ repeating in this section because it has come up in this context.
337370

338371
[eclipse]: http://www.eclipse.org/community/eclipse_newsletter/2017/june/
339372
[intellij]: https://blog.jetbrains.com/idea/2017/07/intellij-idea-2017-2-is-here-smart-sleek-and-snappy/
373+
[shadow-plugin]: https://github.com/johnrengelman/shadow

build.gradle

+25
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,31 @@ allprojects {
516516
tasks.eclipse.dependsOn(cleanEclipse, copyEclipseSettings)
517517
}
518518

519+
allprojects {
520+
/*
521+
* IntelliJ and Eclipse don't know about the shadow plugin so when we're
522+
* in "IntelliJ mode" or "Eclipse mode" add "runtime" dependencies
523+
* eveywhere where we see a "shadow" dependency which will cause them to
524+
* reference shadowed projects directly rather than rely on the shadowing
525+
* to include them. This is the correct thing for it to do because it
526+
* doesn't run the jar shadowing at all. This isn't needed for the project
527+
* itself because the IDE configuration is done by SourceSets but it is
528+
* *is* needed for projects that depends on the project doing the shadowing.
529+
* Without this they won't properly depend on the shadowed project.
530+
*/
531+
if (isEclipse || isIdea) {
532+
configurations.all { Configuration configuration ->
533+
dependencies.all { Dependency dep ->
534+
if (dep instanceof ProjectDependency) {
535+
if (dep.getTargetConfiguration() == 'shadow') {
536+
configuration.dependencies.add(project.dependencies.project(path: dep.dependencyProject.path, configuration: 'runtime'))
537+
}
538+
}
539+
}
540+
}
541+
}
542+
}
543+
519544
// we need to add the same --debug-jvm option as
520545
// the real RunTask has, so we can pass it through
521546
class Run extends DefaultTask {

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

+22-1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ class BuildPlugin implements Plugin<Project> {
131131
runtimeJavaVersionEnum = JavaVersion.toVersion(findJavaSpecificationVersion(project, runtimeJavaHome))
132132
}
133133

134+
String inFipsJvmScript = 'print(java.security.Security.getProviders()[0].name.toLowerCase().contains("fips"));'
135+
boolean inFipsJvm = Boolean.parseBoolean(runJavascript(project, runtimeJavaHome, inFipsJvmScript))
136+
134137
// Build debugging info
135138
println '======================================='
136139
println 'Elasticsearch Build Hamster says Hello!'
@@ -202,6 +205,7 @@ class BuildPlugin implements Plugin<Project> {
202205
project.rootProject.ext.buildChecksDone = true
203206
project.rootProject.ext.minimumCompilerVersion = minimumCompilerVersion
204207
project.rootProject.ext.minimumRuntimeVersion = minimumRuntimeVersion
208+
project.rootProject.ext.inFipsJvm = inFipsJvm
205209
}
206210

207211
project.targetCompatibility = project.rootProject.ext.minimumRuntimeVersion
@@ -213,6 +217,7 @@ class BuildPlugin implements Plugin<Project> {
213217
project.ext.compilerJavaVersion = project.rootProject.ext.compilerJavaVersion
214218
project.ext.runtimeJavaVersion = project.rootProject.ext.runtimeJavaVersion
215219
project.ext.javaVersions = project.rootProject.ext.javaVersions
220+
project.ext.inFipsJvm = project.rootProject.ext.inFipsJvm
216221
}
217222

218223
private static String findCompilerJavaHome() {
@@ -386,6 +391,9 @@ class BuildPlugin implements Plugin<Project> {
386391
project.configurations.compile.dependencies.all(disableTransitiveDeps)
387392
project.configurations.testCompile.dependencies.all(disableTransitiveDeps)
388393
project.configurations.compileOnly.dependencies.all(disableTransitiveDeps)
394+
project.plugins.withType(ShadowPlugin).whenPluginAdded {
395+
project.configurations.shadow.dependencies.all(disableTransitiveDeps)
396+
}
389397
}
390398

391399
/** Adds repositories used by ES dependencies */
@@ -770,7 +778,11 @@ class BuildPlugin implements Plugin<Project> {
770778
systemProperty property.getKey(), property.getValue()
771779
}
772780
}
773-
781+
// Set the system keystore/truststore password if we're running tests in a FIPS-140 JVM
782+
if (project.inFipsJvm) {
783+
systemProperty 'javax.net.ssl.trustStorePassword', 'password'
784+
systemProperty 'javax.net.ssl.keyStorePassword', 'password'
785+
}
774786
boolean assertionsEnabled = Boolean.parseBoolean(System.getProperty('tests.asserts', 'true'))
775787
enableSystemAssertions assertionsEnabled
776788
enableAssertions assertionsEnabled
@@ -873,11 +885,20 @@ class BuildPlugin implements Plugin<Project> {
873885
project.dependencyLicenses.dependencies = project.configurations.runtime.fileCollection {
874886
it.group.startsWith('org.elasticsearch') == false
875887
} - project.configurations.compileOnly
888+
project.plugins.withType(ShadowPlugin).whenPluginAdded {
889+
project.dependencyLicenses.dependencies += project.configurations.shadow.fileCollection {
890+
it.group.startsWith('org.elasticsearch') == false
891+
}
892+
}
876893
}
877894

878895
private static configureDependenciesInfo(Project project) {
879896
Task deps = project.tasks.create("dependenciesInfo", DependenciesInfoTask.class)
880897
deps.runtimeConfiguration = project.configurations.runtime
898+
project.plugins.withType(ShadowPlugin).whenPluginAdded {
899+
deps.runtimeConfiguration = project.configurations.create('infoDeps')
900+
deps.runtimeConfiguration.extendsFrom(project.configurations.runtime, project.configurations.shadow)
901+
}
881902
deps.compileOnlyConfiguration = project.configurations.compileOnly
882903
project.afterEvaluate {
883904
deps.mappings = project.dependencyLicenses.mappings

buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy

+7-14
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,6 @@ public class PluginBuildPlugin extends BuildPlugin {
4848
@Override
4949
public void apply(Project project) {
5050
super.apply(project)
51-
project.plugins.withType(ShadowPlugin).whenPluginAdded {
52-
/*
53-
* We've not tested these plugins together and we're fairly sure
54-
* they aren't going to work properly as is *and* we're not really
55-
* sure *why* you'd want to shade stuff in plugins. So we throw an
56-
* exception here to make you come and read this comment. If you
57-
* have a need for shadow while building plugins then know that you
58-
* are probably going to have to fight with gradle for a while....
59-
*/
60-
throw new InvalidUserDataException('elasticsearch.esplugin is not '
61-
+ 'compatible with com.github.johnrengelman.shadow');
62-
}
6351
configureDependencies(project)
6452
// this afterEvaluate must happen before the afterEvaluate added by integTest creation,
6553
// so that the file name resolution for installing the plugin will be setup
@@ -153,8 +141,13 @@ public class PluginBuildPlugin extends BuildPlugin {
153141
include(buildProperties.descriptorOutput.name)
154142
}
155143
from pluginMetadata // metadata (eg custom security policy)
156-
from project.jar // this plugin's jar
157-
from project.configurations.runtime - project.configurations.compileOnly // the dep jars
144+
/*
145+
* If the plugin is using the shadow plugin then we need to bundle
146+
* "shadow" things rather than the default jar and dependencies so
147+
* we don't hit jar hell.
148+
*/
149+
from { project.plugins.hasPlugin(ShadowPlugin) ? project.shadowJar : project.jar }
150+
from { project.plugins.hasPlugin(ShadowPlugin) ? project.configurations.shadow : project.configurations.runtime - project.configurations.compileOnly }
158151
// extra files for the plugin to go into the zip
159152
from('src/main/packaging') // TODO: move all config/bin/_size/etc into packaging
160153
from('src/main') {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client;
21+
22+
import org.elasticsearch.action.ActionListener;
23+
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
24+
import org.elasticsearch.protocol.xpack.license.PutLicenseResponse;
25+
26+
import java.io.IOException;
27+
28+
import static java.util.Collections.emptySet;
29+
30+
/**
31+
* A wrapper for the {@link RestHighLevelClient} that provides methods for
32+
* accessing the Elastic License-related methods
33+
* <p>
34+
* See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/licensing-apis.html">
35+
* X-Pack Licensing APIs on elastic.co</a> for more information.
36+
*/
37+
public class LicenseClient {
38+
39+
private final RestHighLevelClient restHighLevelClient;
40+
41+
LicenseClient(RestHighLevelClient restHighLevelClient) {
42+
this.restHighLevelClient = restHighLevelClient;
43+
}
44+
45+
/**
46+
* Updates license for the cluster.
47+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
48+
* @return the response
49+
* @throws IOException in case there is a problem sending the request or parsing back the response
50+
*/
51+
public PutLicenseResponse putLicense(PutLicenseRequest request, RequestOptions options) throws IOException {
52+
return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::putLicense, options,
53+
PutLicenseResponse::fromXContent, emptySet());
54+
}
55+
56+
/**
57+
* Asynchronously updates license for the cluster cluster.
58+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
59+
* @param listener the listener to be notified upon request completion
60+
*/
61+
public void putLicenseAsync(PutLicenseRequest request, RequestOptions options, ActionListener<PutLicenseResponse> listener) {
62+
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::putLicense, options,
63+
PutLicenseResponse::fromXContent, listener, emptySet());
64+
}
65+
66+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

+28
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest;
4141
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
4242
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest;
43+
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
4344
import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest;
4445
import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest;
4546
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
@@ -108,6 +109,7 @@
108109
import org.elasticsearch.protocol.xpack.XPackInfoRequest;
109110
import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest;
110111
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
112+
import org.elasticsearch.protocol.xpack.license.PutLicenseRequest;
111113
import org.elasticsearch.rest.action.search.RestSearchAction;
112114
import org.elasticsearch.script.mustache.MultiSearchTemplateRequest;
113115
import org.elasticsearch.script.mustache.SearchTemplateRequest;
@@ -980,6 +982,20 @@ static Request snapshotsStatus(SnapshotsStatusRequest snapshotsStatusRequest) {
980982
return request;
981983
}
982984

985+
static Request restoreSnapshot(RestoreSnapshotRequest restoreSnapshotRequest) throws IOException {
986+
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
987+
.addPathPart(restoreSnapshotRequest.repository())
988+
.addPathPart(restoreSnapshotRequest.snapshot())
989+
.addPathPartAsIs("_restore")
990+
.build();
991+
Request request = new Request(HttpPost.METHOD_NAME, endpoint);
992+
Params parameters = new Params(request);
993+
parameters.withMasterTimeout(restoreSnapshotRequest.masterNodeTimeout());
994+
parameters.withWaitForCompletion(restoreSnapshotRequest.waitForCompletion());
995+
request.setEntity(createEntity(restoreSnapshotRequest, REQUEST_BODY_CONTENT_TYPE));
996+
return request;
997+
}
998+
983999
static Request deleteSnapshot(DeleteSnapshotRequest deleteSnapshotRequest) {
9841000
String endpoint = new EndpointBuilder().addPathPartAsIs("_snapshot")
9851001
.addPathPart(deleteSnapshotRequest.repository())
@@ -1124,6 +1140,18 @@ static Request xpackUsage(XPackUsageRequest usageRequest) {
11241140
return request;
11251141
}
11261142

1143+
static Request putLicense(PutLicenseRequest putLicenseRequest) {
1144+
Request request = new Request(HttpPut.METHOD_NAME, "/_xpack/license");
1145+
Params parameters = new Params(request);
1146+
parameters.withTimeout(putLicenseRequest.timeout());
1147+
parameters.withMasterTimeout(putLicenseRequest.masterNodeTimeout());
1148+
if (putLicenseRequest.isAcknowledge()) {
1149+
parameters.putParam("acknowledge", "true");
1150+
}
1151+
request.setJsonEntity(putLicenseRequest.getLicenseDefinition());
1152+
return request;
1153+
}
1154+
11271155
private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
11281156
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
11291157
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));

client/rest-high-level/src/main/java/org/elasticsearch/client/SnapshotClient.java

+32
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyRepositoryResponse;
3131
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
3232
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
33+
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
34+
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
3335
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest;
3436
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
3537
import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest;
@@ -252,6 +254,36 @@ public void statusAsync(SnapshotsStatusRequest snapshotsStatusRequest, RequestOp
252254
SnapshotsStatusResponse::fromXContent, listener, emptySet());
253255
}
254256

257+
/**
258+
* Restores a snapshot.
259+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
260+
* API on elastic.co</a>
261+
*
262+
* @param restoreSnapshotRequest the request
263+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
264+
* @return the response
265+
* @throws IOException in case there is a problem sending the request or parsing back the response
266+
*/
267+
public RestoreSnapshotResponse restore(RestoreSnapshotRequest restoreSnapshotRequest, RequestOptions options) throws IOException {
268+
return restHighLevelClient.performRequestAndParseEntity(restoreSnapshotRequest, RequestConverters::restoreSnapshot, options,
269+
RestoreSnapshotResponse::fromXContent, emptySet());
270+
}
271+
272+
/**
273+
* Asynchronously restores a snapshot.
274+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore
275+
* API on elastic.co</a>
276+
*
277+
* @param restoreSnapshotRequest the request
278+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
279+
* @param listener the listener to be notified upon request completion
280+
*/
281+
public void restoreAsync(RestoreSnapshotRequest restoreSnapshotRequest, RequestOptions options,
282+
ActionListener<RestoreSnapshotResponse> listener) {
283+
restHighLevelClient.performRequestAsyncAndParseEntity(restoreSnapshotRequest, RequestConverters::restoreSnapshot, options,
284+
RestoreSnapshotResponse::fromXContent, listener, emptySet());
285+
}
286+
255287
/**
256288
* Deletes a snapshot.
257289
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html"> Snapshot and Restore

client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java

+13
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ public final class XPackClient {
4242

4343
private final RestHighLevelClient restHighLevelClient;
4444
private final WatcherClient watcherClient;
45+
private final LicenseClient licenseClient;
4546

4647
XPackClient(RestHighLevelClient restHighLevelClient) {
4748
this.restHighLevelClient = restHighLevelClient;
4849
this.watcherClient = new WatcherClient(restHighLevelClient);
50+
this.licenseClient = new LicenseClient(restHighLevelClient);
4951
}
5052

5153
public WatcherClient watcher() {
@@ -100,4 +102,15 @@ public void usageAsync(XPackUsageRequest request, RequestOptions options, Action
100102
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::xpackUsage, options,
101103
XPackUsageResponse::fromXContent, listener, emptySet());
102104
}
105+
106+
/**
107+
* A wrapper for the {@link RestHighLevelClient} that provides methods for
108+
* accessing the Elastic Licensing APIs.
109+
* <p>
110+
* See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/licensing-apis.html">
111+
* X-Pack APIs on elastic.co</a> for more information.
112+
*/
113+
public LicenseClient license() {
114+
return licenseClient;
115+
}
103116
}

0 commit comments

Comments
 (0)