Commit 7893c078 authored by Yann Garcia's avatar Yann Garcia
Browse files

Add UML model descriptions

parent f2359e48
Loading
Loading
Loading
Loading

uml/00_overview.puml

0 → 100644
+93 −0
Original line number Diff line number Diff line
@startuml 00_overview
!include style.iuml

title Titan Test System Framework — Component Overview

package "TTCN-3 Test Suite (project-specific)" as ttcn_project {
  [Test Components / Test Cases]
}

package "ttcn/ (generic TITAN libraries)" as ttcn_libs {
  [LibHttp\n(HttpPort, HttpMessage, EncdecDeclarations)] as LibHttp
  [LibJson\n(Json value types)] as LibJson
  [LibXsd\n(XSD base types)] as LibXsd
  [LibSecurity\n(Hash, Checksums, Certificates,\nSignature, Hmac)] as LibSecurity
  [LibHelpers\n(time, base64, uuid)] as LibHelpers
}

package "ccsrc/Framework (generic core)" as core {
  [layer / t_layer<TPort>] as LayerCore
  [layer_factory\n+ layer_stack_builder] as LayerBuild
  [codec_gen<TEnc,TDec>] as CodecCore
  [codec_factory\n+ codec_stack_builder] as CodecBuild
  [params] as Params
  [registration<T>] as Registration
  [converter\n(byte/hex/base64/string utils)] as Converter
  [base_time / base_timer] as TimeUtil
}

package "ccsrc/Protocols (plug-in layers & codecs)" as protocols {
  [http_layer\n+ http_codec] as HttpImpl
  [json_codec] as JsonImpl
  [tcp_layer / tcp_offline_layer] as TcpImpl
  [udp_layer] as UdpImpl
  [sctp_layer / sctp_offline_layer] as SctpImpl
  [ethernet_layer] as EthImpl
  [ip_offline_layer] as IpImpl
  [pcap_layer / pcap_offline_layer\n/ pcap_cygwin_layer] as PcapImpl
  [linux_frame_layer] as LinuxFrameImpl
  [xml_converters] as XmlImpl
}

package "ccsrc (cross-cutting)" as crosscutting {
  [loggers\n(TTCN_Logger facade)] as Loggers
  [security\n(certs_db, sha*, hmac,\nchecksums, security_services)] as Security
  [Helpers\n(async_process, externals)] as Helpers
}

database "OS Sockets / NIC / pcap files" as OS

ttcn_project --> LibHttp : send/receive HttpMessage
ttcn_project --> LibSecurity
ttcn_project --> LibHelpers

LibHttp ..> HttpImpl : external function\n(fx_enc/dec_http_message)
LibSecurity ..> Security : external function fx_*
LibHelpers ..> Helpers : external function fx_*
LibJson --> HttpImpl : JsonBody type used by codec

HttpImpl --|> LayerCore : extends t_layer<HttpPort>
TcpImpl --|> LayerCore : extends layer
UdpImpl --|> LayerCore : extends layer
SctpImpl --|> LayerCore : extends layer
EthImpl --|> LayerCore : extends layer
IpImpl --|> LayerCore : extends layer
PcapImpl --|> LayerCore : extends layer
LinuxFrameImpl --|> LayerCore : extends layer

HttpImpl --|> CodecCore : http_codec extends codec_gen
JsonImpl --|> CodecCore : json_codec extends codec_gen

protocols ..> LayerBuild : self-register\n(static factory singleton)
protocols ..> CodecBuild : self-register\n(static factory singleton)
protocols --> Params : configuration & metadata
protocols --> Converter
protocols --> Loggers
HttpImpl --> XmlImpl : XML body support

TcpImpl --> OS : sockets
UdpImpl --> OS : sockets
EthImpl --> OS : raw frames
PcapImpl --> OS : pcap capture/replay

note bottom of protocols
  Every concrete layer/codec ships a static
  self-registering **_factory** singleton
  (e.g. tcp_layer_factory::_f) whose constructor
  calls layer_stack_builder::register_layer_factory("TCP", this)
  or codec_stack_builder::register_codec_factory("json_codec", this).
  This runs before main() (static init order),
  giving a zero-configuration plug-in mechanism.
end note

@enduml

uml/00_overview.svg

0 → 100644
+201 −0

File added.

Preview size limit exceeded, changes collapsed.

+148 −0
Original line number Diff line number Diff line
@startuml 01_framework_core
!include style.iuml

title Framework Core — Layer & Codec Abstractions (ccsrc/Framework)

package "Layer chain (Chain of Responsibility)" {

  class layer {
    - upperLayers : vector<layer*>
    - lowerLayers : vector<layer*>
    - type : std::string
    + layer()
    + layer(p_type : string)
    + ~layer()
    + add_upper_layer(p_layer : layer*)
    + remove_upper_layer(p_layer : layer*)
    + {virtual} send_data(p_data : OCTETSTRING&, p_params : params&)
    + {virtual} receive_data(p_data : OCTETSTRING&, p_params : params&)
    + {virtual} close_connection()
    + to_string() : const string&
    # send_to_all_layers(p_data : OCTETSTRING&, p_params : params&)
    # receive_to_all_layers(p_data : OCTETSTRING&, p_params : params&)
  }

  class "t_layer<TPort>" as t_layer {
    - upperPorts : list<TPort*>
    + t_layer(p_type : string)
    + add_upper_port(p_port : TPort*)
    + remove_upper_port(p_port : TPort*)
    + to_all_upper_ports<TMessage>(p_message : TMessage&, p_params : params&)
  }
  layer <|-- t_layer

  interface layer_factory {
    + {abstract} create_layer(p_type : string, p_params : string) : layer*
  }

  class layer_stack_builder {
    - {static} _instance : layer_stack_builder*
    - _layer_factories : map<string, layer_factory*>
    - layer_stack_builder()
    + {static} get_instance() : layer_stack_builder*
    + {static} register_layer_factory(p_type : string, p_factory : layer_factory*)
    - _register_layer_factory(p_type : string, p_factory : layer_factory*)
    + create_layer_stack(p_descriptor : const char*) : layer*
  }
  layer_stack_builder o-- "0..*" layer_factory : registry\n(keyed by type name)
  layer_stack_builder ..> layer : builds & links\nvia add_upper_layer()
  layer_factory ..> layer : creates
}

package "Codec chain (Strategy)" {

  class "codec_gen<TPDUEnc,TPDUDec>" as codec_gen {
    # _params : params*
    + {abstract} encode(p_message : const TPDUEnc&, p_data : OCTETSTRING&) : int
    + {abstract} decode(p_data : const OCTETSTRING&, p_message : TPDUDec&, p_params : params* = NULL) : int
  }

  interface codec_factory {
    + {abstract} create_codec() : codec_gen<Record_Type,Record_Type>*
  }

  class codec_stack_builder {
    - {static} _instance : codec_stack_builder*
    - _codecs : map<string, codec_factory*>
    + {static} get_instance() : codec_stack_builder*
    + {static} register_codec_factory(p_type : string, p_factory : codec_factory*)
    + get_codec(p_codec_name : const char*) : codec_gen<Record_Type,Record_Type>*
  }
  codec_stack_builder o-- "0..*" codec_factory : registry\n(keyed by codec name)
  codec_factory ..> codec_gen : creates
}

package "Supporting utilities" {

  class params <<std::map<string,string>>> {
    + {static} server : string
    + {static} port : string
    + {static} use_ssl : string
    + {static} method : string
    + {static} codecs : string
    + {static} serialization : string
    + add(p_other : const params&, overwrite : bool = false)
    + reset()
    + {static} convert(p_param : params&, p_parameters : string)
  }

  class "registration<TItem>" as registration {
    - _instance : registration<TItem>*
    - _items : map<string, TItem*>
    + {static} get_instance() : registration<TItem>*
    + add_item(p_name : string, p_item : TItem*)
    + get_item(p_name : string) : TItem*
  }

  class converter <<singleton>> {
    + {static} get_instance() : converter&
    + short_to_bytes() / bytes_to_short()
    + int_to_bytes() / long_to_bytes() / float_to_bytes()
    + bcd_to_bin() / bin_to_bcd()
    + string_to_hexa() / bytes_to_hexa()
    + trim() / split() / replace()
    + to_lower() / to_upper()
    + time_to_string()
  }

  class base_time <<singleton>> {
    + {static} its_base_time_ms : long = 1072915200000
    + get_current_time_ms()
    + get_its_current_time_ms()
    + get_its_current_time_us()
    + set_leap_delay_us() / get_leap_delay_us()
  }

  class base_timer {
    + start(interval, fn, arg)
    + stop()
  }
}

layer ..> params : send_data/receive_data\nmetadata bus
codec_gen ..> params : constructor / decode() context
layer_stack_builder ..> params : parses "k=v,..." per layer

note right of layer_stack_builder
  create_layer_stack() parses a textual DSL:
  "HTTP(codecs=json:json_codec)/TCP(server=h,port=443)"
  regex: (\w+)(\((.*?)\))?(\/|$)
  Builds bottom-up in construction order,
  links via add_upper_layer(), returns the
  topmost (entry) layer.
end note

note right of t_layer
  Only http_layer instantiates this template
  (as t_layer<HttpPort>) — the seam where a
  decoded, typed message crosses from the
  C++ layer chain into the TITAN port/TTCN world.
end note

note right of codec_factory
  create_codec() returns the type-erased
  codec_gen<Record_Type,Record_Type>* because
  a virtual method cannot itself be a template.
end note

@enduml
+224 −0

File added.

Preview size limit exceeded, changes collapsed.

+156 −0
Original line number Diff line number Diff line
@startuml 02_protocol_layers
!include style.iuml

title Concrete Protocol Layers (ccsrc/Protocols) — Live-Capture & Offline Stacks

class layer <<from 01_framework_core>>
class "t_layer<TPort>" as t_layer <<from 01_framework_core>>
interface layer_factory <<from 01_framework_core>>
layer <|-- t_layer

package "TITAN socket base classes (titan.core)" as titan_core {
  class PORT
  class Abstract_Socket
  class SSL_Socket
  Abstract_Socket <|-- SSL_Socket
}

package "Application framing" {
  class http_layer {
    - _codec : http_codec*
    - _device_mode : bool
    + set_codec(p_codec : http_codec*) : bool
    + sendMsg(p_msg : const HttpMessage&, p_params : params&)
    + send_data(p_data : OCTETSTRING&, p_params : params&)
    + receive_data(p_data : OCTETSTRING&, p_params : params&)
  }
  class http_layer_factory {
    - {static} _f : http_layer_factory
    + create_layer(p_type, p_params) : layer* = "new http_layer(...)"
  }
  t_layer <|-- http_layer : t_layer<HttpPort>
  layer_factory <|.. http_layer_factory
  http_layer_factory ..> http_layer : creates
  http_layer_factory --> "layer_stack_builder\nregister_layer_factory('HTTP')" : self-registers
}

package "Transport (live)" {
  class tcp_layer {
    - _params : params
    - _client_id : int
    - _reconnect_on_send : bool
    + init()
    + send_data(p_data : OCTETSTRING&, p_params : params&)
    + receive_data(p_data : OCTETSTRING&, p_params : params&)
    + message_incoming(p_buffer, p_length, p_client_id)
    + close_connection()
  }
  class tcp_layer_factory {
    - {static} _f : tcp_layer_factory
  }
  class udp_layer {
    + init()
    + send_data(p_data : OCTETSTRING&, p_params : params&)
    + receive_data(p_data : OCTETSTRING&, p_params : params&)
    + Handle_Fd_Event_Readable(fd : int)
  }
  class udp_layer_factory
  class sctp_layer
  class sctp_layer_factory

  layer <|-- tcp_layer
  SSL_Socket <|-- tcp_layer
  PORT <|-- tcp_layer
  layer_factory <|.. tcp_layer_factory
  tcp_layer_factory ..> tcp_layer : creates
  tcp_layer_factory --> "register('TCP')"

  layer <|-- udp_layer
  PORT <|-- udp_layer
  layer_factory <|.. udp_layer_factory
  udp_layer_factory ..> udp_layer : creates
  udp_layer_factory --> "register('UDP')"

  layer <|-- sctp_layer
  SSL_Socket <|-- sctp_layer
  PORT <|-- sctp_layer
  layer_factory <|.. sctp_layer_factory
  sctp_layer_factory ..> sctp_layer : creates
  sctp_layer_factory --> "register('SCTP')"
}

package "Transport / link (offline replay, .pcap)" {
  class tcp_offline_layer
  class tcp_offline_layer_factory
  class sctp_offline_layer
  class sctp_offline_layer_factory
  class ip_offline_layer
  class ip_offline_layer_factory
  class ethernet_layer
  class ethernet_layer_factory
  class linux_frame_layer
  class linux_frame_layer_factory
  class pcap_layer
  class pcap_linux_layer
  class pcap_cygwin_layer
  class pcap_offline_layer
  class pcap_layer_factory
  class pcap_offline_layer_factory

  layer <|-- tcp_offline_layer
  layer_factory <|.. tcp_offline_layer_factory
  tcp_offline_layer_factory --> "register('TCP_OFFLINE')"

  layer <|-- sctp_offline_layer
  layer_factory <|.. sctp_offline_layer_factory
  sctp_offline_layer_factory --> "register('SCTP_FILE')"

  layer <|-- ip_offline_layer
  layer_factory <|.. ip_offline_layer_factory
  ip_offline_layer_factory --> "register('IP_OFFLINE')"

  layer <|-- ethernet_layer
  layer_factory <|.. ethernet_layer_factory
  ethernet_layer_factory --> "register('ETH')"

  layer <|-- linux_frame_layer
  layer_factory <|.. linux_frame_layer_factory
  linux_frame_layer_factory --> "register('LINUX_FRAME')"

  layer <|-- pcap_layer
  PORT <|-- pcap_layer
  pcap_layer <|-- pcap_linux_layer
  pcap_layer <|-- pcap_cygwin_layer
  layer_factory <|.. pcap_layer_factory
  pcap_layer_factory --> "register('PCAP')"

  layer <|-- pcap_offline_layer
  layer_factory <|.. pcap_offline_layer_factory
  pcap_offline_layer_factory --> "register('PCAP_FILE')"
}

note bottom of "Transport (live)"
  Live sockets multiply-inherit **layer** (framework chain)
  AND TITAN's **PORT/SSL_Socket/Abstract_Socket** so the
  fd-event loop can drive receive_data() directly from
  OS socket callbacks (message_incoming / Handle_Fd_Event_Readable).
end note

note bottom of "Transport / link (offline replay, .pcap)"
  Offline/pure-framing layers only extend **layer**
  (no live socket) — used for .pcap capture/replay
  stacks, e.g. HTTP(...)/TCP_OFFLINE(...)/IP_OFFLINE(...)
  /ETH(...)/PCAP_FILE(...).
end note

note as N1
  Every *_layer_factory has an identical shape:
    static <T>_layer_factory _f;
    <T>_layer_factory() {
      layer_stack_builder::register_layer_factory("<KEY>", this);
    }
    layer* create_layer(type, params) { return new <T>_layer(type, params); }
  Registered at static-init time, before main().
end note

@enduml
Loading