1 // Source: https://ask.opendaylight.org/question/99/how-does-request-routing-works/
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*.
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.
12 MD-SAL routing behavior is modeled using following terminology and its
13 application to YANG models:
16 Logical type of RPC routing. Context type is modeled as YANG `identity`
17 and is referenced in model to provide scoping information.
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.
23 Field of RPC input payload which contains Instance Identifier referencing
24 *context instance* in which the RPC should be executed.
26 ==== Modeling a routed RPC
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.
32 ===== Declaring a routing context type
36 identity node-context {
37 description "Identity used to mark node context";
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
45 ===== Declaring possible context instances
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
53 import yang-ext { prefix ext; }
55 /** Base structure **/
59 ext:context-instance "node-context";
60 // other node-related fields would go here
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
71 The existence of a *context instance* node in operational or config data tree
72 is not strongly tied to existence of RPC implementation.
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.
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`.
85 ===== Declaring a routed RPC
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*.
91 This is achieved using YANG extension `context-reference` from `yang-ext` model
92 on leaf, which will be used for RPC routing.
96 rpc example-routed-rpc {
99 ext:context-reference "node-context";
100 type "instance-identifier";
102 // other input to the RPC would go here
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*.
112 ==== Using routed RPCs
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.
118 // TODO: Add simple snippet of invoking such RPC even if it does not differ
121 ==== Implementing a routed RPC
123 // TODO: Update this section to show some other example model
124 // along with binding and DOM implementations
128 ===== Registering implementations
130 // FIXME: Clean up bit wording in following section, use different example
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.
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]
145 62 public void onSessionInitiated(ProviderContext session) {
146 63 assertNotNull(session);
147 64 firstReg = session.addRoutedRpcImplementation(SalFlowService.class, salFlowService1);
150 Line 64: We are registering salFlowService1 as implementation of
155 107 NodeRef nodeOne = createNodeRef("foo:node:1");
157 110 * Provider 1 registers path of node 1
159 112 firstReg.registerPath(NodeContext.class, nodeOne);
162 Line 107: We are creating NodeRef (encapsulation of InstanceIdentifier)
165 Line 112: We register salFlowService1 as implementation for nodeOne.
167 The salFlowService1 will be executed only for RPCs which contains
168 Instance Identifier for foo:node:1.