Add ability to save route table updates to disk
[ric-plt/lib/rmr.git] / doc / src / library / rt_tables.xfm
1 .if false
2 ==================================================================================
3    Copyright (c) 2020 Nokia
4    Copyright (c) 2020 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 .fi
19
20 .if false
21         Mnemonic:       rt_tables.xfm
22         Abstract:       An overview of route tables in RMR.
23         Date:           25 February 2020
24         Author:         E. Scott Daniels
25 .fi
26
27 .** constants
28 .dv MT_REQ_TABLE 21
29 .dv MT_TABLE_STATE      22
30 .dv MT_TABLE_DATA 20
31
32 .dv RTMGR ^&ital(Route Manager)
33
34 .** -------------------------------------------------------------------------------
35
36 .** force setup to generate a title and to reverse title/subtitle for rst docs
37 .dv GEN_TITLE 1
38 .dv doc_title RIC Message Router -- RMR
39 .dv doc_subtitle Route Table Guide
40 .dv reverse_titles 1
41
42
43 .dv textfont Helvetica
44 .dv textsize 10p
45 .dv index_snare_file index_snatch.im
46 .dv orig_date 30 April 2020
47
48 .gv e XFM_PASS pass
49
50 .** setup will do the right thing with the index configuration; a common snatch
51 .** file is used for all documents in this directory.
52 .**
53 .dv index_snare_file index_snatch.im
54 .im setup.im
55
56
57 &line_len( &line_size )
58 .** -------------------------------------------------------------------------------
59
60 &h1(Overview)
61 Messages sent via the RIC Message Router (RMR) are routed to an endpoint (another application)
62 based on a combination of the &ital(message type) (MT) and &ital(subscription ID) (SID)
63 supplied in the message.
64 RMR determines the endpoint by matching the MT and SID combination to an entry in a route table
65 which has been supplied dynamically by a &RTMGR service, or as a static table loaded
66 during RMR initialisation.
67 It is also possible to route messages directly to an endpoint which is the &ital(managed entity)
68 "owner," using the &ital(managed entity ID) (MEID).
69
70 &space
71 For most xAPP developers the format of the RMR route table is not important beyond understanding
72 how to create a static table for local testing.
73 For developers of a &RTMGR service, the need is certainly a requirement.
74 This document describes the overall syntax of a route table and the interface between the
75 &RTMGR service and RMR.
76
77
78 &h1(Contents of a Route Table)
79 The table consists of a start record, one or more entry records, and an end record.
80 Each entry record defines one message type, with an optional sender application, and the endpoint(s) which
81 accept the indicated message type.
82 All table records contain fields separated with vertical bars (|), and allow for trailing comments with the
83 standard shell comment symbol (hash, #) provided that the start of the comment is separated from the last
84 token on the record by one or more spaces.
85 Leading and trailing white space in each field is ignored.
86 .gv fig
87 Figure &_fig illustrates a very basic route table with two message types, 1000 and 2000, and two
88 subscription IDs for message type 1000.
89 &half_space
90
91 &ex_start
92   newrt | start | rt-0928
93   rte   | 2000  | logger:30311
94   mse   | 1000  | 10 | forwarder:43086
95   mse   | 1000  | 21 | app0:43086,app1:43086
96   newrt | end   | 3
97 &ex_end
98 &fig(A basic route table.)
99
100
101
102 &h2(Entry record syntax)
103 Two types of table entries are supported for compatibility with the original RMR implementation, but only the &ital(mse)
104 entry type is needed and that should be the entry used when creating new tables.
105 The following shows the syntax for both entry types:
106 &space
107
108 &ex_start
109  rte | <msg-type>[,<sender-endpoint>] | <endpoint-group>[;<endpoint-group>;...]
110  mse | <msg-type>[,<sender-endpoint>] | <sub-id> | <endpoint-group>[;<endpoint-group>;...]
111 &ex_end
112 &space
113
114 Where:
115 &half_space
116
117 &indent
118 &beg_dlist( 1i : Helvetica-bold : 25,70 )
119 &ditem(mse, rte)
120         is the table entry type
121
122 &ditem(<msg-type>)
123         is the integer message type
124
125 &ditem(<sender-endpoint>)
126         is the endpoint description of the message sender; only that sender will read the entry from the table,
127         so a single table may be used for all senders when a common message type is delivered to varying endpoints based on senders.
128         If the sender endpoint is omitted from the entry, then the entry will be used by all applications.
129
130 &ditem(<sub-id>)
131         is the subscription id (integer) for subscription-based messages, or -1 if the message type is not subscription-based.
132         An &ital(mse) entry with a sub-id of -1 is the &bold(same) as an &ital(rte) entry with the same message type.
133
134 &ditem(<endpoint-group>)
135         is one or more, comma separated, endpoint descriptions.
136 &end_dlist
137 &uindent
138 &space
139
140 When an application sends a message with the indicated type, the message will be sent to one endpoint in the group in a
141 round-robin ordering.
142 If multiple endpoint groups are given, then the message is sent to a member selected from each group; 3 groups, then three
143 messages will be sent.
144 The first group is required.
145
146 &h3(Line separation)
147 Table entries &bold(must) end with a record termination sequence which may be one of the following
148 three sequences:
149 &half_space
150 &indent
151 &beg_list(&lic1)
152 &li a single newline (&{backslant}n)
153 &li a DOS style CRLF pair (&{backslant}r&{backslant}n)
154 &li a single carriage return (&{backslant}r)
155 &end_list
156 &uindent
157
158 &space
159
160 Care must be taken when manually editing a static table; some editors do &bold(not) add
161 a final record termination sequence to the last line of a file.
162 RMR expects the final record to have a termination sequence to ensure that the
163 record was not truncated (especially important when receiving dynamic tables).
164
165 &h2(Table framing)
166 The route table parser within RMR assumes that route table entries are sent via RMR messages as a
167 stream.
168 To ensure synchronisation and prevent malformed tables because of broken sessions or lost packets,
169 each table must begin and end with an &ital(newrt) record.
170 Each &ital(newrt) record has one of two possible syntax layouts as described below.
171
172 &half_space
173 &ex_start
174   newrt | begin [| table-id-string]
175   newrt | end  [| record-count]
176 &ex_end
177 &fig(Illustration of the newrt records in the table.)
178 &space
179
180 The &ital(table-id-string) is an optional string which is used by RMR when sending an acknowledgement
181 back to the &RTMGR service (see the &ital(Route Manager Interface) section for more details).
182 If a &ital(record-count) is given as the final field on the &ital(end) record, RMR will verify that the
183 number of &ital(mse) and &ital(rte) entries in the table matches the count; if there is a mismatch in
184 values the table is not used.
185
186
187 &h2(Comments, spaces, and blank lines)
188 Comments may be placed to the right of any table entry line using the standard
189 shell comment symbol (#).
190 The start of a comment must be separated from any previous record content by at least one space or tab.
191 Complete lines are treated as comments when the first non-whitespace character of a line is a comment symbol.
192 Blank lines are also ignored.
193
194 &space
195 Fields on table records are separated using the vertical bar (|) character.
196 Any white space (tabs or spaces) which appear immediately before or after a separator are ignored.
197
198
199 &h2(Endpoint Description)
200 The endpoint description is either the hostname or IP address followed by a port number; the two are separated by a single colon.
201 The illustration below assumes that host names (e.g. forwarder and app1) are defined;
202 they also make the tables easier to read.
203 The port number given is the port number that the user application provides to RMR when the RMR initialisation function is
204 invoked (and thus is the port that RMR is listening on).
205
206
207 &h1(Table Mechanics)
208 Creating a table from the two entry types is fairly simple,
209 however there are some subtleties which should be pointed out to avoid unexpected behaviour.
210 For this discussion the following complete table will be used.
211
212 .cc 20
213
214 &space
215 &beg_table_nb( 75,10  : 4.5i .3i)
216 &row
217 &ex_start
218   newrt | start | rt-0928
219   rte | 2000 | logger:30311
220   mse | 1000 | 10 | forwarder:43086
221   mse | 1000,forwarder:43086 | 10 | app2:43086
222   mse | 1000 | -1 | app0:43086,app1:43086; logger:20311
223   newrt | end | 4
224 &ex_end
225 &col
226 &ex_start
227 (1)
228 (2)
229 (3)
230 (4)
231 (5)
232 (6)
233 &ex_end
234 &end_table
235
236 .gv fig
237 .dv table_fig &_fig
238 &fig( A complete RMR routing table (line numbers to the right for reference). )
239
240 &h2(Table Entry Ordering)
241 Whether a table is read from a file on disk, or is received from a &RTMGR service,
242 RMR parses the records to build an internal route table keeping only the relevant information.
243 Entries are read in the order they appear (from the file or in messages received), and
244 RMR will use only one entry for each MT/SID pair.
245 &space
246
247 For most tables, the ordering of entries is not important, but when there are entries
248 which duplicate the MT/SID pair ordering becomes significant.
249 RMR will use the &bold(last) valid entry for a MT/SID pair that it encounters.
250 An entry is considered valid if there is no sender identified with the message type (line 3),
251 and when the sender (host and port) match the the applications' location and the port provided
252 to RMR for listening.
253 &space
254
255 Using the table in figure &table_fig as an example, there are two entries which match the
256 MT/SID pair of 1000/10.
257 When this table is parsed on any host, RMR will recognise and add the first entry (line 3)
258 to the internal representation; this entry is valid for all applications.
259 The second 1000/10 entry (line 4) is valid when the table is parsed on the &ital(forwarder) host, and
260 only by the application which is listening on port 43086.
261 For this application the entry will override the more generic entry for the MT/SID combination.
262
263 &space
264 As a rule, the ordering of entries for a given MT/SID pair should be from most generic to
265 most specific.
266
267
268
269 &h1(Route Manager Communications)
270 During initialisation RMR will use the value of the  &cw(RMR_RTG_SVC) environment variable to
271 connect to  the &RTMGR service in order to request a route table.
272 The connection between RMR and the &RTMGR is also an RMR session and thus
273 RMR messages will be used to exchange requests and responses.
274
275 &h2(Table Request)
276 During initialisation, RMR establishes a wormhole connection to the &RTMGR and sends
277 a message type of &MT_REQ_TABLE to request a new table.
278 RMR will continue to send table requests until a table is received and accepted; in other
279 words it is fine for the &RTMGR to ignore the requests if it is not ready to respond.
280
281 &h2(Sending Tables To RMR)
282 Table entry data is expected to arrive via RMR message with a message type of &MT_TABLE_DATA.
283 The message may contain one or more entries provided that the entries are newline separated.
284 Current versions of RMR support very large messages, however to ensure compatibility with
285 an xAPP built using an older version of RMR (pre 3.8), messages should be limited to 4 KiB.
286
287 &h2(Table Acceptance and Acknowledgement)
288 When RMR receives the table end entry (newrt|end), it will send a state message back to
289 the &RTMGR to indicate the state of the received table.
290 The message type is &MT_TABLE_STATE and the payload will contain UTF-8 tokens which indicate the state.
291 The second token will be the &ital(table ID) supplied on the start record, or the string "<id-missing>."
292 When the state is an error state, RMR might add a final set of tokens which contain the reason
293 for the failure.
294 &space
295
296 Upon receipt of a status message which indicates an "OK" response, the &RTMGR can assume that
297 the table has been installed and is in use.
298 Any other response indicates that RMR did not use the table and has dropped it; the previous
299 table is still in use.
300
301
302 &h2(Using A Static Route Table)
303 A static route table can be provided to assist with testing, or to provide a bootstrap set of
304 route information until a dynamic table is received from a routing manager.
305 The environment variable &cw(RMR_SEED_RT) is checked during RMR initialisation and
306 if set is expected to reference a file containing a route table.
307 This table will be loaded and used until overlaid by a table sent by the &RTMGR.
308 &space
309
310 To simulate dynamic reloads during testing, and for some specialised use cases,
311 the static table will be reloaded periodically if the &cw(RMR_RTG_SVC) environment
312 variable is set to -1.
313 When set to -1 RMR will not listen for &RTMGR connections, nor will it attempt to request a dynamic table.
314
315 &space
316 If the file given by the &cw(RMR_SEED_RT) variable does not exist, and the &cw(RMR_RTG_SVC) variable
317 is set to -1, RMR will block until the table is created.
318 This simulates a delayed dynamic load during testing, and can be used when the xAPP is reading
319 the route table saved by another local process rather than one sent directly by the &RTMGR.
320
321 &h2(Table Stashing)
322 To assist with debugging, and to allow an application to share the route table received from
323 &RTMGR, RMR will stash the route table updates it received.
324 Updates are stashed in a file named by the &cw(RMR_STASH_RT) environment variable, and if that
325 variable is not present, the &cw(RR_SEED_RT) variable will be used with an added &cw(.stash) extension.
326
327 &space
328 The primary use of route table stashing is to assist with debugging of applications, and because there are
329 risks for an application to share its table, table sharing is &bold(NOT) recommended.
330 Table sharing can be enabled by setting the &cw(RMR_STASH_RT) variable for the application that will be
331 the source of the route table updates, and using the file named for tha application when defining the
332 &cw(RMR_SEED_RT) variable for applications which are to read the table information.
333 Obviously, all applications must be running in the same container, on the same host, or have a
334 common disk volum between their environments.
335 Known risks to using table sharing include
336 &half_space
337
338 &indent
339 &beg_list(&lic1)
340 &li An update to the table (not a complete table) may be received prior to one or more readers
341         accessing the file, and thus the reader may not receive a valid or complete table.
342 &half_space
343
344 &li Any entry which has a sender:port associated with the message type will likely be ignored
345         by all readers.
346 &end_list
347 &uindent
348
349
350 &h1(Routing Using MEID)
351 Starting with version 1.13.0, RMR provides the ability to select the endpoint for a message based on the MEID (managed entity ID)
352 in the message, rather than selecting the endpoint from the round-robin list for the matching route table entry.
353 When the MEID is used, the message is sent to the endpoint which &ital(owns,) or is responsible for the managed entity.
354 Should the &ital(owner) change messages will be routed to the new owner when the route table is updated.
355 To make use of MEID routing, there must be one or more route table entries which list the special endpoint name &cw(%meid)
356 instead of providing a round robin list.
357 As an example, consider the following route table entry:
358 &space
359
360 &ex_start
361   mse| 1000,forwarder:43086 | 10 | %meid
362 &ex_end
363 &fig( Sample route entry with the meid flag.)
364 &space
365
366 The final field of the entry doesn't specify a round-robin group which means that when an application attempts to send a message
367 with type 1000, and the subscription ID of 10, the MEID in the message will be used to select the endpoint.
368
369
370
371 &h2(MEID endpoint selection)
372 To select an endpoint for the message based on the MEID in a message, RMR must know which endpoint owns the MEID.
373 This information, known as an MEID map,  is provided by the &RTMGR over the same communication path as the route
374 table is supplied.
375 The following is the syntax for an MEID map.
376 &half_space
377
378
379 &ex_start
380   meid_map | start | <table-id>
381   mme_ar | <owner-endpoint> | <meid> [<meid>...]
382   mme_del | <meid> [<meid>...]
383   meid_map | end | <count> [| <md5sum> ]
384 &ex_end
385 &fig( Meid map table.)
386 &space
387
388 The mme_ar records are add/update records and allow for the list of MEIDs to be associated with (owned by) the indicated endpoint.
389 The <owner-endpoint> is the hostname:port, or IP address and port, of the application which owns the MEID and thus should
390 receive any messages which are routed based on a route table entry with %meid as the round-robin group.
391  The mme_del records allow  for MEIDs to be deleted from RMR's view.
392 Finally, the <count> is the number of add/replace and delete records which were sent; if RMR does not match the <count> value
393 to the number of records, then it will not add the data to the table.
394  Updates only need to list the ownership changes that are necessary; in other words, the &RTMGR does not need to supply
395 all of the MEID relationships with each update.
396 &space
397
398 The optional <md5sum> field on the end record should be the MD5 hash of all of the records between the start and end records.
399 This allows for a precise verification that the transmitted data was correctly received.
400 &space
401
402 If a static seed file is being used for the route table, a second section can be given which supplies the MEID map.
403 The following is a small example of a seed file:
404 &half_space
405
406 &ex_start
407  newrt|start | id-64306
408  mse|0|-1| %meid
409  mse|1|-1|172.19.0.2:4560
410  mse|2|-1|172.19.0.2:4560
411  mse|3|-1|172.19.0.2:4560
412  mse|4|-1|172.19.0.2:4560
413  mse|5|-1|172.19.0.2:4560
414  newrt|end
415
416  meid_map | start | id-028919
417  mme_ar| 172.19.0.2:4560 | meid000 meid001 meid002 meid003 meid004 meid005
418  mme_ar| 172.19.0.42:4560 | meid100 meid101 meid102 meid103
419  mme_del | meid1000
420  meid_map | end | 1
421 &ex_end
422 &fig( Illustration of both a route table and meid map in the same file. )
423 &space
424
425 The tables above will route all messages with a message type of 0 based on the MEID.
426 There are 10 meids which are owned by two different endpoints.
427 The table also deletes the MEID meid1000 from RMR's view.
428
429
430 &h1(Reserved Message Types)
431 RMR is currently reserving message types in the range of 0 through 99 (inclusive) for its own use.
432 Please do not use these types in any production or test environment as the results may be undesired.
433
434 .** -- appendices ------------------------------
435
436 .dv gloss_appendix A
437 .pa
438 .im glossary.im
439
440 .** ----------- end housekeeping ---------------
441
442 .** if pfm and index was setup, include it now
443 .if index_here
444         .st 8p
445         &index_here
446         .st &textsize
447 .fi
448 .pa
449
450 .** capture all interesting variables to be used as forward references during pass 2
451 .ca expand start p1var_setup.ca
452         .** pass 1 variable settings -- do NOT commit to repo
453
454         .** set vars which need to be referenced prior to use, for example:
455         .** .dv qr_appendix &qr_appendix
456 .ca end