mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-25 01:19:02 +00:00
Reject updates to the _default_
mapping. (#29165)
This will reject mapping updates to the `_default_` mapping with 7.x indices and still emit a deprecation warning with 6.x indices. Relates #15613 Supersedes #28248
This commit is contained in:
parent
1d6ed824c7
commit
8f9d2ee4e2
@ -50,11 +50,6 @@ PUT /twitter-1,twitter-2/_mapping/_doc <1>
|
||||
<1> Note that the indices specified (`twitter-1,twitter-2`) follows <<multi-index,multiple index names>> and wildcard format.
|
||||
|
||||
|
||||
NOTE: When updating the `_default_` mapping with the
|
||||
<<indices-put-mapping,PUT mapping>> API, the new mapping is not merged with
|
||||
the existing mapping. Instead, the new `_default_` mapping replaces the
|
||||
existing one.
|
||||
|
||||
[[updating-field-mappings]]
|
||||
[float]
|
||||
=== Updating field mappings
|
||||
|
@ -36,5 +36,3 @@ include::dynamic/field-mapping.asciidoc[]
|
||||
|
||||
include::dynamic/templates.asciidoc[]
|
||||
|
||||
include::dynamic/default-mapping.asciidoc[]
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
[[default-mapping]]
|
||||
=== `_default_` mapping
|
||||
|
||||
deprecated[6.0.0,See <<removal-of-types>>]
|
||||
|
||||
The default mapping, which will be used as the base mapping for a new
|
||||
mapping type, can be customised by adding a mapping type with the name
|
||||
`_default_` to an index, either when
|
||||
<<indices-create-index,creating the index>> or later on with the
|
||||
<<indices-put-mapping,PUT mapping>> API.
|
||||
|
||||
The documentation for this feature has been removed as it no longer makes
|
||||
sense in 6.x where there can be only a single type per index.
|
||||
|
@ -5,6 +5,12 @@
|
||||
|
||||
The `_all` field deprecated in 6 have now been removed.
|
||||
|
||||
==== The `_default_` mapping is no longer allowed
|
||||
|
||||
The `_default_` mapping has been deprecated in 6.0 and is now no longer allowed
|
||||
in 7.0. Trying to configure a `_default_` mapping on 7.x indices will result in
|
||||
an error.
|
||||
|
||||
==== `index_options` for numeric fields has been removed
|
||||
|
||||
The `index_options` field for numeric fields has been deprecated in 6 and has now been removed.
|
||||
|
@ -373,8 +373,10 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
|
||||
Map<String, DocumentMapper> results = new LinkedHashMap<>(documentMappers.size() + 1);
|
||||
|
||||
if (defaultMapper != null) {
|
||||
if (indexSettings.getIndexVersionCreated().onOrAfter(Version.V_6_0_0_beta1)
|
||||
&& reason == MergeReason.MAPPING_UPDATE) { // only log in case of explicit mapping updates
|
||||
if (indexSettings.getIndexVersionCreated().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||
throw new IllegalArgumentException("The [default] mapping cannot be updated on index [" + index().getName() +
|
||||
"]: defaults mappings are not useful anymore now that indices can have at most one type.");
|
||||
} else if (reason == MergeReason.MAPPING_UPDATE) { // only log in case of explicit mapping updates
|
||||
DEPRECATION_LOGGER.deprecated("[_default_] mapping is deprecated since it is not useful anymore now that indexes " +
|
||||
"cannot have more than one type");
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"_default_":{
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"_default_": {
|
||||
|
||||
"properties": {
|
||||
"script": { "enabled": false },
|
||||
"template": { "enabled": false }
|
||||
}
|
||||
}
|
||||
}
|
@ -235,11 +235,7 @@ public class GetIndexIT extends ESIntegTestCase {
|
||||
assertThat(mappings.size(), equalTo(1));
|
||||
ImmutableOpenMap<String, MappingMetaData> indexMappings = mappings.get(indexName);
|
||||
assertThat(indexMappings, notNullValue());
|
||||
assertThat(indexMappings.size(), anyOf(equalTo(1), equalTo(2)));
|
||||
if (indexMappings.size() == 2) {
|
||||
MappingMetaData mapping = indexMappings.get("_default_");
|
||||
assertThat(mapping, notNullValue());
|
||||
}
|
||||
assertThat(indexMappings.size(), equalTo(1));
|
||||
MappingMetaData mapping = indexMappings.get("type1");
|
||||
assertThat(mapping, notNullValue());
|
||||
assertThat(mapping.type(), equalTo("type1"));
|
||||
@ -251,11 +247,7 @@ public class GetIndexIT extends ESIntegTestCase {
|
||||
assertThat(mappings.size(), equalTo(1));
|
||||
ImmutableOpenMap<String, MappingMetaData> indexMappings = mappings.get(indexName);
|
||||
assertThat(indexMappings, notNullValue());
|
||||
assertThat(indexMappings.size(), anyOf(equalTo(0), equalTo(1)));
|
||||
if (indexMappings.size() == 1) {
|
||||
MappingMetaData mapping = indexMappings.get("_default_");
|
||||
assertThat(mapping, notNullValue());
|
||||
}
|
||||
assertThat(indexMappings.size(), equalTo(0));
|
||||
}
|
||||
|
||||
private void assertAliases(GetIndexResponse response, String indexName) {
|
||||
|
@ -107,32 +107,6 @@ public class SpecificMasterNodesIT extends ESIntegTestCase {
|
||||
assertThat(internalCluster().masterClient().admin().cluster().prepareState().execute().actionGet().getState().nodes().getMasterNode().getName(), equalTo(nextMasterEligableNodeName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that putting custom default mapping and then putting a type mapping will have the default mapping merged
|
||||
* to the type mapping.
|
||||
*/
|
||||
public void testCustomDefaultMapping() throws Exception {
|
||||
logger.info("--> start master node / non data");
|
||||
internalCluster().startNode(Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), false).put(Node.NODE_MASTER_SETTING.getKey(), true));
|
||||
|
||||
logger.info("--> start data node / non master node");
|
||||
internalCluster().startNode(Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), true).put(Node.NODE_MASTER_SETTING.getKey(), false));
|
||||
|
||||
createIndex("test");
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("_default_").setSource("timestamp", "type=date"));
|
||||
|
||||
MappingMetaData defaultMapping = client().admin().cluster().prepareState().get().getState().getMetaData().getIndices().get("test").getMappings().get("_default_");
|
||||
Map<?,?> properties = (Map<?, ?>) defaultMapping.getSourceAsMap().get("properties");
|
||||
assertThat(properties.get("timestamp"), notNullValue());
|
||||
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("_default_").setSource("timestamp", "type=date"));
|
||||
|
||||
assertAcked(client().admin().indices().preparePutMapping("test").setType("type1").setSource("foo", "enabled=true"));
|
||||
MappingMetaData type1Mapping = client().admin().cluster().prepareState().get().getState().getMetaData().getIndices().get("test").getMappings().get("type1");
|
||||
properties = (Map<?, ?>) type1Mapping.getSourceAsMap().get("properties");
|
||||
assertThat(properties.get("timestamp"), notNullValue());
|
||||
}
|
||||
|
||||
public void testAliasFilterValidation() throws Exception {
|
||||
logger.info("--> start master node / non data");
|
||||
internalCluster().startNode(Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), false).put(Node.NODE_MASTER_SETTING.getKey(), true));
|
||||
|
@ -192,7 +192,10 @@ public class DynamicMappingTests extends ESSingleNodeTestCase {
|
||||
XContentBuilder mapping = jsonBuilder().startObject().startObject("_default_")
|
||||
.field("dynamic", "strict")
|
||||
.endObject().endObject();
|
||||
createIndex("test", Settings.EMPTY, "_default_", mapping);
|
||||
Settings settings = Settings.builder()
|
||||
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_6_3_0)
|
||||
.build();
|
||||
createIndex("test", settings, "_default_", mapping);
|
||||
try {
|
||||
client().prepareIndex().setIndex("test").setType("type").setSource(jsonBuilder().startObject().field("test", "test").endObject()).get();
|
||||
fail();
|
||||
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.mapper;
|
||||
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.compress.CompressedXContent;
|
||||
@ -85,25 +86,6 @@ public class MapperServiceTests extends ESSingleNodeTestCase {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("mapping type name [" + type + "] is too long; limit is length 255 but was [256]"));
|
||||
}
|
||||
|
||||
public void testTypes() throws Exception {
|
||||
IndexService indexService1 = createIndex("index1", Settings.builder().put("index.version.created", Version.V_5_6_0) // multi types
|
||||
.build());
|
||||
MapperService mapperService = indexService1.mapperService();
|
||||
assertEquals(Collections.emptySet(), mapperService.types());
|
||||
|
||||
mapperService.merge("type1", new CompressedXContent("{\"type1\":{}}"), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
assertNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
|
||||
assertEquals(Collections.singleton("type1"), mapperService.types());
|
||||
|
||||
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent("{\"_default_\":{}}"), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
assertNotNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
|
||||
assertEquals(Collections.singleton("type1"), mapperService.types());
|
||||
|
||||
mapperService.merge("type2", new CompressedXContent("{\"type2\":{}}"), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
assertNotNull(mapperService.documentMapper(MapperService.DEFAULT_MAPPING));
|
||||
assertEquals(new HashSet<>(Arrays.asList("type1", "type2")), mapperService.types());
|
||||
}
|
||||
|
||||
public void testTypeValidation() {
|
||||
InvalidTypeNameException e = expectThrows(InvalidTypeNameException.class, () -> MapperService.validateTypeName("_type"));
|
||||
assertEquals("mapping type name [_type] can't start with '_' unless it is called [_doc]", e.getMessage());
|
||||
@ -325,9 +307,19 @@ public class MapperServiceTests extends ESSingleNodeTestCase {
|
||||
assertThat(e.getMessage(), Matchers.startsWith("Rejecting mapping update to [test] as the final mapping would have more than 1 type: "));
|
||||
}
|
||||
|
||||
public void testDefaultMappingIsDeprecated() throws IOException {
|
||||
public void testDefaultMappingIsRejectedOn7() throws IOException {
|
||||
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("_default_").endObject().endObject());
|
||||
MapperService mapperService = createIndex("test").mapperService();
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
() -> mapperService.merge("_default_", new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE));
|
||||
assertEquals("The [default] mapping cannot be updated on index [test]: defaults mappings are not useful anymore now that indices " +
|
||||
"can have at most one type.", e.getMessage());
|
||||
}
|
||||
|
||||
public void testDefaultMappingIsDeprecatedOn6() throws IOException {
|
||||
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_6_3_0).build();
|
||||
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("_default_").endObject().endObject());
|
||||
MapperService mapperService = createIndex("test", settings).mapperService();
|
||||
mapperService.merge("_default_", new CompressedXContent(mapping), MergeReason.MAPPING_UPDATE);
|
||||
assertWarnings("[_default_] mapping is deprecated since it is not useful anymore now that indexes " +
|
||||
"cannot have more than one type");
|
||||
|
@ -117,83 +117,7 @@ public class SourceFieldMapperTests extends ESSingleNodeTestCase {
|
||||
assertThat(sourceAsMap.containsKey("path2"), equalTo(true));
|
||||
}
|
||||
|
||||
public void testDefaultMappingAndNoMapping() throws Exception {
|
||||
String defaultMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING)
|
||||
.startObject("_source").field("enabled", false).endObject()
|
||||
.endObject().endObject());
|
||||
|
||||
DocumentMapperParser parser = createIndex("test").mapperService().documentMapperParser();
|
||||
DocumentMapper mapper = parser.parse("my_type", null, defaultMapping);
|
||||
assertThat(mapper.type(), equalTo("my_type"));
|
||||
assertThat(mapper.sourceMapper().enabled(), equalTo(false));
|
||||
try {
|
||||
mapper = parser.parse(null, null, defaultMapping);
|
||||
assertThat(mapper.type(), equalTo("my_type"));
|
||||
assertThat(mapper.sourceMapper().enabled(), equalTo(false));
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
// all is well
|
||||
}
|
||||
try {
|
||||
mapper = parser.parse(null, new CompressedXContent("{}"), defaultMapping);
|
||||
assertThat(mapper.type(), equalTo("my_type"));
|
||||
assertThat(mapper.sourceMapper().enabled(), equalTo(false));
|
||||
fail();
|
||||
} catch (MapperParsingException e) {
|
||||
assertThat(e.getMessage(), equalTo("malformed mapping no root object found"));
|
||||
// all is well
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultMappingAndWithMappingOverride() throws Exception {
|
||||
String defaultMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING)
|
||||
.startObject("_source").field("enabled", false).endObject()
|
||||
.endObject().endObject());
|
||||
|
||||
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("my_type")
|
||||
.startObject("_source").field("enabled", true).endObject()
|
||||
.endObject().endObject());
|
||||
|
||||
DocumentMapper mapper = createIndex("test").mapperService().documentMapperParser()
|
||||
.parse("my_type", new CompressedXContent(mapping), defaultMapping);
|
||||
assertThat(mapper.type(), equalTo("my_type"));
|
||||
assertThat(mapper.sourceMapper().enabled(), equalTo(true));
|
||||
}
|
||||
|
||||
public void testDefaultMappingAndNoMappingWithMapperService() throws Exception {
|
||||
String defaultMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING)
|
||||
.startObject("_source").field("enabled", false).endObject()
|
||||
.endObject().endObject());
|
||||
|
||||
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_5_6_0).build();
|
||||
MapperService mapperService = createIndex("test", settings).mapperService();
|
||||
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent(defaultMapping), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
|
||||
DocumentMapper mapper = mapperService.documentMapperWithAutoCreate("my_type").getDocumentMapper();
|
||||
assertThat(mapper.type(), equalTo("my_type"));
|
||||
assertThat(mapper.sourceMapper().enabled(), equalTo(false));
|
||||
}
|
||||
|
||||
public void testDefaultMappingAndWithMappingOverrideWithMapperService() throws Exception {
|
||||
String defaultMapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING)
|
||||
.startObject("_source").field("enabled", false).endObject()
|
||||
.endObject().endObject());
|
||||
|
||||
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_5_6_0).build();
|
||||
MapperService mapperService = createIndex("test", settings).mapperService();
|
||||
mapperService.merge(MapperService.DEFAULT_MAPPING, new CompressedXContent(defaultMapping), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
|
||||
String mapping = Strings.toString(XContentFactory.jsonBuilder().startObject().startObject("my_type")
|
||||
.startObject("_source").field("enabled", true).endObject()
|
||||
.endObject().endObject());
|
||||
mapperService.merge("my_type", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE);
|
||||
|
||||
DocumentMapper mapper = mapperService.documentMapper("my_type");
|
||||
assertThat(mapper.type(), equalTo("my_type"));
|
||||
assertThat(mapper.sourceMapper().enabled(), equalTo(true));
|
||||
}
|
||||
|
||||
void assertConflicts(String mapping1, String mapping2, DocumentMapperParser parser, String... conflicts) throws IOException {
|
||||
private void assertConflicts(String mapping1, String mapping2, DocumentMapperParser parser, String... conflicts) throws IOException {
|
||||
DocumentMapper docMapper = parser.parse("type", new CompressedXContent(mapping1));
|
||||
docMapper = parser.parse("type", docMapper.mappingSource());
|
||||
if (conflicts.length == 0) {
|
||||
|
@ -26,6 +26,7 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
|
||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.common.Priority;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
@ -203,11 +204,13 @@ public class UpdateMappingIntegrationIT extends ESIntegTestCase {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUpdateDefaultMappingSettings() throws Exception {
|
||||
logger.info("Creating index with _default_ mappings");
|
||||
client().admin().indices().prepareCreate("test").addMapping(MapperService.DEFAULT_MAPPING,
|
||||
JsonXContent.contentBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING)
|
||||
client().admin().indices().prepareCreate("test")
|
||||
.setSettings(Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_6_3_0).build())
|
||||
.addMapping(MapperService.DEFAULT_MAPPING,
|
||||
JsonXContent.contentBuilder().startObject().startObject(MapperService.DEFAULT_MAPPING)
|
||||
.field("date_detection", false)
|
||||
.endObject().endObject()
|
||||
).get();
|
||||
).get();
|
||||
|
||||
GetMappingsResponse getResponse = client().admin().indices().prepareGetMappings("test").addTypes(MapperService.DEFAULT_MAPPING).get();
|
||||
Map<String, Object> defaultMapping = getResponse.getMappings().get("test").get(MapperService.DEFAULT_MAPPING).sourceAsMap();
|
||||
|
@ -629,21 +629,7 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
||||
.setOrder(0)
|
||||
.addMapping("test", "field", "type=text")
|
||||
.addAlias(new Alias("alias1").filter(termQuery("field", "value"))).get();
|
||||
// Indexing into b should succeed, because the field mapping for field 'field' is defined in the _default_ mapping and
|
||||
// the test type exists.
|
||||
client().admin().indices().preparePutTemplate("template2")
|
||||
.setPatterns(Collections.singletonList("b*"))
|
||||
.setOrder(0)
|
||||
.addMapping("_default_", "field", "type=text")
|
||||
.addMapping("test")
|
||||
.addAlias(new Alias("alias2").filter(termQuery("field", "value"))).get();
|
||||
// Indexing into c should succeed, because the field mapping for field 'field' is defined in the _default_ mapping.
|
||||
client().admin().indices().preparePutTemplate("template3")
|
||||
.setPatterns(Collections.singletonList("c*"))
|
||||
.setOrder(0)
|
||||
.addMapping("_default_", "field", "type=text")
|
||||
.addAlias(new Alias("alias3").filter(termQuery("field", "value"))).get();
|
||||
// Indexing into d index should fail, since there is field with name 'field' in the mapping
|
||||
// Indexing into b index should fail, since there is field with name 'field' in the mapping
|
||||
client().admin().indices().preparePutTemplate("template4")
|
||||
.setPatterns(Collections.singletonList("d*"))
|
||||
.setOrder(0)
|
||||
@ -658,24 +644,6 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
||||
assertThat(response.getItems()[0].getId(), equalTo("test"));
|
||||
assertThat(response.getItems()[0].getVersion(), equalTo(1L));
|
||||
|
||||
client().prepareIndex("b1", "test", "test").setSource("{}", XContentType.JSON).get();
|
||||
response = client().prepareBulk().add(new IndexRequest("b2", "test", "test").source("{}", XContentType.JSON)).get();
|
||||
assertThat(response.hasFailures(), is(false));
|
||||
assertThat(response.getItems()[0].isFailed(), equalTo(false));
|
||||
assertThat(response.getItems()[0].getIndex(), equalTo("b2"));
|
||||
assertThat(response.getItems()[0].getType(), equalTo("test"));
|
||||
assertThat(response.getItems()[0].getId(), equalTo("test"));
|
||||
assertThat(response.getItems()[0].getVersion(), equalTo(1L));
|
||||
|
||||
client().prepareIndex("c1", "test", "test").setSource("{}", XContentType.JSON).get();
|
||||
response = client().prepareBulk().add(new IndexRequest("c2", "test", "test").source("{}", XContentType.JSON)).get();
|
||||
assertThat(response.hasFailures(), is(false));
|
||||
assertThat(response.getItems()[0].isFailed(), equalTo(false));
|
||||
assertThat(response.getItems()[0].getIndex(), equalTo("c2"));
|
||||
assertThat(response.getItems()[0].getType(), equalTo("test"));
|
||||
assertThat(response.getItems()[0].getId(), equalTo("test"));
|
||||
assertThat(response.getItems()[0].getVersion(), equalTo(1L));
|
||||
|
||||
// Before 2.0 alias filters were parsed at alias creation time, in order
|
||||
// for filters to work correctly ES required that fields mentioned in those
|
||||
// filters exist in the mapping.
|
||||
@ -684,9 +652,9 @@ public class SimpleIndexTemplateIT extends ESIntegTestCase {
|
||||
// So the aliases defined in the index template for this index will not fail
|
||||
// even though the fields in the alias fields don't exist yet and indexing into
|
||||
// an index that doesn't exist yet will succeed
|
||||
client().prepareIndex("d1", "test", "test").setSource("{}", XContentType.JSON).get();
|
||||
client().prepareIndex("b1", "test", "test").setSource("{}", XContentType.JSON).get();
|
||||
|
||||
response = client().prepareBulk().add(new IndexRequest("d2", "test", "test").source("{}", XContentType.JSON)).get();
|
||||
response = client().prepareBulk().add(new IndexRequest("b2", "test", "test").source("{}", XContentType.JSON)).get();
|
||||
assertThat(response.hasFailures(), is(false));
|
||||
assertThat(response.getItems()[0].isFailed(), equalTo(false));
|
||||
assertThat(response.getItems()[0].getId(), equalTo("test"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user