<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>Hi!</div><div><br></div><div>Yes, I did build Net::RabbitMQ with that version of rabbitmq-c and it ran the script below without crashing.</div></div><br><div><div>On Apr 5, 2012, at 9:18 PM, Alan Antonuk wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">What do you mean by it doesn't segfault with&nbsp;rabbitmq-c-fb6fca832fd2 ? &nbsp;Did you build Net::RabbitMQ with that version of rabbitmq-c and it ran the script below without crashing?<div><br></div><div>-Alan<br><div><div><br>
<div class="gmail_quote">On Wed, Apr 4, 2012 at 3:12 AM, Matti Linnanvuori <span dir="ltr">&lt;<a href="mailto:matti.linnanvuori@portalify.com">matti.linnanvuori@portalify.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi!<br>
<br>
I wonder how it is possible to have recv hang if RabbitMQ server has disconnected. Maybe RabbitMQ server has a bug that it does not disconnect a socket.<br>
<br>
I am afraid I don't have a succinct example that can reproduce this segfault. It occurred with Net::RabbitMQ versions 0.2.0 and 0.2.2, but not with rabbitmq-c-fb6fca832fd2.<br>
<br>
I reported the segmentation fault in CPAN:<br>
<a href="https://rt.cpan.org/Public/Bug/Display.html?id=76205" target="_blank">https://rt.cpan.org/Public/Bug/Display.html?id=76205</a><br>
<br>
I got the segmentation fault in subroutine get. I think it is because memory allocation failed.<br>
I have Net::RabbitMQ version 0.2.2. I got a similar bug in Net::RabbitMQ version 0.2.0, too:<a href="https://rt.cpan.org/Public/Bug/Display.html?id=76156" target="_blank">https://rt.cpan.org/Public/Bug/Display.html?id=76156</a><br>

This is perl, v5.10.0 built for x86_64-linux-thread-multi<br>
Linux pmc-inst-test 2.6.32.12-0.7-default #1 SMP 2010-05-20 11:14:20 +0200 x86_64 x86_64 x86_64 GNU/Linux<br>
<br>
Program received signal SIGSEGV, Segmentation fault.<br>
0x00007ffff724fa41 in memcpy () from /lib64/libc.so.6<br>
(gdb) bt<br>
#0 0x00007ffff724fa41 in memcpy () from /lib64/libc.so.6<br>
#1 0x00007ffff6db2c0d in amqp_handle_input (state=0x7bc8a0,<br>
received_data=..., decoded_frame=0x7fffffffe2c0)<br>
at /usr/include/bits/string3.h:52<br>
#2 0x00007ffff6dbbeec in wait_frame_inner (state=0x7bc8a0,<br>
decoded_frame=0x7fffffffe2c0) at amqp_socket.c:167<br>
#3 0x00007ffff6dbc489 in amqp_simple_rpc (state=0x7bc8a0, channel=3,<br>
request_id=, expected_reply_ids=0x7fffffffe3a0,<br>
decoded_request_method=) at amqp_socket.c:283<br>
#4 0x00007ffff6db156c in amqp_basic_get (state=0x7bc8a0, channel=7,<br>
queue=..., no_ack=1) at amqp_api.c:258<br>
#5 0x00007ffff6da7432 in XS_Net__RabbitMQ_get (my_perl=,<br>
cv=) at RabbitMQ.xs:618<br>
#6 0x000000000047e115 in Perl_pp_entersub ()<br>
#7 0x0000000000455ad3 in Perl_runops_debug ()<br>
#8 0x000000000047a005 in perl_run ()<br>
#9 0x000000000042172c in main ()<br>
(gdb)<br>
<br>
#!/usr/bin/perl -w<br>
<br>
=pod<br>
<br>
=head1 sds2sds_sf_fault.t<br>
<br>
&nbsp;Test 1: publish a Dispatch JSON message with ack_level and valid_until<br>
&nbsp;- from SDS to SDS in exchange.pmc.router-in.<br>
&nbsp;Try to receive a message from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 1 expected result: a message is received from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 2: decode the message as JSON.<br>
&nbsp;Test 2 expected result: the message is decoded as JSON.<br>
&nbsp;Test 3: check that the sender field is the same as in the sent message.<br>
&nbsp;Test 3 expected result: the sender field is the same as in the sent message.<br>
&nbsp;Test 4: check the body of the received message and the sent one.<br>
&nbsp;Test 4 expected result: the body fields are the same.<br>
&nbsp;Test 5: check the timestamp field.<br>
&nbsp;Test 5 expected result: the timestamp field is the same as in the published message.<br>
&nbsp;Test 6: try to receive a message from exchange.pmc.sf-in in 8 seconds.<br>
&nbsp;Test 6 expected result: a message is received from exchange.pmc.sf-in in 8 seconds.<br>
&nbsp;Test 7: decode the message as JSON.<br>
&nbsp;Test 7 expected result: the message is decoded as JSON.<br>
&nbsp;Test 8: check that the sender field is "exchange.pmc.router-in".<br>
&nbsp;Test 8 expected result: the sender field is "exchange.pmc.router-in".<br>
&nbsp;Test 9: check the body of the received message and the sent one.<br>
&nbsp;Test 9 expected result: the body fields are the same.<br>
&nbsp;Test 10: check that the timestamp in an integer.<br>
&nbsp;Test 10 expected result: the timestamp in an integer.<br>
&nbsp;Test 11: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 11 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 12: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 12 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 13: try to receive a message from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 13 expected result: a message is received from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 14: decode the message as JSON.<br>
&nbsp;Test 14 expected result: the message is decoded as JSON.<br>
&nbsp;Test 15: check that the sender field is "exchange.pmc.sf-in".<br>
&nbsp;Test 15 expected result: the sender field is "exchange.pmc.sf-in".<br>
&nbsp;Test 16: check the body of the received message and the sent one.<br>
&nbsp;Test 16 expected result: the body fields are the same.<br>
&nbsp;Test 17: check that the timestamp in an integer.<br>
&nbsp;Test 17 expected result: the timestamp in an integer.<br>
&nbsp;Test 18: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 18 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 19: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 19 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 20: try to receive a message from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 20 expected result: a message is received from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 21: decode the message as JSON.<br>
&nbsp;Test 21 expected result: the message is decoded as JSON.<br>
&nbsp;Test 22: check that the sender field is "exchange.pmc.sf-in".<br>
&nbsp;Test 22 expected result: the sender field is "exchange.pmc.sf-in".<br>
&nbsp;Test 23: check that the timestamp in an integer.<br>
&nbsp;Test 23 expected result: the timestamp in an integer.<br>
&nbsp;Test 24: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 24 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 25: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 25 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 26: check that the id fields of the received and the published messages are the same.<br>
&nbsp;Test 26 expected result: the id fields of the received and the published messages are the same.<br>
&nbsp;Test 27: check that the ack_type field has value "processed".<br>
&nbsp;Test 27 expected result: the ack_type field has value "processed".<br>
&nbsp;Test 28: check that the from field of the received message is the same as<br>
&nbsp;the to field of the published message.<br>
&nbsp;Test 28 expected result: the from field of the received message is the same as<br>
&nbsp;the to field of the published message.<br>
&nbsp;Test 29: check that the type field has value "ack".<br>
&nbsp;Test 29 expected result: the type field has value "ack".<br>
&nbsp;Test 30: check that the version field has value 1.<br>
&nbsp;Test 30 expected result: the version field has value 1.<br>
&nbsp;Test 31: try to receive a message from exchange.pmc.cassidian-in in 8 seconds.<br>
&nbsp;Test 31 expected result: a message is received from exchange.pmc.cassidian-in in 8 seconds.<br>
&nbsp;Test 32: decode the message as JSON.<br>
&nbsp;Test 32 expected result: the message is decoded as JSON.<br>
&nbsp;Test 33: check that the sender field is "exchange.pmc.router-in".<br>
&nbsp;Test 33 expected result: the sender field is "exchange.pmc.router-in".<br>
&nbsp;Test 34: check the body of the received message and the sent one.<br>
&nbsp;Test 34 expected result: the body fields are the same.<br>
&nbsp;Test 35: check that the timestamp in an integer.<br>
&nbsp;Test 35 expected result: the timestamp in an integer.<br>
&nbsp;Test 36: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 36 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 37: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 37 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 38: try to receive a message from exchange.pmc.cassidian-in in 8 seconds.<br>
&nbsp;Test 38 expected result: a message is received from exchange.pmc.cassidian-in in 8 seconds.<br>
&nbsp;Test 39: decode the message as JSON.<br>
&nbsp;Test 39 expected result: the message is decoded as JSON.<br>
&nbsp;Test 40: check that the sender field is "exchange.pmc.router-in".<br>
&nbsp;Test 40 expected result: the sender field is "exchange.pmc.router-in".<br>
&nbsp;Test 41: check that the timestamp in an integer.<br>
&nbsp;Test 41 expected result: the timestamp in an integer.<br>
&nbsp;Test 42: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 42 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 43: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 43 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 44: check that the id fields of the received and the published messages are the same.<br>
&nbsp;Test 44 expected result: the id fields of the received and the published messages are the same.<br>
&nbsp;Test 45: check that the ack_type field has value "processed".<br>
&nbsp;Test 45 expected result: the ack_type field has value "processed".<br>
&nbsp;Test 46: check that the from field of the received message is the same as<br>
&nbsp;the to field of the published message.<br>
&nbsp;Test 46 expected result: the from field of the received message is the same as<br>
&nbsp;the to field of the published message.<br>
&nbsp;Test 47: check that the type field has value "ack".<br>
&nbsp;Test 47 expected result: the type field has value "ack".<br>
&nbsp;Test 48: check that the version field has value 1.<br>
&nbsp;Test 48 expected result: the version field has value 1.<br>
&nbsp;Test 49: publish an Ack sent message from the SSI in exchange.pmc.router-in.<br>
&nbsp;try to receive a message from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 49 expected result: a message is received from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 50: decode the message as JSON.<br>
&nbsp;Test 50 expected result: the message is decoded as JSON.<br>
&nbsp;Test 51: check that the timestamp of the received message is the same as that of published one.<br>
&nbsp;Test 51 expected result:<br>
&nbsp;the timestamp of the received message is the same as that of published one.<br>
&nbsp;Test 52: check the sender field of the received message.<br>
&nbsp;Test 52 expected result:<br>
&nbsp;the sender field of the received message has value "exchange.pmc.cassidian-in".<br>
&nbsp;Test 53: check the body fields of the received and the published messages.<br>
&nbsp;Test 53 expected result:<br>
&nbsp;the body fields of the received and the published messages are the same.<br>
&nbsp;Test 54: try to receive a message from exchange.pmc.sf-in in 8 seconds.<br>
&nbsp;Test 54 expected result: a message is received from exchange.pmc.sf-in in 8 seconds.<br>
&nbsp;Test 55: decode the message as JSON.<br>
&nbsp;Test 55 expected result: the message is decoded as JSON.<br>
&nbsp;Test 56: check the sender field of the received message.<br>
&nbsp;Test 56 expected result:<br>
&nbsp;the sender field of the received message has value "exchange.pmc.router-in".<br>
&nbsp;Test 57: check the body fields of the received and the published messages.<br>
&nbsp;Test 57 expected result:<br>
&nbsp;the body fields of the received and the published messages are the same.<br>
&nbsp;Test 58: check that the timestamp in an integer.<br>
&nbsp;Test 58 expected result: the timestamp in an integer.<br>
&nbsp;Test 59: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 59 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 60: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 60 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 61: try to receive a message from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 61 expected result: a message is received from exchange.pmc.router-in in 8 seconds.<br>
&nbsp;Test 62: decode the message as JSON.<br>
&nbsp;Test 62 expected result: the message is decoded as JSON.<br>
&nbsp;Test 63: check the sender field of the received message.<br>
&nbsp;Test 63 expected result:<br>
&nbsp;the sender field of the received message has value "exchange.pmc.sf-in".<br>
&nbsp;Test 64: check the body fields of the received and the published messages.<br>
&nbsp;Test 64 expected result:<br>
&nbsp;the body fields of the received and the published messages are the same.<br>
&nbsp;Test 65: check that the timestamp in an integer.<br>
&nbsp;Test 65 expected result: the timestamp in an integer.<br>
&nbsp;Test 66: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 66 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 67: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 67 expected result: the timestamp is less than or equal to that of now.<br>
&nbsp;Test 68: try to receive a message from exchange.pmc.cassidian-in in 8 seconds.<br>
&nbsp;Test 68 expected result: a message is received from exchange.pmc.cassidian-in in 8 seconds.<br>
&nbsp;Test 69: decode the message as JSON.<br>
&nbsp;Test 69 expected result: the message is decoded as JSON.<br>
&nbsp;Test 70: check the sender field of the received message.<br>
&nbsp;Test 70 expected result:<br>
&nbsp;the sender field of the received message has value "exchange.pmc.router-in".<br>
&nbsp;Test 71: check the body fields of the received and the published messages.<br>
&nbsp;Test 71 expected result:<br>
&nbsp;the body fields of the received and the published messages are the same.<br>
&nbsp;Test 72: check that the timestamp in an integer.<br>
&nbsp;Test 72 expected result: the timestamp in an integer.<br>
&nbsp;Test 73: check that the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 73 expected result: the timestamp is greater than or equal to that of before publishing.<br>
&nbsp;Test 74: check that the timestamp is less than or equal to that of now.<br>
&nbsp;Test 74 expected result: the timestamp is less than or equal to that of now.<br>
<br>
=cut<br>
<br>
use strict;<br>
<br>
use Net::RabbitMQ;<br>
use Test::More tests =&gt; 74;<br>
use JSON;<br>
use Time::HiRes qw(gettimeofday);<br>
<br>
use constant ROUTER_EXCHANGE &nbsp; &nbsp;=&gt; 'exchange.pmc.router-in';<br>
use constant ROUTER_CHANNEL &nbsp; &nbsp; =&gt; 1;<br>
use constant ROUTER_QUEUE &nbsp; &nbsp; &nbsp; =&gt; 'queue.test.router-in';<br>
use constant SF_EXCHANGE &nbsp; &nbsp; &nbsp; &nbsp;=&gt; 'exchange.pmc.sf-in';<br>
use constant SF_CHANNEL &nbsp; &nbsp; &nbsp; &nbsp; =&gt; 2;<br>
use constant SF_QUEUE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&gt; 'queue.test.sf-in';<br>
use constant CASSIDIAN_EXCHANGE =&gt; 'exchange.pmc.cassidian-in';<br>
use constant CASSIDIAN_CHANNEL &nbsp;=&gt; 3;<br>
use constant CASSIDIAN_QUEUE &nbsp; &nbsp;=&gt; 'queue.test.cassidian-in';<br>
<br>
sub timestamp {<br>
 &nbsp; &nbsp;return int( gettimeofday() * 1000 );<br>
}<br>
<br>
system(<br>
'service pmc-smpp stop &gt;&amp;2; service pmc-cassidian stop &gt;&amp;2; service pmc-email stop &gt;&amp;2; service pmc-sf stop &gt;&amp;2; service pmc-routing stop &gt;&amp;2'<br>
);<br>
<br>
sleep 1; &nbsp; &nbsp;# Wait for the message-sending to stop.<br>
<br>
system(<br>
 &nbsp; &nbsp;'rabbitmqctl stop_app; rabbitmqctl reset; rabbitmqctl start_app; mongo &lt;&lt;END<br>
use database<br>
db.dropDatabase();<br>
END'<br>
);<br>
<br>
system('service pmc-sf start &gt;&amp;2; service pmc-routing start &gt;&amp;2');<br>
<br>
sleep 8; &nbsp; &nbsp;# Wait for Store &amp; Forward and Routing to start.<br>
<br>
my $json_text = '{<br>
"timestamp" : 1330327514213,<br>
"sender" : "' . CASSIDIAN_EXCHANGE . '",<br>
"body" : {<br>
"type" : "dispatch",<br>
"version" : 1,<br>
"id" : "8f970b1b-f8a3-4c78-aa24-3b8e2205648788",<br>
"from" : {<br>
"type" : "ssi",<br>
"address" : "16777215"<br>
},<br>
"to" : {<br>
"type" : "ssi",<br>
"address" : "0"<br>
},<br>
"body" : "This is a test message.",<br>
"ack_level" : "sent",<br>
"valid_until" : 9223372036854775807,<br>
"auxiliary" : {<br>
"timestamp" : 1325376000000,<br>
"sdstl" : {<br>
"protocol_id" : 130,<br>
"message_reference" : 42,<br>
"short_report_allowed" : true,<br>
"protocol_data" : {<br>
"encoding" : 0,<br>
"timestamp" : {<br>
"month" : 1,<br>
"day" : 1,<br>
"hour" : 0,<br>
"minute" : 0<br>
}<br>
}<br>
}<br>
}<br>
}<br>
}';<br>
<br>
my $mq_router = Net::RabbitMQ-&gt;new();<br>
$mq_router-&gt;connect( "localhost", { user =&gt; "guest", password =&gt; "guest" } );<br>
$mq_router-&gt;channel_open(ROUTER_CHANNEL);<br>
$mq_router-&gt;queue_declare(<br>
 &nbsp; &nbsp;ROUTER_CHANNEL,<br>
 &nbsp; &nbsp;ROUTER_QUEUE,<br>
 &nbsp; &nbsp;{<br>
 &nbsp; &nbsp; &nbsp; &nbsp;passive &nbsp; &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;durable &nbsp; &nbsp; =&gt; 1,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exclusive &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;auto_delete =&gt; 0<br>
 &nbsp; &nbsp;}<br>
);<br>
$mq_router-&gt;queue_bind( ROUTER_CHANNEL, ROUTER_QUEUE, ROUTER_EXCHANGE, '' );<br>
$mq_router-&gt;purge( ROUTER_CHANNEL, ROUTER_QUEUE );<br>
$mq_router-&gt;consume( ROUTER_CHANNEL, ROUTER_QUEUE );<br>
<br>
my $mq_sf = Net::RabbitMQ-&gt;new();<br>
$mq_sf-&gt;connect( "localhost", { user =&gt; "guest", password =&gt; "guest" } );<br>
$mq_sf-&gt;channel_open(SF_CHANNEL);<br>
$mq_sf-&gt;exchange_declare(<br>
 &nbsp; &nbsp;SF_CHANNEL,<br>
 &nbsp; &nbsp;SF_EXCHANGE,<br>
 &nbsp; &nbsp;{<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exchange_type =&gt; 'direct',<br>
 &nbsp; &nbsp; &nbsp; &nbsp;passive &nbsp; &nbsp; &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;durable &nbsp; &nbsp; &nbsp; =&gt; 1,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;auto_delete &nbsp; =&gt; 0<br>
 &nbsp; &nbsp;}<br>
);<br>
$mq_sf-&gt;queue_declare(<br>
 &nbsp; &nbsp;SF_CHANNEL,<br>
 &nbsp; &nbsp;SF_QUEUE,<br>
 &nbsp; &nbsp;{<br>
 &nbsp; &nbsp; &nbsp; &nbsp;passive &nbsp; &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;durable &nbsp; &nbsp; =&gt; 1,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exclusive &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;auto_delete =&gt; 0<br>
 &nbsp; &nbsp;}<br>
);<br>
$mq_sf-&gt;queue_bind( SF_CHANNEL, SF_QUEUE, SF_EXCHANGE, '' );<br>
$mq_sf-&gt;purge( SF_CHANNEL, SF_QUEUE );<br>
$mq_sf-&gt;consume( SF_CHANNEL, SF_QUEUE );<br>
<br>
my $mq_cassidian = Net::RabbitMQ-&gt;new();<br>
$mq_cassidian-&gt;connect( "localhost", { user =&gt; "guest", password =&gt; "guest" } );<br>
$mq_cassidian-&gt;channel_open(CASSIDIAN_CHANNEL);<br>
$mq_cassidian-&gt;exchange_declare(<br>
 &nbsp; &nbsp;CASSIDIAN_CHANNEL,<br>
 &nbsp; &nbsp;CASSIDIAN_EXCHANGE,<br>
 &nbsp; &nbsp;{<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exchange_type =&gt; 'direct',<br>
 &nbsp; &nbsp; &nbsp; &nbsp;passive &nbsp; &nbsp; &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;durable &nbsp; &nbsp; &nbsp; =&gt; 1,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;auto_delete &nbsp; =&gt; 0<br>
 &nbsp; &nbsp;}<br>
);<br>
$mq_cassidian-&gt;queue_declare(<br>
 &nbsp; &nbsp;CASSIDIAN_CHANNEL,<br>
 &nbsp; &nbsp;CASSIDIAN_QUEUE,<br>
 &nbsp; &nbsp;{<br>
 &nbsp; &nbsp; &nbsp; &nbsp;passive &nbsp; &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;durable &nbsp; &nbsp; =&gt; 1,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exclusive &nbsp; =&gt; 0,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;auto_delete =&gt; 0<br>
 &nbsp; &nbsp;}<br>
);<br>
$mq_cassidian-&gt;queue_bind( CASSIDIAN_CHANNEL, CASSIDIAN_QUEUE,<br>
 &nbsp; &nbsp;CASSIDIAN_EXCHANGE, '' );<br>
$mq_cassidian-&gt;purge( CASSIDIAN_CHANNEL, CASSIDIAN_QUEUE );<br>
$mq_cassidian-&gt;consume( CASSIDIAN_CHANNEL, CASSIDIAN_QUEUE );<br>
<br>
my $before = timestamp();<br>
<br>
$mq_router-&gt;publish(<br>
 &nbsp; &nbsp;ROUTER_CHANNEL,<br>
 &nbsp; &nbsp;'',<br>
 &nbsp; &nbsp;$json_text,<br>
 &nbsp; &nbsp;{<br>
<br>
 &nbsp; &nbsp; &nbsp; &nbsp;# Options<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exchange =&gt; ROUTER_EXCHANGE<br>
 &nbsp; &nbsp;},<br>
 &nbsp; &nbsp;{<br>
<br>
 &nbsp; &nbsp; &nbsp; &nbsp;# Props<br>
 &nbsp; &nbsp; &nbsp; &nbsp;content_encoding =&gt; "UTF-8",<br>
 &nbsp; &nbsp; &nbsp; &nbsp;content_type &nbsp; &nbsp; =&gt; "application/json"<br>
 &nbsp; &nbsp;}<br>
);<br>
<br>
my $sent = decode_json($json_text);<br>
my $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_router-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received from queue' );<br>
my $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'sender'}, $sent-&gt;{'sender'}, 'sender ' . $sent-&gt;{'sender'} );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
is( $json-&gt;{'timestamp'}, $sent-&gt;{'timestamp'},<br>
 &nbsp; &nbsp;"timestamp " . $sent-&gt;{'timestamp'} );<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_sf-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'sender'}, ROUTER_EXCHANGE, 'sender ' . ROUTER_EXCHANGE );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
my $now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_router-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'A JSON message received' );<br>
is( $json-&gt;{'sender'}, SF_EXCHANGE, 'sender ' . SF_EXCHANGE );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_router-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'A JSON message received' );<br>
is( $json-&gt;{'sender'}, SF_EXCHANGE, 'sender ' . SF_EXCHANGE );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
is( $json-&gt;{'body'}-&gt;{'id'}, $sent-&gt;{'body'}-&gt;{'id'}, 'id the same' );<br>
is( $json-&gt;{'body'}-&gt;{'ack_type'}, 'processed', 'ack_type processed' );<br>
is_deeply(<br>
 &nbsp; &nbsp;$json-&gt;{'body'}-&gt;{'from'},<br>
 &nbsp; &nbsp;$sent-&gt;{'body'}-&gt;{'to'},<br>
 &nbsp; &nbsp;'from is the same as to of sent'<br>
);<br>
is( $json-&gt;{'body'}-&gt;{'type'}, &nbsp; &nbsp;'ack', 'type is ack' );<br>
is( $json-&gt;{'body'}-&gt;{'version'}, 1, &nbsp; &nbsp; 'version is 1' );<br>
<br>
my $end = time() + 8;<br>
undef $message;<br>
do {<br>
 &nbsp; &nbsp;eval {<br>
 &nbsp; &nbsp; &nbsp; &nbsp;$message = $mq_cassidian-&gt;get( CASSIDIAN_CHANNEL, CASSIDIAN_QUEUE );<br>
 &nbsp; &nbsp;};<br>
 &nbsp; &nbsp;if ($@) {<br>
 &nbsp; &nbsp; &nbsp; &nbsp;diag($@);<br>
 &nbsp; &nbsp;}<br>
} until ( defined $message or time() &gt; $end or $@ );<br>
ok( defined $message, 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'sender'}, ROUTER_EXCHANGE, 'sender ' . ROUTER_EXCHANGE );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
<br>
$end = time() + 8;<br>
note("Trying to receive an Ack from Cassidian exchange");<br>
undef $message;<br>
do {<br>
 &nbsp; &nbsp;eval {<br>
 &nbsp; &nbsp; &nbsp; &nbsp;$message = $mq_cassidian-&gt;get( CASSIDIAN_CHANNEL, CASSIDIAN_QUEUE );<br>
 &nbsp; &nbsp;};<br>
 &nbsp; &nbsp;if ($@) {<br>
 &nbsp; &nbsp; &nbsp; &nbsp;diag($@);<br>
 &nbsp; &nbsp;}<br>
} until ( defined $message or time() &gt; $end or $@ );<br>
ok( defined $message, 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'sender'}, ROUTER_EXCHANGE, 'sender ' . ROUTER_EXCHANGE );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
is( $json-&gt;{'body'}-&gt;{'id'}, $sent-&gt;{'body'}-&gt;{'id'}, 'id the same' );<br>
is( $json-&gt;{'body'}-&gt;{'ack_type'}, 'processed', 'ack_type processed' );<br>
is_deeply(<br>
 &nbsp; &nbsp;$json-&gt;{'body'}-&gt;{'from'},<br>
 &nbsp; &nbsp;$sent-&gt;{'body'}-&gt;{'to'},<br>
 &nbsp; &nbsp;'from is the same as to of sent'<br>
);<br>
is( $json-&gt;{'body'}-&gt;{'type'}, &nbsp; &nbsp;'ack', 'type is ack' );<br>
is( $json-&gt;{'body'}-&gt;{'version'}, 1, &nbsp; &nbsp; 'version is 1' );<br>
<br>
my $ack = '{<br>
"timestamp" : 1328020064358,<br>
"sender" : "' . CASSIDIAN_EXCHANGE . '",<br>
"body" : {<br>
"type" : "ack",<br>
"version" : 1,<br>
"id" : "8f970b1b-f8a3-4c78-aa24-3b8e2205648788",<br>
"from" : {<br>
"type" : "ssi",<br>
"address" : "0"<br>
},<br>
"ack_type" : "sent",<br>
"auxiliary" : {<br>
"timestamp" : 1325376000000,<br>
"original_message" : ' . encode_json( $sent-&gt;{'body'} ) . ',<br>
"sdstl" : {<br>
"protocol_id" : 130,<br>
"message_reference" : 42,<br>
"short_report_allowed" : true,<br>
"protocol_data" : {<br>
"encoding" : 0,<br>
"timestamp" : {<br>
"month" : 1,<br>
"day" : 1,<br>
"hour" : 0,<br>
"minute" : 0<br>
}<br>
}<br>
}<br>
}<br>
}<br>
}';<br>
$sent &nbsp; = decode_json($ack);<br>
$before = timestamp();<br>
<br>
$mq_router-&gt;publish(<br>
 &nbsp; &nbsp;ROUTER_CHANNEL,<br>
 &nbsp; &nbsp;'', $ack,<br>
 &nbsp; &nbsp;{<br>
<br>
 &nbsp; &nbsp; &nbsp; &nbsp;# Options<br>
 &nbsp; &nbsp; &nbsp; &nbsp;exchange =&gt; ROUTER_EXCHANGE<br>
 &nbsp; &nbsp;},<br>
 &nbsp; &nbsp;{<br>
<br>
 &nbsp; &nbsp; &nbsp; &nbsp;# Props<br>
 &nbsp; &nbsp; &nbsp; &nbsp;content_encoding =&gt; "UTF-8",<br>
 &nbsp; &nbsp; &nbsp; &nbsp;content_type &nbsp; &nbsp; =&gt; "application/json"<br>
 &nbsp; &nbsp;}<br>
);<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_router-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'timestamp'}, $sent-&gt;{'timestamp'},<br>
 &nbsp; &nbsp;'timestamp ' . $sent-&gt;{'timestamp'} )<br>
 &nbsp;or diag( $message-&gt;{'body'} );<br>
is( $json-&gt;{'sender'}, CASSIDIAN_EXCHANGE, 'sender ' . CASSIDIAN_EXCHANGE )<br>
 &nbsp;or diag( $message-&gt;{'body'} );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' )<br>
 &nbsp;or diag( $message-&gt;{'body'} );<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_sf-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'sender'}, ROUTER_EXCHANGE, 'sender ' . ROUTER_EXCHANGE );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_router-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'A JSON message received' );<br>
is( $json-&gt;{'sender'}, SF_EXCHANGE, 'sender ' . SF_EXCHANGE );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
<br>
undef $message;<br>
eval {<br>
 &nbsp; &nbsp;local $SIG{ALRM} = sub { die "Timeout\n" };<br>
 &nbsp; &nbsp;alarm 8;<br>
 &nbsp; &nbsp;$message = $mq_cassidian-&gt;recv();<br>
 &nbsp; &nbsp;alarm 0;<br>
};<br>
is( $@, '', 'A message was received' );<br>
undef $json;<br>
eval { $json = decode_json( $message-&gt;{'body'} ); };<br>
is( $@, '', 'A JSON message received' );<br>
is( $json-&gt;{'sender'}, ROUTER_EXCHANGE, 'sender ' . ROUTER_EXCHANGE );<br>
is_deeply( $json-&gt;{'body'}, $sent-&gt;{'body'}, 'body the same' );<br>
like( $json-&gt;{'timestamp'}, qr/^\d+$/, "timestamp an integer" );<br>
ok( $json-&gt;{'timestamp'} &gt;= $before,<br>
 &nbsp; &nbsp;'timestamp greater than or equal to that of before publishing' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &lt; $before");<br>
$now = timestamp();<br>
ok( $json-&gt;{'timestamp'} &lt;= $now,<br>
 &nbsp; &nbsp;'timestamp less than or equal to that of now' )<br>
 &nbsp;or diag("$json-&gt;{'timestamp'} &gt; $now");<br>
<br>
END {<br>
 &nbsp; &nbsp;$mq_sf-&gt;queue_unbind( SF_CHANNEL, SF_QUEUE, SF_EXCHANGE, '' );<br>
 &nbsp; &nbsp;$mq_router-&gt;queue_unbind( ROUTER_CHANNEL, ROUTER_QUEUE, ROUTER_EXCHANGE,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;'' );<br>
 &nbsp; &nbsp;$mq_cassidian-&gt;queue_unbind( CASSIDIAN_CHANNEL, CASSIDIAN_QUEUE,<br>
 &nbsp; &nbsp; &nbsp; &nbsp;CASSIDIAN_EXCHANGE, '' );<br>
 &nbsp; &nbsp;system(<br>
'service pmc-smpp start &gt;&amp;2; service pmc-cassidian start &gt;&amp;2; service pmc-email start &gt;&amp;2'<br>
 &nbsp; &nbsp;);<br>
}<br>
<br>
regards, Matti Linnanvuori<br>
</blockquote></div><br></div></div></div>
</blockquote></div><br><div>
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>regards, Matti Linnanvuori</div></div></span></div></span></span>
</div>
<br></body></html>