[CCR] Change get autofollow patterns API response format (#36203)

The current response format is:

```
{
    "pattern1": {
        ...
    },
    "pattern2": {
        ...
    }
}
```

The new format is:

```
{
    "patterns": [
        {
            "name": "pattern1",
            "pattern": {
                ...
            }
        },
        {
            "name": "pattern2",
            "pattern": {
                ...
            }
        }
    ]
}
```

This format is more structured and more friendly for parsing and generating specs.
This is a breaking change, but it is better to do this now while ccr
is still a beta feature than later.

Follow up from #36049
This commit is contained in:
Martijn van Groningen 2018-12-05 08:41:27 +01:00 committed by GitHub
parent 090d766f35
commit b9707c29a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 45 deletions

View File

@ -19,41 +19,59 @@
package org.elasticsearch.client.ccr;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.TreeMap;
import java.util.stream.Collectors;
public final class GetAutoFollowPatternResponse {
public static GetAutoFollowPatternResponse fromXContent(final XContentParser parser) throws IOException {
final Map<String, Pattern> patterns = new HashMap<>();
for (Token token = parser.nextToken(); token != Token.END_OBJECT; token = parser.nextToken()) {
if (token == Token.FIELD_NAME) {
final String name = parser.currentName();
final Pattern pattern = Pattern.PARSER.parse(parser, null);
patterns.put(name, pattern);
}
}
return new GetAutoFollowPatternResponse(patterns);
static final ParseField PATTERNS_FIELD = new ParseField("patterns");
static final ParseField NAME_FIELD = new ParseField("name");
static final ParseField PATTERN_FIELD = new ParseField("pattern");
private static final ConstructingObjectParser<Map.Entry<String, Pattern>, Void> ENTRY_PARSER = new ConstructingObjectParser<>(
"get_auto_follow_pattern_response", args -> new AbstractMap.SimpleEntry<>((String) args[0], (Pattern) args[1]));
static {
ENTRY_PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD);
ENTRY_PARSER.declareObject(ConstructingObjectParser.constructorArg(), Pattern.PARSER, PATTERN_FIELD);
}
private final Map<String, Pattern> patterns;
private static final ConstructingObjectParser<GetAutoFollowPatternResponse, Void> PARSER = new ConstructingObjectParser<>(
"get_auto_follow_pattern_response", args -> {
@SuppressWarnings("unchecked")
List<Map.Entry<String, Pattern>> entries = (List<Map.Entry<String, Pattern>>) args[0];
return new GetAutoFollowPatternResponse(new TreeMap<>(entries.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));
});
GetAutoFollowPatternResponse(Map<String, Pattern> patterns) {
this.patterns = Collections.unmodifiableMap(patterns);
static {
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), ENTRY_PARSER, PATTERNS_FIELD);
}
public Map<String, Pattern> getPatterns() {
public static GetAutoFollowPatternResponse fromXContent(final XContentParser parser) {
return PARSER.apply(parser, null);
}
private final NavigableMap<String, Pattern> patterns;
GetAutoFollowPatternResponse(NavigableMap<String, Pattern> patterns) {
this.patterns = Collections.unmodifiableNavigableMap(patterns);
}
public NavigableMap<String, Pattern> getPatterns() {
return patterns;
}

View File

@ -27,8 +27,9 @@ import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import static org.elasticsearch.client.ccr.PutAutoFollowPatternRequest.FOLLOW_PATTERN_FIELD;
import static org.elasticsearch.client.ccr.PutAutoFollowPatternRequest.LEADER_PATTERNS_FIELD;
@ -48,7 +49,7 @@ public class GetAutoFollowPatternResponseTests extends ESTestCase {
private GetAutoFollowPatternResponse createTestInstance() {
int numPatterns = randomIntBetween(0, 16);
Map<String, GetAutoFollowPatternResponse.Pattern> patterns = new HashMap<>(numPatterns);
NavigableMap<String, GetAutoFollowPatternResponse.Pattern> patterns = new TreeMap<>();
for (int i = 0; i < numPatterns; i++) {
GetAutoFollowPatternResponse.Pattern pattern = new GetAutoFollowPatternResponse.Pattern(
randomAlphaOfLength(4), Collections.singletonList(randomAlphaOfLength(4)), randomAlphaOfLength(4));
@ -90,8 +91,13 @@ public class GetAutoFollowPatternResponseTests extends ESTestCase {
public static void toXContent(GetAutoFollowPatternResponse response, XContentBuilder builder) throws IOException {
builder.startObject();
{
builder.startArray(GetAutoFollowPatternResponse.PATTERNS_FIELD.getPreferredName());
for (Map.Entry<String, GetAutoFollowPatternResponse.Pattern> entry : response.getPatterns().entrySet()) {
builder.startObject(entry.getKey());
builder.startObject();
{
builder.field(GetAutoFollowPatternResponse.NAME_FIELD.getPreferredName(), entry.getKey());
builder.startObject(GetAutoFollowPatternResponse.PATTERN_FIELD.getPreferredName());
{
GetAutoFollowPatternResponse.Pattern pattern = entry.getValue();
builder.field(REMOTE_CLUSTER_FIELD.getPreferredName(), pattern.getRemoteCluster());
builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), pattern.getLeaderIndexPatterns());
@ -99,8 +105,12 @@ public class GetAutoFollowPatternResponseTests extends ESTestCase {
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), pattern.getFollowIndexNamePattern());
}
entry.getValue().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
}
builder.endObject();
}
builder.endObject();
}
builder.endArray();
}
builder.endObject();
}

View File

@ -87,8 +87,10 @@ The API returns the following result:
[source,js]
--------------------------------------------------
{
"my_auto_follow_pattern" :
"patterns": [
{
"name": "my_auto_follow_pattern",
"pattern": {
"remote_cluster" : "remote_cluster",
"leader_index_patterns" :
[
@ -97,5 +99,7 @@ The API returns the following result:
"follow_index_pattern" : "{{leader_index}}-follower"
}
}
]
}
--------------------------------------------------
// TESTRESPONSE

View File

@ -31,15 +31,17 @@
- do:
ccr.get_auto_follow_pattern:
name: my_pattern
- match: { my_pattern.remote_cluster: 'local' }
- match: { my_pattern.leader_index_patterns: ['logs-*'] }
- match: { my_pattern.max_outstanding_read_requests: 2 }
- match: { patterns.0.name: 'my_pattern' }
- match: { patterns.0.pattern.remote_cluster: 'local' }
- match: { patterns.0.pattern.leader_index_patterns: ['logs-*'] }
- match: { patterns.0.pattern.max_outstanding_read_requests: 2 }
- do:
ccr.get_auto_follow_pattern: {}
- match: { my_pattern.remote_cluster: 'local' }
- match: { my_pattern.leader_index_patterns: ['logs-*'] }
- match: { my_pattern.max_outstanding_read_requests: 2 }
- match: { patterns.0.name: 'my_pattern' }
- match: { patterns.0.pattern.remote_cluster: 'local' }
- match: { patterns.0.pattern.leader_index_patterns: ['logs-*'] }
- match: { patterns.0.pattern.max_outstanding_read_requests: 2 }
- do:
ccr.delete_auto_follow_pattern:

View File

@ -111,12 +111,23 @@ public class GetAutoFollowPatternAction extends Action<GetAutoFollowPatternActio
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
{
builder.startArray("patterns");
for (Map.Entry<String, AutoFollowPattern> entry : autoFollowPatterns.entrySet()) {
builder.startObject(entry.getKey());
builder.startObject();
{
builder.field("name", entry.getKey());
builder.startObject("pattern");
{
entry.getValue().toXContent(builder, params);
}
builder.endObject();
}
builder.endObject();
}
builder.endArray();
}
builder.endObject();
return builder;
}