Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » Dual-faced test ports: architectural considerations(Why and how to use dual-faced test ports)
Dual-faced test ports: architectural considerations [message #1736527] Thu, 30 June 2016 08:26 Go to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 807
Registered: January 2015
Senior Member
Greetings.


Typically TTCN-3 code focuses on the behaviour of a protocol layer; this layer will be connected
to the uppermost layer of a communication stack using some glue code named a system adapter(or test port- basically the same thing).
This stack is an IP stack in most of the cases, but it could be an SS7 stack, a serial port, you name it.
Frequently the term "transport" is being used to denote the communication stack in this role; so we have protocols
that connect to and use UDP, or TCP or HTTP as transport.


        +------------------------------------------+
        |                                          |
        |                                          |
        |             Protocol behaviour           |
        |                                          |
        +-------------------+----------------------+
                            | 
        +-------------------v----------------------+
        |                                          |
        |            System adapter/test port      |
        |                                          |
        |                                          |
        +------------------------------------------+
                            | 
        +-------------------v----------------------+
        |                                          |
        |                 Stack                    |
        |                                          |
        |                                          |
        +------------------------------------------+

This article is about reusing the code of the test ports/system adapters.
Let's assume that we have already implemented a test port for a certain transport, say HTTP,
and we have two protocols, A, and B, that use HTTP as transport.

Protocol A is JSON encoded, while B is XML encoded.
The HTTP test port (published on github among Titan-related products, see https://github.com/eclipse/titan.TestPorts.HTTPmsg)
is a generic, protocol-independent port that accepts HTTP requests and responses, plus some control messages (Connect, Close etc.)
Protocol messages of A and B will be encoded and transported in HTTP bodies.



protocol A MsgA1, MsgA2, MsgA3 (JSON encoded)
protocol B MsgB1, MsgB2, MsgB3 (XML encoded)




  
                       +--------------------------------+
                       |                                |
                       |                                |
                       |        Protocol  A (JSON)      |
                       |                                |
        +-----------------------------------------------+
        |              |                                |
        |              |                                |
HTTP    |   Headers    |         Body                   |
        |              |                                |
        +--------------+--------------------------------+







                        +--------------------------------+
                        |                                |
                        |                                |
                        |       Protocol  B (XML)        |
                        |                                |
         +-----------------------------------------------+
         |              |                                |
         |              |                                |
 HTTP    |   Headers    |         Body                   |
         |              |                                |
         +--------------+-------------------------------->
  




The upmost protocol layers describing protocol behaviour will have a test port carrying protocol messages, something like:

 
 type port ProtA_PT message  
{
 inout MsgA1, MsgA2, MsgA3  
}
 
type port ProtB_PT message  
{
 inout MsgB1, MsgB2, MsgB3  
}



OK, so what options we have, short of writing a new test port from scratch, to connect Protocol A to HTTP?


1) Option zero - protocol-specific test ports

We can re-use the code of the HTTP test port (written in C++ for Titan) to create a protocol-specific test port:
add default headers characteristic to A (e.g. Content-Type "application/json"), invoke the appropriate JSON codecs when assembling the HTTP request
or dissecting the HTTP response etc. This is a rather simple exercise; we will have of course to modify the HTTP test port interface accordingly:


type port HTTP_ProtA_PT message  
{
 inout MsgA1, MsgA2, MsgA3  
}
 


but we can achieve a quick result, we have re-used most of the HTTP test port code so ....yay!!!!

OK, now we will have to do something similar for protocol B: add deafult headers(Content-Type "application/xml") , invoke XML codecs etc.
and pretty soon we have a new test port:


type port HTTP_ProtB_PT message  
{
 inout MsgB1, MsgB2, MsgB3  
}  


So now we have three test ports in total: the generic HTTP , the one for protocol A, and the one for protocol B.
And maybe this is the moment when we get a little uncomfortable: what if some new similar protocols will appear?
We will have to have a new test port for each; if any change or correction is needed, this will have to be done across a quickly proliferating set of test ports.
Things can get quickly out of hand and we may decide that having protocol specific test ports, even it's an easy alternative,
it may prove to be difficult to manage and too costly in the long reach.


All right, so what's next???


2) Option one - mapping layer


We can implement mapping between the upper layer protocols and the test port in a separate layer, conveniently
and unsurprisingly named "mapping layer". Basically whatever has been done in C++ (or lower level code in general)
in the test port will have to be done in TTCN-3: assembling /disassembling messages, invoking codecs etc.

type component Mapping_CT
{

  var boolean v_run;
  
  
  port  ProtA_PT 	ProtA_PCO;
  port  HTTPmsg_PT  HTTP_A_PCO;
  
}

type component System_CT  
{
  port  HTTPmsg_PT  HTTP_A_PCO; 
}


        +------------------------------------------+
        |                                          |
        |                                          |
        |             Protocol A                   |
        |                                          |
        +-------------------+----------------------+
                            | ProtA_PT
        +-------------------v----------------------+
        |                                          |
        |            Mapping component             |
        |                                          |
        |                                          |
        +-------------------+----------------------+
                            |
                            |
                            v   HTTP_PT
        +-------------------+----------------------+
        |                                          |
        |                System                    |
        |                                          |
        |                                          |
        +------------------------------------------+







The mapping component will run a loop function, something like:
		
//************************************************************************* 
function f_ScanPorts  runs on Mapping_CT
//*************************************************************************

{//startfunction ScanPorts



  v_run := true;
 

  while (v_run)
  {//startwhile
    alt
    {//startalt

      //************************************************************************* 
      // Messages  received  on the upper (protocol)  port
      //*************************************************************************

      [] ProtA_PCO.receive(MsgA1:?) -> value vl_msgA1

        {//startStatementBlock
		
         //JSON-encode vl_msgA1 and make it the body of an HTTP message     
         //assemble HTTP headers
		 //open HTTP 
		 //send HTTP request
		 //close HTTP

        }//endStatementBlock
		
		:
		:

      //************************************************************************* 
      // Messages  received from the HTTP port
      //*************************************************************************


      []HTTP_PCO.receive(HTTPResponse: ?) -> value vl_HTTPResponse;
      {//startStatementBlock
       
	   
	   //extract body from HTTP response
	   //JSON-decode it into protocol message
	   //send message on the upper port 

   

      }//endStatementBlock

:
:


    }//endalt

  }//endwhile

}//endfunction  ScanPorts



v_run can be set to false for instance at the reception of an appropriate message on an internal control port,
permitting a controlled termination of the mapping component.




All right, this seems a bit better: in the end we have only one test port (so one separate product to maintain), at the expense of some extra TTCN-3 code and a separate mapping layer.
This separate layer could be a good option when we need to implement some complex stateful behaviour but in general this should not be necessary.
Also, one may object that we simply moved the problem out of the test port and into the TTCN-3 code of the mapping layer.
Still not an ideal situation .......

OK, anything else?

3)Option two- dual-faced test port


Dual faced test ports implement the above idea in a more elegant and transparent manner, without the need for a separate component.


This is the original definition of the HTTP test port:

  type port HTTPmsg_PT message
  {
    // Connection handling ASPs
    inout   Close;
    out     Connect;
    in      Connect_result;
    in      Client_connected;
    inout   Half_close;
    out     Listen;
    in      Listen_result;
    inout   Shutdown;

    // Message to send and receive
    inout   HTTPMessage;
  }with { extension "provider" };



This can be extended with declarations that describe the mapping between the northern face( accepting protocol A, B, etc. messages)
and the southern face( the HTTP port itself)


type port ProtA_PT message  //DualFace port
{
inout MsgA1, MsgA2, MsgA3          
}with 
{ extension 
   "user HTTPmsg_PT
      out(
        MsgA1 -> HTTPMessage: function(f_assemble_Request_from_MsgA1);
        MsgA2 -> HTTPMessage: function(f_assemble_Request_from_MsgA2);
        MsgA3 -> HTTPMessage: function(f_assemble_Request_from_MsgA3)
    )    
      in(
        HTTPMessage ->  MsgA1 : function(f_dec_Response_to_MsgA1),
	                    MsgA2 : function(f_dec_Response_to_MsgA2),
	                    MsgA3 : function(f_dec_Response_to_MsgA3);
	    Close       ->   -    : .....           
    )
   " 
   
}



The mapping functions will have to be implemented manually and will do all steps of the mapping: encoding/decoding, message assembling/disassembling etc.)

function f_assemble_Request_from_MsgA1 runs on ProtocolA_CT
{

var HTTPRequest v_HTTPRequest
var HTTPMessage v_HTTPMessage

//MsgA received 
//send Connect 
//if Connect_result is OK
//v_HTTPRequest.client_id optional,
//v_HTTPRequest.method:= "GET";
//v_HTTPRequest.uri:=....;
//v_HTTPRequest.version_major:=1;
//v_HTTPRequest.version_minor:=0;
//v_HTTPRequest.header:=
//v_HTTPRequest.body =f_encode(v_msgA1)  //JSON encoding of msgA1
//v_HTTPMessage.request:=v_HTTPRequest;
//port.send(v_HTTPMessage) 
//send Close
}




The end result: only one test port, no additional layer or component, and a minimal number of extra lines of easily readable TTCN-3 code.

So far, this seems to be the winning option. Viewed from a product perspective,
all transport issues can be solved with a small number of test ports (UDP, TCP, SCTP, HTTP and so on..), one for each transport stack.

In fact, instead of HTTP, I could also have used UDP or TCP as an example.

Several dual-faced test port examples have been published in this forum:

Dual-faced IPL4 test port in UDP mode
Example of ping (ICMP) over a layer 2 test port with Titan
Example of SNMP over UDP


and the reference guide supplies further details.

The standard describes these ports as "ports with translation capability" in

TTCN-3 Language Extensions:
Configuration and Deployment Support
5.2 Ports with translation capability


Besides the above example, the dual-faced test ports can be used in all kinds of protocol translations, such as translating between two different versions of the same protocol,
but also translating between say SIP and ISUP, as a protocol gateway, connecting the IP and SS7 realm.



Best regards

Elemer

[Updated on: Thu, 30 June 2016 14:16]

Report message to a moderator

Re: Dual-faced test ports: architectural considerations [message #1739108 is a reply to message #1736527] Wed, 27 July 2016 14:41 Go to previous messageGo to next message
Gustavo Gonnet is currently offline Gustavo GonnetFriend
Messages: 34
Registered: October 2015
Location: Montreal, Quebec, Canada
Member
great article! it helped me understand better what a dual-faced test port is, I had so many questions in my head all this years, now answered by your article.
Gustavo.
Re: Dual-faced test ports: architectural considerations [message #1739123 is a reply to message #1739108] Wed, 27 July 2016 15:42 Go to previous message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 807
Registered: January 2015
Senior Member
Thank you, Gustavo.
Previous Topic:Titan compiler crashing while compilation
Next Topic:The unfinished business of multiple encodings
Goto Forum:
  


Current Time: Wed Sep 19 02:49:15 GMT 2018

Powered by FUDForum. Page generated in 0.01721 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top