[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:
parent
090d766f35
commit
b9707c29a1
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,17 +91,26 @@ 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());
|
||||
GetAutoFollowPatternResponse.Pattern pattern = entry.getValue();
|
||||
builder.field(REMOTE_CLUSTER_FIELD.getPreferredName(), pattern.getRemoteCluster());
|
||||
builder.field(LEADER_PATTERNS_FIELD.getPreferredName(), pattern.getLeaderIndexPatterns());
|
||||
if (pattern.getFollowIndexNamePattern()!= null) {
|
||||
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), pattern.getFollowIndexNamePattern());
|
||||
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());
|
||||
if (pattern.getFollowIndexNamePattern()!= null) {
|
||||
builder.field(FOLLOW_PATTERN_FIELD.getPreferredName(), pattern.getFollowIndexNamePattern());
|
||||
}
|
||||
entry.getValue().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
entry.getValue().toXContentFragment(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
|
|
@ -87,15 +87,19 @@ The API returns the following result:
|
|||
[source,js]
|
||||
--------------------------------------------------
|
||||
{
|
||||
"my_auto_follow_pattern" :
|
||||
{
|
||||
"remote_cluster" : "remote_cluster",
|
||||
"leader_index_patterns" :
|
||||
[
|
||||
"leader_index*"
|
||||
],
|
||||
"follow_index_pattern" : "{{leader_index}}-follower"
|
||||
}
|
||||
"patterns": [
|
||||
{
|
||||
"name": "my_auto_follow_pattern",
|
||||
"pattern": {
|
||||
"remote_cluster" : "remote_cluster",
|
||||
"leader_index_patterns" :
|
||||
[
|
||||
"leader_index*"
|
||||
],
|
||||
"follow_index_pattern" : "{{leader_index}}-follower"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
--------------------------------------------------
|
||||
// TESTRESPONSE
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -111,10 +111,21 @@ public class GetAutoFollowPatternAction extends Action<GetAutoFollowPatternActio
|
|||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
for (Map.Entry<String, AutoFollowPattern> entry : autoFollowPatterns.entrySet()) {
|
||||
builder.startObject(entry.getKey());
|
||||
entry.getValue().toXContent(builder, params);
|
||||
builder.endObject();
|
||||
{
|
||||
builder.startArray("patterns");
|
||||
for (Map.Entry<String, AutoFollowPattern> entry : autoFollowPatterns.entrySet()) {
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue