1 === OpenDaylight Controller MD-SAL: Restconf
3 ==== Restconf operations overview
5 Restconf allows access to datastores in the controller. +
6 There are two datastores: +
8 * Config: Contains data inserted via controller
9 * Operational: Contains other data
11 NOTE: Each request must start with the URI /restconf. +
12 Restconf listens on port 8080 for HTTP requests.
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.
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.]
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].
31 ===== OPTIONS /restconf +
33 * Returns the XML description of the resources with the required request and response media types in Web Application Description Language (WADL)
35 ===== GET /restconf/config/<identifier> +
37 * Returns a data node from the Config datastore.
38 * <identifier> points to a data node which must be retrieved.
40 ===== GET /restconf/operational/<identifier> +
42 * Returns the value of the data node from the Operational datastore.
43 * <identifier> points to a data node which must be retrieved.
45 ===== PUT /restconf/config/<identifier>
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.
52 PUT http://<controllerIP>:8080/restconf/config/module1:foo/bar
53 Content-Type: applicaton/xml
58 *Example with mount point:* +
60 PUT http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo/bar
61 Content-Type: applicaton/xml
66 ===== POST /restconf/config
67 * Creates the data if it does not exist
71 POST URL: http://localhost:8080/restconf/config/
72 content-type: application/yang.data+json
78 "toaster:toasterManufacturer" : "General Electric",
79 "toaster:toasterModelNumber" : "123",
80 "toaster:toasterStatus" : "up"
84 ===== POST /restconf/config/<identifier>
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.)
92 POST http://<controllerIP>:8080/restconf/config/module1:foo
93 Content-Type: applicaton/xml/
94 <bar xmlns=“module1namespace”>
98 *Example with mount point:*
100 http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo
101 Content-Type: applicaton/xml
102 <bar xmlns=“module2namespace”>
106 ===== POST /restconf/operations/<moduleName>:<rpcName>
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”.
115 POST http://<controllerIP>:8080/restconf/operations/module1:fooRpc
116 Content-Type: applicaton/xml
117 Accept: applicaton/xml
122 The answer from the server could be:
127 *An example using a JSON payload:* +
129 POST http://localhost:8080/restconf/operations/toaster:make-toast
130 Content-Type: application/yang.data+json
134 "toaster:toasterDoneness" : "10",
135 "toaster:toasterToastType":"wheat-bread"
140 NOTE: Even though this is a default for the toasterToastType value in the yang, you still need to define it.
142 ===== DELETE /restconf/config/<identifier>
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.
147 More information is available in the http://tools.ietf.org/html/draft-bierman-netconf-restconf-02[Restconf RFC].
149 ==== How Restconf works
150 Restconf uses these base classes: +
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
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.
167 image::Get.png[width=500]
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.
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.
181 image::Put.png[width=500]
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.
188 === Something practical
190 . Create a new flow on the switch openflow:1 in table 2.
195 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2
196 Content-Type: application/xml
199 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
201 xmlns="urn:opendaylight:flow:inventory">
202 <strict>false</strict>
214 <table_id>2</table_id>
216 <cookie_mask>10</cookie_mask>
217 <out_port>10</out_port>
218 <installHw>false</installHw>
219 <out_group>2</out_group>
226 <ipv4-destination>10.0.0.1/24</ipv4-destination>
228 <hard-timeout>0</hard-timeout>
230 <idle-timeout>0</idle-timeout>
231 <flow-name>FooXf22</flow-name>
232 <priority>2</priority>
233 <barrier>false</barrier>
238 Status: 204 No Content
241 . Change _strict_ to _true_ in the previous flow.
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
250 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
252 xmlns="urn:opendaylight:flow:inventory">
253 <strict>true</strict>
265 <table_id>2</table_id>
267 <cookie_mask>10</cookie_mask>
268 <out_port>10</out_port>
269 <installHw>false</installHw>
270 <out_group>2</out_group>
277 <ipv4-destination>10.0.0.1/24</ipv4-destination>
279 <hard-timeout>0</hard-timeout>
281 <idle-timeout>0</idle-timeout>
282 <flow-name>FooXf22</flow-name>
283 <priority>2</priority>
284 <barrier>false</barrier>
292 . Show flow: check that _strict_ is _true_.
297 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
298 Accept: application/xml
306 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
308 xmlns="urn:opendaylight:flow:inventory">
309 <strict>true</strict>
321 <table_id>2</table_id>
323 <cookie_mask>10</cookie_mask>
324 <out_port>10</out_port>
325 <installHw>false</installHw>
326 <out_group>2</out_group>
333 <ipv4-destination>10.0.0.1/24</ipv4-destination>
335 <hard-timeout>0</hard-timeout>
337 <idle-timeout>0</idle-timeout>
338 <flow-name>FooXf22</flow-name>
339 <priority>2</priority>
340 <barrier>false</barrier>
344 . Delete the flow created.
349 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111