18
18
*/
19
19
package org .elasticsearch .transport ;
20
20
21
+ import java .util .EnumSet ;
21
22
import java .util .function .Supplier ;
22
23
import org .elasticsearch .Version ;
23
24
import org .elasticsearch .cluster .metadata .ClusterNameExpressionResolver ;
24
25
import org .elasticsearch .cluster .node .DiscoveryNode ;
26
+ import org .elasticsearch .common .Strings ;
27
+ import org .elasticsearch .common .UUIDs ;
28
+ import org .elasticsearch .common .collect .Tuple ;
25
29
import org .elasticsearch .common .component .AbstractComponent ;
26
30
import org .elasticsearch .common .settings .ClusterSettings ;
27
31
import org .elasticsearch .common .settings .Setting ;
@@ -66,6 +70,22 @@ public abstract class RemoteClusterAware extends AbstractComponent {
66
70
public static final char REMOTE_CLUSTER_INDEX_SEPARATOR = ':' ;
67
71
public static final String LOCAL_CLUSTER_GROUP_KEY = "" ;
68
72
73
+ /**
74
+ * A proxy address for the remote cluster.
75
+ * NOTE: this settings is undocumented until we have at last one transport that supports passing
76
+ * on the hostname via a mechanism like SNI.
77
+ */
78
+ public static final Setting .AffixSetting <String > REMOTE_CLUSTERS_PROXY = Setting .affixKeySetting (
79
+ "search.remote." ,
80
+ "proxy" ,
81
+ key -> Setting .simpleString (key , s -> {
82
+ if (Strings .hasLength (s )) {
83
+ parsePort (s );
84
+ }
85
+ return s ;
86
+ }, Setting .Property .NodeScope , Setting .Property .Dynamic ), REMOTE_CLUSTERS_SEEDS );
87
+
88
+
69
89
protected final ClusterNameExpressionResolver clusterNameResolver ;
70
90
71
91
/**
@@ -77,25 +97,42 @@ protected RemoteClusterAware(Settings settings) {
77
97
this .clusterNameResolver = new ClusterNameExpressionResolver (settings );
78
98
}
79
99
80
- protected static Map <String , List <Supplier <DiscoveryNode >>> buildRemoteClustersSeeds (Settings settings ) {
100
+ /**
101
+ * Builds the dynamic per-cluster config from the given settings. This is a map keyed by the cluster alias that points to a tuple
102
+ * (ProxyAddresss, [SeedNodeSuppliers]). If a cluster is configured with a proxy address all seed nodes will point to
103
+ * {@link TransportAddress#META_ADDRESS} and their configured address will be used as the hostname for the generated discovery node.
104
+ */
105
+ protected static Map <String , Tuple <String , List <Supplier <DiscoveryNode >>>> buildRemoteClustersDynamicConfig (Settings settings ) {
81
106
Stream <Setting <List <String >>> allConcreteSettings = REMOTE_CLUSTERS_SEEDS .getAllConcreteSettings (settings );
82
107
return allConcreteSettings .collect (
83
108
Collectors .toMap (REMOTE_CLUSTERS_SEEDS ::getNamespace , concreteSetting -> {
84
109
String clusterName = REMOTE_CLUSTERS_SEEDS .getNamespace (concreteSetting );
85
110
List <String > addresses = concreteSetting .get (settings );
111
+ final boolean proxyMode = REMOTE_CLUSTERS_PROXY .getConcreteSettingForNamespace (clusterName ).exists (settings );
86
112
List <Supplier <DiscoveryNode >> nodes = new ArrayList <>(addresses .size ());
87
113
for (String address : addresses ) {
88
- nodes .add (() -> {
89
- TransportAddress transportAddress = new TransportAddress (RemoteClusterAware .parseSeedAddress (address ));
90
- return new DiscoveryNode (clusterName + "#" + transportAddress .toString (),
91
- transportAddress ,
92
- Version .CURRENT .minimumCompatibilityVersion ());
93
- });
114
+ nodes .add (() -> buildSeedNode (clusterName , address , proxyMode ));
94
115
}
95
- return nodes ;
116
+ return new Tuple <>( REMOTE_CLUSTERS_PROXY . getConcreteSettingForNamespace ( clusterName ). get ( settings ), nodes ) ;
96
117
}));
97
118
}
98
119
120
+ static DiscoveryNode buildSeedNode (String clusterName , String address , boolean proxyMode ) {
121
+ if (proxyMode ) {
122
+ TransportAddress transportAddress = new TransportAddress (TransportAddress .META_ADDRESS , 0 );
123
+ String hostName = address .substring (0 , indexOfPortSeparator (address ));
124
+ return new DiscoveryNode ("" , clusterName + "#" + address , UUIDs .randomBase64UUID (), hostName , address ,
125
+ transportAddress , Collections
126
+ .emptyMap (), EnumSet .allOf (DiscoveryNode .Role .class ),
127
+ Version .CURRENT .minimumCompatibilityVersion ());
128
+ } else {
129
+ TransportAddress transportAddress = new TransportAddress (RemoteClusterAware .parseSeedAddress (address ));
130
+ return new DiscoveryNode (clusterName + "#" + transportAddress .toString (),
131
+ transportAddress ,
132
+ Version .CURRENT .minimumCompatibilityVersion ());
133
+ }
134
+ }
135
+
99
136
/**
100
137
* Groups indices per cluster by splitting remote cluster-alias, index-name pairs on {@link #REMOTE_CLUSTER_INDEX_SEPARATOR}. All
101
138
* indices per cluster are collected as a list in the returned map keyed by the cluster alias. Local indices are grouped under
@@ -138,20 +175,24 @@ public Map<String, List<String>> groupClusterIndices(String[] requestIndices, Pr
138
175
139
176
protected abstract Set <String > getRemoteClusterNames ();
140
177
178
+
141
179
/**
142
180
* Subclasses must implement this to receive information about updated cluster aliases. If the given address list is
143
181
* empty the cluster alias is unregistered and should be removed.
144
182
*/
145
- protected abstract void updateRemoteCluster (String clusterAlias , List <String > addresses );
183
+ protected abstract void updateRemoteCluster (String clusterAlias , List <String > addresses , String proxy );
146
184
147
185
/**
148
186
* Registers this instance to listen to updates on the cluster settings.
149
187
*/
150
188
public void listenForUpdates (ClusterSettings clusterSettings ) {
151
- clusterSettings .addAffixUpdateConsumer (RemoteClusterAware .REMOTE_CLUSTERS_SEEDS , this ::updateRemoteCluster ,
189
+ clusterSettings .addAffixUpdateConsumer (RemoteClusterAware .REMOTE_CLUSTERS_PROXY ,
190
+ RemoteClusterAware .REMOTE_CLUSTERS_SEEDS ,
191
+ (key , value ) -> updateRemoteCluster (key , value .v2 (), value .v1 ()),
152
192
(namespace , value ) -> {});
153
193
}
154
194
195
+
155
196
protected static InetSocketAddress parseSeedAddress (String remoteHost ) {
156
197
String host = remoteHost .substring (0 , indexOfPortSeparator (remoteHost ));
157
198
InetAddress hostAddress ;
0 commit comments