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