Home » Eclipse Projects » Eclipse Titan » Support for STOMP in Titan
Support for STOMP in Titan [message #1770103] |
Tue, 08 August 2017 11:24 |
|
Dear all,
STOMP is a text-oriented messaging protocol maybe not so exciting in itself ( sometimes it is quoted as being an IoT protocol, but it has not been specifically designed for over-the-wire efficiency); but besides its' own capabilities, I will use it to demonstrate Websocket subprotocols and coding/configuring a translation port.
Support for STOMP version 1.2 (as specified in https://stomp.github.io/stomp-specification-1.2.html) comes in the form of a protocol module
git://git.eclipse.org/gitroot/titan/titan.ProtocolModules.STOMP.git
As the messages are a mix of UTF-8 and unrestricted binary, a handwritten codec has been produced.
The protocol is typically being used over TCP or TLS so it should be combined with the TCP or the ( more feature rich) IPL4 test port.
As a message broker I have used a default installation of Apache Apollo 1.7.1, which "is a faster, more reliable, easier to maintain
messaging broker built from the foundations of the original ActiveMQ", but I guess any STOMP-capable message broker could be equally used.
The installation instructions for Apollo can be found in
https://activemq.apache.org/apollo/documentation/getting-started.html
After starting the message broker installed in /var/lib with
"/var/lib/mybroker/bin/apollo-broker" run
the following is displayed:
_____ .__ .__
/ _ \ ______ ____ | | | | ____
/ /_\ \\____ \ / _ \| | | | / _ \
/ | \ |_> > <_> ) |_| |_( <_> )
\____|__ / __/ \____/|____/____/\____/
\/|__| Apache Apollo (1.7.1)
Loading configuration file '/var/lib/mybroker/etc/apollo.xml'.
INFO | OS : Linux 4.4.0-83-generic (Ubuntu 16.04.2 LTS)
INFO | JVM : OpenJDK 64-Bit Server VM 1.8.0_131 (Oracle Corporation)
INFO | Apollo : 1.7.1 (at: /home/ntaf/apache-apollo-1.7.1)
INFO | OS is restricting the open file limit to: 100000
INFO | Accepting connections at: tcp://0.0.0.0:61613
INFO | Accepting connections at: tls://0.0.0.0:61614
INFO | Starting store: leveldb store at /var/lib/mybroker/data
INFO | Accepting connections at: ws://0.0.0.0:61623/
INFO | Accepting connections at: wss://0.0.0.0:61624/
INFO | virtual host startup is waiting on store startup
INFO | virtual host startup is no longer waiting. It waited a total of 1 seconds.
INFO | Administration interface available at: https://127.0.0.1:61681/
INFO | Administration interface available at: http://127.0.0.1:61680/
As indicated, TCP connections are expected on port 61613, while TLS connections on port 61614.
The TTCN-3 code used establishes a TCP/TLS connection (depending on the value of the module parameter tsp_use_ssl)
if(tsp_use_ssl) {
vl_result :=f_IPL4_connect(p, tsp_hostname, 61614,"",0, -1, {ssl := {} }, {} );
}
else {
vl_result :=f_IPL4_connect( p, tsp_hostname, 61613,"",0, -1, {tcp := {} }, {} );
}
after which it sends a CONNECT message with the default credentials (remember to change these in a production environment) ,
followed by a SEND with a text message.
module STOMP_test
{
modulepar {
charstring tsp_hostname:="127.0.0.1"
boolean tsp_use_ssl:=false
}
import from IPL4asp_Types all;
import from IPL4asp_PortType all;
import from STOMP_Types all;
//*************************************************************************
function f_STOMPMessage_len( in octetstring stream, inout ro_integer args) return integer
//*************************************************************************
{
// return f_calc_STOMP_length(stream);
return f_GetSTOMPmsgLength(stream);
}
type component GeneralComp
{
port IPL4asp_PT p;
timer t;
var IPL4asp_Types.Result c_res:= { errorCode := omit, connId := omit, os_error_code:=omit, os_error_text:= omit };
}
type component SystemComp
{
port IPL4asp_PT p;
}
//*******************************************************************************************
//Templates
template STOMPFrame t_message:=
{
command:=MESSAGE,
headers:={ {header_name:="foo", header_value:="Hello"}, {header_name:="foo", header_value:="World"}},
payload:=omit
}
template STOMPFrame t_send:=
{
command:=SEND,
headers:={ {header_name:="destination", header_value:="/queue/a"}, {header_name:="receipt", header_value:="message-12345"}/*,{header_name:="content-length", header_value:="14"}*/},
payload:=char2oct("Hello queue of Titans!!")
}
:
:
template STOMPFrame t_connect0:=
{
command:=CONNECT,
headers:={ {header_name:="accept-version", header_value:="1.2"}, {header_name:="host", header_value:="mybroker"},
{header_name:="login", header_value:="admin"},{header_name:="passcode", header_value:="password"}},
payload:=omit
}
template ASP_Send t_data(in integer p_id, in octetstring pdu ) :={
connId:=p_id,
proto:=omit,
msg:=pdu
}
testcase TC_stomp() runs on GeneralComp system SystemComp {
var ASP_RecvFrom v_ASP_RecvFrom
var STOMPFrame v_frame;
var octetstring v_pdu:=''O;
var IPL4asp_Types.Result vl_result;
var integer v_cid, v_ret;
map(self:p, system:p);
vl_result := c_res;
if(tsp_use_ssl) {
vl_result :=f_IPL4_connect(p, tsp_hostname, 61614,"",0, -1, {ssl := {} }, {} );
}
else {
vl_result :=f_IPL4_connect( p, tsp_hostname, 61613,"",0, -1, {tcp := {} }, {} );
}
log("connect result",vl_result);
if (not(ispresent(vl_result.connId)))
{
log("Could not connect");
stop;
}
v_cid:=vl_result.connId;
//register message length function of STOMP with IPL4:
//*************************************************************************
var f_IPL4_getMsgLen getMsg_Func := refers(f_STOMPMessage_len);
f_IPL4_setGetMsgLen(p,v_cid, getMsg_Func, {});
//*************************************************************************
v_ret:=f_STOMP_enc(valueof(t_connect0), v_pdu)
p.send(t_data(v_cid, v_pdu));
t.start(1.0)
alt
{
[] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom
{
v_ret:= f_STOMP_dec(v_ASP_RecvFrom.msg, v_frame);
log(v_frame);
}
[] t.timeout{log("Bye")}
}
v_ret:=f_STOMP_enc(valueof(t_send), v_pdu)
log("----------> :",v_pdu);
p.send(t_data(v_cid, v_pdu));
t.start(1.0)
alt
{
[] p.receive(ASP_RecvFrom:?) -> value v_ASP_RecvFrom
{
log("----------> :",oct2char(v_ASP_RecvFrom.msg));
v_ret:= f_STOMP_dec(v_ASP_RecvFrom.msg,v_frame);
log(v_frame);
}
[] t.timeout{log("Bye")}
}
//close TCP/TLS connection
vl_result := f_IPL4_close(p, v_cid)
log("close result",vl_result)
setverdict(pass);
}
control {
execute(TC_stomp());
}
}
After compilation and execution, the following log file is generated (with tsp_use_ssl:=true)
08:57:11.042462 - TTCN-3 Main Test Component started on esekilxxen1844. Version: CRL 113 200/6 R2A.
08:57:11.042595 - TTCN Logger v2.2 options: TimeStampFormat:=Time; LogEntityName:=No; LogEventTypes:=No; SourceInfoFormat:=Single; *.FileMask:=LOG_ALL; *.ConsoleMask:=ERROR | USER; LogFileSize:=0; LogFileNumber:=1; DiskFullAction:=Error
08:57:11.042778 - Connected to MC.
08:57:11.049736 - Executing control part of module STOMP_test.
08:57:11.049777 STOMP_test.ttcn:339 Execution of control part in module STOMP_test started.
08:57:11.049850 STOMP_test.ttcn:255 Test case TC_stomp started.
08:57:11.049885 STOMP_test.ttcn:255 Initializing variables, timers and ports of component type STOMP_test.GeneralComp inside testcase TC_stomp.
08:57:11.049999 STOMP_test.ttcn:255 Port p was started.
08:57:11.050027 STOMP_test.ttcn:255 Component type STOMP_test.GeneralComp was initialized.
08:57:11.050073 STOMP_test.ttcn:264 Mapping port mtc:p to system:p.
08:57:11.050146 STOMP_test.ttcn:264 Port p was mapped to system:p.
08:57:11.050215 STOMP_test.ttcn:264 Map operation of mtc:p to system:p finished.
08:57:11.050275 STOMP_test.ttcn:269 entering f__IPL4__PROVIDER__connect: :0 -> 127.0.0.1:61614 / SSL
08:57:11.140974 STOMP_test.ttcn:276 connect result{ errorCode := omit, connId := 1, os_error_code := omit, os_error_text := omit }
08:57:11.141235 STOMP_test.ttcn:296 Sent on p to system @IPL4asp_Types.ASP_Send : { connId := 1, proto := omit, msg := '434F4E4E4543540A6163636570742D76657273696F6E3A312E320A686F73743A6D7962726F6B65720A6C6F67696E3A61646D696E0A70617373636F64653A70617373776F72640A0A00'O }
08:57:11.141349 STOMP_test.ttcn:297 Start timer t: 1 s
08:57:11.144155 STOMP_test.ttcn:299 Message enqueued on p from system @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "127.0.0.1", remPort := 61614, locName := "127.0.0.1", locPort := 55414, proto := { ssl := { } }, userData := 0, msg := '434F4E4E45435445440A76657273696F6E3A312E320A7365727665723A6170616368652D61706F6C6C6F2F312E372E310A686F73742D69643A6D7962726F6B65720A73657373696F6E3A6D7962726F6B65722D37370A68656172742D626561743A3130302C31303030300A757365722D69643A61646D696E0A0A000A'O } id 1
08:57:11.144228 STOMP_test.ttcn:301 Receive operation on port p succeeded, message from system(): @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "127.0.0.1", remPort := 61614, locName := "127.0.0.1", locPort := 55414, proto := { ssl := { } }, userData := 0, msg := '434F4E4E45435445440A76657273696F6E3A312E320A7365727665723A6170616368652D61706F6C6C6F2F312E372E310A686F73742D69643A6D7962726F6B65720A73657373696F6E3A6D7962726F6B65722D37370A68656172742D626561743A3130302C31303030300A757365722D69643A61646D696E0A0A000A'O } id 1
08:57:11.144254 STOMP_test.ttcn:301 Message with id 1 was extracted from the queue of p.
08:57:11.144295 STOMP_test.ttcn:304 { command := CONNECTED (9), headers := { { header_name := "version", header_value := "1.2" }, { header_name := "server", header_value := "apache-apollo/1.7.1" }, { header_name := "host-id", header_value := "mybroker" }, { header_name := "session", header_value := "mybroker-77" }, { header_name := "heart-beat", header_value := "100,10000" }, { header_name := "user-id", header_value := "admin" } }, payload := omit }
08:57:11.144389 STOMP_test.ttcn:313 ----------> :'53454E440A64657374696E6174696F6E3A2F71756575652F610A726563656970743A6D6573736167652D31323334350A636F6E74656E742D6C656E6774683A32330A0A48656C6C6F207175657565206F6620546974616E73212100'O
08:57:11.144496 STOMP_test.ttcn:315 Sent on p to system @IPL4asp_Types.ASP_Send : { connId := 1, proto := omit, msg := '53454E440A64657374696E6174696F6E3A2F71756575652F610A726563656970743A6D6573736167652D31323334350A636F6E74656E742D6C656E6774683A32330A0A48656C6C6F207175657565206F6620546974616E73212100'O }
08:57:11.144572 STOMP_test.ttcn:316 Warning: Re-starting timer t, which is already active (running or expired).
08:57:11.144597 STOMP_test.ttcn:316 Start timer t: 1 s
08:57:11.146214 STOMP_test.ttcn:318 Message enqueued on p from system @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "127.0.0.1", remPort := 61614, locName := "127.0.0.1", locPort := 55414, proto := { ssl := { } }, userData := 0, msg := '524543454950540A726563656970742D69643A6D6573736167652D31323334350A0A000A'O } id 2
08:57:11.146279 STOMP_test.ttcn:320 Receive operation on port p succeeded, message from system(): @IPL4asp_Types.ASP_RecvFrom : { connId := 1, remName := "127.0.0.1", remPort := 61614, locName := "127.0.0.1", locPort := 55414, proto := { ssl := { } }, userData := 0, msg := '524543454950540A726563656970742D69643A6D6573736167652D31323334350A0A000A'O } id 2
08:57:11.146301 STOMP_test.ttcn:320 Message with id 2 was extracted from the queue of p.
08:57:11.146316 STOMP_test.ttcn:322 ----------> :"RECEIPT\nreceipt-id:message-12345\n\n" & char(0, 0, 0, 0) & "\n"
08:57:11.146378 STOMP_test.ttcn:325 { command := RECEIPT (13), headers := { { header_name := "receipt-id", header_value := "message-12345" } }, payload := omit }
08:57:11.146416 STOMP_test.ttcn:333 p: f__IPL4__close: proto { unspecified := { } } connId 1
08:57:11.146528 STOMP_test.ttcn:334 close result{ errorCode := omit, connId := 1, os_error_code := omit, os_error_text := omit }
08:57:11.146564 STOMP_test.ttcn:336 setverdict(pass): none -> pass
08:57:11.146594 STOMP_test.ttcn:336 Terminating component type STOMP_test.GeneralComp.
08:57:11.146611 STOMP_test.ttcn:336 Stop timer t: 1 s
08:57:11.146628 STOMP_test.ttcn:336 Removing unterminated mapping between port p and system:p.
08:57:11.146648 STOMP_test.ttcn:336 Port p was unmapped from system:p.
08:57:11.146674 STOMP_test.ttcn:336 Port p was stopped.
08:57:11.146690 STOMP_test.ttcn:336 Component type STOMP_test.GeneralComp was shut down inside testcase TC_stomp.
08:57:11.146705 STOMP_test.ttcn:336 Waiting for PTCs to finish.
08:57:11.146773 STOMP_test.ttcn:336 Setting final verdict of the test case.
08:57:11.146800 STOMP_test.ttcn:336 Local verdict of MTC: pass
08:57:11.146819 STOMP_test.ttcn:336 No PTCs were created.
08:57:11.146833 STOMP_test.ttcn:336 Test case TC_stomp finished. Verdict: pass
08:57:11.146851 STOMP_test.ttcn:341 Execution of control part in module STOMP_test finished.
08:57:11.153706 - Verdict statistics: 0 none (0.00 %), 1 pass (100.00 %), 0 inconc (0.00 %), 0 fail (0.00 %), 0 error (0.00 %).
08:57:11.153784 - Test execution summary: 1 test case was executed. Overall verdict: pass
08:57:11.153800 - Exit was requested from MC. Terminating MTC.
CONNECT is acknowledged with CONNECTED, and SEND with a RECEIPT.
Code is attached as usual. Next we will examine using STOMP over websocket and what it entails from TTCN-3 code perspective.
Best regards
Elemer
-
Attachment: STOMP.tgz
(Size: 306.90KB, Downloaded 120 times)
|
|
|
Goto Forum:
Current Time: Tue Apr 23 04:02:08 GMT 2024
Powered by FUDForum. Page generated in 0.03819 seconds
|