|
33 | 33 | package org.opensearch.cluster.node;
|
34 | 34 |
|
35 | 35 | import org.opensearch.Version;
|
| 36 | +import org.opensearch.cluster.metadata.Metadata; |
36 | 37 | import org.opensearch.common.UUIDs;
|
37 | 38 | import org.opensearch.common.annotation.PublicApi;
|
38 | 39 | import org.opensearch.common.settings.Setting;
|
|
43 | 44 | import org.opensearch.core.common.transport.TransportAddress;
|
44 | 45 | import org.opensearch.core.xcontent.ToXContentFragment;
|
45 | 46 | import org.opensearch.core.xcontent.XContentBuilder;
|
| 47 | +import org.opensearch.core.xcontent.XContentParser; |
46 | 48 | import org.opensearch.node.Node;
|
47 | 49 |
|
48 | 50 | import java.io.IOException;
|
|
60 | 62 | import java.util.stream.Collectors;
|
61 | 63 | import java.util.stream.Stream;
|
62 | 64 |
|
| 65 | +import static org.opensearch.cluster.metadata.Metadata.CONTEXT_MODE_API; |
| 66 | +import static org.opensearch.cluster.metadata.Metadata.CONTEXT_MODE_PARAM; |
63 | 67 | import static org.opensearch.node.NodeRoleSettings.NODE_ROLES_SETTING;
|
64 | 68 | import static org.opensearch.node.remotestore.RemoteStoreNodeAttribute.REMOTE_STORE_NODE_ATTRIBUTE_KEY_PREFIX;
|
65 | 69 |
|
|
72 | 76 | public class DiscoveryNode implements Writeable, ToXContentFragment {
|
73 | 77 |
|
74 | 78 | static final String COORDINATING_ONLY = "coordinating_only";
|
| 79 | + static final String KEY_NAME = "name"; |
| 80 | + static final String KEY_EPHEMERAL_ID = "ephemeral_id"; |
| 81 | + static final String KEY_HOST_NAME = "host_name"; |
| 82 | + static final String KEY_HOST_ADDRESS = "host_address"; |
| 83 | + static final String KEY_TRANSPORT_ADDRESS = "transport_address"; |
| 84 | + static final String KEY_ATTRIBUTES = "attributes"; |
| 85 | + static final String KEY_VERSION = "version"; |
| 86 | + static final String KEY_ROLES = "roles"; |
75 | 87 |
|
76 | 88 | public static boolean nodeRequiresLocalStorage(Settings settings) {
|
77 | 89 | boolean localStorageEnable = Node.NODE_LOCAL_STORAGE_SETTING.get(settings);
|
@@ -544,21 +556,97 @@ public String toString() {
|
544 | 556 |
|
545 | 557 | @Override
|
546 | 558 | public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
| 559 | + Metadata.XContentContext context = Metadata.XContentContext.valueOf(params.param(CONTEXT_MODE_PARAM, CONTEXT_MODE_API)); |
547 | 560 | builder.startObject(getId());
|
548 |
| - builder.field("name", getName()); |
549 |
| - builder.field("ephemeral_id", getEphemeralId()); |
550 |
| - builder.field("transport_address", getAddress().toString()); |
| 561 | + builder.field(KEY_NAME, getName()); |
| 562 | + builder.field(KEY_EPHEMERAL_ID, getEphemeralId()); |
| 563 | + builder.field(KEY_TRANSPORT_ADDRESS, getAddress().toString()); |
551 | 564 |
|
552 |
| - builder.startObject("attributes"); |
| 565 | + builder.startObject(KEY_ATTRIBUTES); |
553 | 566 | for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
554 | 567 | builder.field(entry.getKey(), entry.getValue());
|
555 | 568 | }
|
556 | 569 | builder.endObject();
|
| 570 | + if (context == Metadata.XContentContext.GATEWAY) { |
| 571 | + builder.field(KEY_HOST_NAME, getHostName()); |
| 572 | + builder.field(KEY_HOST_ADDRESS, getHostAddress()); |
| 573 | + builder.field(KEY_VERSION, getVersion().toString()); |
| 574 | + builder.startArray(KEY_ROLES); |
| 575 | + for (DiscoveryNodeRole role : roles) { |
| 576 | + builder.value(role.roleName()); |
| 577 | + } |
| 578 | + builder.endArray(); |
| 579 | + } |
557 | 580 |
|
558 | 581 | builder.endObject();
|
559 | 582 | return builder;
|
560 | 583 | }
|
561 | 584 |
|
| 585 | + public static DiscoveryNode fromXContent(XContentParser parser, String nodeId) throws IOException { |
| 586 | + if (parser.currentToken() == null) { |
| 587 | + parser.nextToken(); |
| 588 | + } |
| 589 | + if (parser.currentToken() == XContentParser.Token.START_OBJECT) { |
| 590 | + parser.nextToken(); |
| 591 | + } |
| 592 | + if (parser.currentToken() != XContentParser.Token.FIELD_NAME) { |
| 593 | + throw new IllegalArgumentException("expected field name but got a " + parser.currentToken()); |
| 594 | + } |
| 595 | + String nodeName = null; |
| 596 | + String hostName = null; |
| 597 | + String hostAddress = null; |
| 598 | + String ephemeralId = null; |
| 599 | + TransportAddress transportAddress = null; |
| 600 | + Map<String, String> attributes = new HashMap<>(); |
| 601 | + Set<DiscoveryNodeRole> roles = new HashSet<>(); |
| 602 | + Version version = null; |
| 603 | + String currentFieldName = parser.currentName(); |
| 604 | + // token should be start object at this point |
| 605 | + // XContentParser.Token token = parser.nextToken(); |
| 606 | + // if (token != XContentParser.Token.START_OBJECT) { |
| 607 | + // throw new IllegalArgumentException("expected object but got a " + token); |
| 608 | + // } |
| 609 | + XContentParser.Token token; |
| 610 | + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { |
| 611 | + if (token == XContentParser.Token.FIELD_NAME) { |
| 612 | + currentFieldName = parser.currentName(); |
| 613 | + } else if (token.isValue()) { |
| 614 | + if (KEY_NAME.equals(currentFieldName)) { |
| 615 | + nodeName = parser.text(); |
| 616 | + } else if (KEY_EPHEMERAL_ID.equals(currentFieldName)) { |
| 617 | + ephemeralId = parser.text(); |
| 618 | + } else if (KEY_TRANSPORT_ADDRESS.equals(currentFieldName)) { |
| 619 | + transportAddress = TransportAddress.fromString(parser.text()); |
| 620 | + } else if (KEY_HOST_NAME.equals(currentFieldName)) { |
| 621 | + hostName = parser.text(); |
| 622 | + } else if (KEY_HOST_ADDRESS.equals(currentFieldName)) { |
| 623 | + hostAddress = parser.text(); |
| 624 | + } else if (KEY_VERSION.equals(currentFieldName)) { |
| 625 | + version = Version.fromString(parser.text()); |
| 626 | + } |
| 627 | + } else if (token == XContentParser.Token.START_OBJECT) { |
| 628 | + if (KEY_ATTRIBUTES.equals(currentFieldName)) { |
| 629 | + while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { |
| 630 | + if (token == XContentParser.Token.FIELD_NAME) { |
| 631 | + currentFieldName = parser.currentName(); |
| 632 | + } else if (token.isValue()) { |
| 633 | + attributes.put(currentFieldName, parser.text()); |
| 634 | + } |
| 635 | + } |
| 636 | + } |
| 637 | + } else if (token == XContentParser.Token.START_ARRAY) { |
| 638 | + if (KEY_ROLES.equals(currentFieldName)) { |
| 639 | + while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { |
| 640 | + roles.add(getRoleFromRoleName(parser.text())); |
| 641 | + } |
| 642 | + } |
| 643 | + } else { |
| 644 | + throw new IllegalArgumentException("unexpected token " + token); |
| 645 | + } |
| 646 | + } |
| 647 | + return new DiscoveryNode(nodeName, nodeId, ephemeralId, hostName, hostAddress, transportAddress, attributes, roles, version); |
| 648 | + } |
| 649 | + |
562 | 650 | private static Map<String, DiscoveryNodeRole> rolesToMap(final Stream<DiscoveryNodeRole> roles) {
|
563 | 651 | return Collections.unmodifiableMap(roles.collect(Collectors.toMap(DiscoveryNodeRole::roleName, Function.identity())));
|
564 | 652 | }
|
|
0 commit comments