;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Lolevel binding to the HBase Stargate REST API ;;; http://wiki.apache.org/hadoop/Hbase/Stargate ;;; ;;; Copyright (C) 2015, Andy Bennett, Skipjaq Inc. ;;; All rights reserved. ;;; ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions are met: ;;; ;;; Redistributions of source code must retain the above copyright notice, this ;;; list of conditions and the following disclaimer. ;;; Redistributions in binary form must reproduce the above copyright notice, ;;; this list of conditions and the following disclaimer in the documentation ;;; and/or other materials provided with the distribution. ;;; Neither the name of the author nor the names of its contributors may be ;;; used to endorse or promote products derived from this software without ;;; specific prior written permission. ;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE ;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ;;; POSSIBILITY OF SUCH DAMAGE. ;;; ;;; Andy Bennett , 2015/06 ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (module stargate-lolevel (tables schema metadata single-cell single-cell-by-ts create-scanner scanner-get-next delete-scanner) (import chicken scheme) ; Units - http://api.call-cc.org/doc/chicken/language (use data-structures extras) ; Eggs - http://wiki.call-cc.org/chicken-projects/egg-index-4.html (use rest-bind http-client intarweb uri-common medea) (define *base-uri* (uri-reference "http://localhost:8080")) ;;;;;;;;;; ;;; Faster read-u8vector from sjamaan (use extras srfi-4) (define (read-u8vector #!optional n (p ##sys#standard-input)) (let ((str (##sys#read-string/port n p))) (##core#inline "C_string_to_bytevector" str) (##sys#make-structure 'u8vector str))) ;;;;;;;;;; (define (relative-uri str) (uri-relative-to *base-uri* (uri-reference str))) (define (make-json-request method a-relative-uri) (make-request uri: (relative-uri a-relative-uri) method: method headers: (headers '((accept #(application/json ((1 . 0.5)))))))) (define (make-octet-stream-request method a-relative-uri) (make-request uri: (relative-uri a-relative-uri) method: method major: 1 minor: 0 headers: (headers '((accept #(application/octet-stream ((1 . 0.5)))))))) ; Query Table List ; http://wiki.apache.org/hadoop/Hbase/Stargate#Query_Table_List ; Retrieves the list of available tables. ; ; The rest-bind body-reader decodes ; {"Table":[{"name":"content"},{"name":"urls"}]} ; to a list of strings representing the relative urls of the tables. (define-method (tables) (make-json-request 'GET "/") #f (lambda (port) (map cdar (vector->list (alist-ref 'table (read-json port)))))) ; Query Table Schema ; http://wiki.apache.org/hadoop/Hbase/Stargate#Query_Table_Schema ; Retrieves table schema. (define-method (schema table "schema") (make-json-request 'GET "/") #f read-json) ; Query Table Metadata ; http://wiki.apache.org/hadoop/Hbase/Stargate#Query_Table_Metadata ; Retrieves table region metadata. (define-method (metadata table "regions") (make-json-request 'GET "/") #f read-json) ; Cell Query (Single Value) ; http://wiki.apache.org/hadoop/Hbase/Stargate#Cell_Query_.28Single_Value.29 ; Retrieves one cell, with optional specification of timestamp. ; TODO: Read response headers (define-method (single-cell table row column #!key timestamp) (make-octet-stream-request 'GET "/") #f (cut read-string #f <>) identity) (define-method (single-cell-by-ts table row column timestamp) (make-octet-stream-request 'GET "/") #f (lambda (port) (string->blob (read-string #f port))) identity) ; Scanner Creation ; http://wiki.apache.org/hadoop/Hbase/Stargate#Scanner_Creation ; Allocates a new table scanner. If not successful, returns appropriate HTTP ; error status code. If successful, returns HTTP 201 status (created) and the ; URI which should be used to address the scanner. ; TODO: Read response headers (define-method (create-scanner table "scanner") (make-request uri: (relative-uri "/") method: 'PUT headers: (headers '((content-type #(text/xml ()))))) (lambda (_) "") (cut read-string #f <>) identity) ; Scanner Get Next ; http://wiki.apache.org/hadoop/Hbase/Stargate#Scanner_Get_Next ; Returns the values of the next cells found by the scanner, up to the ; configured batch amount. If result is successful but the scanner is ; exhausted, returns HTTP 204 status (no content). ; TODO: Read response headers. ; TODO: Deal with 204 (define-method (scanner-get-next table "scanner" scanner-id) (make-octet-stream-request 'GET "/") #f (lambda (port) ;(string->blob (read-string #f port))) (u8vector->blob/shared (read-u8vector #f port))) identity) ; Scanner Deletion ; http://wiki.apache.org/hadoop/Hbase/Stargate#Scanner_Deletion ; Deletes resources associated with the scanner. This is an optional action. ; Scanners will expire after some globally configurable interval has elapsed ; with no activity on the scanner. (define-method (delete-scanner table "scanner" scanner-id) (make-request uri: (relative-uri "/") method: 'DELETE) #f (lambda (port) (read-string #f port) #t)) ) ; (use stargate-lolevel) ; (tables)