Merge "Added docs for SNMP"
[docs.git] / manuals / developer-guide / src / main / asciidoc / controller / restconf.adoc
1 === OpenDaylight Controller MD-SAL: Restconf
2
3 ==== Restconf operations overview
4
5 Restconf allows access to datastores in the controller. +
6 There are two datastores: +
7
8 * Config: Contains data inserted via controller
9 * Operational: Contains other data
10
11 NOTE: Each request must start with the URI /restconf. +
12 Restconf listens on port 8080 for HTTP requests.
13
14 Restconf supports *OPTIONS*, *GET*, *PUT*, *POST*, and *DELETE* operations. Request and response data can either be in the XML or JSON format. XML structures according to yang are defined at: http://tools.ietf.org/html/rfc6020[XML-YANG]. JSON structures are defined at: http://tools.ietf.org/html/draft-lhotka-netmod-yang-json-02[JSON-YANG]. Data in the request must have a correctly set *Content-Type* field in the http header with the allowed value of the media type. The media type of the requested data has to be set in the *Accept* field. Get the media types for each resource by calling the OPTIONS operation.
15 Most of the paths of the pathsRestconf endpoints use https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Concepts#Instance_Identifier[Instance Identifier]. +<identifier>+ is used in the explanation of the operations.
16
17 *<identifier>* +
18
19 * It must start with <moduleName>:<nodeName> where <moduleName> is a name of the module and <nodeName> is the name of a node in the module. It is sufficient to just use <nodeName> after <moduleName>:<nodeName>. Each <nodeName> has to be separated by /.
20 * <nodeName> can represent a data node which is a list or container yang built-in type. If the data node is a list, there must be defined keys of the list behind the data node name for example, <nodeName>/<valueOfKey1>/<valueOfKey2>.
21 * The format <moduleName>:<nodeName> has to be used in this case as well: +
22 Module A has node A1. Module B augments node A1 by adding node X. Module C augments node A1 by adding node X. For clarity, it has to be known which node is X (for example: C:X).
23 For more details about encoding, see: http://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-5.3.1[Restconf 02 - Encoding YANG Instance Identifiers in the Request URI.]
24
25 === Mount point
26 A Node can be behind a mount point. In this case, the URI has to be in format <identifier>/*yang-ext:mount*/<identifier>. The first <identifier> is the path to a mount point and the second <identifier> is the path to a node behind the mount point. A URI can end in a mount point itself by using <identifier>/*yang-ext:mount*. +
27 More information on how to actually use mountpoints is available at: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:Netconf[ OpenDaylight Controller:Config:Examples:Netconf].
28
29 ==== HTTP methods
30
31 ===== OPTIONS /restconf +
32
33 * Returns the XML description of the resources with the required request and response media types in Web Application Description Language (WADL)
34
35 ===== GET /restconf/config/<identifier> +
36
37 * Returns a data node from the Config datastore.
38 * <identifier> points to a data node which must be retrieved.
39
40 ===== GET /restconf/operational/<identifier> +
41
42 * Returns the value of the data node from the Operational datastore.
43 * <identifier> points to a data node which must be retrieved.
44
45 ===== PUT /restconf/config/<identifier>
46
47 * Updates or creates data in the Config datastore and returns the state about success.
48 * <identifier> points to a data node which must be stored.
49
50 *Example:* +
51 ----
52 PUT http://<controllerIP>:8080/restconf/config/module1:foo/bar
53 Content-Type: applicaton/xml
54 <bar>
55   …
56 </bar>
57 ----
58 *Example with mount point:* +
59 ----
60 PUT http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo/bar
61 Content-Type: applicaton/xml
62 <bar>
63   …
64 </bar>
65 ----
66 ===== POST /restconf/config
67 * Creates the data if it does not exist
68
69 For example: +
70 ----
71 POST URL: http://localhost:8080/restconf/config/
72 content-type: application/yang.data+json
73 JSON payload:
74
75    {
76      "toaster:toaster" :
77      {
78        "toaster:toasterManufacturer" : "General Electric",
79        "toaster:toasterModelNumber" : "123",
80        "toaster:toasterStatus" : "up"
81      }
82   }
83 ----
84 ===== POST /restconf/config/<identifier>
85
86 * Creates the data if it does not exist in the Config datastore, and returns the state about success.
87 * <identifier> points to a data node where data must be stored.
88 * The root element of data must have the namespace (data are in XML) or module name (data are in JSON.)
89
90 *Example:* +
91 ----
92 POST http://<controllerIP>:8080/restconf/config/module1:foo
93 Content-Type: applicaton/xml/
94 <bar xmlns=“module1namespace”>
95   …
96 </bar>
97 ----
98 *Example with mount point:*
99 ----
100 http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo
101 Content-Type: applicaton/xml
102 <bar xmlns=“module2namespace”>
103   …
104 </bar>
105 ----
106 ===== POST /restconf/operations/<moduleName>:<rpcName>
107
108 * Invokes RPC.
109 * <moduleName>:<rpcName> - <moduleName> is the name of the module and <rpcName> is the name of the RPC in this module.
110 * The Root element of the data sent to RPC must have the name “input”.
111 * The result can be the status code or the retrieved data having the root element “output”.
112
113 *Example:* +
114 ----
115 POST http://<controllerIP>:8080/restconf/operations/module1:fooRpc
116 Content-Type: applicaton/xml
117 Accept: applicaton/xml
118 <input>
119   …
120 </input>
121
122 The answer from the server could be:
123 <output>
124   …
125 </output>
126 ----
127 *An example using a JSON payload:* +
128 ----
129 POST http://localhost:8080/restconf/operations/toaster:make-toast
130 Content-Type: application/yang.data+json
131 {
132   "input" :
133   {
134      "toaster:toasterDoneness" : "10",
135      "toaster:toasterToastType":"wheat-bread"
136   }
137 }
138 ----
139
140 NOTE: Even though this is a default for the toasterToastType value in the yang, you still need to define it.
141
142 ===== DELETE /restconf/config/<identifier>
143
144 * Removes the data node in the Config datastore and returns the state about success.
145 * <identifier> points to a data node which must be removed.
146
147 More information is available in the http://tools.ietf.org/html/draft-bierman-netconf-restconf-02[Restconf RFC].
148
149 ==== How Restconf works
150 Restconf uses these base classes: +
151
152 InstanceIdentifier:: Represents the path in the data tree
153 ConsumerSession:: Used for invoking RPCs
154 DataBrokerService:: Offers manipulation with transactions and reading data from the datastores
155 SchemaContext:: Holds information about yang modules
156 MountService:: Returns MountInstance based on the InstanceIdentifier pointing to a mount point
157 MountInstace:: Contains the SchemaContext behind the mount point
158 DataSchemaNode:: Provides information about the schema node
159 SimpleNode:: Possesses the same name as the schema node, and contains the value representing the data node value
160 CompositeNode:: Can contain CompositeNode-s and SimpleNode-s
161
162 ==== GET in action
163 Figure 1 shows the GET operation with URI restconf/config/M:N where M is the module name, and N is the node name.
164
165
166 .Get
167 image::Get.png[width=500]
168
169 . The requested URI is translated into the InstanceIdentifier which points to the data node. During this translation, the DataSchemaNode that conforms to the data node is obtained. If the data node is behind the mount point, the MountInstance is obtained as well.
170 . Restconf asks for the value of the data node from DataBrokerService based on InstanceIdentifier.
171 . DataBrokerService returns CompositeNode as data.
172 . StructuredDataToXmlProvider or StructuredDataToJsonProvider is called based on the *Accept* field from the http request. These two providers can transform CompositeNode regarding DataSchemaNode to an XML or JSON document.
173 . XML or JSON is returned as the answer on the request from the client.
174
175 ==== PUT in action
176
177 Figure 2 shows the PUT operation with the URI restconf/config/M:N where M is the module name, and N is the node name. Data is sent in the request either in the XML or JSON format.
178
179 .Put
180
181 image::Put.png[width=500]
182
183 . Input data is sent to JsonToCompositeNodeProvider or XmlToCompositeNodeProvider. The correct provider is selected based on the Content-Type field from the http request. These two providers can transform input data to CompositeNode. However, this CompositeNode does not contain enough information for transactions.
184 . The requested URI is translated into InstanceIdentifier which points to the data node. DataSchemaNode conforming to the data node is obtained during this translation. If the data node is behind the mount point, the MountInstance is obtained as well.
185 . CompositeNode can be normalized by adding additional information from DataSchemaNode.
186 . Restconf begins the transaction, and puts CompositeNode with InstanceIdentifier into it. The response on the request from the client is the status code which depends on the result from the transaction.
187
188 === Something practical
189
190 . Create a new flow on the switch openflow:1 in table 2.
191
192 *HTTP request* +
193 ----
194 Operation: POST
195 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2
196 Content-Type: application/xml
197 ----
198 ----
199 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
200 <flow
201     xmlns="urn:opendaylight:flow:inventory">
202     <strict>false</strict>
203     <instructions>
204         <instruction>
205                 <order>1</order>
206             <apply-actions>
207                 <action>
208                   <order>1</order>
209                     <flood-all-action/>
210                 </action>
211             </apply-actions>
212         </instruction>
213     </instructions>
214     <table_id>2</table_id>
215     <id>111</id>
216     <cookie_mask>10</cookie_mask>
217     <out_port>10</out_port>
218     <installHw>false</installHw>
219     <out_group>2</out_group>
220     <match>
221         <ethernet-match>
222             <ethernet-type>
223                 <type>2048</type>
224             </ethernet-type>
225         </ethernet-match>
226         <ipv4-destination>10.0.0.1/24</ipv4-destination>
227     </match>
228     <hard-timeout>0</hard-timeout>
229     <cookie>10</cookie>
230     <idle-timeout>0</idle-timeout>
231     <flow-name>FooXf22</flow-name>
232     <priority>2</priority>
233     <barrier>false</barrier>
234 </flow>
235 ----
236 *HTTP response* +
237 ----
238 Status: 204 No Content
239 ----
240 [start=2]
241 . Change _strict_ to _true_ in the previous flow.
242
243 *HTTP request* +
244 ----
245 Operation: PUT
246 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
247 Content-Type: application/xml
248 ----
249 ----
250 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
251 <flow
252     xmlns="urn:opendaylight:flow:inventory">
253     <strict>true</strict>
254     <instructions>
255         <instruction>
256                 <order>1</order>
257             <apply-actions>
258                 <action>
259                   <order>1</order>
260                     <flood-all-action/>
261                 </action>
262             </apply-actions>
263         </instruction>
264     </instructions>
265     <table_id>2</table_id>
266     <id>111</id>
267     <cookie_mask>10</cookie_mask>
268     <out_port>10</out_port>
269     <installHw>false</installHw>
270     <out_group>2</out_group>
271     <match>
272         <ethernet-match>
273             <ethernet-type>
274                 <type>2048</type>
275             </ethernet-type>
276         </ethernet-match>
277         <ipv4-destination>10.0.0.1/24</ipv4-destination>
278     </match>
279     <hard-timeout>0</hard-timeout>
280     <cookie>10</cookie>
281     <idle-timeout>0</idle-timeout>
282     <flow-name>FooXf22</flow-name>
283     <priority>2</priority>
284     <barrier>false</barrier>
285 </flow>
286 ----
287 *HTTP response* +
288 ----
289 Status: 200 OK
290 ----
291 [start=3]
292 . Show flow: check that _strict_ is _true_.
293
294 *HTTP request* +
295 ----
296 Operation: GET
297 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
298 Accept: application/xml
299 ----
300 *HTTP response* +
301 ----
302 Status: 200 OK
303 ----
304
305 ----
306 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
307 <flow
308     xmlns="urn:opendaylight:flow:inventory">
309     <strict>true</strict>
310     <instructions>
311         <instruction>
312                 <order>1</order>
313             <apply-actions>
314                 <action>
315                   <order>1</order>
316                     <flood-all-action/>
317                 </action>
318             </apply-actions>
319         </instruction>
320     </instructions>
321     <table_id>2</table_id>
322     <id>111</id>
323     <cookie_mask>10</cookie_mask>
324     <out_port>10</out_port>
325     <installHw>false</installHw>
326     <out_group>2</out_group>
327     <match>
328         <ethernet-match>
329             <ethernet-type>
330                 <type>2048</type>
331             </ethernet-type>
332         </ethernet-match>
333         <ipv4-destination>10.0.0.1/24</ipv4-destination>
334     </match>
335     <hard-timeout>0</hard-timeout>
336     <cookie>10</cookie>
337     <idle-timeout>0</idle-timeout>
338     <flow-name>FooXf22</flow-name>
339     <priority>2</priority>
340     <barrier>false</barrier>
341 </flow>
342 ----
343 [start=4]
344 . Delete the flow created.
345
346 *HTTP request* +
347 ----
348 Operation: DELETE
349 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
350 ----
351 *HTTP response* +
352 ----
353 Status: 200 OK
354 ----