37
37
import org .opensearch .cluster .ClusterState ;
38
38
import org .opensearch .cluster .Diff ;
39
39
import org .opensearch .cluster .coordination .CoordinationMetadata .VotingConfiguration ;
40
+ import org .opensearch .cluster .metadata .Metadata ;
40
41
import org .opensearch .cluster .node .DiscoveryNode ;
41
42
import org .opensearch .cluster .node .DiscoveryNodes ;
42
43
import org .opensearch .common .settings .ClusterSettings ;
43
44
import org .opensearch .common .settings .Settings ;
44
45
import org .opensearch .core .common .io .stream .StreamOutput ;
46
+ import org .opensearch .gateway .remote .ClusterMetadataManifest ;
47
+ import org .opensearch .gateway .remote .RemoteClusterStateService ;
45
48
import org .opensearch .node .Node ;
46
49
import org .opensearch .telemetry .tracing .noop .NoopTracer ;
47
50
import org .opensearch .test .OpenSearchTestCase ;
48
51
import org .opensearch .test .transport .CapturingTransport ;
49
52
import org .opensearch .transport .TransportService ;
53
+ import org .junit .Before ;
50
54
51
55
import java .io .IOException ;
52
56
import java .util .Collections ;
57
+ import java .util .Optional ;
58
+ import java .util .function .Function ;
59
+
60
+ import org .mockito .Mockito ;
53
61
54
62
import static org .hamcrest .Matchers .containsString ;
55
63
import static org .hamcrest .Matchers .instanceOf ;
64
+ import static org .hamcrest .Matchers .is ;
65
+ import static org .mockito .Mockito .mock ;
66
+ import static org .mockito .Mockito .times ;
67
+ import static org .mockito .Mockito .when ;
56
68
57
69
public class PublicationTransportHandlerTests extends OpenSearchTestCase {
58
70
59
- public void testDiffSerializationFailure () {
60
- DeterministicTaskQueue deterministicTaskQueue = new DeterministicTaskQueue (
71
+ private static final long TERM = 5 ;
72
+ private static final long VERSION = 5 ;
73
+ private static final String CLUSTER_NAME = "test-cluster" ;
74
+ private static final String CLUSTER_UUID = "test-cluster-UUID" ;
75
+ private static final String MANIFEST_FILE = "path/to/manifest" ;
76
+ private static final String LOCAL_NODE_ID = "localNode" ;
77
+
78
+ private DeterministicTaskQueue deterministicTaskQueue ;
79
+ private TransportService transportService ;
80
+ private DiscoveryNode localNode ;
81
+ private DiscoveryNode secondNode ;
82
+
83
+ @ Before
84
+ public void setup () {
85
+ deterministicTaskQueue = new DeterministicTaskQueue (
61
86
Settings .builder ().put (Node .NODE_NAME_SETTING .getKey (), "test" ).build (),
62
87
random ()
63
88
);
64
89
final ClusterSettings clusterSettings = new ClusterSettings (Settings .EMPTY , ClusterSettings .BUILT_IN_CLUSTER_SETTINGS );
65
- final DiscoveryNode localNode = new DiscoveryNode ("localNode" , buildNewFakeTransportAddress (), Version .CURRENT );
66
- final TransportService transportService = new CapturingTransport ().createTransportService (
90
+ localNode = new DiscoveryNode (LOCAL_NODE_ID , buildNewFakeTransportAddress (), Version .CURRENT );
91
+ secondNode = new DiscoveryNode ("secondNode" , buildNewFakeTransportAddress (), Version .CURRENT );
92
+ transportService = new CapturingTransport ().createTransportService (
67
93
Settings .EMPTY ,
68
94
deterministicTaskQueue .getThreadPool (),
69
95
TransportService .NOOP_TRANSPORT_INTERCEPTOR ,
@@ -72,15 +98,10 @@ public void testDiffSerializationFailure() {
72
98
Collections .emptySet (),
73
99
NoopTracer .INSTANCE
74
100
);
75
- final PublicationTransportHandler handler = new PublicationTransportHandler (
76
- transportService ,
77
- writableRegistry (),
78
- pu -> null ,
79
- (pu , l ) -> {},
80
- null
81
- );
82
- transportService .start ();
83
- transportService .acceptIncomingRequests ();
101
+ }
102
+
103
+ public void testDiffSerializationFailure () {
104
+ final PublicationTransportHandler handler = getPublicationTransportHandler (p -> null , null );
84
105
85
106
final DiscoveryNode otherNode = new DiscoveryNode ("otherNode" , buildNewFakeTransportAddress (), Version .CURRENT );
86
107
final ClusterState clusterState = CoordinationStateTests .clusterState (
@@ -118,4 +139,175 @@ public void writeTo(StreamOutput out) throws IOException {
118
139
assertThat (e .getCause (), instanceOf (IOException .class ));
119
140
assertThat (e .getCause ().getMessage (), containsString ("Simulated failure of diff serialization" ));
120
141
}
142
+
143
+ public void testHandleRemoteIncomingPublishRequestWhenNoCurrentPublishRequest () {
144
+ RemoteClusterStateService remoteClusterStateService = mock (RemoteClusterStateService .class );
145
+
146
+ PublishWithJoinResponse expectedPublishResponse = new PublishWithJoinResponse (new PublishResponse (TERM , VERSION ), Optional .empty ());
147
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest = p -> expectedPublishResponse ;
148
+ final PublicationTransportHandler handler = getPublicationTransportHandler (handlePublishRequest , remoteClusterStateService );
149
+ RemotePublishRequest remotePublishRequest = new RemotePublishRequest (
150
+ localNode ,
151
+ TERM ,
152
+ VERSION ,
153
+ CLUSTER_NAME ,
154
+ CLUSTER_UUID ,
155
+ MANIFEST_FILE
156
+ );
157
+
158
+ IllegalStateException e = expectThrows (
159
+ IllegalStateException .class ,
160
+ () -> handler .handleIncomingRemotePublishRequest (remotePublishRequest )
161
+ );
162
+ assertThat (e .getMessage (), containsString ("publication to self failed" ));
163
+ Mockito .verifyNoInteractions (remoteClusterStateService );
164
+ }
165
+
166
+ public void testHandleRemoteIncomingPublishRequestWhenTermMismatch () {
167
+ RemoteClusterStateService remoteClusterStateService = mock (RemoteClusterStateService .class );
168
+
169
+ PublishWithJoinResponse expectedPublishResponse = new PublishWithJoinResponse (new PublishResponse (TERM , VERSION ), Optional .empty ());
170
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest = p -> expectedPublishResponse ;
171
+ final PublicationTransportHandler handler = getPublicationTransportHandler (handlePublishRequest , remoteClusterStateService );
172
+ RemotePublishRequest remotePublishRequest = new RemotePublishRequest (
173
+ localNode ,
174
+ TERM ,
175
+ VERSION ,
176
+ CLUSTER_NAME ,
177
+ CLUSTER_UUID ,
178
+ MANIFEST_FILE
179
+ );
180
+ ClusterState clusterState = buildClusterState (6L , VERSION );
181
+ PublishRequest publishRequest = new PublishRequest (clusterState );
182
+ handler .setCurrentPublishRequestToSelf (publishRequest );
183
+ IllegalStateException e = expectThrows (
184
+ IllegalStateException .class ,
185
+ () -> handler .handleIncomingRemotePublishRequest (remotePublishRequest )
186
+ );
187
+ assertThat (e .getMessage (), containsString ("publication to self failed" ));
188
+ Mockito .verifyNoInteractions (remoteClusterStateService );
189
+ }
190
+
191
+ public void testHandleRemoteIncomingPublishRequestWhenVersionMismatch () {
192
+ RemoteClusterStateService remoteClusterStateService = mock (RemoteClusterStateService .class );
193
+
194
+ PublishWithJoinResponse expectedPublishResponse = new PublishWithJoinResponse (new PublishResponse (TERM , VERSION ), Optional .empty ());
195
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest = p -> expectedPublishResponse ;
196
+ final PublicationTransportHandler handler = getPublicationTransportHandler (handlePublishRequest , remoteClusterStateService );
197
+ RemotePublishRequest remotePublishRequest = new RemotePublishRequest (
198
+ localNode ,
199
+ TERM ,
200
+ VERSION ,
201
+ CLUSTER_NAME ,
202
+ CLUSTER_UUID ,
203
+ MANIFEST_FILE
204
+ );
205
+ ClusterState clusterState = buildClusterState (TERM , 11L );
206
+ PublishRequest publishRequest = new PublishRequest (clusterState );
207
+ handler .setCurrentPublishRequestToSelf (publishRequest );
208
+ IllegalStateException e = expectThrows (
209
+ IllegalStateException .class ,
210
+ () -> handler .handleIncomingRemotePublishRequest (remotePublishRequest )
211
+ );
212
+ assertThat (e .getMessage (), containsString ("publication to self failed" ));
213
+ Mockito .verifyNoInteractions (remoteClusterStateService );
214
+ }
215
+
216
+ public void testHandleRemoteIncomingPublishRequestForLocalNode () throws IOException {
217
+ RemoteClusterStateService remoteClusterStateService = mock (RemoteClusterStateService .class );
218
+
219
+ PublishWithJoinResponse expectedPublishResponse = new PublishWithJoinResponse (new PublishResponse (TERM , VERSION ), Optional .empty ());
220
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest = p -> expectedPublishResponse ;
221
+ final PublicationTransportHandler handler = getPublicationTransportHandler (handlePublishRequest , remoteClusterStateService );
222
+ RemotePublishRequest remotePublishRequest = new RemotePublishRequest (
223
+ localNode ,
224
+ TERM ,
225
+ VERSION ,
226
+ CLUSTER_NAME ,
227
+ CLUSTER_UUID ,
228
+ MANIFEST_FILE
229
+ );
230
+ ClusterState clusterState = buildClusterState (TERM , VERSION );
231
+ PublishRequest publishRequest = new PublishRequest (clusterState );
232
+ handler .setCurrentPublishRequestToSelf (publishRequest );
233
+ PublishWithJoinResponse publishWithJoinResponse = handler .handleIncomingRemotePublishRequest (remotePublishRequest );
234
+ assertThat (publishWithJoinResponse , is (expectedPublishResponse ));
235
+ Mockito .verifyNoInteractions (remoteClusterStateService );
236
+ }
237
+
238
+ public void testHandleRemoteIncomingPublishRequestWhenManifestNotFound () throws IOException {
239
+ RemoteClusterStateService remoteClusterStateService = mock (RemoteClusterStateService .class );
240
+
241
+ PublishWithJoinResponse expectedPublishResponse = new PublishWithJoinResponse (new PublishResponse (TERM , VERSION ), Optional .empty ());
242
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest = p -> expectedPublishResponse ;
243
+ final PublicationTransportHandler handler = getPublicationTransportHandler (handlePublishRequest , remoteClusterStateService );
244
+ RemotePublishRequest remotePublishRequest = new RemotePublishRequest (
245
+ secondNode ,
246
+ TERM ,
247
+ VERSION ,
248
+ CLUSTER_NAME ,
249
+ CLUSTER_UUID ,
250
+ MANIFEST_FILE
251
+ );
252
+ when (remoteClusterStateService .getClusterMetadataManifestByFileName (CLUSTER_UUID , MANIFEST_FILE )).thenReturn (null );
253
+ ClusterState clusterState = buildClusterState (TERM , VERSION );
254
+ PublishRequest publishRequest = new PublishRequest (clusterState );
255
+ handler .setCurrentPublishRequestToSelf (publishRequest );
256
+ IllegalStateException e = expectThrows (
257
+ IllegalStateException .class ,
258
+ () -> handler .handleIncomingRemotePublishRequest (remotePublishRequest )
259
+ );
260
+ assertThat (e .getMessage (), containsString ("Publication failed as manifest was not found for" ));
261
+ Mockito .verify (remoteClusterStateService , times (1 )).getClusterMetadataManifestByFileName (Mockito .any (), Mockito .any ());
262
+ }
263
+
264
+ public void testHandleRemoteIncomingPublishRequestWhenNoLastSeenState () throws IOException {
265
+ RemoteClusterStateService remoteClusterStateService = mock (RemoteClusterStateService .class );
266
+
267
+ PublishWithJoinResponse expectedPublishResponse = new PublishWithJoinResponse (new PublishResponse (TERM , VERSION ), Optional .empty ());
268
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest = p -> expectedPublishResponse ;
269
+ final PublicationTransportHandler handler = getPublicationTransportHandler (handlePublishRequest , remoteClusterStateService );
270
+ RemotePublishRequest remotePublishRequest = new RemotePublishRequest (
271
+ secondNode ,
272
+ TERM ,
273
+ VERSION ,
274
+ CLUSTER_NAME ,
275
+ CLUSTER_UUID ,
276
+ MANIFEST_FILE
277
+ );
278
+ ClusterMetadataManifest manifest = ClusterMetadataManifest .builder ().clusterTerm (TERM ).stateVersion (VERSION ).build ();
279
+ when (remoteClusterStateService .getClusterMetadataManifestByFileName (CLUSTER_UUID , MANIFEST_FILE )).thenReturn (manifest );
280
+ when (remoteClusterStateService .getClusterStateForManifest (CLUSTER_NAME , manifest , LOCAL_NODE_ID , true )).thenReturn (
281
+ buildClusterState (TERM , VERSION )
282
+ );
283
+ ClusterState clusterState = buildClusterState (TERM , VERSION );
284
+ PublishRequest publishRequest = new PublishRequest (clusterState );
285
+ handler .setCurrentPublishRequestToSelf (publishRequest );
286
+ PublishWithJoinResponse publishWithJoinResponse = handler .handleIncomingRemotePublishRequest (remotePublishRequest );
287
+ assertThat (publishWithJoinResponse , is (expectedPublishResponse ));
288
+ Mockito .verify (remoteClusterStateService , times (1 )).getClusterMetadataManifestByFileName (Mockito .any (), Mockito .any ());
289
+ }
290
+
291
+ private PublicationTransportHandler getPublicationTransportHandler (
292
+ Function <PublishRequest , PublishWithJoinResponse > handlePublishRequest ,
293
+ RemoteClusterStateService remoteClusterStateService
294
+ ) {
295
+ final PublicationTransportHandler handler = new PublicationTransportHandler (
296
+ transportService ,
297
+ writableRegistry (),
298
+ handlePublishRequest ,
299
+ (pu , l ) -> {},
300
+ remoteClusterStateService
301
+ );
302
+ transportService .start ();
303
+ transportService .acceptIncomingRequests ();
304
+ return handler ;
305
+ }
306
+
307
+ private ClusterState buildClusterState (long term , long version ) {
308
+ CoordinationMetadata .Builder coordMetadataBuilder = CoordinationMetadata .builder ().term (term );
309
+ Metadata newMetadata = Metadata .builder ().coordinationMetadata (coordMetadataBuilder .build ()).build ();
310
+ DiscoveryNodes nodes = DiscoveryNodes .builder ().add (localNode ).add (secondNode ).localNodeId (LOCAL_NODE_ID ).build ();
311
+ return ClusterState .builder (ClusterState .EMPTY_STATE ).version (version ).metadata (newMetadata ).nodes (nodes ).build ();
312
+ }
121
313
}
0 commit comments