11
11
import org .opensearch .action .LatchedActionListener ;
12
12
import org .opensearch .action .admin .cluster .node .stats .NodeStats ;
13
13
import org .opensearch .action .admin .cluster .node .stats .NodesStatsResponse ;
14
+ import org .opensearch .action .admin .cluster .repositories .get .GetRepositoriesRequest ;
15
+ import org .opensearch .action .admin .cluster .repositories .get .GetRepositoriesResponse ;
16
+ import org .opensearch .cluster .metadata .RepositoryMetadata ;
14
17
import org .opensearch .common .collect .Tuple ;
15
18
import org .opensearch .common .settings .Settings ;
16
19
import org .opensearch .common .unit .TimeValue ;
17
20
import org .opensearch .core .action .ActionListener ;
18
21
import org .opensearch .indices .RemoteStoreSettings ;
19
22
import org .opensearch .node .remotestore .RemoteStorePinnedTimestampService ;
23
+ import org .opensearch .repositories .fs .ReloadableFsRepository ;
20
24
import org .opensearch .test .OpenSearchIntegTestCase ;
21
25
22
26
import java .util .List ;
27
+ import java .util .Locale ;
23
28
import java .util .Map ;
24
29
import java .util .Optional ;
25
30
import java .util .Set ;
26
31
import java .util .concurrent .CountDownLatch ;
32
+ import java .util .concurrent .ExecutionException ;
27
33
28
34
import static org .opensearch .action .admin .cluster .node .stats .NodesStatsRequest .Metric .REMOTE_STORE ;
35
+ import static org .opensearch .node .remotestore .RemoteStoreNodeAttribute .REMOTE_STORE_REPOSITORY_TYPE_ATTRIBUTE_KEY_FORMAT ;
36
+ import static org .opensearch .repositories .fs .ReloadableFsRepository .REPOSITORIES_SLOWDOWN_SETTING ;
29
37
30
38
@ OpenSearchIntegTestCase .ClusterScope (scope = OpenSearchIntegTestCase .Scope .TEST , numDataNodes = 0 )
31
39
public class RemoteStorePinnedTimestampsIT extends RemoteStoreBaseIntegTestCase {
32
40
static final String INDEX_NAME = "remote-store-test-idx-1" ;
33
41
34
42
@ Override
35
43
protected Settings nodeSettings (int nodeOrdinal ) {
44
+ String segmentRepoTypeAttributeKey = String .format (
45
+ Locale .getDefault (),
46
+ "node.attr." + REMOTE_STORE_REPOSITORY_TYPE_ATTRIBUTE_KEY_FORMAT ,
47
+ REPOSITORY_NAME
48
+ );
49
+
36
50
return Settings .builder ()
37
51
.put (super .nodeSettings (nodeOrdinal ))
52
+ .put (segmentRepoTypeAttributeKey , ReloadableFsRepository .TYPE )
38
53
.put (RemoteStoreSettings .CLUSTER_REMOTE_STORE_PINNED_TIMESTAMP_ENABLED .getKey (), true )
39
54
.build ();
40
55
}
41
56
42
57
ActionListener <Void > noOpActionListener = new ActionListener <>() {
43
58
@ Override
44
- public void onResponse (Void unused ) {}
59
+ public void onResponse (Void unused ) {
60
+ // do nothing
61
+ }
45
62
46
63
@ Override
47
- public void onFailure (Exception e ) {}
64
+ public void onFailure (Exception e ) {
65
+ fail ();
66
+ }
48
67
};
49
68
50
69
public void testTimestampPinUnpin () throws Exception {
@@ -57,15 +76,8 @@ public void testTimestampPinUnpin() throws Exception {
57
76
);
58
77
59
78
Tuple <Long , Set <Long >> pinnedTimestampWithFetchTimestamp = RemoteStorePinnedTimestampService .getPinnedTimestamps ();
60
- long lastFetchTimestamp = pinnedTimestampWithFetchTimestamp .v1 ();
61
- assertEquals (-1L , lastFetchTimestamp );
62
79
assertEquals (Set .of (), pinnedTimestampWithFetchTimestamp .v2 ());
63
80
64
- assertThrows (
65
- IllegalArgumentException .class ,
66
- () -> remoteStorePinnedTimestampService .pinTimestamp (1234L , "ss1" , noOpActionListener )
67
- );
68
-
69
81
long timestamp1 = System .currentTimeMillis () + 30000L ;
70
82
long timestamp2 = System .currentTimeMillis () + 60000L ;
71
83
long timestamp3 = System .currentTimeMillis () + 900000L ;
@@ -197,6 +209,104 @@ public void onFailure(Exception e) {
197
209
remoteStorePinnedTimestampService .rescheduleAsyncUpdatePinnedTimestampTask (TimeValue .timeValueMinutes (3 ));
198
210
}
199
211
212
+ public void testPinExceptionsOlderTimestamp () throws InterruptedException {
213
+ prepareCluster (1 , 1 , INDEX_NAME , 0 , 2 );
214
+ ensureGreen (INDEX_NAME );
215
+
216
+ RemoteStorePinnedTimestampService remoteStorePinnedTimestampService = internalCluster ().getInstance (
217
+ RemoteStorePinnedTimestampService .class ,
218
+ primaryNodeName (INDEX_NAME )
219
+ );
220
+
221
+ CountDownLatch latch = new CountDownLatch (1 );
222
+ remoteStorePinnedTimestampService .pinTimestamp (1234L , "ss1" , new LatchedActionListener <>(new ActionListener <>() {
223
+ @ Override
224
+ public void onResponse (Void unused ) {
225
+ // We expect onFailure to be called
226
+ fail ();
227
+ }
228
+
229
+ @ Override
230
+ public void onFailure (Exception e ) {
231
+ assertTrue (e instanceof IllegalArgumentException );
232
+ }
233
+ }, latch ));
234
+
235
+ latch .await ();
236
+ }
237
+
238
+ public void testPinExceptionsRemoteStoreCallTakeTime () throws InterruptedException , ExecutionException {
239
+ prepareCluster (1 , 1 , INDEX_NAME , 0 , 2 );
240
+ ensureGreen (INDEX_NAME );
241
+
242
+ RemoteStorePinnedTimestampService remoteStorePinnedTimestampService = internalCluster ().getInstance (
243
+ RemoteStorePinnedTimestampService .class ,
244
+ primaryNodeName (INDEX_NAME )
245
+ );
246
+
247
+ CountDownLatch latch = new CountDownLatch (1 );
248
+ slowDownRepo (REPOSITORY_NAME , 10 );
249
+ RemoteStoreSettings .setPinnedTimestampsLookbackInterval (TimeValue .timeValueSeconds (1 ));
250
+ long timestampToBePinned = System .currentTimeMillis () + 600000 ;
251
+ remoteStorePinnedTimestampService .pinTimestamp (timestampToBePinned , "ss1" , new LatchedActionListener <>(new ActionListener <>() {
252
+ @ Override
253
+ public void onResponse (Void unused ) {
254
+ // We expect onFailure to be called
255
+ fail ();
256
+ }
257
+
258
+ @ Override
259
+ public void onFailure (Exception e ) {
260
+ logger .error (e .getMessage ());
261
+ assertTrue (e instanceof RuntimeException );
262
+ assertTrue (e .getMessage ().contains ("Timestamp pinning took" ));
263
+
264
+ // Check if the timestamp was unpinned
265
+ remoteStorePinnedTimestampService .forceSyncPinnedTimestamps ();
266
+ assertFalse (RemoteStorePinnedTimestampService .getPinnedTimestamps ().v2 ().contains (timestampToBePinned ));
267
+ }
268
+ }, latch ));
269
+
270
+ latch .await ();
271
+ }
272
+
273
+ protected void slowDownRepo (String repoName , int value ) throws ExecutionException , InterruptedException {
274
+ GetRepositoriesRequest gr = new GetRepositoriesRequest (new String [] { repoName });
275
+ GetRepositoriesResponse res = client ().admin ().cluster ().getRepositories (gr ).get ();
276
+ RepositoryMetadata rmd = res .repositories ().get (0 );
277
+ Settings .Builder settings = Settings .builder ()
278
+ .put ("location" , rmd .settings ().get ("location" ))
279
+ .put (REPOSITORIES_SLOWDOWN_SETTING .getKey (), value );
280
+ createRepository (repoName , rmd .type (), settings );
281
+ }
282
+
283
+ public void testUnpinException () throws InterruptedException {
284
+ prepareCluster (1 , 1 , INDEX_NAME , 0 , 2 );
285
+ ensureGreen (INDEX_NAME );
286
+
287
+ RemoteStorePinnedTimestampService remoteStorePinnedTimestampService = internalCluster ().getInstance (
288
+ RemoteStorePinnedTimestampService .class ,
289
+ primaryNodeName (INDEX_NAME )
290
+ );
291
+
292
+ CountDownLatch latch = new CountDownLatch (1 );
293
+ remoteStorePinnedTimestampService .unpinTimestamp (1234L , "dummy-entity" , new LatchedActionListener <>(new ActionListener <>() {
294
+ @ Override
295
+ public void onResponse (Void unused ) {
296
+ // We expect onFailure to be called
297
+ fail ();
298
+ }
299
+
300
+ @ Override
301
+ public void onFailure (Exception e ) {
302
+ logger .error (e .getMessage ());
303
+ assertTrue (e instanceof IllegalArgumentException );
304
+ }
305
+ }, latch ));
306
+
307
+ latch .await ();
308
+ }
309
+
200
310
public void testLastSuccessfulFetchOfPinnedTimestampsPresentInNodeStats () throws Exception {
201
311
logger .info ("Starting up cluster manager" );
202
312
logger .info ("cluster.remote_store.pinned_timestamps.enabled set to true" );
0 commit comments