Skip to content

Commit e517aa5

Browse files
authored
Merge branch '9.1' into backport/9.1/pr-130377
2 parents b596ccc + 9d6b0cd commit e517aa5

File tree

58 files changed

+1005
-160
lines changed

Some content is hidden

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

58 files changed

+1005
-160
lines changed

build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/PublishPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ private void addNameAndDescriptionToPom(Project project, NamedDomainObjectSet<Ma
175175
private static void configureWithShadowPlugin(Project project, MavenPublication publication) {
176176
var shadow = project.getExtensions().getByType(ShadowExtension.class);
177177
shadow.component(publication);
178+
publication.artifact(project.getTasks().named("javadocJar"));
179+
publication.artifact(project.getTasks().named("sourcesJar"));
178180
}
179181

180182
private static void addScmInfo(XmlProvider xml, GitInfo gitInfo) {

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchTestBasePlugin.java

Lines changed: 104 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
import java.io.File;
3535
import java.util.List;
3636
import java.util.Map;
37+
import java.util.stream.Stream;
3738

3839
import javax.inject.Inject;
3940

41+
import static java.util.stream.Collectors.joining;
4042
import static org.elasticsearch.gradle.internal.util.ParamsUtils.loadBuildParams;
4143
import static org.elasticsearch.gradle.util.FileUtils.mkdirs;
4244
import static org.elasticsearch.gradle.util.GradleUtils.maybeConfigure;
@@ -173,6 +175,16 @@ public void execute(Task t) {
173175
// we use 'temp' relative to CWD since this is per JVM and tests are forbidden from writing to CWD
174176
nonInputProperties.systemProperty("java.io.tmpdir", test.getWorkingDir().toPath().resolve("temp"));
175177

178+
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
179+
SourceSet mainSourceSet = sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME);
180+
SourceSet testSourceSet = sourceSets.findByName(SourceSet.TEST_SOURCE_SET_NAME);
181+
if ("test".equals(test.getName()) && mainSourceSet != null && testSourceSet != null) {
182+
FileCollection mainRuntime = mainSourceSet.getRuntimeClasspath();
183+
FileCollection testRuntime = testSourceSet.getRuntimeClasspath();
184+
FileCollection testOnlyFiles = testRuntime.minus(mainRuntime);
185+
test.doFirst(task -> test.environment("es.entitlement.testOnlyPath", testOnlyFiles.getAsPath()));
186+
}
187+
176188
test.systemProperties(getProviderFactory().systemPropertiesPrefixedBy("tests.").get());
177189
test.systemProperties(getProviderFactory().systemPropertiesPrefixedBy("es.").get());
178190

@@ -205,46 +217,122 @@ public void execute(Task t) {
205217
}
206218

207219
/*
208-
* If this project builds a shadow JAR than any unit tests should test against that artifact instead of
220+
* If this project builds a shadow JAR then any unit tests should test against that artifact instead of
209221
* compiled class output and dependency jars. This better emulates the runtime environment of consumers.
210222
*/
211223
project.getPluginManager().withPlugin("com.gradleup.shadow", p -> {
212224
if (test.getName().equals(JavaPlugin.TEST_TASK_NAME)) {
213225
// Remove output class files and any other dependencies from the test classpath, since the shadow JAR includes these
214-
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
215-
FileCollection mainRuntime = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath();
216226
// Add any "shadow" dependencies. These are dependencies that are *not* bundled into the shadow JAR
217227
Configuration shadowConfig = project.getConfigurations().getByName(ShadowBasePlugin.CONFIGURATION_NAME);
218228
// Add the shadow JAR artifact itself
219229
FileCollection shadowJar = project.files(project.getTasks().named("shadowJar"));
220-
FileCollection testRuntime = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME).getRuntimeClasspath();
230+
FileCollection mainRuntime = mainSourceSet.getRuntimeClasspath();
231+
FileCollection testRuntime = testSourceSet.getRuntimeClasspath();
221232
test.setClasspath(testRuntime.minus(mainRuntime).plus(shadowConfig).plus(shadowJar));
222233
}
223234
});
224235
});
225-
configureImmutableCollectionsPatch(project);
236+
configureJavaBaseModuleOptions(project);
237+
configureEntitlements(project);
238+
}
239+
240+
/**
241+
* Computes and sets the {@code --patch-module=java.base} and {@code --add-opens=java.base} JVM command line options.
242+
*/
243+
private void configureJavaBaseModuleOptions(Project project) {
244+
project.getTasks().withType(Test.class).matching(task -> task.getName().equals("test")).configureEach(test -> {
245+
FileCollection patchedImmutableCollections = patchedImmutableCollections(project);
246+
if (patchedImmutableCollections != null) {
247+
test.getInputs().files(patchedImmutableCollections);
248+
test.systemProperty("tests.hackImmutableCollections", "true");
249+
}
250+
251+
FileCollection entitlementBridge = entitlementBridge(project);
252+
if (entitlementBridge != null) {
253+
test.getInputs().files(entitlementBridge);
254+
}
255+
256+
test.getJvmArgumentProviders().add(() -> {
257+
String javaBasePatch = Stream.concat(
258+
singleFilePath(patchedImmutableCollections).map(str -> str + "/java.base"),
259+
singleFilePath(entitlementBridge)
260+
).collect(joining(File.pathSeparator));
261+
262+
return javaBasePatch.isEmpty()
263+
? List.of()
264+
: List.of("--patch-module=java.base=" + javaBasePatch, "--add-opens=java.base/java.util=ALL-UNNAMED");
265+
});
266+
});
226267
}
227268

228-
private void configureImmutableCollectionsPatch(Project project) {
269+
private Stream<String> singleFilePath(FileCollection collection) {
270+
return Stream.ofNullable(collection).filter(fc -> fc.isEmpty() == false).map(FileCollection::getSingleFile).map(File::toString);
271+
}
272+
273+
private static FileCollection patchedImmutableCollections(Project project) {
229274
String patchProject = ":test:immutable-collections-patch";
230275
if (project.findProject(patchProject) == null) {
231-
return; // build tests may not have this project, just skip
276+
return null; // build tests may not have this project, just skip
232277
}
233278
String configurationName = "immutableCollectionsPatch";
234279
FileCollection patchedFileCollection = project.getConfigurations()
235280
.create(configurationName, config -> config.setCanBeConsumed(false));
236281
var deps = project.getDependencies();
237282
deps.add(configurationName, deps.project(Map.of("path", patchProject, "configuration", "patch")));
238-
project.getTasks().withType(Test.class).matching(task -> task.getName().equals("test")).configureEach(test -> {
239-
test.getInputs().files(patchedFileCollection);
240-
test.systemProperty("tests.hackImmutableCollections", "true");
241-
test.getJvmArgumentProviders()
242-
.add(
243-
() -> List.of(
244-
"--patch-module=java.base=" + patchedFileCollection.getSingleFile() + "/java.base",
245-
"--add-opens=java.base/java.util=ALL-UNNAMED"
246-
)
283+
return patchedFileCollection;
284+
}
285+
286+
private static FileCollection entitlementBridge(Project project) {
287+
return project.getConfigurations().findByName("entitlementBridge");
288+
}
289+
290+
/**
291+
* Sets the required JVM options and system properties to enable entitlement enforcement on tests.
292+
* <p>
293+
* One command line option is set in {@link #configureJavaBaseModuleOptions} out of necessity,
294+
* since the command line can have only one {@code --patch-module} option for a given module.
295+
*/
296+
private static void configureEntitlements(Project project) {
297+
Configuration agentConfig = project.getConfigurations().create("entitlementAgent");
298+
Project agent = project.findProject(":libs:entitlement:agent");
299+
if (agent != null) {
300+
agentConfig.defaultDependencies(
301+
deps -> { deps.add(project.getDependencies().project(Map.of("path", ":libs:entitlement:agent"))); }
302+
);
303+
}
304+
FileCollection agentFiles = agentConfig;
305+
306+
Configuration bridgeConfig = project.getConfigurations().create("entitlementBridge");
307+
Project bridge = project.findProject(":libs:entitlement:bridge");
308+
if (bridge != null) {
309+
bridgeConfig.defaultDependencies(
310+
deps -> { deps.add(project.getDependencies().project(Map.of("path", ":libs:entitlement:bridge"))); }
311+
);
312+
}
313+
FileCollection bridgeFiles = bridgeConfig;
314+
315+
project.getTasks().withType(Test.class).configureEach(test -> {
316+
// See also SystemJvmOptions.maybeAttachEntitlementAgent.
317+
318+
// Agent
319+
if (agentFiles.isEmpty() == false) {
320+
test.getInputs().files(agentFiles);
321+
test.systemProperty("es.entitlement.agentJar", agentFiles.getAsPath());
322+
test.systemProperty("jdk.attach.allowAttachSelf", true);
323+
}
324+
325+
// Bridge
326+
if (bridgeFiles.isEmpty() == false) {
327+
String modulesContainingEntitlementInstrumentation = "java.logging,java.net.http,java.naming,jdk.net";
328+
test.getInputs().files(bridgeFiles);
329+
// Tests may not be modular, but the JDK still is
330+
test.jvmArgs(
331+
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=ALL-UNNAMED,"
332+
+ modulesContainingEntitlementInstrumentation
247333
);
334+
}
248335
});
249336
}
337+
250338
}

build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ReleaseNotesGeneratorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private ChangelogEntry makeHighlightsEntry(int pr, boolean notable) {
188188
}
189189

190190
private String getResource(String name) throws Exception {
191-
return Files.readString(Paths.get(Objects.requireNonNull(this.getClass().getResource(name)).toURI()), StandardCharsets.UTF_8);
191+
return Files.readString(Paths.get(Objects.requireNonNull(this.getClass().getResource(name)).toURI()), StandardCharsets.UTF_8).replace("\r", "");
192192
}
193193

194194
private void writeResource(String name, String contents) throws Exception {

build-tools/src/main/java/org/elasticsearch/gradle/test/TestBuildInfoPlugin.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
import org.gradle.api.provider.ProviderFactory;
1919
import org.gradle.api.tasks.SourceSet;
2020
import org.gradle.api.tasks.SourceSetContainer;
21+
import org.gradle.api.tasks.testing.Test;
2122
import org.gradle.language.jvm.tasks.ProcessResources;
2223

24+
import java.util.List;
25+
2326
import javax.inject.Inject;
2427

2528
/**
@@ -53,5 +56,11 @@ public void apply(Project project) {
5356
project.getTasks().withType(ProcessResources.class).named("processResources").configure(task -> {
5457
task.into("META-INF", copy -> copy.from(testBuildInfoTask));
5558
});
59+
60+
if (project.getRootProject().getName().equals("elasticsearch")) {
61+
project.getTasks().withType(Test.class).matching(test -> List.of("test").contains(test.getName())).configureEach(test -> {
62+
test.systemProperty("es.entitlement.enableForTests", "true");
63+
});
64+
}
5665
}
5766
}

docs/changelog/127797.yaml

Lines changed: 0 additions & 6 deletions
This file was deleted.

docs/changelog/130303.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 130303
2+
summary: Drain responses on completion for `TransportNodesAction`
3+
area: Distributed
4+
type: bug
5+
issues: []

docs/changelog/130421.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 130421
2+
summary: Support avg on aggregate metric double
3+
area: ES|QL
4+
type: bug
5+
issues: []

docs/reference/elasticsearch/configuration-reference/thread-pool-settings.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,11 @@ $$$search-throttled$$$`search_throttled`
5959
`flush`
6060
: For [flush](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-flush) and [translog](/reference/elasticsearch/index-settings/translog.md) `fsync` operations. Thread pool type is `scaling` with a keep-alive of `5m` and a default maximum size of `min(5, (`[`# of allocated processors`](#node.processors)`) / 2)`.
6161

62+
`merge`
63+
: For [merge](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-merge.html) operations of all the shards on the node. Thread pool type is `scaling` with a keep-alive of `5m` and a default maximum size of [`# of allocated processors`](#node.processors).
64+
6265
`force_merge`
63-
: For [force merge](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-forcemerge) operations. Thread pool type is `fixed` with a size of `max(1, (`[`# of allocated processors`](#node.processors)`) / 8)` and an unbounded queue size.
66+
: For waiting on blocking [force merge](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-forcemerge) operations. Thread pool type is `fixed` with a size of `max(1, (`[`# of allocated processors`](#node.processors)`) / 8)` and an unbounded queue size.
6467

6568
`management`
6669
: For cluster management. Thread pool type is `scaling` with a keep-alive of `5m` and a default maximum size of `5`.

docs/reference/elasticsearch/index-settings/merge.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,32 @@ The merge process uses auto-throttling to balance the use of hardware resources
1313

1414
## Merge scheduling [merge-scheduling]
1515

16-
The merge scheduler (ConcurrentMergeScheduler) controls the execution of merge operations when they are needed. Merges run in separate threads, and when the maximum number of threads is reached, further merges will wait until a merge thread becomes available.
16+
The merge scheduler controls the execution of merge operations when they are needed.
17+
Merges run on the dedicated `merge` thread pool.
18+
Smaller merges are prioritized over larger ones, across all shards on the node.
19+
Merges are disk IO throttled so that bursts, while merging activity is otherwise low, are smoothed out in order to not impact indexing throughput.
20+
There is no limit on the number of merges that can be enqueued for execution on the thread pool.
21+
However, beyond a certain per-shard limit, after merging is completely disk IO un-throttled, indexing for the shard will itself be throttled until merging catches up.
1722

18-
The merge scheduler supports the following *dynamic* setting:
23+
The available disk space is periodically monitored, such that no new merge tasks are scheduled for execution when the available disk space is low.
24+
This is in order to prevent that the temporary disk space, which is required while merges are executed, completely fills up the disk space on the node.
25+
26+
The merge scheduler supports the following *dynamic* settings:
1927

2028
`index.merge.scheduler.max_thread_count`
21-
: The maximum number of threads on a single shard that may be merging at once. Defaults to `Math.max(1, Math.min(4, <<node.processors, node.processors>> / 2))` which works well for a good solid-state-disk (SSD). If your index is on spinning platter drives instead, decrease this to 1.
29+
: The maximum number of threads on a **single** shard that may be merging at once. Defaults to `Math.max(1, Math.min(4, <<node.processors, node.processors>> / 2))` which works well for a good solid-state-disk (SSD). If your index is on spinning platter drives instead, decrease this to 1.
30+
31+
`indices.merge.disk.check_interval`
32+
: The time interval for checking the available disk space. Defaults to `5s`.
33+
34+
`indices.merge.disk.watermark.high`
35+
: Controls the disk usage watermark, which defaults to `95%`, beyond which no merge tasks can start execution.
36+
The disk usage tally includes the estimated temporary disk space still required by all the currently executing merge tasks.
37+
Any merge task scheduled *before* the limit is reached continues execution, even if the limit is exceeded while executing
38+
(merge tasks are not aborted).
39+
40+
`indices.merge.disk.watermark.high.max_headroom`
41+
: Controls the max headroom for the merge disk usage watermark, in case it is specified as percentage or ratio values.
42+
Defaults to `100GB` when `indices.merge.disk.watermark.high` is not explicitly set.
43+
This caps the amount of free disk space before merge scheduling is blocked.
2244

libs/build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,14 @@ configure(childProjects.values()) {
4545
*/
4646
apply plugin: 'elasticsearch.build'
4747
}
48+
49+
// This is for any code potentially included in the server at runtime.
50+
// Omit oddball libraries that aren't in server.
51+
def nonServerLibs = ['plugin-scanner']
52+
if (false == nonServerLibs.contains(project.name)) {
53+
project.getTasks().withType(Test.class).matching(test -> ['test'].contains(test.name)).configureEach(test -> {
54+
test.systemProperty('es.entitlement.enableForTests', 'true')
55+
})
56+
}
57+
4858
}

0 commit comments

Comments
 (0)