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.
7 ============================================================================================
9 ============================================================================================
10 --------------------------------------------------------------------------------------------
11 RIC Message Router -- RMR
12 --------------------------------------------------------------------------------------------
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*
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.
37 Contents of a Route Table
38 =========================
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.
56 newrt | start | rt-0928
57 rte | 2000 | logger:30311
58 mse | 1000 | 10 | forwarder:43086
59 mse | 1000 | 21 | app0:43086,app1:43086
62 Figure 1: A basic route table.
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
77 rte | <msg-type>[,<sender-endpoint>] | <endpoint-group>[;<endpoint-group>;...]
78 mse | <msg-type>[,<sender-endpoint>] | <sub-id> | <endpoint-group>[;<endpoint-group>;...]
91 is the table entry type
95 is the integer message type
97 * - **<sender-endpoint>**
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.
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.
113 * - **<endpoint-group>**
115 is one or more, comma separated, endpoint descriptions.
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.
129 Table entries **must** end with a record termination sequence
130 which may be one of the following three sequences:
133 * a single newline (\\n)
134 * a DOS style CRLF pair (\\r\\n)
135 * a single carriage return (\\r)
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
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.
159 newrt | begin [| table-id-string]
160 newrt | end [| record-count]
162 Figure 2: Illustration of the newrt records in the table.
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.
173 Comments, spaces, and blank lines
174 ---------------------------------
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.
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.
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).
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.
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
238 Figure 3: A complete RMR routing table (line numbers to the
239 right for reference).
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.
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
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.
271 As a rule, the ordering of entries for a given MT/SID pair
272 should be from most generic to most specific.
275 Route Manager Communications
276 ============================
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.
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.
297 Sending Tables To RMR
298 ---------------------
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
309 Table Acceptance and Acknowledgement
310 ------------------------------------
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.
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.
328 Providing A Static Table
329 ========================
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
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
369 mse| 1000,forwarder:43086 | 10 | %meid
371 Figure 4: Sample route entry with the meid flag.
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.
379 MEID endpoint selection
380 -----------------------
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.
391 meid_map | start | <table-id>
392 mme_ar | <owner-endpoint> | <meid> [<meid>...]
393 mme_del | <meid> [<meid>...]
394 meid_map | end | <count> [| <md5sum> ]
396 Figure 5: Meid map table.
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.
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.
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:
425 newrt|start | id-64306
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
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
440 Figure 6: Illustration of both a route table and meid map in
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.
449 Reserved Message Types
450 ======================
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.
459 Appendix A -- Glossary
460 ======================
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.
475 A programme which uses RMR to send and/or receive messages
476 to/from another RMR based application.
478 * - **Critical error**
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.
486 An RMR based application that is defined as being capable of
487 receiving one or more types of messages (as defined by a
490 * - **Environment variable**
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.
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.
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.)
516 Internet protocol. A low level transmission protocol which
517 governs the transmission of datagrams across network
520 * - **Listen socket**
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
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).
533 * - **Message buffer**
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
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.*
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.
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.
561 The method of selecting an *endpoint* from a list such that
562 all *endpoints* are selected before starting at the head of
567 A series of "rules" which define the possible *endpoints* for
570 * - **Route table manager**
572 An application responsible for building a *route table* and
573 then distributing it to all applicable RMR based
578 The process of selecting an *endpoint* which will be the
579 recipient of a message.
583 A combination of *message type* and *subscription ID* which
584 RMR uses to select the destination *endpoint* when sending a
589 The sender of a message.
591 * - **Subscription ID**
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
600 The *endpoint* selected to receive a message.
604 Transmission Control Protocol. A connection based internet
605 protocol which provides for lossless packet transportation,
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.
619 * - **Transaction ID**
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
627 * - **Transient failure**
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
636 A warning occurs when RMR has encountered something that it
637 believes isn't correct, but has a defined work round.
641 A direct connection managed by RMR between the user
642 application and a remote, RMR based, application.