Skip to content

Commit b9707c2

Browse files
authored
[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
1 parent 090d766 commit b9707c2

File tree

5 files changed

+90
-45
lines changed

5 files changed

+90
-45
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/ccr/GetAutoFollowPatternResponse.java

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,59 @@
1919

2020
package org.elasticsearch.client.ccr;
2121

22+
import org.elasticsearch.common.ParseField;
2223
import org.elasticsearch.common.unit.ByteSizeValue;
2324
import org.elasticsearch.common.unit.TimeValue;
2425
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
2526
import org.elasticsearch.common.xcontent.ObjectParser;
2627
import org.elasticsearch.common.xcontent.XContentParser;
27-
import org.elasticsearch.common.xcontent.XContentParser.Token;
2828

29-
import java.io.IOException;
29+
import java.util.AbstractMap;
3030
import java.util.Collections;
31-
import java.util.HashMap;
3231
import java.util.List;
3332
import java.util.Map;
33+
import java.util.NavigableMap;
3434
import java.util.Objects;
35+
import java.util.TreeMap;
36+
import java.util.stream.Collectors;
3537

3638
public final class GetAutoFollowPatternResponse {
3739

38-
public static GetAutoFollowPatternResponse fromXContent(final XContentParser parser) throws IOException {
39-
final Map<String, Pattern> patterns = new HashMap<>();
40-
for (Token token = parser.nextToken(); token != Token.END_OBJECT; token = parser.nextToken()) {
41-
if (token == Token.FIELD_NAME) {
42-
final String name = parser.currentName();
43-
final Pattern pattern = Pattern.PARSER.parse(parser, null);
44-
patterns.put(name, pattern);
45-
}
46-
}
47-
return new GetAutoFollowPatternResponse(patterns);
40+
static final ParseField PATTERNS_FIELD = new ParseField("patterns");
41+
static final ParseField NAME_FIELD = new ParseField("name");
42+
static final ParseField PATTERN_FIELD = new ParseField("pattern");
43+
44+
private static final ConstructingObjectParser<Map.Entry<String, Pattern>, Void> ENTRY_PARSER = new ConstructingObjectParser<>(
45+
"get_auto_follow_pattern_response", args -> new AbstractMap.SimpleEntry<>((String) args[0], (Pattern) args[1]));
46+
47+
static {
48+
ENTRY_PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME_FIELD);
49+
ENTRY_PARSER.declareObject(ConstructingObjectParser.constructorArg(), Pattern.PARSER, PATTERN_FIELD);
50+
}
51+
52+
private static final ConstructingObjectParser<GetAutoFollowPatternResponse, Void> PARSER = new ConstructingObjectParser<>(
53+
"get_auto_follow_pattern_response", args -> {
54+
@SuppressWarnings("unchecked")
55+
List<Map.Entry<String, Pattern>> entries = (List<Map.Entry<String, Pattern>>) args[0];
56+
return new GetAutoFollowPatternResponse(new TreeMap<>(entries.stream()
57+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));
58+
});
59+
60+
static {
61+
PARSER.declareObjectArray(ConstructingObjectParser.constructorArg(), ENTRY_PARSER, PATTERNS_FIELD);
62+
}
63+
64+
public static GetAutoFollowPatternResponse fromXContent(final XContentParser parser) {
65+
return PARSER.apply(parser, null);
4866
}
4967

50-
private final Map<String, Pattern> patterns;
68+
private final NavigableMap<String, Pattern> patterns;
5169

52-
GetAutoFollowPatternResponse(Map<String, Pattern> patterns) {
53-
this.patterns = Collections.unmodifiableMap(patterns);
70+
GetAutoFollowPatternResponse(NavigableMap<String, Pattern> patterns) {
71+
this.patterns = Collections.unmodifiableNavigableMap(patterns);
5472
}
5573

56-
public Map<String, Pattern> getPatterns() {
74+
public NavigableMap<String, Pattern> getPatterns() {
5775
return patterns;
5876
}
5977

client/rest-high-level/src/test/java/org/elasticsearch/client/ccr/GetAutoFollowPatternResponseTests.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727

2828
import java.io.IOException;
2929
import java.util.Collections;
30-
import java.util.HashMap;
3130
import java.util.Map;
31+
import java.util.NavigableMap;
32+
import java.util.TreeMap;
3233

3334
import static org.elasticsearch.client.ccr.PutAutoFollowPatternRequest.FOLLOW_PATTERN_FIELD;
3435
import static org.elasticsearch.client.ccr.PutAutoFollowPatternRequest.LEADER_PATTERNS_FIELD;
@@ -48,7 +49,7 @@ public void testFromXContent() throws IOException {
4849

4950
private GetAutoFollowPatternResponse createTestInstance() {
5051
int numPatterns = randomIntBetween(0, 16);
51-
Map<String, GetAutoFollowPatternResponse.Pattern> patterns = new HashMap<>(numPatterns);
52+
NavigableMap<String, GetAutoFollowPatternResponse.Pattern> patterns = new TreeMap<>();
5253
for (int i = 0; i < numPatterns; i++) {
5354
GetAutoFollowPatternResponse.Pattern pattern = new GetAutoFollowPatternResponse.Pattern(
5455
randomAlphaOfLength(4), Collections.singletonList(randomAlphaOfLength(4)), randomAlphaOfLength(4));
@@ -90,17 +91,26 @@ private GetAutoFollowPatternResponse createTestInstance() {
9091
public static void toXContent(GetAutoFollowPatternResponse response, XContentBuilder builder) throws IOException {
9192
builder.startObject();
9293
{
94+
builder.startArray(GetAutoFollowPatternResponse.PATTERNS_FIELD.getPreferredName());
9395
for (Map.Entry<String, GetAutoFollowPatternResponse.Pattern> entry : response.getPatterns().entrySet()) {
94-
builder.startObject(entry.getKey());
95-
GetAutoFollowPatternResponse.Pattern pattern = entry.getValue();
96-
builder.field(REMOTE_CLUSTER_FIELD.getPreferredName(), pattern.getRemoteCluster());
97-
builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), pattern.getLeaderIndexPatterns());
98-
if (pattern.getFollowIndexNamePattern()!= null) {
99-
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), pattern.getFollowIndexNamePattern());
96+
builder.startObject();
97+
{
98+
builder.field(GetAutoFollowPatternResponse.NAME_FIELD.getPreferredName(), entry.getKey());
99+
builder.startObject(GetAutoFollowPatternResponse.PATTERN_FIELD.getPreferredName());
100+
{
101+
GetAutoFollowPatternResponse.Pattern pattern = entry.getValue();
102+
builder.field(REMOTE_CLUSTER_FIELD.getPreferredName(), pattern.getRemoteCluster());
103+
builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), pattern.getLeaderIndexPatterns());
104+
if (pattern.getFollowIndexNamePattern()!= null) {
105+
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), pattern.getFollowIndexNamePattern());
106+
}
107+
entry.getValue().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
108+
}
109+
builder.endObject();
100110
}
101-
entry.getValue().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
102111
builder.endObject();
103112
}
113+
builder.endArray();
104114
}
105115
builder.endObject();
106116
}

docs/reference/ccr/apis/auto-follow/get-auto-follow-pattern.asciidoc

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,19 @@ The API returns the following result:
8787
[source,js]
8888
--------------------------------------------------
8989
{
90-
"my_auto_follow_pattern" :
91-
{
92-
"remote_cluster" : "remote_cluster",
93-
"leader_index_patterns" :
94-
[
95-
"leader_index*"
96-
],
97-
"follow_index_pattern" : "{{leader_index}}-follower"
98-
}
90+
"patterns": [
91+
{
92+
"name": "my_auto_follow_pattern",
93+
"pattern": {
94+
"remote_cluster" : "remote_cluster",
95+
"leader_index_patterns" :
96+
[
97+
"leader_index*"
98+
],
99+
"follow_index_pattern" : "{{leader_index}}-follower"
100+
}
101+
}
102+
]
99103
}
100104
--------------------------------------------------
101105
// TESTRESPONSE

x-pack/plugin/ccr/qa/rest/src/test/resources/rest-api-spec/test/ccr/auto_follow.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,17 @@
3131
- do:
3232
ccr.get_auto_follow_pattern:
3333
name: my_pattern
34-
- match: { my_pattern.remote_cluster: 'local' }
35-
- match: { my_pattern.leader_index_patterns: ['logs-*'] }
36-
- match: { my_pattern.max_outstanding_read_requests: 2 }
34+
- match: { patterns.0.name: 'my_pattern' }
35+
- match: { patterns.0.pattern.remote_cluster: 'local' }
36+
- match: { patterns.0.pattern.leader_index_patterns: ['logs-*'] }
37+
- match: { patterns.0.pattern.max_outstanding_read_requests: 2 }
3738

3839
- do:
3940
ccr.get_auto_follow_pattern: {}
40-
- match: { my_pattern.remote_cluster: 'local' }
41-
- match: { my_pattern.leader_index_patterns: ['logs-*'] }
42-
- match: { my_pattern.max_outstanding_read_requests: 2 }
41+
- match: { patterns.0.name: 'my_pattern' }
42+
- match: { patterns.0.pattern.remote_cluster: 'local' }
43+
- match: { patterns.0.pattern.leader_index_patterns: ['logs-*'] }
44+
- match: { patterns.0.pattern.max_outstanding_read_requests: 2 }
4345

4446
- do:
4547
ccr.delete_auto_follow_pattern:

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ccr/action/GetAutoFollowPatternAction.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,21 @@ public void writeTo(StreamOutput out) throws IOException {
111111
@Override
112112
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
113113
builder.startObject();
114-
for (Map.Entry<String, AutoFollowPattern> entry : autoFollowPatterns.entrySet()) {
115-
builder.startObject(entry.getKey());
116-
entry.getValue().toXContent(builder, params);
117-
builder.endObject();
114+
{
115+
builder.startArray("patterns");
116+
for (Map.Entry<String, AutoFollowPattern> entry : autoFollowPatterns.entrySet()) {
117+
builder.startObject();
118+
{
119+
builder.field("name", entry.getKey());
120+
builder.startObject("pattern");
121+
{
122+
entry.getValue().toXContent(builder, params);
123+
}
124+
builder.endObject();
125+
}
126+
builder.endObject();
127+
}
128+
builder.endArray();
118129
}
119130
builder.endObject();
120131
return builder;

0 commit comments

Comments
 (0)