CI: Add silent cmake SonarCloud scan
[ric-plt/lib/rmr.git] / docs / rt_tables.rst
1 .. This work is licensed under a Creative Commons Attribution 4.0 International License.
2 .. SPDX-License-Identifier: CC-BY-4.0
3 .. CAUTION: this document is generated from source in doc/src/rtd.
4 .. To make changes edit the source and recompile the document.
5 .. Do NOT make changes directly to .rst or .md files.
6
7 ============================================================================================
8 Route Table Guide
9 ============================================================================================
10 --------------------------------------------------------------------------------------------
11 RIC Message Router -- RMR
12 --------------------------------------------------------------------------------------------
13
14
15 Overview
16 ========
17
18 Messages sent via the RIC Message Router (RMR) are routed to
19 an endpoint (another application) based on a combination of
20 the *message type* (MT) and *subscription ID* (SID) supplied
21 in the message. RMR determines the endpoint by matching the
22 MT and SID combination to an entry in a route table which has
23 been supplied dynamically by a *Route Manager* service, or as
24 a static table loaded during RMR initialisation. It is also
25 possible to route messages directly to an endpoint which is
26 the *managed entity* "owner," using the *managed entity ID*
27 (MEID).
28
29 For most xAPP developers the format of the RMR route table is
30 not important beyond understanding how to create a static
31 table for local testing. For developers of a *Route Manager*
32 service, the need is certainly a requirement. This document
33 describes the overall syntax of a route table and the
34 interface between the *Route Manager* service and RMR.
35
36
37 Contents of a Route Table
38 =========================
39
40 The table consists of a start record, one or more entry
41 records, and an end record. Each entry record defines one
42 message type, with an optional sender application, and the
43 endpoint(s) which accept the indicated message type. All
44 table records contain fields separated with vertical bars
45 (|), and allow for trailing comments with the standard shell
46 comment symbol (hash, #) provided that the start of the
47 comment is separated from the last token on the record by one
48 or more spaces. Leading and trailing white space in each
49 field is ignored. Figure 1 illustrates a very basic route
50 table with two message types, 1000 and 2000, and two
51 subscription IDs for message type 1000.
52
53
54 ::
55
56     newrt | start | rt-0928
57     rte   | 2000  | logger:30311
58     mse   | 1000  | 10 | forwarder:43086
59     mse   | 1000  | 21 | app0:43086,app1:43086
60     newrt | end   | 3
61
62 Figure 1: A basic route table.
63
64
65 Entry record syntax
66 -------------------
67
68 Two types of table entries are supported for compatibility
69 with the original RMR implementation, but only the *mse*
70 entry type is needed and that should be the entry used when
71 creating new tables. The following shows the syntax for both
72 entry types:
73
74
75 ::
76
77    rte | <msg-type>[,<sender-endpoint>] | <endpoint-group>[;<endpoint-group>;...]
78    mse | <msg-type>[,<sender-endpoint>] | <sub-id> | <endpoint-group>[;<endpoint-group>;...]
79
80
81 Where:
82
83
84     .. list-table::
85       :widths: 25,70
86       :header-rows: 0
87       :class: borderless
88
89       * - **mse, rte**
90         -
91           is the table entry type
92
93       * - **<msg-type>**
94         -
95           is the integer message type
96
97       * - **<sender-endpoint>**
98         -
99           is the endpoint description of the message sender; only that
100           sender will read the entry from the table, so a single table
101           may be used for all senders when a common message type is
102           delivered to varying endpoints based on senders. If the
103           sender endpoint is omitted from the entry, then the entry
104           will be used by all applications.
105
106       * - **<sub-id>**
107         -
108           is the subscription id (integer) for subscription-based
109           messages, or -1 if the message type is not
110           subscription-based. An *mse* entry with a sub-id of -1 is the
111           **same** as an *rte* entry with the same message type.
112
113       * - **<endpoint-group>**
114         -
115           is one or more, comma separated, endpoint descriptions.
116
117
118
119 When an application sends a message with the indicated type,
120 the message will be sent to one endpoint in the group in a
121 round-robin ordering. If multiple endpoint groups are given,
122 then the message is sent to a member selected from each
123 group; 3 groups, then three messages will be sent. The first
124 group is required.
125
126
127 Line separation
128 ---------------
129
130 Table entries **must** end with a record termination sequence
131 which may be one of the following three sequences:
132
133
134 * a single newline (\\n)
135 * a DOS style CRLF pair (\\r\\n)
136 * a single carriage return (\\r)
137
138
139 Care must be taken when manually editing a static table; some
140 editors do **not** add a final record termination sequence to
141 the last line of a file. RMR expects the final record to have
142 a termination sequence to ensure that the record was not
143 truncated (especially important when receiving dynamic
144 tables).
145
146
147 Table framing
148 -------------
149
150 The route table parser within RMR assumes that route table
151 entries are sent via RMR messages as a stream. To ensure
152 synchronisation and prevent malformed tables because of
153 broken sessions or lost packets, each table must begin and
154 end with an *newrt* record. Each *newrt* record has one of
155 two possible syntax layouts as described below.
156
157
158 ::
159
160     newrt | begin [| table-id-string]
161     newrt | end  [| record-count]
162
163 Figure 2: Illustration of the newrt records in the table.
164
165 The *table-id-string* is an optional string which is used by
166 RMR when sending an acknowledgement back to the *Route
167 Manager* service (see the *Route Manager Interface* section
168 for more details). If a *record-count* is given as the final
169 field on the *end* record, RMR will verify that the number of
170 *mse* and *rte* entries in the table matches the count; if
171 there is a mismatch in values the table is not used.
172
173
174 Comments, spaces, and blank lines
175 ---------------------------------
176
177 Comments may be placed to the right of any table entry line
178 using the standard shell comment symbol (#). The start of a
179 comment must be separated from any previous record content by
180 at least one space or tab. Complete lines are treated as
181 comments when the first non-whitespace character of a line is
182 a comment symbol. Blank lines are also ignored.
183
184 Fields on table records are separated using the vertical bar
185 (|) character. Any white space (tabs or spaces) which appear
186 immediately before or after a separator are ignored.
187
188
189 Endpoint Description
190 --------------------
191
192 The endpoint description is either the hostname or IP address
193 followed by a port number; the two are separated by a single
194 colon. The illustration below assumes that host names (e.g.
195 forwarder and app1) are defined; they also make the tables
196 easier to read. The port number given is the port number that
197 the user application provides to RMR when the RMR
198 initialisation function is invoked (and thus is the port that
199 RMR is listening on).
200
201
202 Table Mechanics
203 ===============
204
205 Creating a table from the two entry types is fairly simple,
206 however there are some subtleties which should be pointed out
207 to avoid unexpected behaviour. For this discussion the
208 following complete table will be used.
209
210 .. list-table::
211   :widths: 75,10
212   :header-rows: 0
213   :class: borderless
214
215
216   * -
217
218         ::
219
220             newrt | start | rt-0928
221             rte | 2000 | logger:30311
222             mse | 1000 | 10 | forwarder:43086
223             mse | 1000,forwarder:43086 | 10 | app2:43086
224             mse | 1000 | -1 | app0:43086,app1:43086; logger:20311
225             newrt | end | 4
226
227     -
228
229         ::
230
231           (1)
232           (2)
233           (3)
234           (4)
235           (5)
236           (6)
237
238
239 Figure 3: A complete RMR routing table (line numbers to the
240 right for reference).
241
242
243 Table Entry Ordering
244 --------------------
245
246 Whether a table is read from a file on disk, or is received
247 from a *Route Manager* service, RMR parses the records to
248 build an internal route table keeping only the relevant
249 information. Entries are read in the order they appear (from
250 the file or in messages received), and RMR will use only one
251 entry for each MT/SID pair.
252
253 For most tables, the ordering of entries is not important,
254 but when there are entries which duplicate the MT/SID pair
255 ordering becomes significant. RMR will use the **last** valid
256 entry for a MT/SID pair that it encounters. An entry is
257 considered valid if there is no sender identified with the
258 message type (line 3), and when the sender (host and port)
259 match the the applications' location and the port provided to
260 RMR for listening.
261
262 Using the table in figure 3 as an example, there are two
263 entries which match the MT/SID pair of 1000/10. When this
264 table is parsed on any host, RMR will recognise and add the
265 first entry (line 3) to the internal representation; this
266 entry is valid for all applications. The second 1000/10 entry
267 (line 4) is valid when the table is parsed on the *forwarder*
268 host, and only by the application which is listening on port
269 43086. For this application the entry will override the more
270 generic entry for the MT/SID combination.
271
272 As a rule, the ordering of entries for a given MT/SID pair
273 should be from most generic to most specific.
274
275
276 Route Manager Communications
277 ============================
278
279 During initialisation RMR will use the value of the
280 ``RMR_RTG_SVC`` environment variable to connect to the *Route
281 Manager* service in order to request a route table. The
282 connection between RMR and the *Route Manager* is also an RMR
283 session and thus RMR messages will be used to exchange
284 requests and responses.
285
286
287 Table Request
288 -------------
289
290 During initialisation, RMR establishes a wormhole connection
291 to the *Route Manager* and sends a message type of 21 to
292 request a new table. RMR will continue to send table requests
293 until a table is received and accepted; in other words it is
294 fine for the *Route Manager* to ignore the requests if it is
295 not ready to respond.
296
297
298 Sending Tables To RMR
299 ---------------------
300
301 Table entry data is expected to arrive via RMR message with a
302 message type of 20. The message may contain one or more
303 entries provided that the entries are newline separated.
304 Current versions of RMR support very large messages, however
305 to ensure compatibility with an xAPP built using an older
306 version of RMR (pre 3.8), messages should be limited to 4
307 KiB.
308
309
310 Table Acceptance and Acknowledgement
311 ------------------------------------
312
313 When RMR receives the table end entry (newrt|end), it will
314 send a state message back to the *Route Manager* to indicate
315 the state of the received table. The message type is 22 and
316 the payload will contain UTF-8 tokens which indicate the
317 state. The second token will be the *table ID* supplied on
318 the start record, or the string "<id-missing>." When the
319 state is an error state, RMR might add a final set of tokens
320 which contain the reason for the failure.
321
322 Upon receipt of a status message which indicates an "OK"
323 response, the *Route Manager* can assume that the table has
324 been installed and is in use. Any other response indicates
325 that RMR did not use the table and has dropped it; the
326 previous table is still in use.
327
328
329 Using A Static Route Table
330 --------------------------
331
332 A static route table can be provided to assist with testing,
333 or to provide a bootstrap set of route information until a
334 dynamic table is received from a routing manager. The
335 environment variable ``RMR_SEED_RT`` is checked during RMR
336 initialisation and if set is expected to reference a file
337 containing a route table. This table will be loaded and used
338 until overlaid by a table sent by the *Route Manager*.
339
340 To simulate dynamic reloads during testing, and for some
341 specialised use cases, the static table will be reloaded
342 periodically if the ``RMR_RTG_SVC`` environment variable is
343 set to -1. When set to -1 RMR will not listen for *Route
344 Manager* connections, nor will it attempt to request a
345 dynamic table.
346
347 If the file given by the ``RMR_SEED_RT`` variable does not
348 exist, and the ``RMR_RTG_SVC`` variable is set to -1, RMR
349 will block until the table is created. This simulates a
350 delayed dynamic load during testing, and can be used when the
351 xAPP is reading the route table saved by another local
352 process rather than one sent directly by the *Route Manager*.
353
354
355 Table Stashing
356 --------------
357
358 To assist with debugging, and to allow an application to
359 share the route table received from *Route Manager*, RMR will
360 stash the route table updates it received. Updates are
361 stashed in a file named by the ``RMR_STASH_RT`` environment
362 variable, and if that variable is not present, the
363 ``RR_SEED_RT`` variable will be used with an added
364 ``.stash`` extension.
365
366 The primary use of route table stashing is to assist with
367 debugging of applications, and because there are risks for an
368 application to share its table, table sharing is **NOT**
369 recommended. Table sharing can be enabled by setting the
370 ``RMR_STASH_RT`` variable for the application that will be
371 the source of the route table updates, and using the file
372 named for tha application when defining the
373 ``RMR_SEED_RT`` variable for applications which are to read
374 the table information. Obviously, all applications must be
375 running in the same container, on the same host, or have a
376 common disk volum between their environments. Known risks to
377 using table sharing include
378
379
380 * An update to the table (not a complete table) may be
381   received prior to one or more readers accessing the file,
382   and thus the reader may not receive a valid or complete
383   table.
384
385 * Any entry which has a sender:port associated with the
386   message type will likely be ignored by all readers.
387
388
389
390 Routing Using MEID
391 ==================
392
393 Starting with version 1.13.0, RMR provides the ability to
394 select the endpoint for a message based on the MEID (managed
395 entity ID) in the message, rather than selecting the endpoint
396 from the round-robin list for the matching route table entry.
397 When the MEID is used, the message is sent to the endpoint
398 which *owns,* or is responsible for the managed entity.
399 Should the *owner* change messages will be routed to the new
400 owner when the route table is updated. To make use of MEID
401 routing, there must be one or more route table entries which
402 list the special endpoint name ``%meid`` instead of providing
403 a round robin list. As an example, consider the following
404 route table entry:
405
406
407 ::
408
409     mse| 1000,forwarder:43086 | 10 | %meid
410
411 Figure 4: Sample route entry with the meid flag.
412
413 The final field of the entry doesn't specify a round-robin
414 group which means that when an application attempts to send a
415 message with type 1000, and the subscription ID of 10, the
416 MEID in the message will be used to select the endpoint.
417
418
419 MEID endpoint selection
420 -----------------------
421
422 To select an endpoint for the message based on the MEID in a
423 message, RMR must know which endpoint owns the MEID. This
424 information, known as an MEID map, is provided by the *Route
425 Manager* over the same communication path as the route table
426 is supplied. The following is the syntax for an MEID map.
427
428
429 ::
430
431     meid_map | start | <table-id>
432     mme_ar | <owner-endpoint> | <meid> [<meid>...]
433     mme_del | <meid> [<meid>...]
434     meid_map | end | <count> [| <md5sum> ]
435
436 Figure 5: Meid map table.
437
438 The mme_ar records are add/update records and allow for the
439 list of MEIDs to be associated with (owned by) the indicated
440 endpoint. The <owner-endpoint> is the hostname:port, or IP
441 address and port, of the application which owns the MEID and
442 thus should receive any messages which are routed based on a
443 route table entry with %meid as the round-robin group. The
444 mme_del records allow for MEIDs to be deleted from RMR's
445 view. Finally, the <count> is the number of add/replace and
446 delete records which were sent; if RMR does not match the
447 <count> value to the number of records, then it will not add
448 the data to the table. Updates only need to list the
449 ownership changes that are necessary; in other words, the
450 *Route Manager* does not need to supply all of the MEID
451 relationships with each update.
452
453 The optional <md5sum> field on the end record should be the
454 MD5 hash of all of the records between the start and end
455 records. This allows for a precise verification that the
456 transmitted data was correctly received.
457
458 If a static seed file is being used for the route table, a
459 second section can be given which supplies the MEID map. The
460 following is a small example of a seed file:
461
462
463 ::
464
465    newrt|start | id-64306
466    mse|0|-1| %meid
467    mse|1|-1|172.19.0.2:4560
468    mse|2|-1|172.19.0.2:4560
469    mse|3|-1|172.19.0.2:4560
470    mse|4|-1|172.19.0.2:4560
471    mse|5|-1|172.19.0.2:4560
472    newrt|end
473
474    meid_map | start | id-028919
475    mme_ar| 172.19.0.2:4560 | meid000 meid001 meid002 meid003 meid004 meid005
476    mme_ar| 172.19.0.42:4560 | meid100 meid101 meid102 meid103
477    mme_del | meid1000
478    meid_map | end | 1
479
480 Figure 6: Illustration of both a route table and meid map in
481 the same file.
482
483 The tables above will route all messages with a message type
484 of 0 based on the MEID. There are 10 meids which are owned by
485 two different endpoints. The table also deletes the MEID
486 meid1000 from RMR's view.
487
488
489 Reserved Message Types
490 ======================
491
492 RMR is currently reserving message types in the range of 0
493 through 99 (inclusive) for its own use. Please do not use
494 these types in any production or test environment as the
495 results may be undesired.
496
497
498
499 Appendix A -- Glossary
500 ======================
501
502 Many terms in networking can be interpreted with multiple
503 meanings, and several terms used in various RMR documentation
504 are RMR specific. The following definitions are the meanings
505 of terms used within RMR documentation and should help the
506 reader to understand the intent of meaning.
507
508     .. list-table::
509       :widths: 25,70
510       :header-rows: 0
511       :class: borderless
512
513       * - **application**
514         -
515           A programme which uses RMR to send and/or receive messages
516           to/from another RMR based application.
517
518       * - **Critical error**
519         -
520           An error that RMR has encountered which will prevent further
521           successful processing by RMR. Critical errors usually
522           indicate that the application should abort.
523
524       * - **Endpoint**
525         -
526           An RMR based application that is defined as being capable of
527           receiving one or more types of messages (as defined by a
528           *routing key.*)
529
530       * - **Environment variable**
531         -
532           A key/value pair which is set externally to the application,
533           but which is available to the application (and referenced
534           libraries) through the ``getenv`` system call. Environment
535           variables are the main method of communicating information
536           such as port numbers to RMR.
537
538       * - **Error**
539         -
540           An abnormal condition that RMR has encountered, but will not
541           affect the overall processing by RMR, but may impact certain
542           aspects such as the ability to communicate with a specific
543           endpoint. Errors generally indicate that something, usually
544           external to RMR, must be addressed.
545
546       * - **Host name**
547         -
548           The name of the host as returned by the ``gethostbyname``
549           system call. In a containerised environment this might be the
550           container or service name depending on how the container is
551           started. From RMR's point of view, a host name can be used to
552           resolve an *endpoint* definition in a *route* table.)
553
554       * - **IP**
555         -
556           Internet protocol. A low level transmission protocol which
557           governs the transmission of datagrams across network
558           boundaries.
559
560       * - **Listen socket**
561         -
562           A *TCP* socket used to await incoming connection requests.
563           Listen sockets are defined by an interface and port number
564           combination where the port number is unique for the
565           interface.
566
567       * - **Message**
568         -
569           A series of bytes transmitted from the application to another
570           RMR based application. A message is comprised of RMR specific
571           data (a header), and application data (a payload).
572
573       * - **Message buffer**
574         -
575           A data structure used to describe a message which is to be
576           sent or has been received. The message buffer includes the
577           payload length, message type, message source, and other
578           information.
579
580       * - **Message type**
581         -
582           A signed integer (0-32000) which identifies the type of
583           message being transmitted, and is one of the two components
584           of a *routing key.* See *Subscription ID.*
585
586       * - **Payload**
587         -
588           The portion of a message which holds the user data to be
589           transmitted to the remote *endpoint.* The payload contents
590           are completely application defined.
591
592       * - **RMR context**
593         -
594           A set of information which defines the current state of the
595           underlying transport connections that RMR is managing. The
596           application will be give a context reference (pointer) that
597           is supplied to most RMR functions as the first parameter.
598
599       * - **Round robin**
600         -
601           The method of selecting an *endpoint* from a list such that
602           all *endpoints* are selected before starting at the head of
603           the list.
604
605       * - **Route table**
606         -
607           A series of "rules" which define the possible *endpoints* for
608           each *routing key.*
609
610       * - **Route table manager**
611         -
612           An application responsible for building a *route table* and
613           then distributing it to all applicable RMR based
614           applications.
615
616       * - **Routing**
617         -
618           The process of selecting an *endpoint* which will be the
619           recipient of a message.
620
621       * - **Routing key**
622         -
623           A combination of *message type* and *subscription ID* which
624           RMR uses to select the destination *endpoint* when sending a
625           message.
626
627       * - **Source**
628         -
629           The sender of a message.
630
631       * - **Subscription ID**
632         -
633           A signed integer value (0-32000) which identifies the
634           subscription characteristic of a message. It is used in
635           conjunction with the *message type* to determine the *routing
636           key.*
637
638       * - **Target**
639         -
640           The *endpoint* selected to receive a message.
641
642       * - **TCP**
643         -
644           Transmission Control Protocol. A connection based internet
645           protocol which provides for lossless packet transportation,
646           usually over IP.
647
648       * - **Thread**
649         -
650           Also called a *process thread, or pthread.* This is a
651           lightweight process which executes in concurrently with the
652           application and shares the same address space. RMR uses
653           threads to manage asynchronous functions such as route table
654           updates.
655
656       * - **Trace information**
657         -
658           An optional portion of the message buffer that the
659           application may populate with data that allows for tracing
660           the progress of the transaction or application activity
661           across components. RMR makes no use of this data.
662
663       * - **Transaction ID**
664         -
665           A fixed number of bytes in the *message* buffer) which the
666           application may populate with information related to the
667           transaction. RMR makes use of the transaction ID for matching
668           response messages with the &c function is used to send a
669           message.
670
671       * - **Transient failure**
672         -
673           An error state that is believed to be short lived and that
674           the operation, if retried by the application, might be
675           successful. C programmers will recognise this as
676           ``EAGAIN.``
677
678       * - **Warning**
679         -
680           A warning occurs when RMR has encountered something that it
681           believes isn't correct, but has a defined work round.
682
683       * - **Wormhole**
684         -
685           A direct connection managed by RMR between the user
686           application and a remote, RMR based, application.
687
688
689