Fix serialization issue in WatcherMetaData

Watcher meta data parser doesn't read the closing '}' which causes all following custom metadata to be ignored.

Similar to elastic/elasticsearch#1190

Original commit: elastic/x-pack-elasticsearch@d15b9ea466
This commit is contained in:
Igor Motov 2016-09-26 23:41:07 +02:00
parent d44ba28d27
commit aafc75ac51
2 changed files with 84 additions and 1 deletions

View File

@ -55,6 +55,7 @@ public class WatcherMetaData extends AbstractDiffable<MetaData.Custom> implement
@Override
public MetaData.Custom fromXContent(XContentParser parser) throws IOException {
XContentParser.Token token;
Boolean manuallyStopped = null;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
switch (token) {
@ -63,11 +64,14 @@ public class WatcherMetaData extends AbstractDiffable<MetaData.Custom> implement
break;
case VALUE_BOOLEAN:
if (ParseFieldMatcher.STRICT.match(currentFieldName, Field.MANUALLY_STOPPED)) {
return new WatcherMetaData(parser.booleanValue());
manuallyStopped = parser.booleanValue();
}
break;
}
}
if (manuallyStopped != null) {
return new WatcherMetaData(manuallyStopped);
}
return null;
}

View File

@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.watcher;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.metadata.RepositoriesMetaData;
import org.elasticsearch.cluster.metadata.RepositoryMetaData;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ESTestCase;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
public class WatcherMetaDataSerializationTests extends ESTestCase {
public void testXContentSerializationOneSignedWatcher() throws Exception {
boolean manuallyStopped = randomBoolean();
WatcherMetaData watcherMetaData = new WatcherMetaData(manuallyStopped);
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
builder.startObject("watcher");
watcherMetaData.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
builder.endObject();
WatcherMetaData watchersMetaDataFromXContent = getWatcherMetaDataFromXContent(builder.bytes());
assertThat(watchersMetaDataFromXContent.manuallyStopped(), equalTo(manuallyStopped));
}
public void testWatcherMetadataParsingDoesNotSwallowOtherMetaData() throws Exception {
new Watcher(Settings.EMPTY); // makes sure WatcherMetaData is registered in Custom MetaData
boolean manuallyStopped = randomBoolean();
WatcherMetaData watcherMetaData = new WatcherMetaData(manuallyStopped);
RepositoryMetaData repositoryMetaData = new RepositoryMetaData("repo", "fs", Settings.EMPTY);
RepositoriesMetaData repositoriesMetaData = new RepositoriesMetaData(repositoryMetaData);
final MetaData.Builder metaDataBuilder = MetaData.builder();
if (randomBoolean()) { // random order of insertion
metaDataBuilder.putCustom(watcherMetaData.type(), watcherMetaData);
metaDataBuilder.putCustom(repositoriesMetaData.type(), repositoriesMetaData);
} else {
metaDataBuilder.putCustom(repositoriesMetaData.type(), repositoriesMetaData);
metaDataBuilder.putCustom(watcherMetaData.type(), watcherMetaData);
}
// serialize metadata
XContentBuilder builder = XContentFactory.jsonBuilder();
ToXContent.Params params = new ToXContent.MapParams(Collections.singletonMap(MetaData.CONTEXT_MODE_PARAM,
MetaData.CONTEXT_MODE_GATEWAY));
builder.startObject();
builder = metaDataBuilder.build().toXContent(builder, params);
builder.endObject();
String serializedMetaData = builder.string();
// deserialize metadata again
MetaData metaData = MetaData.Builder.fromXContent(XContentFactory.xContent(XContentType.JSON).createParser(serializedMetaData));
// check that custom metadata still present
assertThat(metaData.custom(watcherMetaData.type()), notNullValue());
assertThat(metaData.custom(repositoriesMetaData.type()), notNullValue());
}
private static WatcherMetaData getWatcherMetaDataFromXContent(BytesReference bytes) throws Exception {
final XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(bytes);
parser.nextToken(); // consume null
parser.nextToken(); // consume "watcher"
WatcherMetaData watcherMetaDataFromXContent = (WatcherMetaData)WatcherMetaData.PROTO.fromXContent(parser);
parser.nextToken(); // consume endObject
assertThat(parser.nextToken(), nullValue());
return watcherMetaDataFromXContent;
}
}