20
20
import reactor .util .function .Tuple2 ;
21
21
22
22
import java .net .InetSocketAddress ;
23
+ import java .time .Duration ;
23
24
import java .util .ArrayList ;
24
25
import java .util .Collection ;
25
26
import java .util .Collections ;
29
30
import java .util .concurrent .ConcurrentHashMap ;
30
31
import java .util .function .Supplier ;
31
32
33
+ import org .slf4j .Logger ;
34
+ import org .slf4j .LoggerFactory ;
32
35
import org .springframework .data .elasticsearch .client .ElasticsearchHost ;
33
36
import org .springframework .data .elasticsearch .client .ElasticsearchHost .State ;
34
37
import org .springframework .data .elasticsearch .client .NoReachableHostException ;
47
50
*/
48
51
class MultiNodeHostProvider implements HostProvider <MultiNodeHostProvider > {
49
52
53
+ private final static Logger LOG = LoggerFactory .getLogger (MultiNodeHostProvider .class );
54
+
50
55
private final WebClientProvider clientProvider ;
51
56
private final Supplier <HttpHeaders > headersSupplier ;
52
57
private final Map <InetSocketAddress , ElasticsearchHost > hosts ;
@@ -60,6 +65,8 @@ class MultiNodeHostProvider implements HostProvider<MultiNodeHostProvider> {
60
65
for (InetSocketAddress endpoint : endpoints ) {
61
66
this .hosts .put (endpoint , new ElasticsearchHost (endpoint , State .UNKNOWN ));
62
67
}
68
+
69
+ LOG .debug ("initialized with " + hosts );
63
70
}
64
71
65
72
/*
@@ -68,7 +75,7 @@ class MultiNodeHostProvider implements HostProvider<MultiNodeHostProvider> {
68
75
*/
69
76
@ Override
70
77
public Mono <ClusterInformation > clusterInfo () {
71
- return nodes (null ).map (this ::updateNodeState ).buffer (hosts .size ())
78
+ return checkNodes (null ).map (this ::updateNodeState ).buffer (hosts .size ())
72
79
.then (Mono .just (new ClusterInformation (new LinkedHashSet <>(this .hosts .values ()))));
73
80
}
74
81
@@ -88,14 +95,19 @@ public WebClient createWebClient(InetSocketAddress endpoint) {
88
95
@ Override
89
96
public Mono <InetSocketAddress > lookupActiveHost (Verification verification ) {
90
97
98
+ LOG .trace ("lookupActiveHost " + verification + " from " + hosts ());
99
+
91
100
if (Verification .LAZY .equals (verification )) {
92
101
for (ElasticsearchHost entry : hosts ()) {
93
102
if (entry .isOnline ()) {
103
+ LOG .trace ("lookupActiveHost returning " + entry );
94
104
return Mono .just (entry .getEndpoint ());
95
105
}
96
106
}
107
+ LOG .trace ("no online host found with LAZY" );
97
108
}
98
109
110
+ LOG .trace ("searching for active host" );
99
111
return findActiveHostInKnownActives () //
100
112
.switchIfEmpty (findActiveHostInUnresolved ()) //
101
113
.switchIfEmpty (findActiveHostInDead ()) //
@@ -107,20 +119,30 @@ Collection<ElasticsearchHost> getCachedHostState() {
107
119
}
108
120
109
121
private Mono <InetSocketAddress > findActiveHostInKnownActives () {
110
- return findActiveForSate (State .ONLINE );
122
+ return findActiveForState (State .ONLINE );
111
123
}
112
124
113
125
private Mono <InetSocketAddress > findActiveHostInUnresolved () {
114
- return findActiveForSate (State .UNKNOWN );
126
+ return findActiveForState (State .UNKNOWN );
115
127
}
116
128
117
129
private Mono <InetSocketAddress > findActiveHostInDead () {
118
- return findActiveForSate (State .OFFLINE );
130
+ return findActiveForState (State .OFFLINE );
119
131
}
120
132
121
- private Mono <InetSocketAddress > findActiveForSate (State state ) {
122
- return nodes (state ).map (this ::updateNodeState ).filter (ElasticsearchHost ::isOnline )
123
- .map (ElasticsearchHost ::getEndpoint ).next ();
133
+ private Mono <InetSocketAddress > findActiveForState (State state ) {
134
+
135
+ LOG .trace ("findActiveForState state " + state + ", current hosts: " + hosts );
136
+
137
+ return checkNodes (state ) //
138
+ .map (this ::updateNodeState ) //
139
+ .filter (ElasticsearchHost ::isOnline ) //
140
+ .map (elasticsearchHost -> {
141
+ LOG .trace ("findActiveForState returning host " + elasticsearchHost );
142
+ return elasticsearchHost ;
143
+ }).map (ElasticsearchHost ::getEndpoint ) //
144
+ .takeLast (1 ) //
145
+ .next ();
124
146
}
125
147
126
148
private ElasticsearchHost updateNodeState (Tuple2 <InetSocketAddress , State > tuple2 ) {
@@ -131,28 +153,36 @@ private ElasticsearchHost updateNodeState(Tuple2<InetSocketAddress, State> tuple
131
153
return elasticsearchHost ;
132
154
}
133
155
134
- private Flux <Tuple2 <InetSocketAddress , State >> nodes (@ Nullable State state ) {
156
+ private Flux <Tuple2 <InetSocketAddress , State >> checkNodes (@ Nullable State state ) {
157
+
158
+ LOG .trace ("checkNodes() with state " + state );
135
159
136
160
return Flux .fromIterable (hosts ()) //
137
161
.filter (entry -> state == null || entry .getState ().equals (state )) //
138
162
.map (ElasticsearchHost ::getEndpoint ) //
139
- .flatMap (host -> {
163
+ .concatMap (host -> {
164
+
165
+ LOG .trace ("checking host " + host );
140
166
141
167
Mono <ClientResponse > clientResponseMono = createWebClient (host ) //
142
168
.head ().uri ("/" ) //
143
169
.headers (httpHeaders -> httpHeaders .addAll (headersSupplier .get ())) //
144
170
.exchangeToMono (Mono ::just ) //
171
+ .timeout (Duration .ofSeconds (1 )) //
145
172
.doOnError (throwable -> {
173
+ LOG .trace ("error checking host " + host + ", " + throwable .getMessage ());
146
174
hosts .put (host , new ElasticsearchHost (host , State .OFFLINE ));
147
175
clientProvider .getErrorListener ().accept (throwable );
148
176
});
149
177
150
178
return Mono .just (host ) //
151
- .zipWith ( //
152
- clientResponseMono .flatMap (it -> it .releaseBody () //
153
- .thenReturn (it .statusCode ().isError () ? State .OFFLINE : State .ONLINE )));
179
+ .zipWith (clientResponseMono .flatMap (it -> it .releaseBody () //
180
+ .thenReturn (it .statusCode ().isError () ? State .OFFLINE : State .ONLINE )));
154
181
}) //
155
- .onErrorContinue ((throwable , o ) -> clientProvider .getErrorListener ().accept (throwable ));
182
+ .map (tuple -> {
183
+ LOG .trace ("check result " + tuple );
184
+ return tuple ;
185
+ }).onErrorContinue ((throwable , o ) -> clientProvider .getErrorListener ().accept (throwable ));
156
186
}
157
187
158
188
private List <ElasticsearchHost > hosts () {
0 commit comments