Merge "Bgpcep user guides."
[docs.git] / manuals / developer-guide / src / main / asciidoc / controller / md-sal-rpc-routing.adoc
1 // Source: https://ask.opendaylight.org/question/99/how-does-request-routing-works/
2 === MD-SAL RPC routing
3
4 The MD-SAL provides a way to deliver Remote Procedure Calls (RPCs) to a
5 particular implementation based on content in the input as it is modeled in
6 YANG. This part of the the RPC input is referred to as a *context reference*.
7
8 The MD-SAL does not dictate the name of the leaf which is used for this RPC
9 routing, but provides necessary functionality for YANG model author to define
10 their *context reference* in their model of RPCs.
11
12 MD-SAL routing behavior is modeled using following terminology and its
13 application to YANG models:
14
15 Context Type::
16   Logical type of RPC routing. Context type is modeled as YANG `identity`
17   and is referenced in model to provide scoping information.
18 Context Instance::
19   Conceptual location in data tree, which represents context in which RPC
20   could be executed. Context instance usually represent logical point
21   to which RPC execution is attached.
22 Context Reference::
23   Field of RPC input payload which contains Instance Identifier referencing
24   *context instance*  in which the RPC should be executed.
25
26 ==== Modeling a routed RPC
27
28 In order to define routed RPCs, the YANG model author needs to declare (or
29 reuse) a *context type*, set of possible *context instances* and finally RPCs
30 which will contain *context reference* on which they will be routed.
31
32 ===== Declaring a routing context type
33
34 [source,yang]
35 ----
36 identity node-context {
37     description "Identity used to mark node context";
38 }
39 ----
40
41 This declares an identity named `node-context`, which is used as marker
42 for node-based routing and is used in other places to reference that routing
43 type.
44
45 ===== Declaring possible context instances
46
47 In order to define possible values of *context instances* for routed RPCs, we
48 need to model that set accordingly using `context-instance` extension from the
49 `yang-ext` model.
50
51 [source,yang]
52 ----
53 import yang-ext { prefix ext; }
54
55 /** Base structure **/
56 container nodes {
57     list node {
58         key "id";
59         ext:context-instance "node-context";
60         // other node-related fields would go here
61     }
62 }
63 ----
64
65 The statement `ext:context-instance "node-context";` marks any element of the
66 `list node` as a possible valid *context instance* in `node-context` based
67 routing.
68
69 [NOTE]
70 ====
71 The existence of a *context instance* node in operational or config data tree
72 is not strongly tied to existence of RPC implementation.
73
74 For most routed RPC models, there is relationship between the data present in
75 operational data tree and RPC implementation availability, but this is
76 not enforced by MD-SAL. This provides some flexibility for YANG model writers
77 to better specify their routing model and requirements for implementations.
78 Details when RPC implementations are available should be documented in YANG model.
79
80 If user invokes RPC with a *context instance* that has no registered
81 implementation, the RPC invocation will fail with the exception
82 `DOMRpcImplementationNotAvailableException`.
83 ====
84
85 ===== Declaring a routed RPC
86
87 To declare RPC to be routed based on `node-context` we need to add leaf
88 of `instance-identifier` type (or type derived from `instance-identifier`)
89 to the RPC and mark it as *context reference*.
90
91 This is achieved using YANG extension `context-reference` from `yang-ext` model
92 on leaf, which will be used for RPC routing.
93
94 [source,yang]
95 ----
96 rpc example-routed-rpc  {
97     input {
98         leaf node {
99             ext:context-reference "node-context";
100             type "instance-identifier";
101         }
102         // other input to the RPC would go here
103     }
104 }
105 ----
106
107 The statement `ext:context-reference "node-context"` marks `leaf node` as
108 *context reference* of type `node-context`. The value of this leaf, will be used
109 by the MD-SAL to select the particular RPC implementation that registered itself
110 as the implementation of the RPC for particular *context instance*.
111
112 ==== Using routed RPCs
113
114 From a user perspective (e.g. invoking RPCs) there is no difference between
115 routed and non-routed RPCs. Routing information is just an additional leaf in
116 RPC which must be populated.
117
118 // TODO: Add simple snippet of invoking such RPC even if it does not differ
119 // from normal one.
120
121 ==== Implementing a routed RPC
122
123 // TODO: Update this section to show some other example model
124 // along with binding and DOM implementations
125
126 Implementation
127
128 ===== Registering implementations
129
130 // FIXME: Clean up bit wording in following section, use different example
131
132 Implementations of a routed RPC (e.g., southbound plugins) will specify an
133 instance-identifier for the *context reference* (in this case a node) for which
134 they want to provide an implementation during registration. Consumers, e.g.,
135 those calling the RPC are required to specify that instance-identifier (in this
136 case the identifier of a node) when invoking RPC.
137
138 Simple code which showcases that for add-flow via Binding-Aware APIs
139 (https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blob;f=opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/RoutedServiceTest.java;h=d49d6f0e25e271e43c8550feb5eef63d96301184;hb=HEAD[RoutedServiceTest.java]
140 ):
141
142 [source, java]
143 ----
144  61  @Override
145  62  public void onSessionInitiated(ProviderContext session) {
146  63      assertNotNull(session);
147  64      firstReg = session.addRoutedRpcImplementation(SalFlowService.class, salFlowService1);
148  65  }
149 ----
150 Line 64: We are registering salFlowService1 as implementation of
151 SalFlowService RPC
152
153 [source, java]
154 ----
155 107  NodeRef nodeOne = createNodeRef("foo:node:1");
156 109  /**
157 110   * Provider 1 registers path of node 1
158 111   */
159 112  firstReg.registerPath(NodeContext.class, nodeOne);
160 ----
161
162 Line 107: We are creating NodeRef (encapsulation of InstanceIdentifier)
163 for "foo:node:1".
164
165 Line 112: We register salFlowService1 as implementation for nodeOne.
166
167 The salFlowService1 will be executed only for RPCs which contains
168 Instance Identifier for foo:node:1.