28
28
import static io .grpc .xds .XdsTestUtils .getWrrLbConfigAsMap ;
29
29
import static org .junit .Assert .assertEquals ;
30
30
import static org .junit .Assert .assertNotNull ;
31
+ import static org .junit .Assert .assertNotSame ;
31
32
import static org .junit .Assert .assertNull ;
32
33
import static org .junit .Assert .assertSame ;
33
34
import static org .junit .Assert .assertTrue ;
34
35
import static org .mockito .ArgumentMatchers .eq ;
35
36
import static org .mockito .Mockito .mock ;
37
+ import static org .mockito .Mockito .times ;
36
38
import static org .mockito .Mockito .verify ;
37
39
38
40
import com .google .common .collect .ImmutableList ;
@@ -89,8 +91,8 @@ public class GcpAuthenticationFilterTest {
89
91
90
92
@ Test
91
93
public void testNewFilterInstancesPerFilterName () {
92
- assertThat (new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME1" ))
93
- .isNotEqualTo (new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME1" ));
94
+ assertThat (new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME1" , 10 ))
95
+ .isNotEqualTo (new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME1" , 10 ));
94
96
}
95
97
96
98
@ Test
@@ -152,7 +154,7 @@ public void testClientInterceptor_success() throws IOException, ResourceInvalidE
152
154
.withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
153
155
.withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
154
156
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
155
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
157
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
156
158
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
157
159
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
158
160
Channel mockChannel = Mockito .mock (Channel .class );
@@ -181,7 +183,7 @@ public void testClientInterceptor_createsAndReusesCachedCredentials()
181
183
.withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
182
184
.withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
183
185
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
184
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
186
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
185
187
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
186
188
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
187
189
Channel mockChannel = Mockito .mock (Channel .class );
@@ -190,7 +192,7 @@ public void testClientInterceptor_createsAndReusesCachedCredentials()
190
192
interceptor .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel );
191
193
interceptor .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel );
192
194
193
- verify (mockChannel , Mockito . times (2 ))
195
+ verify (mockChannel , times (2 ))
194
196
.newCall (eq (methodDescriptor ), callOptionsCaptor .capture ());
195
197
CallOptions firstCapturedOptions = callOptionsCaptor .getAllValues ().get (0 );
196
198
CallOptions secondCapturedOptions = callOptionsCaptor .getAllValues ().get (1 );
@@ -202,7 +204,7 @@ public void testClientInterceptor_createsAndReusesCachedCredentials()
202
204
@ Test
203
205
public void testClientInterceptor_withoutClusterSelectionKey () throws Exception {
204
206
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
205
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
207
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
206
208
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
207
209
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
208
210
Channel mockChannel = mock (Channel .class );
@@ -233,7 +235,7 @@ public void testClientInterceptor_clusterSelectionKeyWithoutPrefix() throws Exce
233
235
Channel mockChannel = mock (Channel .class );
234
236
235
237
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
236
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
238
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
237
239
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
238
240
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
239
241
interceptor .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel );
@@ -244,7 +246,7 @@ public void testClientInterceptor_clusterSelectionKeyWithoutPrefix() throws Exce
244
246
@ Test
245
247
public void testClientInterceptor_xdsConfigDoesNotExist () throws Exception {
246
248
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
247
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
249
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
248
250
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
249
251
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
250
252
Channel mockChannel = mock (Channel .class );
@@ -274,7 +276,7 @@ public void testClientInterceptor_incorrectClusterName() throws Exception {
274
276
.withOption (CLUSTER_SELECTION_KEY , "cluster:cluster" )
275
277
.withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
276
278
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
277
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
279
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
278
280
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
279
281
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
280
282
Channel mockChannel = mock (Channel .class );
@@ -300,7 +302,7 @@ public void testClientInterceptor_statusOrError() throws Exception {
300
302
.withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
301
303
.withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
302
304
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
303
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
305
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
304
306
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
305
307
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
306
308
Channel mockChannel = mock (Channel .class );
@@ -329,7 +331,7 @@ public void testClientInterceptor_notAudienceWrapper()
329
331
.withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
330
332
.withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
331
333
GcpAuthenticationConfig config = new GcpAuthenticationConfig (10 );
332
- GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" );
334
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 10 );
333
335
ClientInterceptor interceptor = filter .buildClientInterceptor (config , null , null );
334
336
MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
335
337
Channel mockChannel = Mockito .mock (Channel .class );
@@ -342,6 +344,115 @@ public void testClientInterceptor_notAudienceWrapper()
342
344
assertThat (clientCall .error .getDescription ()).contains ("GCP Authn found wrong type" );
343
345
}
344
346
347
+ @ Test
348
+ public void testLruCacheAcrossInterceptors () throws IOException , ResourceInvalidException {
349
+ XdsConfig .XdsClusterConfig clusterConfig = new XdsConfig .XdsClusterConfig (
350
+ CLUSTER_NAME , cdsUpdate , new EndpointConfig (StatusOr .fromValue (edsUpdate )));
351
+ XdsConfig defaultXdsConfig = new XdsConfig .XdsConfigBuilder ()
352
+ .setListener (ldsUpdate )
353
+ .setRoute (rdsUpdate )
354
+ .setVirtualHost (rdsUpdate .virtualHosts .get (0 ))
355
+ .addCluster (CLUSTER_NAME , StatusOr .fromValue (clusterConfig )).build ();
356
+ CallOptions callOptionsWithXds = CallOptions .DEFAULT
357
+ .withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
358
+ .withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
359
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 2 );
360
+ ClientInterceptor interceptor1
361
+ = filter .buildClientInterceptor (new GcpAuthenticationConfig (2 ), null , null );
362
+ MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
363
+ Channel mockChannel = Mockito .mock (Channel .class );
364
+ ArgumentCaptor <CallOptions > callOptionsCaptor = ArgumentCaptor .forClass (CallOptions .class );
365
+
366
+ interceptor1 .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel );
367
+ verify (mockChannel ).newCall (eq (methodDescriptor ), callOptionsCaptor .capture ());
368
+ CallOptions capturedOptions1 = callOptionsCaptor .getAllValues ().get (0 );
369
+ assertNotNull (capturedOptions1 .getCredentials ());
370
+ ClientInterceptor interceptor2
371
+ = filter .buildClientInterceptor (new GcpAuthenticationConfig (1 ), null , null );
372
+ interceptor2 .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel );
373
+ verify (mockChannel , times (2 ))
374
+ .newCall (eq (methodDescriptor ), callOptionsCaptor .capture ());
375
+ CallOptions capturedOptions2 = callOptionsCaptor .getAllValues ().get (1 );
376
+ assertNotNull (capturedOptions2 .getCredentials ());
377
+
378
+ assertSame (capturedOptions1 .getCredentials (), capturedOptions2 .getCredentials ());
379
+ }
380
+
381
+ @ Test
382
+ public void testLruCacheEvictionOnResize () throws IOException , ResourceInvalidException {
383
+ XdsConfig .XdsClusterConfig clusterConfig = new XdsConfig .XdsClusterConfig (
384
+ CLUSTER_NAME , cdsUpdate , new EndpointConfig (StatusOr .fromValue (edsUpdate )));
385
+ XdsConfig defaultXdsConfig = new XdsConfig .XdsConfigBuilder ()
386
+ .setListener (ldsUpdate )
387
+ .setRoute (rdsUpdate )
388
+ .setVirtualHost (rdsUpdate .virtualHosts .get (0 ))
389
+ .addCluster (CLUSTER_NAME , StatusOr .fromValue (clusterConfig )).build ();
390
+ CallOptions callOptionsWithXds = CallOptions .DEFAULT
391
+ .withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
392
+ .withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
393
+ GcpAuthenticationFilter filter = new GcpAuthenticationFilter ("FILTER_INSTANCE_NAME" , 2 );
394
+ MethodDescriptor <Void , Void > methodDescriptor = TestMethodDescriptors .voidMethod ();
395
+
396
+ ClientInterceptor interceptor1 =
397
+ filter .buildClientInterceptor (new GcpAuthenticationConfig (2 ), null , null );
398
+ Channel mockChannel1 = Mockito .mock (Channel .class );
399
+ ArgumentCaptor <CallOptions > captor = ArgumentCaptor .forClass (CallOptions .class );
400
+ interceptor1 .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel1 );
401
+ verify (mockChannel1 ).newCall (eq (methodDescriptor ), captor .capture ());
402
+ CallOptions options1 = captor .getValue ();
403
+ // This will recreate the cache with max size of 1 and copy the credential for audience1.
404
+ ClientInterceptor interceptor2 =
405
+ filter .buildClientInterceptor (new GcpAuthenticationConfig (1 ), null , null );
406
+ Channel mockChannel2 = Mockito .mock (Channel .class );
407
+ interceptor2 .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel2 );
408
+ verify (mockChannel2 ).newCall (eq (methodDescriptor ), captor .capture ());
409
+ CallOptions options2 = captor .getValue ();
410
+
411
+ assertSame (options1 .getCredentials (), options2 .getCredentials ());
412
+
413
+ clusterConfig = new XdsConfig .XdsClusterConfig (
414
+ CLUSTER_NAME , getCdsUpdate2 (), new EndpointConfig (StatusOr .fromValue (edsUpdate )));
415
+ defaultXdsConfig = new XdsConfig .XdsConfigBuilder ()
416
+ .setListener (ldsUpdate )
417
+ .setRoute (rdsUpdate )
418
+ .setVirtualHost (rdsUpdate .virtualHosts .get (0 ))
419
+ .addCluster (CLUSTER_NAME , StatusOr .fromValue (clusterConfig )).build ();
420
+ callOptionsWithXds = CallOptions .DEFAULT
421
+ .withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
422
+ .withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
423
+
424
+ // This will evict the credential for audience1 and add new credential for audience2
425
+ ClientInterceptor interceptor3 =
426
+ filter .buildClientInterceptor (new GcpAuthenticationConfig (1 ), null , null );
427
+ Channel mockChannel3 = Mockito .mock (Channel .class );
428
+ interceptor3 .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel3 );
429
+ verify (mockChannel3 ).newCall (eq (methodDescriptor ), captor .capture ());
430
+ CallOptions options3 = captor .getValue ();
431
+
432
+ assertNotSame (options1 .getCredentials (), options3 .getCredentials ());
433
+
434
+ clusterConfig = new XdsConfig .XdsClusterConfig (
435
+ CLUSTER_NAME , cdsUpdate , new EndpointConfig (StatusOr .fromValue (edsUpdate )));
436
+ defaultXdsConfig = new XdsConfig .XdsConfigBuilder ()
437
+ .setListener (ldsUpdate )
438
+ .setRoute (rdsUpdate )
439
+ .setVirtualHost (rdsUpdate .virtualHosts .get (0 ))
440
+ .addCluster (CLUSTER_NAME , StatusOr .fromValue (clusterConfig )).build ();
441
+ callOptionsWithXds = CallOptions .DEFAULT
442
+ .withOption (CLUSTER_SELECTION_KEY , "cluster:cluster0" )
443
+ .withOption (XDS_CONFIG_CALL_OPTION_KEY , defaultXdsConfig );
444
+
445
+ // This will create new credential for audience1 because it has been evicted
446
+ ClientInterceptor interceptor4 =
447
+ filter .buildClientInterceptor (new GcpAuthenticationConfig (1 ), null , null );
448
+ Channel mockChannel4 = Mockito .mock (Channel .class );
449
+ interceptor4 .interceptCall (methodDescriptor , callOptionsWithXds , mockChannel4 );
450
+ verify (mockChannel4 ).newCall (eq (methodDescriptor ), captor .capture ());
451
+ CallOptions options4 = captor .getValue ();
452
+
453
+ assertNotSame (options1 .getCredentials (), options4 .getCredentials ());
454
+ }
455
+
345
456
private static LdsUpdate getLdsUpdate () {
346
457
Filter .NamedFilterConfig routerFilterConfig = new Filter .NamedFilterConfig (
347
458
serverName , RouterFilter .ROUTER_CONFIG );
@@ -384,6 +495,19 @@ private static CdsUpdate getCdsUpdate() {
384
495
}
385
496
}
386
497
498
+ private static CdsUpdate getCdsUpdate2 () {
499
+ ImmutableMap .Builder <String , Object > parsedMetadata = ImmutableMap .builder ();
500
+ parsedMetadata .put ("FILTER_INSTANCE_NAME" , new AudienceWrapper ("NEW_TEST_AUDIENCE" ));
501
+ try {
502
+ CdsUpdate .Builder cdsUpdate = CdsUpdate .forEds (
503
+ CLUSTER_NAME , EDS_NAME , null , null , null , null , false )
504
+ .lbPolicyConfig (getWrrLbConfigAsMap ());
505
+ return cdsUpdate .parsedMetadata (parsedMetadata .build ()).build ();
506
+ } catch (IOException ex ) {
507
+ return null ;
508
+ }
509
+ }
510
+
387
511
private static CdsUpdate getCdsUpdateWithIncorrectAudienceWrapper () throws IOException {
388
512
ImmutableMap .Builder <String , Object > parsedMetadata = ImmutableMap .builder ();
389
513
parsedMetadata .put ("FILTER_INSTANCE_NAME" , "TEST_AUDIENCE" );
0 commit comments