Skip to content

Commit 5ff49ca

Browse files
Merge remote-tracking branch 'origin/master' into reindex_v2
2 parents 9c8143f + 8d29df0 commit 5ff49ca

File tree

477 files changed

+15444
-9962
lines changed

Some content is hidden

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

477 files changed

+15444
-9962
lines changed

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import org.gradle.authentication.http.HttpHeaderAuthentication
7878
import org.gradle.external.javadoc.CoreJavadocOptions
7979
import org.gradle.internal.jvm.Jvm
8080
import org.gradle.language.base.plugins.LifecycleBasePlugin
81+
import org.gradle.process.CommandLineArgumentProvider
8182
import org.gradle.process.ExecResult
8283
import org.gradle.process.ExecSpec
8384
import org.gradle.util.GradleVersion
@@ -834,10 +835,9 @@ class BuildPlugin implements Plugin<Project> {
834835

835836
test.jvmArgs "-Xmx${System.getProperty('tests.heap.size', '512m')}",
836837
"-Xms${System.getProperty('tests.heap.size', '512m')}",
837-
'-XX:+HeapDumpOnOutOfMemoryError',
838-
"-XX:HeapDumpPath=$heapdumpDir",
839838
'--illegal-access=warn'
840839

840+
test.jvmArgumentProviders.add({ ['-XX:+HeapDumpOnOutOfMemoryError', "-XX:HeapDumpPath=$heapdumpDir"] } as CommandLineArgumentProvider)
841841

842842
if (System.getProperty('tests.jvm.argline')) {
843843
test.jvmArgs System.getProperty('tests.jvm.argline').split(" ")
@@ -848,8 +848,7 @@ class BuildPlugin implements Plugin<Project> {
848848
}
849849

850850
// we use './temp' since this is per JVM and tests are forbidden from writing to CWD
851-
test.systemProperties 'gradle.dist.lib': new File(project.class.location.toURI()).parent,
852-
'java.io.tmpdir': './temp',
851+
test.systemProperties 'java.io.tmpdir': './temp',
853852
'java.awt.headless': 'true',
854853
'tests.gradle': 'true',
855854
'tests.artifact': project.name,
@@ -865,6 +864,7 @@ class BuildPlugin implements Plugin<Project> {
865864
}
866865

867866
// don't track these as inputs since they contain absolute paths and break cache relocatability
867+
nonInputProperties.systemProperty('gradle.dist.lib', new File(project.class.location.toURI()).parent)
868868
nonInputProperties.systemProperty('gradle.worker.jar', "${project.gradle.getGradleUserHomeDir()}/caches/${project.gradle.gradleVersion}/workerMain/gradle-worker.jar")
869869
nonInputProperties.systemProperty('gradle.user.home', project.gradle.getGradleUserHomeDir())
870870

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/DistroTestPlugin.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ private static TaskProvider<?> configureDistroTest(Project project, Provider<Dir
283283
}
284284

285285
private static TaskProvider<BatsTestTask> configureBatsTest(Project project, String type, Provider<Directory> distributionsDir,
286-
TaskProvider<Copy> copyPackagingArchives, Object... deps) {
286+
Object... deps) {
287287
return project.getTasks().register("destructiveBatsTest." + type, BatsTestTask.class,
288288
t -> {
289289
Directory batsDir = project.getLayout().getProjectDirectory().dir("bats");

buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java

+61-33
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import org.gradle.api.Project;
88
import org.gradle.api.plugins.ExtraPropertiesExtension;
99
import org.gradle.internal.jvm.Jvm;
10-
import org.gradle.process.ExecResult;
1110

1211
import java.io.BufferedReader;
1312
import java.io.ByteArrayOutputStream;
@@ -16,18 +15,19 @@
1615
import java.io.IOException;
1716
import java.io.InputStreamReader;
1817
import java.io.UncheckedIOException;
18+
import java.nio.charset.StandardCharsets;
19+
import java.nio.file.Files;
20+
import java.nio.file.Path;
21+
import java.nio.file.Paths;
1922
import java.time.ZoneOffset;
2023
import java.time.ZonedDateTime;
2124
import java.util.ArrayList;
2225
import java.util.Arrays;
2326
import java.util.HashMap;
2427
import java.util.List;
2528
import java.util.Map;
26-
import java.util.concurrent.atomic.AtomicReference;
2729
import java.util.stream.Collectors;
2830

29-
import static java.nio.charset.StandardCharsets.UTF_8;
30-
3131
public class GlobalBuildInfoPlugin implements Plugin<Project> {
3232
private static final String GLOBAL_INFO_EXTENSION_NAME = "globalInfo";
3333
private static Integer _defaultParallel = null;
@@ -46,8 +46,6 @@ public void apply(Project project) {
4646
File compilerJavaHome = findCompilerJavaHome();
4747
File runtimeJavaHome = findRuntimeJavaHome(compilerJavaHome);
4848

49-
Object gitRevisionResolver = createGitRevisionResolver(project);
50-
5149
final List<JavaHome> javaVersions = new ArrayList<>();
5250
for (int version = 8; version <= Integer.parseInt(minimumCompilerVersion.getMajorVersion()); version++) {
5351
if (System.getenv(getJavaHomeEnvVarName(Integer.toString(version))) != null) {
@@ -95,7 +93,7 @@ public void apply(Project project) {
9593
ext.set("minimumCompilerVersion", minimumCompilerVersion);
9694
ext.set("minimumRuntimeVersion", minimumRuntimeVersion);
9795
ext.set("gradleJavaVersion", Jvm.current().getJavaVersion());
98-
ext.set("gitRevision", gitRevisionResolver);
96+
ext.set("gitRevision", gitRevision(project));
9997
ext.set("buildDate", ZonedDateTime.now(ZoneOffset.UTC));
10098
});
10199
}
@@ -206,35 +204,65 @@ private static int findDefaultParallel(Project project) {
206204
return _defaultParallel;
207205
}
208206

209-
private Object createGitRevisionResolver(final Project project) {
210-
return new Object() {
211-
private final AtomicReference<String> gitRevision = new AtomicReference<>();
212-
213-
@Override
214-
public String toString() {
215-
if (gitRevision.get() == null) {
216-
final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
217-
final ByteArrayOutputStream stderr = new ByteArrayOutputStream();
218-
final ExecResult result = project.exec(spec -> {
219-
spec.setExecutable("git");
220-
spec.setArgs(Arrays.asList("rev-parse", "HEAD"));
221-
spec.setStandardOutput(stdout);
222-
spec.setErrorOutput(stderr);
223-
spec.setIgnoreExitValue(true);
224-
});
225-
226-
final String revision;
227-
if (result.getExitValue() != 0) {
228-
revision = "unknown";
229-
} else {
230-
revision = stdout.toString(UTF_8).trim();
231-
}
232-
this.gitRevision.compareAndSet(null, revision);
207+
private String gitRevision(final Project project) {
208+
try {
209+
/*
210+
* We want to avoid forking another process to run git rev-parse HEAD. Instead, we will read the refs manually. The
211+
* documentation for this follows from https://git-scm.com/docs/gitrepository-layout and https://git-scm.com/docs/git-worktree.
212+
*
213+
* There are two cases to consider:
214+
* - a plain repository with .git directory at the root of the working tree
215+
* - a worktree with a plain text .git file at the root of the working tree
216+
*
217+
* In each case, our goal is to parse the HEAD file to get either a ref or a bare revision (in the case of being in detached
218+
* HEAD state).
219+
*
220+
* In the case of a plain repository, we can read the HEAD file directly, resolved directly from the .git directory.
221+
*
222+
* In the case of a worktree, we read the gitdir from the plain text .git file. This resolves to a directory from which we read
223+
* the HEAD file and resolve commondir to the plain git repository.
224+
*/
225+
final Path dotGit = project.getRootProject().getRootDir().toPath().resolve(".git");
226+
final String revision;
227+
if (Files.exists(dotGit) == false) {
228+
return "unknown";
229+
}
230+
final Path head;
231+
final Path gitDir;
232+
if (Files.isDirectory(dotGit)) {
233+
// this is a git repository, we can read HEAD directly
234+
head = dotGit.resolve("HEAD");
235+
gitDir = dotGit;
236+
} else {
237+
// this is a git worktree, follow the pointer to the repository
238+
final Path workTree = Paths.get(readFirstLine(dotGit).substring("gitdir:".length()).trim());
239+
head = workTree.resolve("HEAD");
240+
final Path commonDir = Paths.get(readFirstLine(workTree.resolve("commondir")));
241+
if (commonDir.isAbsolute()) {
242+
gitDir = commonDir;
243+
} else {
244+
// this is the common case
245+
gitDir = workTree.resolve(commonDir);
233246
}
234-
return gitRevision.get();
235247
}
236-
};
248+
final String ref = readFirstLine(head);
249+
if (ref.startsWith("ref:")) {
250+
revision = readFirstLine(gitDir.resolve(ref.substring("ref:".length()).trim()));
251+
} else {
252+
// we are in detached HEAD state
253+
revision = ref;
254+
}
255+
return revision;
256+
} catch (final IOException e) {
257+
// for now, do not be lenient until we have better understanding of real-world scenarios where this happens
258+
throw new GradleException("unable to read the git revision", e);
259+
}
260+
}
237261

262+
private String readFirstLine(final Path path) throws IOException {
263+
return Files.lines(path, StandardCharsets.UTF_8)
264+
.findFirst()
265+
.orElseThrow(() -> new IOException("file [" + path + "] is empty"));
238266
}
239267

240268
}

client/rest-high-level/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ idea {
4949
dependencies {
5050
compile project(':server')
5151
compile project(':client:rest')
52+
compile project(':modules:mapper-extras')
5253
compile project(':modules:parent-join')
5354
compile project(':modules:aggs-matrix-stats')
5455
compile project(':modules:rank-eval')
5556
compile project(':modules:lang-mustache')
5657
shadow project(':server')
5758
shadow project(':client:rest')
59+
bundle project(':modules:mapper-extras')
5860
bundle project(':modules:parent-join')
5961
bundle project(':modules:aggs-matrix-stats')
6062
bundle project(':modules:rank-eval')

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

+10
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.elasticsearch.client.ml.DeleteForecastRequest;
4040
import org.elasticsearch.client.ml.DeleteJobRequest;
4141
import org.elasticsearch.client.ml.DeleteModelSnapshotRequest;
42+
import org.elasticsearch.client.ml.EstimateMemoryUsageRequest;
4243
import org.elasticsearch.client.ml.EvaluateDataFrameRequest;
4344
import org.elasticsearch.client.ml.FindFileStructureRequest;
4445
import org.elasticsearch.client.ml.FlushJobRequest;
@@ -700,6 +701,15 @@ static Request evaluateDataFrame(EvaluateDataFrameRequest evaluateRequest) throw
700701
return request;
701702
}
702703

704+
static Request estimateMemoryUsage(EstimateMemoryUsageRequest estimateRequest) throws IOException {
705+
String endpoint = new EndpointBuilder()
706+
.addPathPartAsIs("_ml", "data_frame", "analytics", "_estimate_memory_usage")
707+
.build();
708+
Request request = new Request(HttpPost.METHOD_NAME, endpoint);
709+
request.setEntity(createEntity(estimateRequest, REQUEST_BODY_CONTENT_TYPE));
710+
return request;
711+
}
712+
703713
static Request putFilter(PutFilterRequest putFilterRequest) throws IOException {
704714
String endpoint = new EndpointBuilder()
705715
.addPathPartAsIs("_ml")

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

+44
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.elasticsearch.client.ml.DeleteJobRequest;
3535
import org.elasticsearch.client.ml.DeleteJobResponse;
3636
import org.elasticsearch.client.ml.DeleteModelSnapshotRequest;
37+
import org.elasticsearch.client.ml.EstimateMemoryUsageRequest;
38+
import org.elasticsearch.client.ml.EstimateMemoryUsageResponse;
3739
import org.elasticsearch.client.ml.EvaluateDataFrameRequest;
3840
import org.elasticsearch.client.ml.EvaluateDataFrameResponse;
3941
import org.elasticsearch.client.ml.FindFileStructureRequest;
@@ -2185,4 +2187,46 @@ public void evaluateDataFrameAsync(EvaluateDataFrameRequest request, RequestOpti
21852187
listener,
21862188
Collections.emptySet());
21872189
}
2190+
2191+
/**
2192+
* Estimates memory usage for the given Data Frame Analytics
2193+
* <p>
2194+
* For additional info
2195+
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/estimate-memory-usage-dfanalytics.html">
2196+
* Estimate Memory Usage for Data Frame Analytics documentation</a>
2197+
*
2198+
* @param request The {@link EstimateMemoryUsageRequest}
2199+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
2200+
* @return {@link EstimateMemoryUsageResponse} response object
2201+
* @throws IOException when there is a serialization issue sending the request or receiving the response
2202+
*/
2203+
public EstimateMemoryUsageResponse estimateMemoryUsage(EstimateMemoryUsageRequest request,
2204+
RequestOptions options) throws IOException {
2205+
return restHighLevelClient.performRequestAndParseEntity(request,
2206+
MLRequestConverters::estimateMemoryUsage,
2207+
options,
2208+
EstimateMemoryUsageResponse::fromXContent,
2209+
Collections.emptySet());
2210+
}
2211+
2212+
/**
2213+
* Estimates memory usage for the given Data Frame Analytics asynchronously and notifies listener upon completion
2214+
* <p>
2215+
* For additional info
2216+
* see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/estimate-memory-usage-dfanalytics.html">
2217+
* Estimate Memory Usage for Data Frame Analytics documentation</a>
2218+
*
2219+
* @param request The {@link EstimateMemoryUsageRequest}
2220+
* @param options Additional request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
2221+
* @param listener Listener to be notified upon request completion
2222+
*/
2223+
public void estimateMemoryUsageAsync(EstimateMemoryUsageRequest request, RequestOptions options,
2224+
ActionListener<EstimateMemoryUsageResponse> listener) {
2225+
restHighLevelClient.performRequestAsyncAndParseEntity(request,
2226+
MLRequestConverters::estimateMemoryUsage,
2227+
options,
2228+
EstimateMemoryUsageResponse::fromXContent,
2229+
listener,
2230+
Collections.emptySet());
2231+
}
21882232
}

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

+10-10
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ public abstract class IndexerJobStats {
3636
public static ParseField SEARCH_FAILURES = new ParseField("search_failures");
3737
public static ParseField INDEX_FAILURES = new ParseField("index_failures");
3838

39-
private final long numPages;
40-
private final long numInputDocuments;
41-
private final long numOuputDocuments;
42-
private final long numInvocations;
43-
private final long indexTime;
44-
private final long indexTotal;
45-
private final long searchTime;
46-
private final long searchTotal;
47-
private final long indexFailures;
48-
private final long searchFailures;
39+
protected final long numPages;
40+
protected final long numInputDocuments;
41+
protected final long numOuputDocuments;
42+
protected final long numInvocations;
43+
protected final long indexTime;
44+
protected final long indexTotal;
45+
protected final long searchTime;
46+
protected final long searchTotal;
47+
protected final long indexFailures;
48+
protected final long searchFailures;
4949

5050
public IndexerJobStats(long numPages, long numInputDocuments, long numOutputDocuments, long numInvocations,
5151
long indexTime, long searchTime, long indexTotal, long searchTotal, long indexFailures, long searchFailures) {

0 commit comments

Comments
 (0)