@@ -58,6 +58,9 @@ groups() ->
58
58
sender_settle_mode_unsettled ,
59
59
sender_settle_mode_unsettled_fanout ,
60
60
sender_settle_mode_mixed ,
61
+ durable_field_classic_queue ,
62
+ durable_field_quorum_queue ,
63
+ durable_field_stream ,
61
64
invalid_transfer_settled_flag ,
62
65
quorum_queue_rejects ,
63
66
receiver_settle_mode_first ,
@@ -916,6 +919,77 @@ sender_settle_mode_mixed(Config) ->
916
919
rabbitmq_amqp_client :delete_queue (LinkPair , QName )),
917
920
ok = close (Init ).
918
921
922
+ durable_field_classic_queue (Config ) ->
923
+ QName = atom_to_binary (? FUNCTION_NAME ),
924
+ durable_field (Config , <<" classic" >>, QName ).
925
+
926
+ durable_field_quorum_queue (Config ) ->
927
+ QName = atom_to_binary (? FUNCTION_NAME ),
928
+ durable_field (Config , <<" quorum" >>, QName ).
929
+
930
+ durable_field_stream (Config ) ->
931
+ QName = atom_to_binary (? FUNCTION_NAME ),
932
+ durable_field (Config , <<" stream" >>, QName ).
933
+
934
+ durable_field (Config , QueueType , QName )
935
+ when is_binary (QueueType ) ->
936
+ Address = rabbitmq_amqp_address :queue (QName ),
937
+ {_Connection , Session , LinkPair } = Init = init (Config ),
938
+ QProps = #{arguments => #{<<" x-queue-type" >> => {utf8 , QueueType }}},
939
+ {ok , #{type := QueueType }} = rabbitmq_amqp_client :declare_queue (LinkPair , QName , QProps ),
940
+ {ok , Sender } = amqp10_client :attach_sender_link (
941
+ Session , <<" test-sender" >>, Address , unsettled ),
942
+ wait_for_credit (Sender ),
943
+
944
+ ok = amqp10_client :send_msg (Sender ,
945
+ amqp10_msg :set_headers (
946
+ #{durable => true },
947
+ amqp10_msg :new (<<" t1" >>, <<" durable" >>))),
948
+ ok = amqp10_client :send_msg (Sender ,
949
+ amqp10_msg :set_headers (
950
+ #{durable => false },
951
+ amqp10_msg :new (<<" t2" >>, <<" non-durable" >>))),
952
+ % % Even though the AMQP spec defines durable=false as default
953
+ % % (i.e. durable is false if the field is omitted on the wire),
954
+ % % we expect our AMQP Erlang library to be safe by default,
955
+ % % and therefore send the message as durable=true on behalf of us.
956
+ ok = amqp10_client :send_msg (
957
+ Sender , amqp10_msg :new (<<" t3" >>, <<" lib publishes as durable by default" >>)),
958
+ % % When we expliclitly publish without a header section, RabbitMQ should interpret
959
+ % % durable as false according to the AMQP spec.
960
+ ok = amqp10_client :send_msg (
961
+ Sender ,
962
+ amqp10_msg :from_amqp_records (
963
+ [# 'v1_0.transfer' {delivery_tag = {binary , <<" t4" >>},
964
+ settled = false ,
965
+ message_format = {uint , 0 }},
966
+ # 'v1_0.data' {content = <<" publish without header section" >>}])),
967
+
968
+ ok = wait_for_accepts (4 ),
969
+ ok = detach_link_sync (Sender ),
970
+ flush (sent ),
971
+
972
+ Filter = consume_from_first (QueueType ),
973
+ {ok , Receiver } = amqp10_client :attach_receiver_link (
974
+ Session , <<" test-receiver" >>, Address , unsettled ,
975
+ none , Filter ),
976
+
977
+ ok = amqp10_client :flow_link_credit (Receiver , 4 , never ),
978
+ [M1 , M2 , M3 , M4 ] = Msgs = receive_messages (Receiver , 4 ),
979
+ ? assertEqual (<<" durable" >>, amqp10_msg :body_bin (M1 )),
980
+ ? assertMatch (#{durable := true }, amqp10_msg :headers (M1 )),
981
+ ? assertEqual (<<" non-durable" >>, amqp10_msg :body_bin (M2 )),
982
+ ? assertMatch (#{durable := false }, amqp10_msg :headers (M2 )),
983
+ ? assertEqual (<<" lib publishes as durable by default" >>, amqp10_msg :body_bin (M3 )),
984
+ ? assertMatch (#{durable := true }, amqp10_msg :headers (M3 )),
985
+ ? assertEqual (<<" publish without header section" >>, amqp10_msg :body_bin (M4 )),
986
+ ? assertMatch (#{durable := false }, amqp10_msg :headers (M4 )),
987
+ [ok = amqp10_client :accept_msg (Receiver , M ) || M <- Msgs ],
988
+
989
+ ok = detach_link_sync (Receiver ),
990
+ {ok , _ } = rabbitmq_amqp_client :delete_queue (LinkPair , QName ),
991
+ close (Init ).
992
+
919
993
invalid_transfer_settled_flag (Config ) ->
920
994
OpnConf = connection_config (Config ),
921
995
{ok , Connection } = amqp10_client :open_connection (OpnConf ),
@@ -1301,7 +1375,7 @@ amqp_amqpl(QType, Config) ->
1301
1375
Body6 = [# 'v1_0.data' {content = <<0 , 1 >>},
1302
1376
# 'v1_0.data' {content = <<2 , 3 >>}],
1303
1377
1304
- % % Send only body sections
1378
+ % % Send only header and body sections
1305
1379
[ok = amqp10_client :send_msg (Sender , amqp10_msg :new (<<>>, Body , true )) ||
1306
1380
Body <- [Body1 , Body2 , Body3 , Body4 , Body5 , Body6 ]],
1307
1381
% % Send with application-properties
@@ -1342,6 +1416,11 @@ amqp_amqpl(QType, Config) ->
1342
1416
#{<<" x-array" >> => {array , utf8 , [{utf8 , <<" e1" >>},
1343
1417
{utf8 , <<" e2" >>}]}},
1344
1418
amqp10_msg :new (<<>>, Body1 , true ))),
1419
+ ok = amqp10_client :send_msg (
1420
+ Sender ,
1421
+ amqp10_msg :set_headers (
1422
+ #{durable => false },
1423
+ amqp10_msg :new (<<>>, Body1 , true ))),
1345
1424
1346
1425
ok = amqp10_client :detach_link (Sender ),
1347
1426
flush (detached ),
@@ -1365,8 +1444,10 @@ amqp_amqpl(QType, Config) ->
1365
1444
receive {# 'basic.deliver' {consumer_tag = CTag ,
1366
1445
redelivered = false },
1367
1446
# amqp_msg {payload = Payload1 ,
1368
- props = # 'P_basic' {type = <<" amqp-1.0" >>}}} ->
1369
- ? assertEqual ([Body1 ], amqp10_framing :decode_bin (Payload1 ))
1447
+ props = # 'P_basic' {delivery_mode = DelMode2 ,
1448
+ type = <<" amqp-1.0" >>}}} ->
1449
+ ? assertEqual ([Body1 ], amqp10_framing :decode_bin (Payload1 )),
1450
+ ? assertEqual (2 , DelMode2 )
1370
1451
after 30000 -> ct :fail ({missing_deliver , ? LINE })
1371
1452
end ,
1372
1453
receive {_ , # amqp_msg {payload = Payload2 ,
@@ -1428,6 +1509,12 @@ amqp_amqpl(QType, Config) ->
1428
1509
rabbit_misc :table_lookup (Headers11 , <<" x-array" >>))
1429
1510
after 30000 -> ct :fail ({missing_deliver , ? LINE })
1430
1511
end ,
1512
+ receive {_ , # amqp_msg {payload = Payload12 ,
1513
+ props = # 'P_basic' {delivery_mode = DelMode1 }}} ->
1514
+ ? assertEqual ([Body1 ], amqp10_framing :decode_bin (Payload12 )),
1515
+ ? assertNotEqual (2 , DelMode1 )
1516
+ after 30000 -> ct :fail ({missing_deliver , ? LINE })
1517
+ end ,
1431
1518
1432
1519
ok = rabbit_ct_client_helpers :close_connection_and_channel (Conn , Ch ),
1433
1520
{ok , _ } = rabbitmq_amqp_client :delete_queue (LinkPair , QName ),
@@ -1514,10 +1601,17 @@ amqp091_to_amqp10_header_conversion(Session, Ch, QName, Address) ->
1514
1601
amqp_channel :cast (
1515
1602
Ch ,
1516
1603
# 'basic.publish' {routing_key = QName },
1517
- # amqp_msg {props = # 'P_basic' {headers = Amqp091Headers },
1604
+ # amqp_msg {props = # 'P_basic' {delivery_mode = 2 ,
1605
+ priority = 5 ,
1606
+ headers = Amqp091Headers },
1518
1607
payload = <<" foobar" >>}),
1519
1608
1520
1609
{ok , [Msg ]} = drain_queue (Session , Address , 1 ),
1610
+
1611
+ ? assertMatch (#{durable := true ,
1612
+ priority := 5 },
1613
+ amqp10_msg :headers (Msg )),
1614
+
1521
1615
Amqp10MA = amqp10_msg :message_annotations (Msg ),
1522
1616
? assertEqual (<<" my-string" >>, maps :get (<<" x-string" >>, Amqp10MA , undefined )),
1523
1617
? assertEqual (92 , maps :get (<<" x-int" >>, Amqp10MA , undefined )),
@@ -3278,7 +3372,7 @@ max_message_size_client_to_server(Config) ->
3278
3372
{ok , Sender } = amqp10_client :attach_sender_link (Session , <<" sender" >>, Address , mixed ),
3279
3373
ok = wait_for_credit (Sender ),
3280
3374
3281
- PayloadSmallEnough = binary :copy (<<0 >>, MaxMessageSize - 10 ),
3375
+ PayloadSmallEnough = binary :copy (<<0 >>, MaxMessageSize - 20 ),
3282
3376
? assertEqual (ok ,
3283
3377
amqp10_client :send_msg (Sender , amqp10_msg :new (<<" t1" >>, PayloadSmallEnough , false ))),
3284
3378
ok = wait_for_accepted (<<" t1" >>),
0 commit comments