Skip to content

Commit 1bf0130

Browse files
Merge branch 'main' into ironscales-add_ilm_delete_index
2 parents 083d8c2 + 14629f9 commit 1bf0130

File tree

42 files changed

+1275
-737
lines changed

Some content is hidden

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

42 files changed

+1275
-737
lines changed

docs/changelog/137677.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 137677
2+
summary: "[Inference] Implementing the completion task type on EIS"
3+
area: "Inference"
4+
type: enhancement
5+
issues: []

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramXContent.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ public static void serialize(XContentBuilder builder, @Nullable ExponentialHisto
6363
builder.startObject();
6464

6565
builder.field(SCALE_FIELD, histogram.scale());
66-
builder.field(SUM_FIELD, histogram.sum());
66+
67+
if (histogram.sum() != 0.0 || histogram.valueCount() > 0) {
68+
builder.field(SUM_FIELD, histogram.sum());
69+
}
6770
if (Double.isNaN(histogram.min()) == false) {
6871
builder.field(MIN_FIELD, histogram.min());
6972
}

libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramXContentTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void testNullHistogram() {
4040

4141
public void testEmptyHistogram() {
4242
ExponentialHistogram emptyHistogram = ExponentialHistogram.empty();
43-
assertThat(toJson(emptyHistogram), equalTo("{\"scale\":" + emptyHistogram.scale() + ",\"sum\":0.0}"));
43+
assertThat(toJson(emptyHistogram), equalTo("{\"scale\":" + emptyHistogram.scale() + "}"));
4444
}
4545

4646
public void testFullHistogram() {

muted-tests.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ tests:
417417
- class: org.elasticsearch.xpack.ml.integration.RevertModelSnapshotIT
418418
method: testRevertModelSnapshot_DeleteInterveningResults
419419
issue: https://github.com/elastic/elasticsearch/issues/132349
420+
- class: org.elasticsearch.xpack.security.authc.jwt.JwtRealmAuthenticateTests
421+
method: testJwkUpdatesByReloadWithFile
422+
issue: https://github.com/elastic/elasticsearch/issues/138397
423+
- class: org.elasticsearch.compute.data.ExponentialHistogramBlockTests
424+
method: testComponentAccess
425+
issue: https://github.com/elastic/elasticsearch/issues/138399
420426

421427
# Examples:
422428
#

test/framework/src/main/java/org/elasticsearch/index/mapper/TestBlock.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,12 +833,13 @@ public static TestBlock parseHistogramsToBlock(
833833
}
834834
CompressedExponentialHistogram result = new CompressedExponentialHistogram();
835835
try {
836+
Double sum = (Double) sums.get(i);
836837
Double min = (Double) minima.get(i);
837838
Double max = (Double) maxima.get(i);
838839
result.reset(
839840
(Double) zeroThresholds.get(i),
840841
(Long) valueCounts.get(i),
841-
(Double) sums.get(i),
842+
sum == null ? 0.0 : sum,
842843
min == null ? Double.NaN : min,
843844
max == null ? Double.NaN : max,
844845
(BytesRef) encodedHistograms.get(i)

x-pack/plugin/downsample/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dependencies {
1515
compileOnly project(xpackModule('core'))
1616
testImplementation project(':modules:data-streams')
1717
testImplementation project(xpackModule('ilm'))
18+
compileOnly project(xpackModule('analytics'))
1819
compileOnly project(xpackModule('mapper-aggregate-metric'))
1920
testImplementation(testArtifact(project(xpackModule('core'))))
2021
testImplementation project(xpackModule('ccr'))

x-pack/plugin/downsample/src/internalClusterTest/java/org/elasticsearch/xpack/downsample/DownsampleIT.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,18 @@ public void testLastValueMode() throws Exception {
147147
"metrics.cpu_usage": {
148148
"type": "double",
149149
"time_series_metric": "gauge"
150+
},
151+
"my_labels": {
152+
"properties": {
153+
"my_histogram": {
154+
"type": "histogram"
155+
},
156+
"my_aggregate": {
157+
"type": "aggregate_metric_double",
158+
"metrics": [ "min", "max", "sum", "value_count" ],
159+
"default_metric": "max"
160+
}
161+
}
150162
}
151163
}
152164
}
@@ -157,12 +169,25 @@ public void testLastValueMode() throws Exception {
157169
Supplier<XContentBuilder> sourceSupplier = () -> {
158170
String ts = randomDateForRange(now.minusSeconds(60 * 60).toEpochMilli(), now.plusSeconds(60 * 29).toEpochMilli());
159171
try {
172+
int maxHistogramSize = randomIntBetween(2, 10);
160173
return XContentFactory.jsonBuilder()
161174
.startObject()
162175
.field("@timestamp", ts)
163176
.field("attributes.host.name", randomFrom("host1", "host2", "host3"))
164177
.field("attributes.os.name", randomFrom("linux", "windows", "macos"))
165178
.field("metrics.cpu_usage", randomDouble())
179+
180+
.startObject("my_labels.my_histogram")
181+
.array("values", randomHistogramValues(maxHistogramSize))
182+
.array("counts", randomHistogramValueCounts(maxHistogramSize))
183+
.endObject()
184+
185+
.startObject("my_labels.my_aggregate")
186+
.field("min", randomFloatBetween(0.0f, 10.0f, true))
187+
.field("max", randomFloatBetween(10.0f, 20.0f, true))
188+
.field("sum", randomFloatBetween(20.0f, 30.0f, true))
189+
.field("value_count", randomIntBetween(1, 10))
190+
.endObject()
166191
.endObject();
167192
} catch (IOException e) {
168193
throw new RuntimeException(e);
@@ -536,4 +561,21 @@ private String rolloverAndDownsample(String dataStreamName, DownsampleConfig dow
536561
private EsqlQueryResponse esqlCommand(String command) throws IOException {
537562
return client().execute(EsqlQueryAction.INSTANCE, new EsqlQueryRequest().query(command)).actionGet(30, TimeUnit.SECONDS);
538563
}
564+
565+
private static double[] randomHistogramValues(int size) {
566+
final double[] array = new double[size];
567+
double minHistogramValue = randomDoubleBetween(0.0, 0.1, true);
568+
for (int i = 0; i < array.length; i++) {
569+
array[i] = minHistogramValue += randomDoubleBetween(0.0, 0.5, true);
570+
}
571+
return array;
572+
}
573+
574+
private static int[] randomHistogramValueCounts(int size) {
575+
final int[] array = new int[size];
576+
for (int i = 0; i < array.length; i++) {
577+
array[i] = randomIntBetween(1, 100);
578+
}
579+
return array;
580+
}
539581
}

x-pack/plugin/downsample/src/internalClusterTest/java/org/elasticsearch/xpack/downsample/DownsamplingIntegTestCase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.elasticsearch.xcontent.XContentBuilder;
4545
import org.elasticsearch.xcontent.XContentFactory;
4646
import org.elasticsearch.xpack.aggregatemetric.AggregateMetricMapperPlugin;
47+
import org.elasticsearch.xpack.analytics.AnalyticsPlugin;
4748
import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;
4849
import org.elasticsearch.xpack.esql.plugin.EsqlPlugin;
4950

@@ -88,7 +89,8 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
8889
LocalStateCompositeXPackPlugin.class,
8990
Downsample.class,
9091
AggregateMetricMapperPlugin.class,
91-
EsqlPlugin.class
92+
EsqlPlugin.class,
93+
AnalyticsPlugin.class
9294
);
9395
}
9496

x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/AggregateMetricFieldSerializer.java

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
import java.io.IOException;
1313
import java.util.Collection;
1414

15+
/**
16+
* This serialiser can be used to convert a list of producers to an aggregate metric double field. The producer should produce an
17+
* aggregate metric double or a sub metric of one, any other producers will trigger an error.
18+
*/
1519
final class AggregateMetricFieldSerializer implements DownsampleFieldSerializer {
1620
private final Collection<AbstractDownsampleFieldProducer> producers;
1721
private final String name;
@@ -36,31 +40,33 @@ public void write(XContentBuilder builder) throws IOException {
3640
builder.startObject(name);
3741
for (AbstractDownsampleFieldProducer fieldProducer : producers) {
3842
assert name.equals(fieldProducer.name()) : "producer has a different name";
39-
if (fieldProducer.isEmpty() == false) {
40-
if (fieldProducer instanceof MetricFieldProducer metricFieldProducer) {
41-
if (metricFieldProducer instanceof MetricFieldProducer.AggregateScalarMetricFieldProducer gaugeProducer) {
42-
builder.field("max", gaugeProducer.max);
43-
builder.field("min", gaugeProducer.min);
44-
builder.field("sum", gaugeProducer.sum.value());
45-
builder.field("value_count", gaugeProducer.count);
46-
} else if (metricFieldProducer instanceof MetricFieldProducer.LastValueScalarMetricFieldProducer lastValueProducer) {
47-
builder.field(lastValueProducer.sampleLabel(), lastValueProducer.lastValue);
48-
} else if (metricFieldProducer instanceof MetricFieldProducer.AggregatePreAggregatedMetricFieldProducer producer) {
49-
switch (producer.metric) {
50-
case max -> builder.field("max", producer.max);
51-
case min -> builder.field("min", producer.min);
52-
case sum -> builder.field("sum", producer.sum.value());
53-
case value_count -> builder.field("value_count", producer.count);
54-
}
55-
} else {
56-
throw new IllegalStateException();
43+
if (fieldProducer.isEmpty()) {
44+
continue;
45+
}
46+
switch (fieldProducer) {
47+
case MetricFieldProducer.AggregateGaugeMetricFieldProducer producer -> {
48+
builder.field("max", producer.max);
49+
builder.field("min", producer.min);
50+
builder.field("sum", producer.sum.value());
51+
builder.field("value_count", producer.count);
52+
}
53+
case MetricFieldProducer.AggregateSubMetricFieldProducer producer -> {
54+
switch (producer.metric) {
55+
case max -> builder.field("max", producer.max);
56+
case min -> builder.field("min", producer.min);
57+
case sum -> builder.field("sum", producer.sum.value());
58+
case value_count -> builder.field("value_count", producer.count);
5759
}
58-
} else if (fieldProducer instanceof LabelFieldProducer labelFieldProducer) {
59-
LabelFieldProducer.Label label = labelFieldProducer.label();
60-
if (label.get() != null) {
61-
builder.field(label.name(), label.get());
60+
}
61+
case LastValueFieldProducer.AggregateSubMetricFieldProducer lastValueFieldProducer -> {
62+
Object lastValue = lastValueFieldProducer.lastValue();
63+
if (lastValue != null) {
64+
builder.field(lastValueFieldProducer.subMetric(), lastValue);
6265
}
6366
}
67+
default -> throw new IllegalStateException(
68+
"Unexpected field producer class: " + fieldProducer.getClass().getSimpleName() + " for " + name + " field"
69+
);
6470
}
6571
}
6672
builder.endObject();

x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/AggregateMetricFieldValueFetcher.java renamed to x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/AggregateSubMetricFieldValueFetcher.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,24 @@
1111
import org.elasticsearch.index.fielddata.IndexFieldData;
1212
import org.elasticsearch.index.mapper.MappedFieldType;
1313
import org.elasticsearch.index.mapper.NumberFieldMapper;
14+
import org.elasticsearch.index.query.SearchExecutionContext;
1415
import org.elasticsearch.xpack.aggregatemetric.mapper.AggregateMetricDoubleFieldMapper;
1516
import org.elasticsearch.xpack.aggregatemetric.mapper.AggregateMetricDoubleFieldMapper.AggregateMetricDoubleFieldType;
1617

17-
public final class AggregateMetricFieldValueFetcher extends FieldValueFetcher {
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
21+
/**
22+
* This {@link FieldValueFetcher} is responsible for fetching the values of aggregate metric double fields.
23+
* For performance reasons, we load an aggregate metric double by loading its sub-metrics separately.
24+
*/
25+
public final class AggregateSubMetricFieldValueFetcher extends FieldValueFetcher {
1826

1927
private final AggregateMetricDoubleFieldType aggMetricFieldType;
2028

2129
private final AbstractDownsampleFieldProducer fieldProducer;
2230

23-
AggregateMetricFieldValueFetcher(
31+
AggregateSubMetricFieldValueFetcher(
2432
MappedFieldType fieldType,
2533
AggregateMetricDoubleFieldType aggMetricFieldType,
2634
IndexFieldData<?> fieldData,
@@ -31,10 +39,31 @@ public final class AggregateMetricFieldValueFetcher extends FieldValueFetcher {
3139
this.fieldProducer = createFieldProducer(samplingMethod);
3240
}
3341

42+
@Override
3443
public AbstractDownsampleFieldProducer fieldProducer() {
3544
return fieldProducer;
3645
}
3746

47+
/**
48+
* For aggregate_metric_double fields we create separate fetchers for each sub-metric. This is usually a downsample-of-downsample case.
49+
*/
50+
static List<AggregateSubMetricFieldValueFetcher> create(
51+
SearchExecutionContext context,
52+
AggregateMetricDoubleFieldMapper.AggregateMetricDoubleFieldType aggMetricFieldType,
53+
DownsampleConfig.SamplingMethod samplingMethod
54+
) {
55+
List<AggregateSubMetricFieldValueFetcher> fetchers = new ArrayList<>();
56+
// If the field is an aggregate_metric_double field, we should load all its subfields
57+
// This is usually a downsample-of-downsample case
58+
for (NumberFieldMapper.NumberFieldType metricSubField : aggMetricFieldType.getMetricFields().values()) {
59+
if (context.fieldExistsInIndex(metricSubField.name())) {
60+
IndexFieldData<?> fieldData = context.getForField(metricSubField, MappedFieldType.FielddataOperation.SEARCH);
61+
fetchers.add(new AggregateSubMetricFieldValueFetcher(metricSubField, aggMetricFieldType, fieldData, samplingMethod));
62+
}
63+
}
64+
return fetchers;
65+
}
66+
3867
private AbstractDownsampleFieldProducer createFieldProducer(DownsampleConfig.SamplingMethod samplingMethod) {
3968
AggregateMetricDoubleFieldMapper.Metric metric = null;
4069
for (var e : aggMetricFieldType.getMetricFields().entrySet()) {
@@ -50,13 +79,13 @@ private AbstractDownsampleFieldProducer createFieldProducer(DownsampleConfig.Sam
5079
if (samplingMethod != DownsampleConfig.SamplingMethod.LAST_VALUE) {
5180
// If the field is an aggregate_metric_double field, we should use the correct subfields
5281
// for each aggregation. This is a downsample-of-downsample case
53-
return new MetricFieldProducer.AggregatePreAggregatedMetricFieldProducer(aggMetricFieldType.name(), metric);
82+
return new MetricFieldProducer.AggregateSubMetricFieldProducer(aggMetricFieldType.name(), metric);
5483
} else {
55-
return new MetricFieldProducer.LastValueScalarMetricFieldProducer(aggMetricFieldType.name(), metric);
84+
return LastValueFieldProducer.createForAggregateSubMetricMetric(aggMetricFieldType.name(), metric);
5685
}
5786
} else {
58-
// If field is not a metric, we downsample it as a label
59-
return new LabelFieldProducer.AggregateMetricFieldProducer.AggregateMetricFieldProducer(aggMetricFieldType.name(), metric);
87+
// If a field is not a metric, we downsample it as a label
88+
return LastValueFieldProducer.createForAggregateSubMetricLabel(aggMetricFieldType.name(), metric);
6089
}
6190
}
6291
}

0 commit comments

Comments
 (0)