Skip to content

Commit 97cd3fc

Browse files
committed
Modify state of VerifyRepositoryResponse for bwc (#30762)
The VerifyRepositoryResponse class holds a DiscoveryNode[], but the nodes themselves are not serialized to a REST API consumer. Since we do not want to put all of a DiscoveryNode over the wire, be it REST or Transport since its unused, this change introduces a BWC compatible change in ser/deser of the Response. Anything 6.4 and above will read/write a NodeView, and anything prior will read/write a DiscoveryNode. Further changes to 7.0 will be introduced to remove the BWC shim and only read/write NodeView, and hold a List<NodeView> as the VerifyRepositoryResponse internal state.
1 parent 74abdb0 commit 97cd3fc

File tree

4 files changed

+118
-26
lines changed

4 files changed

+118
-26
lines changed

server/src/main/java/org/elasticsearch/action/admin/cluster/repositories/verify/VerifyRepositoryResponse.java

Lines changed: 115 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,112 @@
1919

2020
package org.elasticsearch.action.admin.cluster.repositories.verify;
2121

22+
import org.elasticsearch.Version;
2223
import org.elasticsearch.action.ActionResponse;
2324
import org.elasticsearch.cluster.ClusterName;
2425
import org.elasticsearch.cluster.node.DiscoveryNode;
26+
import org.elasticsearch.common.ParseField;
2527
import org.elasticsearch.common.Strings;
2628
import org.elasticsearch.common.io.stream.StreamInput;
2729
import org.elasticsearch.common.io.stream.StreamOutput;
30+
import org.elasticsearch.common.io.stream.Writeable;
31+
import org.elasticsearch.common.transport.TransportAddress;
32+
import org.elasticsearch.common.xcontent.ObjectParser;
2833
import org.elasticsearch.common.xcontent.ToXContentObject;
2934
import org.elasticsearch.common.xcontent.XContentBuilder;
3035

3136
import java.io.IOException;
37+
import java.util.Arrays;
38+
import java.util.Collections;
39+
import java.util.List;
40+
import java.util.Objects;
41+
import java.util.stream.Collectors;
3242

3343
/**
34-
* Unregister repository response
44+
* Verify repository response
3545
*/
3646
public class VerifyRepositoryResponse extends ActionResponse implements ToXContentObject {
3747

38-
private DiscoveryNode[] nodes;
48+
static final String NODES = "nodes";
49+
static final String NAME = "name";
50+
51+
public static class NodeView implements Writeable, ToXContentObject {
52+
private static final ObjectParser.NamedObjectParser<NodeView, Void> PARSER;
53+
static {
54+
ObjectParser<NodeView, Void> internalParser = new ObjectParser<>(NODES);
55+
internalParser.declareString(NodeView::setName, new ParseField(NAME));
56+
PARSER = (p, v, name) -> internalParser.parse(p, new NodeView(name), null);
57+
}
58+
59+
final String nodeId;
60+
String name;
61+
62+
public NodeView(String nodeId) { this.nodeId = nodeId; }
63+
64+
public NodeView(String nodeId, String name) {
65+
this(nodeId);
66+
this.name = name;
67+
}
68+
69+
public NodeView(StreamInput in) throws IOException {
70+
this(in.readString(), in.readString());
71+
}
72+
73+
@Override
74+
public void writeTo(StreamOutput out) throws IOException {
75+
out.writeString(nodeId);
76+
out.writeString(name);
77+
}
78+
79+
void setName(String name) { this.name = name; }
80+
81+
public String getName() { return name; }
82+
83+
public String getNodeId() { return nodeId; }
84+
85+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
86+
builder.startObject(nodeId);
87+
{
88+
builder.field(NAME, name);
89+
}
90+
builder.endObject();
91+
return builder;
92+
}
93+
94+
/**
95+
* Temporary method that allows turning a {@link NodeView} into a {@link DiscoveryNode}. This representation will never be used in
96+
* practice, because in >= 6.4 a consumer of the response will only be able to retrieve a representation of {@link NodeView}
97+
* objects.
98+
*
99+
* Effectively this will be used to hold the state of the object in 6.x so there is no need to have 2 backing objects that
100+
* represent the state of the Response. In practice these will always be read by a consumer as a NodeView, but it eases the
101+
* transition to master which will not contain any representation of a {@link DiscoveryNode}.
102+
*/
103+
DiscoveryNode convertToDiscoveryNode() {
104+
return new DiscoveryNode(name, nodeId, "", "", "", new TransportAddress(TransportAddress.META_ADDRESS, 0),
105+
Collections.emptyMap(), Collections.emptySet(), Version.CURRENT);
106+
}
107+
108+
@Override
109+
public boolean equals(Object obj) {
110+
if (obj == null) {
111+
return false;
112+
}
113+
if (getClass() != obj.getClass()) {
114+
return false;
115+
}
116+
NodeView other = (NodeView) obj;
117+
return Objects.equals(nodeId, other.nodeId) &&
118+
Objects.equals(name, other.name);
119+
}
120+
121+
@Override
122+
public int hashCode() {
123+
return Objects.hash(nodeId, name);
124+
}
125+
}
126+
127+
private List<DiscoveryNode> nodes;
39128

40129
private ClusterName clusterName;
41130

@@ -45,53 +134,56 @@ public class VerifyRepositoryResponse extends ActionResponse implements ToXConte
45134

46135
public VerifyRepositoryResponse(ClusterName clusterName, DiscoveryNode[] nodes) {
47136
this.clusterName = clusterName;
48-
this.nodes = nodes;
137+
this.nodes = Arrays.asList(nodes);
49138
}
50139

51140
@Override
52141
public void readFrom(StreamInput in) throws IOException {
53142
super.readFrom(in);
54-
clusterName = new ClusterName(in);
55-
nodes = new DiscoveryNode[in.readVInt()];
56-
for (int i=0; i<nodes.length; i++){
57-
nodes[i] = new DiscoveryNode(in);
143+
if (in.getVersion().onOrAfter(Version.V_6_4_0)) {
144+
this.nodes = in.readList(NodeView::new).stream().map(n -> n.convertToDiscoveryNode()).collect(Collectors.toList());
145+
} else {
146+
clusterName = new ClusterName(in);
147+
this.nodes = in.readList(DiscoveryNode::new);
58148
}
59149
}
60150

61151
@Override
62152
public void writeTo(StreamOutput out) throws IOException {
63153
super.writeTo(out);
64-
clusterName.writeTo(out);
65-
out.writeVInt(nodes.length);
66-
for (DiscoveryNode node : nodes) {
67-
node.writeTo(out);
154+
if (Version.CURRENT.onOrAfter(Version.V_6_4_0)) {
155+
out.writeList(getNodes());
156+
} else {
157+
clusterName.writeTo(out);
158+
out.writeList(nodes);
68159
}
69160
}
70161

71-
public DiscoveryNode[] getNodes() {
72-
return nodes;
162+
public List<NodeView> getNodes() {
163+
return nodes.stream().map(dn -> new NodeView(dn.getId(), dn.getName())).collect(Collectors.toList());
73164
}
74165

75166
public ClusterName getClusterName() {
76167
return clusterName;
77168
}
78169

79-
static final class Fields {
80-
static final String NODES = "nodes";
81-
static final String NAME = "name";
82-
}
83-
84170
@Override
85171
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
86172
builder.startObject();
87-
builder.startObject(Fields.NODES);
88-
for (DiscoveryNode node : nodes) {
89-
builder.startObject(node.getId());
90-
builder.field(Fields.NAME, node.getName());
173+
{
174+
builder.startObject(NODES);
175+
{
176+
for (DiscoveryNode node : nodes) {
177+
builder.startObject(node.getId());
178+
{
179+
builder.field(NAME, node.getName());
180+
}
181+
builder.endObject();
182+
}
183+
}
91184
builder.endObject();
92185
}
93186
builder.endObject();
94-
builder.endObject();
95187
return builder;
96188
}
97189

server/src/test/java/org/elasticsearch/action/admin/cluster/repositories/RepositoryBlocksIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void testVerifyRepositoryWithBlocks() {
6767
try {
6868
setClusterReadOnly(true);
6969
VerifyRepositoryResponse response = client().admin().cluster().prepareVerifyRepository("test-repo-blocks").execute().actionGet();
70-
assertThat(response.getNodes().length, equalTo(cluster().numDataAndMasterNodes()));
70+
assertThat(response.getNodes().size(), equalTo(cluster().numDataAndMasterNodes()));
7171
} finally {
7272
setClusterReadOnly(false);
7373
}

server/src/test/java/org/elasticsearch/action/admin/cluster/snapshots/SnapshotBlocksIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protected void setUpRepository() throws Exception {
7373

7474
logger.info("--> verify the repository");
7575
VerifyRepositoryResponse verifyResponse = client().admin().cluster().prepareVerifyRepository(REPOSITORY_NAME).get();
76-
assertThat(verifyResponse.getNodes().length, equalTo(cluster().numDataAndMasterNodes()));
76+
assertThat(verifyResponse.getNodes().size(), equalTo(cluster().numDataAndMasterNodes()));
7777

7878
logger.info("--> create a snapshot");
7979
CreateSnapshotResponse snapshotResponse = client().admin().cluster().prepareCreateSnapshot(REPOSITORY_NAME, SNAPSHOT_NAME)

server/src/test/java/org/elasticsearch/snapshots/RepositoriesIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void testRepositoryCreation() throws Exception {
6161
logger.info("--> verify the repository");
6262
int numberOfFiles = FileSystemUtils.files(location).length;
6363
VerifyRepositoryResponse verifyRepositoryResponse = client.admin().cluster().prepareVerifyRepository("test-repo-1").get();
64-
assertThat(verifyRepositoryResponse.getNodes().length, equalTo(cluster().numDataAndMasterNodes()));
64+
assertThat(verifyRepositoryResponse.getNodes().size(), equalTo(cluster().numDataAndMasterNodes()));
6565

6666
logger.info("--> verify that we didn't leave any files as a result of verification");
6767
assertThat(FileSystemUtils.files(location).length, equalTo(numberOfFiles));

0 commit comments

Comments
 (0)