mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 01:22:26 -04:00
Refactor FieldCapabilities creation by adding a proper builder object (#121310)
Reduce boilerplate associated with creating `FieldCapabilities` instances. Since it's a class with a huge number of fields, it makes sense to define a builder object, as that can also help with all the Boolean and null blindness going on. Note while there is a static Builder class in `FieldCapabilities`, it is not a proper builder object (no setters, still need to pass a lot of otherwise default parameters) and also package-private. To avoid changing that, I defined a new `FieldCapabilitiesBuilder` class. I also went over the code and refactored places which used the old constructor.
This commit is contained in:
parent
b1c75d1868
commit
a6e47ae85b
15 changed files with 213 additions and 242 deletions
|
@ -10,6 +10,7 @@
|
|||
package org.elasticsearch.index.mapper.extras;
|
||||
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.support.ActiveShardCount;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
|
@ -19,7 +20,6 @@ import org.junit.Before;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
|
@ -59,10 +59,7 @@ public class FieldCapsRankFeatureTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooRankField = response.getField("fooRank");
|
||||
assertEquals(1, fooRankField.size());
|
||||
assertThat(fooRankField, Matchers.hasKey("rank_feature"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("fooRank", "rank_feature", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooRankField.get("rank_feature")
|
||||
);
|
||||
assertEquals(fieldCapabilities("fooRank"), fooRankField.get("rank_feature"));
|
||||
}
|
||||
|
||||
public void testRankFeatureInIndexAfterRestart() throws Exception {
|
||||
|
@ -79,10 +76,7 @@ public class FieldCapsRankFeatureTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooRankField = response.getField("fooRank");
|
||||
assertEquals(1, fooRankField.size());
|
||||
assertThat(fooRankField, Matchers.hasKey("rank_feature"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("fooRank", "rank_feature", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooRankField.get("rank_feature")
|
||||
);
|
||||
assertEquals(fieldCapabilities("fooRank"), fooRankField.get("rank_feature"));
|
||||
}
|
||||
|
||||
public void testAllRankFeatureReturnedIfOneIsPresent() {
|
||||
|
@ -98,18 +92,16 @@ public class FieldCapsRankFeatureTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooRankField = response.getField("fooRank");
|
||||
assertEquals(1, fooRankField.size());
|
||||
assertThat(fooRankField, Matchers.hasKey("rank_feature"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("fooRank", "rank_feature", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooRankField.get("rank_feature")
|
||||
);
|
||||
assertEquals(fieldCapabilities("fooRank"), fooRankField.get("rank_feature"));
|
||||
assertThat(response.get(), Matchers.hasKey("barRank"));
|
||||
// Check the capabilities for the 'barRank' field.
|
||||
Map<String, FieldCapabilities> barRankField = response.getField("barRank");
|
||||
assertEquals(1, barRankField.size());
|
||||
assertThat(barRankField, Matchers.hasKey("rank_feature"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("barRank", "rank_feature", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
barRankField.get("rank_feature")
|
||||
);
|
||||
assertEquals(fieldCapabilities("barRank"), barRankField.get("rank_feature"));
|
||||
}
|
||||
|
||||
private static FieldCapabilities fieldCapabilities(String fieldName) {
|
||||
return new FieldCapabilitiesBuilder(fieldName, "rank_feature").isAggregatable(false).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteUtils;
|
|||
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesFailure;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
|
@ -219,24 +220,11 @@ public class FieldCapabilitiesIT extends ESIntegTestCase {
|
|||
assertEquals(2, distance.size());
|
||||
|
||||
assertTrue(distance.containsKey("double"));
|
||||
assertEquals(
|
||||
new FieldCapabilities(
|
||||
"distance",
|
||||
"double",
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
new String[] { "old_index" },
|
||||
null,
|
||||
null,
|
||||
Collections.emptyMap()
|
||||
),
|
||||
distance.get("double")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("distance", "double").indices("old_index").build(), distance.get("double"));
|
||||
|
||||
assertTrue(distance.containsKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("distance", "text", false, true, false, new String[] { "new_index" }, null, null, Collections.emptyMap()),
|
||||
new FieldCapabilitiesBuilder("distance", "text").isAggregatable(false).indices("new_index").build(),
|
||||
distance.get("text")
|
||||
);
|
||||
|
||||
|
@ -245,10 +233,7 @@ public class FieldCapabilitiesIT extends ESIntegTestCase {
|
|||
assertEquals(1, routeLength.size());
|
||||
|
||||
assertTrue(routeLength.containsKey("double"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("route_length_miles", "double", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
routeLength.get("double")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("route_length_miles", "double").build(), routeLength.get("double"));
|
||||
}
|
||||
|
||||
public void testFieldAliasWithWildcard() {
|
||||
|
@ -284,24 +269,11 @@ public class FieldCapabilitiesIT extends ESIntegTestCase {
|
|||
assertEquals(2, oldField.size());
|
||||
|
||||
assertTrue(oldField.containsKey("long"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("old_field", "long", false, true, true, new String[] { "old_index" }, null, null, Collections.emptyMap()),
|
||||
oldField.get("long")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("old_field", "long").indices("old_index").build(), oldField.get("long"));
|
||||
|
||||
assertTrue(oldField.containsKey("unmapped"));
|
||||
assertEquals(
|
||||
new FieldCapabilities(
|
||||
"old_field",
|
||||
"unmapped",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
new String[] { "new_index" },
|
||||
null,
|
||||
null,
|
||||
Collections.emptyMap()
|
||||
),
|
||||
new FieldCapabilitiesBuilder("old_field", "unmapped").isSearchable(false).isAggregatable(false).indices("new_index").build(),
|
||||
oldField.get("unmapped")
|
||||
);
|
||||
|
||||
|
@ -309,10 +281,7 @@ public class FieldCapabilitiesIT extends ESIntegTestCase {
|
|||
assertEquals(1, newField.size());
|
||||
|
||||
assertTrue(newField.containsKey("long"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("new_field", "long", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
newField.get("long")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("new_field", "long").build(), newField.get("long"));
|
||||
}
|
||||
|
||||
public void testWithIndexAlias() {
|
||||
|
@ -431,7 +400,7 @@ public class FieldCapabilitiesIT extends ESIntegTestCase {
|
|||
|
||||
assertTrue(idField.containsKey("_id"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("_id", "_id", true, true, false, null, null, null, Collections.emptyMap()),
|
||||
new FieldCapabilitiesBuilder("_id", "_id").isMetadataField(true).isAggregatable(false).build(),
|
||||
idField.get("_id")
|
||||
);
|
||||
|
||||
|
@ -439,10 +408,7 @@ public class FieldCapabilitiesIT extends ESIntegTestCase {
|
|||
assertEquals(1, testField.size());
|
||||
|
||||
assertTrue(testField.containsKey("keyword"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("_test", "keyword", true, true, true, null, null, null, Collections.emptyMap()),
|
||||
testField.get("keyword")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("_test", "keyword").isMetadataField(true).build(), testField.get("keyword"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ package org.elasticsearch.search.fieldcaps;
|
|||
|
||||
import org.elasticsearch.action.DocWriteResponse;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.support.ActiveShardCount;
|
||||
|
@ -76,10 +77,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
}
|
||||
|
||||
public void testOnlyFieldsWithValueInAlias() {
|
||||
|
@ -94,10 +92,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
}
|
||||
|
||||
public void testOnlyFieldsWithValueInSpecifiedIndex() {
|
||||
|
@ -112,10 +107,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
}
|
||||
|
||||
public void testOnlyFieldsWithValueInSpecifiedAlias() {
|
||||
|
@ -130,10 +122,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
}
|
||||
|
||||
public void testFieldsWithValueAfterUpdate() {
|
||||
|
@ -150,18 +139,12 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
// Check the capabilities for the 'bar' field.
|
||||
Map<String, FieldCapabilities> barField = response.getField("bar");
|
||||
assertEquals(1, barField.size());
|
||||
assertThat(barField, Matchers.hasKey("keyword"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("bar", "keyword", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
barField.get("keyword")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("bar", "keyword").build(), barField.get("keyword"));
|
||||
}
|
||||
|
||||
public void testOnlyFieldsWithValueAfterNodesRestart() throws Exception {
|
||||
|
@ -177,10 +160,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
}
|
||||
|
||||
public void testFieldsAndAliasWithValue() {
|
||||
|
@ -198,26 +178,17 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
// Check the capabilities for the 'bar' field.
|
||||
Map<String, FieldCapabilities> barField = response.getField("bar");
|
||||
assertEquals(1, barField.size());
|
||||
assertThat(barField, Matchers.hasKey("keyword"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("bar", "keyword", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
barField.get("keyword")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("bar", "keyword").build(), barField.get("keyword"));
|
||||
// Check the capabilities for the 'bar-alias' field.
|
||||
Map<String, FieldCapabilities> barAlias = response.getField("bar-alias");
|
||||
assertEquals(1, barAlias.size());
|
||||
assertThat(barAlias, Matchers.hasKey("keyword"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("bar-alias", "keyword", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
barAlias.get("keyword")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("bar-alias", "keyword").build(), barAlias.get("keyword"));
|
||||
}
|
||||
|
||||
public void testUnmappedFieldsWithValueAfterRestart() throws Exception {
|
||||
|
@ -238,7 +209,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
assertEquals(2, unmappedField.size());
|
||||
assertThat(unmappedField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("unmapped", "text", false, true, false, new String[] { INDEX1 }, null, null, Collections.emptyMap()),
|
||||
new FieldCapabilitiesBuilder("unmapped", "text").isAggregatable(false).indices(INDEX1).build(),
|
||||
unmappedField.get("text")
|
||||
);
|
||||
}
|
||||
|
@ -257,18 +228,12 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
// Check the capabilities for the 'bar' field.
|
||||
Map<String, FieldCapabilities> barField = response.getField("bar");
|
||||
assertEquals(1, barField.size());
|
||||
assertThat(barField, Matchers.hasKey("date"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("bar", "date", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
barField.get("date")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("bar", "date").build(), barField.get("date"));
|
||||
}
|
||||
|
||||
public void testSameFieldNameTwoIndices() {
|
||||
|
@ -284,15 +249,9 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> barField = response.getField("bar");
|
||||
assertEquals(2, barField.size());
|
||||
assertThat(barField, Matchers.hasKey("keyword"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("bar", "keyword", false, true, true, new String[] { INDEX1 }, null, null, Collections.emptyMap()),
|
||||
barField.get("keyword")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("bar", "keyword").indices(INDEX1).build(), barField.get("keyword"));
|
||||
assertThat(barField, Matchers.hasKey("date"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("bar", "date", false, true, true, new String[] { INDEX2 }, null, null, Collections.emptyMap()),
|
||||
barField.get("date")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("bar", "date").indices(INDEX2).build(), barField.get("date"));
|
||||
}
|
||||
|
||||
public void testDeletedDocsReturned() {
|
||||
|
@ -311,10 +270,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
Map<String, FieldCapabilities> fooField = response.getField("foo");
|
||||
assertEquals(1, fooField.size());
|
||||
assertThat(fooField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("foo", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
fooField.get("text")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("foo", "text").isAggregatable(false).build(), fooField.get("text"));
|
||||
}
|
||||
|
||||
public void testNoNestedFieldsInEmptyIndex() {
|
||||
|
@ -339,7 +295,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
assertEquals(1, nestedTypeField.size());
|
||||
assertThat(nestedTypeField, Matchers.hasKey("nested"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("nested_type", "nested", false, false, false, null, null, null, Collections.emptyMap()),
|
||||
new FieldCapabilitiesBuilder("nested_type", "nested").isSearchable(false).isAggregatable(false).build(),
|
||||
nestedTypeField.get("nested")
|
||||
);
|
||||
// Check the capabilities for the 'nested_type.nested_field' field.
|
||||
|
@ -347,7 +303,7 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
assertEquals(1, nestedTypeNestedField.size());
|
||||
assertThat(nestedTypeNestedField, Matchers.hasKey("text"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("nested_type.nested_field", "text", false, true, false, null, null, null, Collections.emptyMap()),
|
||||
new FieldCapabilitiesBuilder("nested_type.nested_field", "text").isAggregatable(false).build(),
|
||||
nestedTypeNestedField.get("text")
|
||||
);
|
||||
}
|
||||
|
@ -374,17 +330,14 @@ public class FieldCapsHasValueTests extends ESIntegTestCase {
|
|||
assertEquals(1, objectTypeField.size());
|
||||
assertThat(objectTypeField, Matchers.hasKey("object"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("object", "object", false, false, false, null, null, null, Collections.emptyMap()),
|
||||
new FieldCapabilitiesBuilder("object", "object").isSearchable(false).isAggregatable(false).build(),
|
||||
objectTypeField.get("object")
|
||||
);
|
||||
// Check the capabilities for the 'object.sub_field' field.
|
||||
Map<String, FieldCapabilities> objectSubfield = response.getField("object.sub_field");
|
||||
assertEquals(1, objectSubfield.size());
|
||||
assertThat(objectSubfield, Matchers.hasKey("keyword"));
|
||||
assertEquals(
|
||||
new FieldCapabilities("object.sub_field", "keyword", false, true, true, null, null, null, Collections.emptyMap()),
|
||||
objectSubfield.get("keyword")
|
||||
);
|
||||
assertEquals(new FieldCapabilitiesBuilder("object.sub_field", "keyword").build(), objectSubfield.get("keyword"));
|
||||
}
|
||||
|
||||
public void testWithIndexFilter() throws InterruptedException {
|
||||
|
|
|
@ -152,47 +152,25 @@ public class MergedFieldCapabilitiesResponseTests extends AbstractChunkedSeriali
|
|||
|
||||
private static FieldCapabilitiesResponse createSimpleResponse() {
|
||||
Map<String, FieldCapabilities> titleCapabilities = new HashMap<>();
|
||||
titleCapabilities.put(
|
||||
"text",
|
||||
new FieldCapabilities("title", "text", false, true, false, false, null, null, null, null, null, null, Collections.emptyMap())
|
||||
);
|
||||
titleCapabilities.put("text", new FieldCapabilitiesBuilder("title", "text").isAggregatable(false).build());
|
||||
|
||||
Map<String, FieldCapabilities> ratingCapabilities = new HashMap<>();
|
||||
ratingCapabilities.put(
|
||||
"long",
|
||||
new FieldCapabilities(
|
||||
"rating",
|
||||
"long",
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
TimeSeriesParams.MetricType.COUNTER,
|
||||
new String[] { "index1", "index2" },
|
||||
null,
|
||||
new String[] { "index1" },
|
||||
new String[] { "index4" },
|
||||
null,
|
||||
Collections.emptyMap()
|
||||
)
|
||||
new FieldCapabilitiesBuilder("rating", "long").isAggregatable(false)
|
||||
.metricType(TimeSeriesParams.MetricType.COUNTER)
|
||||
.indices("index1", "index2")
|
||||
.nonAggregatableIndices("index1")
|
||||
.nonDimensionIndices("index4")
|
||||
.build()
|
||||
);
|
||||
ratingCapabilities.put(
|
||||
"keyword",
|
||||
new FieldCapabilities(
|
||||
"rating",
|
||||
"keyword",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
null,
|
||||
new String[] { "index3", "index4" },
|
||||
new String[] { "index4" },
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
Collections.emptyMap()
|
||||
)
|
||||
new FieldCapabilitiesBuilder("rating", "keyword").isSearchable(false)
|
||||
.isDimension(true)
|
||||
.indices("index3", "index4")
|
||||
.nonSearchableIndices("index4")
|
||||
.build()
|
||||
);
|
||||
|
||||
Map<String, Map<String, FieldCapabilities>> responses = new HashMap<>();
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
package org.elasticsearch.action.fieldcaps;
|
||||
|
||||
import org.elasticsearch.core.Nullable;
|
||||
import org.elasticsearch.index.mapper.TimeSeriesParams;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class FieldCapabilitiesBuilder {
|
||||
private final String name;
|
||||
private final String type;
|
||||
|
||||
private boolean isMetadataField;
|
||||
private boolean isSearchable;
|
||||
private boolean isAggregatable;
|
||||
private boolean isDimension;
|
||||
private @Nullable TimeSeriesParams.MetricType metricType;
|
||||
|
||||
private @Nullable String[] indices;
|
||||
private @Nullable String[] nonSearchableIndices;
|
||||
private @Nullable String[] nonAggregatableIndices;
|
||||
private @Nullable String[] nonDimensionIndices;
|
||||
private @Nullable String[] metricConflictsIndices;
|
||||
|
||||
private Map<String, Set<String>> meta;
|
||||
|
||||
public FieldCapabilitiesBuilder(String name, String type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
||||
this.isSearchable = true;
|
||||
this.isAggregatable = true;
|
||||
|
||||
this.meta = Collections.emptyMap();
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder isMetadataField(boolean isMetadataField) {
|
||||
this.isMetadataField = isMetadataField;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder isSearchable(boolean isSearchable) {
|
||||
this.isSearchable = isSearchable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder isAggregatable(boolean isAggregatable) {
|
||||
this.isAggregatable = isAggregatable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder isDimension(boolean isDimension) {
|
||||
this.isDimension = isDimension;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder metricType(TimeSeriesParams.MetricType metricType) {
|
||||
this.metricType = metricType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder indices(String... indices) {
|
||||
this.indices = copyStringArray(indices);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder nonSearchableIndices(String... nonSearchableIndices) {
|
||||
this.nonSearchableIndices = copyStringArray(nonSearchableIndices);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder nonAggregatableIndices(String... nonAggregatableIndices) {
|
||||
this.nonAggregatableIndices = copyStringArray(nonAggregatableIndices);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder nonDimensionIndices(String... nonDimensionIndices) {
|
||||
this.nonDimensionIndices = copyStringArray(nonDimensionIndices);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder metricConflictsIndices(String... metricConflictsIndices) {
|
||||
this.metricConflictsIndices = copyStringArray(metricConflictsIndices);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static String[] copyStringArray(@Nullable String[] strings) {
|
||||
return strings != null ? Arrays.copyOf(strings, strings.length) : null;
|
||||
}
|
||||
|
||||
public FieldCapabilitiesBuilder meta(Map<String, Set<String>> meta) {
|
||||
this.meta = meta != null ? new TreeMap<>(meta) : null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FieldCapabilities build() {
|
||||
return new FieldCapabilities(
|
||||
name,
|
||||
type,
|
||||
isMetadataField,
|
||||
isSearchable,
|
||||
isAggregatable,
|
||||
isDimension,
|
||||
metricType,
|
||||
indices,
|
||||
nonSearchableIndices,
|
||||
nonAggregatableIndices,
|
||||
nonDimensionIndices,
|
||||
metricConflictsIndices,
|
||||
meta
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ package org.elasticsearch.xpack.core.ml.dataframe.analyses;
|
|||
import org.elasticsearch.ElasticsearchStatusException;
|
||||
import org.elasticsearch.TransportVersion;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
|
@ -582,6 +583,6 @@ public class ClassificationTests extends AbstractBWCSerializationTestCase<Classi
|
|||
}
|
||||
|
||||
private static FieldCapabilities createFieldCapabilities(String field, String type) {
|
||||
return new FieldCapabilities(field, type, false, true, true, null, null, null, Collections.emptyMap());
|
||||
return new FieldCapabilitiesBuilder(field, type).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.elasticsearch.xpack.eql.analysis;
|
|||
import org.elasticsearch.TransportVersion;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.search.SearchRequest;
|
||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||
|
@ -48,7 +49,6 @@ import java.util.Map;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
@ -118,19 +118,9 @@ public class CancellationTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private Map<String, Map<String, FieldCapabilities>> fields(String[] indices) {
|
||||
FieldCapabilities fooField = new FieldCapabilities("foo", "integer", false, true, true, indices, null, null, emptyMap());
|
||||
FieldCapabilities categoryField = new FieldCapabilities(
|
||||
"event.category",
|
||||
"keyword",
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
indices,
|
||||
null,
|
||||
null,
|
||||
emptyMap()
|
||||
);
|
||||
FieldCapabilities timestampField = new FieldCapabilities("@timestamp", "date", false, true, true, indices, null, null, emptyMap());
|
||||
FieldCapabilities fooField = new FieldCapabilitiesBuilder("foo", "integer").indices(indices).build();
|
||||
FieldCapabilities categoryField = new FieldCapabilitiesBuilder("event.category", "keyword").indices(indices).build();
|
||||
FieldCapabilities timestampField = new FieldCapabilitiesBuilder("@timestamp", "date").indices(indices).build();
|
||||
Map<String, Map<String, FieldCapabilities>> fields = new HashMap<>();
|
||||
fields.put(fooField.getName(), singletonMap(fooField.getName(), fooField));
|
||||
fields.put(categoryField.getName(), singletonMap(categoryField.getName(), categoryField));
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.xpack.esql.telemetry;
|
|||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.OriginalIndices;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesIndexResponse;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.fieldcaps.IndexFieldCapabilities;
|
||||
|
@ -194,8 +195,8 @@ public class PlanExecutorMetricsTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private Map<String, Map<String, FieldCapabilities>> fields(String[] indices) {
|
||||
FieldCapabilities fooField = new FieldCapabilities("foo", "integer", false, true, true, indices, null, null, Map.of());
|
||||
FieldCapabilities barField = new FieldCapabilities("bar", "long", false, true, true, indices, null, null, Map.of());
|
||||
FieldCapabilities fooField = new FieldCapabilitiesBuilder("foo", "integer").indices(indices).build();
|
||||
FieldCapabilities barField = new FieldCapabilitiesBuilder("bar", "long").indices(indices).build();
|
||||
Map<String, Map<String, FieldCapabilities>> fields = new HashMap<>();
|
||||
fields.put(fooField.getName(), Map.of(fooField.getName(), fooField));
|
||||
fields.put(barField.getName(), Map.of(barField.getName(), barField));
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsAction;
|
|||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
|
||||
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.fieldcaps.TransportFieldCapabilitiesAction;
|
||||
|
@ -800,6 +801,6 @@ public class DestinationIndexTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private static FieldCapabilities createFieldCapabilities(String field, String type) {
|
||||
return new FieldCapabilities(field, type, false, true, true, null, null, null, Collections.emptyMap());
|
||||
return new FieldCapabilitiesBuilder(field, type).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.elasticsearch.xpack.ml.dataframe.extractor;
|
|||
|
||||
import org.elasticsearch.ElasticsearchStatusException;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.common.util.Maps;
|
||||
import org.elasticsearch.core.Tuple;
|
||||
|
@ -1715,7 +1716,7 @@ public class ExtractedFieldsDetectorTests extends ESTestCase {
|
|||
for (String type : types) {
|
||||
caps.put(
|
||||
type,
|
||||
new FieldCapabilities(field, type, isMetadataField, true, isAggregatable, null, null, null, Collections.emptyMap())
|
||||
new FieldCapabilitiesBuilder(field, type).isMetadataField(isMetadataField).isAggregatable(isAggregatable).build()
|
||||
);
|
||||
}
|
||||
fieldCaps.put(field, caps);
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.elasticsearch.xpack.sql.analysis;
|
|||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.search.ClosePointInTimeRequest;
|
||||
import org.elasticsearch.action.search.ClosePointInTimeResponse;
|
||||
|
@ -50,7 +51,6 @@ import java.util.Map;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
@ -94,19 +94,9 @@ public class CancellationTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private Map<String, Map<String, FieldCapabilities>> fields(String[] indices) {
|
||||
FieldCapabilities fooField = new FieldCapabilities("foo", "integer", false, true, true, indices, null, null, emptyMap());
|
||||
FieldCapabilities categoryField = new FieldCapabilities(
|
||||
"event.category",
|
||||
"keyword",
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
indices,
|
||||
null,
|
||||
null,
|
||||
emptyMap()
|
||||
);
|
||||
FieldCapabilities timestampField = new FieldCapabilities("@timestamp", "date", false, true, true, indices, null, null, emptyMap());
|
||||
FieldCapabilities fooField = new FieldCapabilitiesBuilder("foo", "integer").indices(indices).build();
|
||||
FieldCapabilities categoryField = new FieldCapabilitiesBuilder("event.category", "keyword").indices(indices).build();
|
||||
FieldCapabilities timestampField = new FieldCapabilitiesBuilder("@timestamp", "date").indices(indices).build();
|
||||
Map<String, Map<String, FieldCapabilities>> fields = new HashMap<>();
|
||||
fields.put(fooField.getName(), singletonMap(fooField.getName(), fooField));
|
||||
fields.put(categoryField.getName(), singletonMap(categoryField.getName(), categoryField));
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.elasticsearch.xpack.sql.analysis.index;
|
||||
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapsUtils;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
|
@ -282,24 +283,8 @@ public class IndexResolverTests extends ESTestCase {
|
|||
addFieldCaps(fieldCaps, fieldName + ".keyword", "keyword", true, true);
|
||||
|
||||
Map<String, FieldCapabilities> multi = new HashMap<>();
|
||||
multi.put(
|
||||
"long",
|
||||
new FieldCapabilities(fieldName, "long", false, true, true, new String[] { "one-index" }, null, null, Collections.emptyMap())
|
||||
);
|
||||
multi.put(
|
||||
"text",
|
||||
new FieldCapabilities(
|
||||
fieldName,
|
||||
"text",
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
new String[] { "another-index" },
|
||||
null,
|
||||
null,
|
||||
Collections.emptyMap()
|
||||
)
|
||||
);
|
||||
multi.put("long", new FieldCapabilitiesBuilder(fieldName, "long").indices("one-index").build());
|
||||
multi.put("text", new FieldCapabilitiesBuilder(fieldName, "text").indices("another-index").isAggregatable(false).build());
|
||||
fieldCaps.put(fieldName, multi);
|
||||
|
||||
String wildcard = "*";
|
||||
|
@ -400,7 +385,7 @@ public class IndexResolverTests extends ESTestCase {
|
|||
"_version",
|
||||
singletonMap(
|
||||
"_index",
|
||||
new FieldCapabilities("_version", "_version", true, false, false, null, null, null, Collections.emptyMap())
|
||||
new FieldCapabilitiesBuilder("_version", "_version").isMetadataField(true).isAggregatable(false).isSearchable(false).build()
|
||||
)
|
||||
);
|
||||
assertTrue(mergedMappings("*", new String[] { "empty" }, versionFC).isValid());
|
||||
|
@ -599,7 +584,10 @@ public class IndexResolverTests extends ESTestCase {
|
|||
Map<String, FieldCapabilities> cap = new HashMap<>();
|
||||
cap.put(
|
||||
type,
|
||||
new FieldCapabilities(name, type, isMetadataField, isSearchable, isAggregatable, null, null, null, Collections.emptyMap())
|
||||
new FieldCapabilitiesBuilder(name, type).isMetadataField(isMetadataField)
|
||||
.isSearchable(isSearchable)
|
||||
.isAggregatable(isAggregatable)
|
||||
.build()
|
||||
);
|
||||
fieldCaps.put(name, cap);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package org.elasticsearch.xpack.transform.transforms.common;
|
||||
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -104,16 +105,9 @@ public class DocumentConversionUtilsTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private static FieldCapabilities createFieldCapabilities(String name, String type) {
|
||||
return new FieldCapabilities(
|
||||
name,
|
||||
type,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
Strings.EMPTY_ARRAY,
|
||||
Strings.EMPTY_ARRAY,
|
||||
Strings.EMPTY_ARRAY,
|
||||
Collections.emptyMap()
|
||||
);
|
||||
return new FieldCapabilitiesBuilder(name, type).indices(Strings.EMPTY_ARRAY)
|
||||
.nonSearchableIndices(Strings.EMPTY_ARRAY)
|
||||
.nonAggregatableIndices(Strings.EMPTY_ARRAY)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionResponse;
|
|||
import org.elasticsearch.action.ActionType;
|
||||
import org.elasticsearch.action.LatchedActionListener;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.support.ActionTestUtils;
|
||||
|
@ -92,10 +93,7 @@ public class AggregationSchemaAndResultTests extends ESTestCase {
|
|||
String[] nameTypePair = Strings.split(field, "_");
|
||||
String type = nameTypePair != null ? nameTypePair[0] : "long";
|
||||
|
||||
fieldCaps.put(
|
||||
field,
|
||||
Collections.singletonMap(type, new FieldCapabilities(field, type, false, true, true, null, null, null, emptyMap()))
|
||||
);
|
||||
fieldCaps.put(field, Collections.singletonMap(type, new FieldCapabilitiesBuilder(field, type).build()));
|
||||
}
|
||||
|
||||
// FieldCapabilitiesResponse is package private, thats why we use a mock
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionResponse;
|
|||
import org.elasticsearch.action.ActionType;
|
||||
import org.elasticsearch.action.LatchedActionListener;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilities;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesBuilder;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest;
|
||||
import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse;
|
||||
import org.elasticsearch.action.support.ActionTestUtils;
|
||||
|
@ -33,7 +34,6 @@ import org.elasticsearch.xpack.core.transform.transforms.pivot.PivotConfig;
|
|||
import org.elasticsearch.xpack.core.transform.transforms.pivot.TermsGroupSource;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -297,17 +297,10 @@ public class SchemaUtilTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private static FieldCapabilities createFieldCapabilities(String name, String type) {
|
||||
return new FieldCapabilities(
|
||||
name,
|
||||
type,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
Strings.EMPTY_ARRAY,
|
||||
Strings.EMPTY_ARRAY,
|
||||
Strings.EMPTY_ARRAY,
|
||||
Collections.emptyMap()
|
||||
);
|
||||
return new FieldCapabilitiesBuilder(name, type).indices(Strings.EMPTY_ARRAY)
|
||||
.nonSearchableIndices(Strings.EMPTY_ARRAY)
|
||||
.nonAggregatableIndices(Strings.EMPTY_ARRAY)
|
||||
.build();
|
||||
}
|
||||
|
||||
private <T> void assertAsync(Consumer<ActionListener<T>> function, Consumer<T> furtherTests) throws InterruptedException {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue