13
13
-include_lib (" common_test/include/ct.hrl" ).
14
14
-include_lib (" eunit/include/eunit.hrl" ).
15
15
-include_lib (" amqp_client/include/amqp_client.hrl" ).
16
+ -include_lib (" amqp10_client/include/amqp10_client.hrl" ).
16
17
-include_lib (" amqp10_common/include/amqp10_framing.hrl" ).
17
18
-include_lib (" amqp10_common/include/amqp10_filter.hrl" ).
18
19
@@ -26,7 +27,8 @@ groups() ->
26
27
amqp_credit_multiple_grants ,
27
28
amqp_credit_single_grant ,
28
29
amqp_attach_sub_batch ,
29
- amqp_filter_expression
30
+ amqp_property_filter ,
31
+ amqp_sql_filter
30
32
]
31
33
}].
32
34
@@ -272,9 +274,9 @@ amqp_attach_sub_batch(Config) ->
272
274
ok = amqp10_client :detach_link (Receiver ),
273
275
ok = amqp10_client :close_connection (Connection ).
274
276
275
- % % Test that AMQP filter expressions work when messages
277
+ % % Test that AMQP property filter works when messages
276
278
% % are published via the stream protocol and consumed via AMQP.
277
- amqp_filter_expression (Config ) ->
279
+ amqp_property_filter (Config ) ->
278
280
Stream = atom_to_binary (? FUNCTION_NAME ),
279
281
publish_via_stream_protocol (Stream , Config ),
280
282
@@ -317,6 +319,87 @@ amqp_filter_expression(Config) ->
317
319
ok = amqp10_client :detach_link (Receiver ),
318
320
ok = amqp10_client :close_connection (Connection ).
319
321
322
+ amqp_sql_filter (Config ) ->
323
+ Stream = atom_to_binary (? FUNCTION_NAME ),
324
+ Address = <<" /queue/" , Stream /binary >>,
325
+
326
+ AppProps1 = # 'v1_0.application_properties' {content = [{{utf8 , <<" key" >>}, {byte , 1 }}]},
327
+ AppProps2 = # 'v1_0.application_properties' {content = [{{utf8 , <<" key" >>}, {byte , 2 }}]},
328
+ {ok , S , C0 } = stream_test_utils :connect (Config , 0 ),
329
+ {ok , C1 } = stream_test_utils :create_stream (S , C0 , Stream ),
330
+ PublisherId = 55 ,
331
+ {ok , C2 } = stream_test_utils :declare_publisher (S , C1 , Stream , PublisherId ),
332
+ Bodies = lists :duplicate (2000 , <<" middle" >>),
333
+ UncompressedSubbatch1 = stream_test_utils :sub_batch_entry_uncompressed (1 , AppProps1 , [<<" first" >>]),
334
+ UncompressedSubbatch2 = stream_test_utils :sub_batch_entry_uncompressed (2 , AppProps2 , Bodies ),
335
+ UncompressedSubbatch3 = stream_test_utils :sub_batch_entry_uncompressed (3 , AppProps2 , Bodies ),
336
+ UncompressedSubbatch4 = stream_test_utils :sub_batch_entry_uncompressed (4 , AppProps1 , [<<" last" >>]),
337
+ {ok , _ , C3 } = stream_test_utils :publish_entries (S , C2 , PublisherId , 1 , UncompressedSubbatch1 ),
338
+ {ok , _ , C4 } = stream_test_utils :publish_entries (S , C3 , PublisherId , 1 , UncompressedSubbatch2 ),
339
+ {ok , _ , C5 } = stream_test_utils :publish_entries (S , C4 , PublisherId , 1 , UncompressedSubbatch3 ),
340
+ {ok , _ , C6 } = stream_test_utils :publish_entries (S , C5 , PublisherId , 1 , UncompressedSubbatch4 ),
341
+ {ok , _ } = stream_test_utils :close (S , C6 ),
342
+
343
+ OpnConf = connection_config (Config ),
344
+ {ok , Connection } = amqp10_client :open_connection (OpnConf ),
345
+ {ok , Session } = amqp10_client :begin_session_sync (Connection ),
346
+
347
+ SQL = <<" a.key % 2 = 1" >>,
348
+ Filter = #{<<" from start" >> => # filter {descriptor = <<" rabbitmq:stream-offset-spec" >>,
349
+ value = {symbol , <<" first" >>}},
350
+ ? FILTER_NAME_SQL => # filter {descriptor = ? DESCRIPTOR_NAME_SQL_FILTER ,
351
+ value = {utf8 , SQL }}},
352
+ {ok , Receiver1 } = amqp10_client :attach_receiver_link (
353
+ Session , <<" receiver 1" >>, Address ,
354
+ settled , configuration , Filter ),
355
+ {ok , Receiver2 } = amqp10_client :attach_receiver_link (
356
+ Session , <<" receiver 2" >>, Address ,
357
+ settled , configuration , Filter ),
358
+ receive {amqp10_event , {link , Receiver1 , attached }} -> ok
359
+ after 9000 -> ct :fail ({missing_msg , ? LINE })
360
+ end ,
361
+ receive {amqp10_event , {link , Receiver2 , attached }} -> ok
362
+ after 9000 -> ct :fail ({missing_msg , ? LINE })
363
+ end ,
364
+
365
+ ok = amqp10_client :flow_link_credit (Receiver1 , 3 , never , true ),
366
+ ok = amqp10_client :flow_link_credit (Receiver2 , 3 , never , true ),
367
+
368
+ % % For two links filtering on the same session, we expect that RabbitMQ
369
+ % % delivers messages concurrently (instead of scanning the entire stream
370
+ % % for the 1st receiver before scanning the entire stream for the 2nd receiver).
371
+ receive {amqp10_msg , _ , First1 } ->
372
+ ? assertEqual ([<<" first" >>], amqp10_msg :body (First1 ))
373
+ after 9000 -> ct :fail ({missing_msg , ? LINE })
374
+ end ,
375
+ receive {amqp10_msg , _ , First2 } ->
376
+ ? assertEqual ([<<" first" >>], amqp10_msg :body (First2 ))
377
+ after 9000 -> ct :fail ({missing_msg , ? LINE })
378
+ end ,
379
+
380
+ receive {amqp10_msg , _ , Last1 } ->
381
+ ? assertEqual ([<<" last" >>], amqp10_msg :body (Last1 ))
382
+ after 60_000 -> ct :fail ({missing_msg , ? LINE })
383
+ end ,
384
+ receive {amqp10_msg , _ , Last2 } ->
385
+ ? assertEqual ([<<" last" >>], amqp10_msg :body (Last2 ))
386
+ after 60_000 -> ct :fail ({missing_msg , ? LINE })
387
+ end ,
388
+
389
+ receive {amqp10_event , {link , Receiver1 , credit_exhausted }} -> ok
390
+ after 9000 -> ct :fail ({missing_event , ? LINE })
391
+ end ,
392
+ receive {amqp10_event , {link , Receiver2 , credit_exhausted }} -> ok
393
+ after 9000 -> ct :fail ({missing_event , ? LINE })
394
+ end ,
395
+
396
+ ok = amqp10_client :detach_link (Receiver1 ),
397
+ ok = amqp10_client :detach_link (Receiver2 ),
398
+ ok = amqp10_client :close_connection (Connection ),
399
+ receive {amqp10_event , {connection , Connection , {closed , normal }}} -> ok
400
+ after 9000 -> ct :fail ({missing_event , ? LINE })
401
+ end .
402
+
320
403
% % -------------------------------------------------------------------
321
404
% % Helpers
322
405
% % -------------------------------------------------------------------
@@ -330,15 +413,16 @@ publish_via_stream_protocol(Stream, Config) ->
330
413
{ok , C2 } = stream_test_utils :declare_publisher (S , C1 , Stream , PublisherId ),
331
414
332
415
M1 = stream_test_utils :simple_entry (1 , <<" m1" >>),
333
- M2 = stream_test_utils : simple_entry ( 2 , <<" m2 " >>, # 'v1_0.application_properties' {
334
- content = [{{ utf8 , <<" my key " >>},
335
- { utf8 , <<" my value " >>}}]} ),
416
+ AppProps = # 'v1_0.application_properties' { content = [{{ utf8 , <<" my key " >>},
417
+ { utf8 , <<" my value " >>}}] },
418
+ M2 = stream_test_utils : simple_entry ( 2 , <<" m2 " >>, AppProps ),
336
419
M3 = stream_test_utils :simple_entry (3 , <<" m3" >>),
337
420
Messages1 = [M1 , M2 , M3 ],
338
421
339
422
{ok , _ , C3 } = stream_test_utils :publish_entries (S , C2 , PublisherId , length (Messages1 ), Messages1 ),
340
423
341
- UncompressedSubbatch = stream_test_utils :sub_batch_entry_uncompressed (4 , [<<" m4" >>, <<" m5" >>, <<" m6" >>]),
424
+ UncompressedSubbatch = stream_test_utils :sub_batch_entry_uncompressed (
425
+ 4 , AppProps , [<<" m4" >>, <<" m5" >>, <<" m6" >>]),
342
426
{ok , _ , C4 } = stream_test_utils :publish_entries (S , C3 , PublisherId , 1 , UncompressedSubbatch ),
343
427
344
428
CompressedSubbatch = stream_test_utils :sub_batch_entry_compressed (5 , [<<" m7" >>, <<" m8" >>, <<" m9" >>]),
0 commit comments