SPEC.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. # Licensed to the Apache Software Foundation (ASF) under one or more
  2. # contributor license agreements. See the NOTICE file distributed with
  3. # this work for additional information regarding copyright ownership.
  4. # The ASF licenses this file to You under the Apache License, Version 2.0
  5. # (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. A REST HTTP gateway for ZooKeeper
  16. =================================
  17. Specification Version: 2
  18. ZooKeeper is meant to enable distributed coordination and also store
  19. system configuration and other relatively small amounts of information
  20. that must be stored in a persistent and consistent manner. The
  21. information stored in ZooKeeper is meant to be highly available to a
  22. large number of nodes in a distributed-computing cluster.
  23. ZooKeeper offers a client-side library that supports rich semantics
  24. that include strict ordering guarantees on operations, the creation of
  25. ephemeral znodes, and the ability to watch for changes to state.
  26. However, where clients need simple "CRUD" (create, read, update,
  27. delete) operations, the ZooKeeper libraries can be cumbersome, both to
  28. the programmers who have to use them (who are increasingly used to
  29. REST-style APIs), and to the operators who have to deploy and update
  30. them (for whom deploying and updating client libraries can be very
  31. painful).
  32. It turns out that most languages comes with client libraries for HTTP
  33. that are easy and familiar to program against, and deployed as part of
  34. the language runtime. Thus, for simple CRUD clients, an HTTP gateway
  35. would be a less cumbersome interface than the ZooKeeper library.
  36. This document describes a gateway for using HTTP to interact with a
  37. ZooKeeper repository.
  38. Binding ZooKeeper to HTTP
  39. -------------------------
  40. Encoding
  41. --------
  42. UTF-8 unless otherwise noted
  43. Paths
  44. -----
  45. A ZooKeeper paths are mapped to IRIs and URIs as follows. ZK paths
  46. are converted to IRIs by simply percent-encoding any characters in the
  47. ZK path that are not allowed in IRI paths. ZK paths are converted to
  48. URIs by mapping them first to IRIs, then converting to URIs in the
  49. standard way.
  50. Going from URIs and IRIs is the reverse of the above but for one
  51. difference: any "." and ".." segments in an IRI or URI must be folded
  52. before conversion. (Fortunately, ZK does not allow "." and ".."
  53. segments in its paths.)
  54. ZK and IRIs recommend the same practices when it comes to Unicode
  55. normalization: ultimately, normalization is left to application
  56. designers, but both recommend that application designers use NFC as a
  57. best practice.
  58. Root
  59. ----
  60. The following examples assume that the ZooKeeper znode hierarchy is
  61. bound to the root of the HTTP servers namespace. This may not be the
  62. case in practice however, the gateway may bind to some prefix, for
  63. example the URL for accessing /a/b/c may be:
  64. http://localhost/zookeeper/znodes/v1/a/b/c
  65. This is perfectly valid. Users of the REST service should be aware of
  66. this fact and code their clients to support any root (in this case
  67. "/zookeeper" on the server localhost).
  68. Basics: GET, PUT, HEAD, and DELETE
  69. ----------------------------------
  70. HTTP's GET, PUT, HEAD, and DELETE operations map naturally to
  71. ZooKeeper's "get," "set," "exists," and "delete" operations.
  72. ZooKeeper znodes have a version number that changes each time the
  73. znode's value is updated. This number is returned by "get," "set," and
  74. "exists" operations. The "set" and "delete" operations optionally take
  75. a version number. If one is supplied, then "set" or "delete" will fail
  76. if the current version of the znode doesn't match the version-number
  77. supplied in the call. This mechanism supports atomic read-modify-write
  78. cycles. Set/delete requests may include an optional parameter
  79. "version" which defaults to no version check.
  80. Getting ZooKeeper children
  81. --------------------------
  82. We overload the GET method to return the children of a ZooKeeper. In
  83. particular, the GET method takes an optional parameter "view" which
  84. could be set to one of type values, either "data" or "children". The
  85. default is "data". Thus, to get the children of a znode named
  86. "/a/b/c", then the GET request should start:
  87. GET /znodes/v1/a/b/c?view=children HTTP/1.1
  88. If the requested view is "data", then the data of a znode is returned
  89. as described in the previous section. If the requested view is
  90. "children", then a list of children is returned in either an XML
  91. document, or in a JSON object. (The default is JSON, but this can be
  92. controlled changed by setting the Accept header.)
  93. Creating a ZooKeeper session
  94. ----------------------------
  95. In order to be able to create ephemeral nodes you first need to start
  96. a new session.
  97. POST /sessions/v1?op=create&expire=<SECONDS> HTTP/1.1
  98. If the session creation is successful, then a 201 code will be returned.
  99. A session is just a UUID that you can pass around as a parameter and
  100. the REST server will forward your request on the attached persistent
  101. connection.
  102. Keeping a session alive
  103. -----------------------
  104. To keep a session alive you must send heartbeat requests:
  105. PUT /sessions/v1/<SESSION-UUID> HTTP/1.1
  106. Closing a ZooKeeper session
  107. ---------------------------
  108. You can close a connection by sending a DELETE request.
  109. DELETE /sessions/v1/<SESSION-UUID> HTTP/1.1
  110. If you don't close a session it will automatically expire after
  111. the amount of time you specified on creation.
  112. Creating a ZooKeeper znode
  113. --------------------------
  114. We use the POST method to create a ZooKeeper znode. For example, to
  115. create a znode named "c" under a parent named "/a/b", then the POST
  116. request should start:
  117. POST /znodes/v1/a/b?op=create&name=c HTTP/1.1
  118. If the creation is successful, then a 201 code will be returned. If
  119. it fails, then a number of different codes might be returned
  120. (documented in a later subsection).
  121. ZooKeeper's create operation has a flag that tells the server to
  122. append a sequence-number to the client-supplied znode-name in order to
  123. make the znode-name unique. If you set this flag and ask to create a
  124. znode named "/a/b/c", and a znode named "/a/b" already exists, then
  125. "create" will create a znode named "/a/b/c-#" instead, where "#" is and
  126. integer required to generate a unique name in for format %10d.
  127. To obtain this behavior, an additional "sequence=true" parameter
  128. should be added to the parameters of the POST. (Note that "sequence"
  129. is an optional parameter, that defaults to "false"; this default may
  130. be provided explicitly if desired.)
  131. On success the actual path of the created znode will be returned.
  132. If you want to create an ephemeral node you need to specify an
  133. additional "ephemeral=true" parameter. (Note that "ephemeral" is an optional
  134. parameter, that defaults to "false")
  135. (Note: ZooKeeper also allows the client to set ACLs for the
  136. newly-created znode. This feature is not currently supported by the
  137. HTTP gateway to ZooKeeper.)
  138. Content types and negotiation
  139. -----------------------------
  140. ZooKeeper REST gateway implementations may support three content-types
  141. for request and response messages:
  142. * application/octet-stream
  143. HEAD - returns nothing (note below: status = 204)
  144. GET - returns the znode data as an octet-stream
  145. PUT - send binary data, returns nothing
  146. POST - send binary data, returns the name of the znode
  147. DELETE - returns nothing
  148. For PUT and HEAD some other content-type (i.e. JSON or XML) must be
  149. used to access the Stat information of a znode.
  150. * application/json, application/javascript & application/xml
  151. HEAD - returns nothing
  152. GET - returns a STAT or CHILD structure
  153. PUT - send binary data, returns a STAT structure (sans data field)
  154. POST - send binary data, returns a PATH structure
  155. DELETE - returns nothing
  156. (structures defined below)
  157. Results returning DATA may include an optional "dataformat"
  158. parameter which has two possible values; base64 (default) or
  159. utf8. This allows the caller to control the format of returned data
  160. and may simplify usage -- for example cat'ing results to the command
  161. line with something like curl, or accessing a url through a browser.
  162. Care should be exercised however, if utf8 is used on non character
  163. data errors may result.
  164. "application/javascript" requests may include an optional "callback"
  165. parameter. The response is wrapped in a callback method of your
  166. choice. e.g. appending &callback=foo to your request will result in
  167. a response body of: foo(...). Callbacks may only contain
  168. alphanumeric characters and underscores.
  169. PATH
  170. path : string
  171. uri: string
  172. path is the full path to the znode as seen by ZooKeeper
  173. uri is the full URI of the znode as seen by the REST server, does not
  174. include any query parameters (i.e. it's the path to the REST resource)
  175. SESSION
  176. id : string UUID
  177. uri : string
  178. CHILD
  179. PATH
  180. child_uri_template: string
  181. children : [ string* ]
  182. The children list of strings contains only the name of the child
  183. znodes, not the full path.
  184. child_uri_template is a template for URI of child znodes as seen by the
  185. REST server. e.g. "http://localhost:9998/znodes/v1/foo/{child}", where
  186. foo is the parent node, and {child} can be substituted with the name
  187. of each child in the children array in order to access that resource.
  188. This template is provided to simplify child access.
  189. STAT
  190. PATH
  191. encoding : value of "base64" or "utf8"
  192. data : base64 or utf8 encoded string
  193. stat :
  194. czxid : number
  195. mzxid : number
  196. ctime : number
  197. mtime : number
  198. version : number
  199. cversion : number
  200. aversion : number
  201. ephemeralOwner : number
  202. datalength : number
  203. numChildren : number
  204. pzxid : number
  205. Error Codes
  206. -----------
  207. The ZooKeeper gateway uses HTTP response codes as follows:
  208. * 200 (Success) - ZOK for "get" "set" "delete", "yes" case of "exists" (json/xml)
  209. * 201 (Created) - ZOK for "create"
  210. * 204 (No Content) - ZOK for "yes" case of "exists" (octet)
  211. * 400 (Bad Request) - ZINVALIDACL, ZBADARGUMENTS, version param not a number
  212. * 401 (Unauthorized) - ZAUTHFAILED
  213. * 404 (Not Found) - ZOK for "no" case of "exists;" ZNONODE for "get," "set," and "delete"
  214. * 409 (Conflict) - ZNODEEXISTS, ZNONODE for "create," ZNOTEMPTY,
  215. * 412 (Precondition Failed) - ZBADVERSION
  216. * 415 (Unsupported Media Type) - if content-type of PUT or POST is not "application/octet-stream"
  217. * 500 (Internal Server Error) - Failure in gateway code
  218. * 501 (Not Implemented) - HTTP method other than GET, PUT, HEAD, DELETE
  219. * 502 (Bad Gateway) - All other ZooKeeper error codes
  220. * 503 (Service Unavailable) - ZSESSIONEXPIRED, ZCONNECTIONLOSS, (gateway will try to reestablish the connection, but will not hold the request waiting...)
  221. * 504 (Gateway Timeout) - ZOPERATIONTIMEOUT, or ZooKeeper does not return in a timely manner
  222. Note that these are the codes used by the HTTP-to-Gateway software
  223. itself. Depending on how this software is configured into a Web
  224. server, the resulting Web Server might behave differently, e.g., it
  225. might do redirection, check other headers, etc.
  226. Error Messages
  227. --------------
  228. Error messages are returned to the caller, format is dependent on the
  229. format requested in the call.
  230. * application/octet-stream
  231. A string containing the error message. It should include the request
  232. and information detailing the reason for the error.
  233. * application/json
  234. { "request":"GET /a/b/c", "message":"Node doesn't exist" }
  235. * application/xml
  236. <?xml version="1.0" encoding="UTF-8"?>
  237. <error>
  238. <request>GET /a/b/c</request>
  239. <message>Node doesn't exist</message>
  240. </error>
  241. Binding ZooKeeper to an HTTP server
  242. -----------------------------------
  243. It might be sage to assume that everyone is happy to run an Apache
  244. server, and thus write a "mod_zookeeper" for Apache that works only
  245. for the Apache Web Server. However, different operational
  246. environments prefer different Web Servers, and it would be nice to
  247. support more than one Web server.
  248. Issues:
  249. * Configuration.
  250. * Defining a root: Need to provide a URL alias and associate it
  251. with a server. Need to be able to map different aliases to
  252. different servers (implemented via multiple ZK connections).
  253. * Sharing connection across multiple processes.
  254. * Asynchronous.
  255. * Adaptors.
  256. * Code re-use.
  257. Authentication -- TBD, not currently supported
  258. ...the config file should contain authentication material for the gateway
  259. ...the config file should contain an ACL list to be passed along to "create"
  260. ...would we ever want to authenticate each request to ZooKeeper?...