Updated Branches: refs/heads/0.1.5 39c899d29 -> 02f4f70f0
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/02f4f70f/src/blur-gui/src/main/webapp/js/thrift.js ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/js/thrift.js b/src/blur-gui/src/main/webapp/js/thrift.js new file mode 100644 index 0000000..e8436b9 --- /dev/null +++ b/src/blur-gui/src/main/webapp/js/thrift.js @@ -0,0 +1,775 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +var Thrift = { + Version: '0.9.0', +/* + Description: 'JavaScript bindings for the Apache Thrift RPC system', + License: 'http://www.apache.org/licenses/LICENSE-2.0', + Homepage: 'http://thrift.apache.org', + BugReports: 'https://issues.apache.org/jira/browse/THRIFT', + Maintainer: '[email protected]', +*/ + + Type: { + 'STOP' : 0, + 'VOID' : 1, + 'BOOL' : 2, + 'BYTE' : 3, + 'I08' : 3, + 'DOUBLE' : 4, + 'I16' : 6, + 'I32' : 8, + 'I64' : 10, + 'STRING' : 11, + 'UTF7' : 11, + 'STRUCT' : 12, + 'MAP' : 13, + 'SET' : 14, + 'LIST' : 15, + 'UTF8' : 16, + 'UTF16' : 17 + }, + + MessageType: { + 'CALL' : 1, + 'REPLY' : 2, + 'EXCEPTION' : 3 + }, + + objectLength: function(obj) { + var length = 0; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + length++; + } + } + + return length; + }, + + inherits: function(constructor, superConstructor) { + //Prototypal Inheritance http://javascript.crockford.com/prototypal.html + function F() {} + F.prototype = superConstructor.prototype; + constructor.prototype = new F(); + } +}; + + + +Thrift.TException = function(message) { + this.message = message; +}; +Thrift.inherits(Thrift.TException, Error); +Thrift.TException.prototype.name = 'TException'; + +Thrift.TApplicationExceptionType = { + 'UNKNOWN' : 0, + 'UNKNOWN_METHOD' : 1, + 'INVALID_MESSAGE_TYPE' : 2, + 'WRONG_METHOD_NAME' : 3, + 'BAD_SEQUENCE_ID' : 4, + 'MISSING_RESULT' : 5, + 'INTERNAL_ERROR' : 6, + 'PROTOCOL_ERROR' : 7 +}; + +Thrift.TApplicationException = function(message, code) { + this.message = message; + this.code = (code === null) ? 0 : code; +}; +Thrift.inherits(Thrift.TApplicationException, Thrift.TException); +Thrift.TApplicationException.prototype.name = 'TApplicationException'; + +Thrift.TApplicationException.prototype.read = function(input) { + while (1) { + var ret = input.readFieldBegin(); + + if (ret.ftype == Thrift.Type.STOP) { + break; + } + + var fid = ret.fid; + + switch (fid) { + case 1: + if (ret.ftype == Thrift.Type.STRING) { + ret = input.readString(); + this.message = ret.value; + } else { + ret = input.skip(ret.ftype); + } + break; + case 2: + if (ret.ftype == Thrift.Type.I32) { + ret = input.readI32(); + this.code = ret.value; + } else { + ret = input.skip(ret.ftype); + } + break; + default: + ret = input.skip(ret.ftype); + break; + } + + input.readFieldEnd(); + } + + input.readStructEnd(); +}; + +Thrift.TApplicationException.prototype.write = function(output) { + var xfer = 0; + + output.writeStructBegin('TApplicationException'); + + if (this.message) { + output.writeFieldBegin('message', Thrift.Type.STRING, 1); + output.writeString(this.getMessage()); + output.writeFieldEnd(); + } + + if (this.code) { + output.writeFieldBegin('type', Thrift.Type.I32, 2); + output.writeI32(this.code); + output.writeFieldEnd(); + } + + output.writeFieldStop(); + output.writeStructEnd(); +}; + +Thrift.TApplicationException.prototype.getCode = function() { + return this.code; +}; + +Thrift.TApplicationException.prototype.getMessage = function() { + return this.message; +}; + +/** + *If you do not specify a url then you must handle ajax on your own. + *This is how to use js bindings in a async fashion. + */ +Thrift.Transport = function(url) { + this.url = url; + this.wpos = 0; + this.rpos = 0; + + this.send_buf = ''; + this.recv_buf = ''; +}; + +Thrift.Transport.prototype = { + + //Gets the browser specific XmlHttpRequest Object + getXmlHttpRequestObject: function() { + try { return new XMLHttpRequest(); } catch (e1) { } + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { } + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { } + + throw "Your browser doesn't support the XmlHttpRequest object."; + }, + + flush: function(async) { + //async mode + if (async || this.url === undefined || this.url === '') { + return this.send_buf; + } + + var xreq = this.getXmlHttpRequestObject(); + + if (xreq.overrideMimeType) { + xreq.overrideMimeType('application/json'); + } + + xreq.open('POST', this.url, false); + xreq.send(this.send_buf); + + if (xreq.readyState != 4) { + throw 'encountered an unknown ajax ready state: ' + xreq.readyState; + } + + if (xreq.status != 200) { + throw 'encountered a unknown request status: ' + xreq.status; + } + + this.recv_buf = xreq.responseText; + this.recv_buf_sz = this.recv_buf.length; + this.wpos = this.recv_buf.length; + this.rpos = 0; + }, + + jqRequest: function(client, postData, args, recv_method) { + if (typeof jQuery === 'undefined' || + typeof jQuery.Deferred === 'undefined') { + throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests'; + } + + var thriftTransport = this; + + var jqXHR = jQuery.ajax({ + url: this.url, + data: postData, + type: 'POST', + cache: false, + dataType: 'text thrift', + converters: { + 'text thrift' : function(responseData) { + thriftTransport.setRecvBuffer(responseData); + var value = recv_method.call(client); + return value; + } + }, + context: client, + success: jQuery.makeArray(args).pop() + }); + + return jqXHR; + }, + + setRecvBuffer: function(buf) { + this.recv_buf = buf; + this.recv_buf_sz = this.recv_buf.length; + this.wpos = this.recv_buf.length; + this.rpos = 0; + }, + + isOpen: function() { + return true; + }, + + open: function() {}, + + close: function() {}, + + read: function(len) { + var avail = this.wpos - this.rpos; + + if (avail === 0) { + return ''; + } + + var give = len; + + if (avail < len) { + give = avail; + } + + var ret = this.read_buf.substr(this.rpos, give); + this.rpos += give; + + //clear buf when complete? + return ret; + }, + + readAll: function() { + return this.recv_buf; + }, + + write: function(buf) { + this.send_buf = buf; + }, + + getSendBuffer: function() { + return this.send_buf; + } + +}; + + + +Thrift.Protocol = function(transport) { + this.transport = transport; +}; + +Thrift.Protocol.Type = {}; +Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"'; +Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"'; +Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"'; +Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"'; +Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"'; +Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"'; +Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"'; +Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"'; +Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"'; +Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"'; +Thrift.Protocol.Type[Thrift.Type.SET] = '"set"'; + + +Thrift.Protocol.RType = {}; +Thrift.Protocol.RType.tf = Thrift.Type.BOOL; +Thrift.Protocol.RType.i8 = Thrift.Type.BYTE; +Thrift.Protocol.RType.i16 = Thrift.Type.I16; +Thrift.Protocol.RType.i32 = Thrift.Type.I32; +Thrift.Protocol.RType.i64 = Thrift.Type.I64; +Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE; +Thrift.Protocol.RType.rec = Thrift.Type.STRUCT; +Thrift.Protocol.RType.str = Thrift.Type.STRING; +Thrift.Protocol.RType.map = Thrift.Type.MAP; +Thrift.Protocol.RType.lst = Thrift.Type.LIST; +Thrift.Protocol.RType.set = Thrift.Type.SET; + +Thrift.Protocol.Version = 1; + +Thrift.Protocol.prototype = { + + getTransport: function() { + return this.transport; + }, + + //Write functions + writeMessageBegin: function(name, messageType, seqid) { + this.tstack = []; + this.tpos = []; + + this.tstack.push([Thrift.Protocol.Version, '"' + + name + '"', messageType, seqid]); + }, + + writeMessageEnd: function() { + var obj = this.tstack.pop(); + + this.wobj = this.tstack.pop(); + this.wobj.push(obj); + + this.wbuf = '[' + this.wobj.join(',') + ']'; + + this.transport.write(this.wbuf); + }, + + + writeStructBegin: function(name) { + this.tpos.push(this.tstack.length); + this.tstack.push({}); + }, + + writeStructEnd: function() { + + var p = this.tpos.pop(); + var struct = this.tstack[p]; + var str = '{'; + var first = true; + for (var key in struct) { + if (first) { + first = false; + } else { + str += ','; + } + + str += key + ':' + struct[key]; + } + + str += '}'; + this.tstack[p] = str; + }, + + writeFieldBegin: function(name, fieldType, fieldId) { + this.tpos.push(this.tstack.length); + this.tstack.push({ 'fieldId': '"' + + fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType] + }); + + }, + + writeFieldEnd: function() { + var value = this.tstack.pop(); + var fieldInfo = this.tstack.pop(); + + this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' + + fieldInfo.fieldType + ':' + value + '}'; + this.tpos.pop(); + }, + + writeFieldStop: function() { + //na + }, + + writeMapBegin: function(keyType, valType, size) { + //size is invalid, we'll set it on end. + this.tpos.push(this.tstack.length); + this.tstack.push([Thrift.Protocol.Type[keyType], + Thrift.Protocol.Type[valType], 0]); + }, + + writeMapEnd: function() { + var p = this.tpos.pop(); + + if (p == this.tstack.length) { + return; + } + + if ((this.tstack.length - p - 1) % 2 !== 0) { + this.tstack.push(''); + } + + var size = (this.tstack.length - p - 1) / 2; + + this.tstack[p][this.tstack[p].length - 1] = size; + + var map = '}'; + var first = true; + while (this.tstack.length > p + 1) { + var v = this.tstack.pop(); + var k = this.tstack.pop(); + if (first) { + first = false; + } else { + map = ',' + map; + } + + if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings + map = k + ':' + v + map; + } + map = '{' + map; + + this.tstack[p].push(map); + this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + }, + + writeListBegin: function(elemType, size) { + this.tpos.push(this.tstack.length); + this.tstack.push([Thrift.Protocol.Type[elemType], size]); + }, + + writeListEnd: function() { + var p = this.tpos.pop(); + + while (this.tstack.length > p + 1) { + var tmpVal = this.tstack[p + 1]; + this.tstack.splice(p + 1, 1); + this.tstack[p].push(tmpVal); + } + + this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + }, + + writeSetBegin: function(elemType, size) { + this.tpos.push(this.tstack.length); + this.tstack.push([Thrift.Protocol.Type[elemType], size]); + }, + + writeSetEnd: function() { + var p = this.tpos.pop(); + + while (this.tstack.length > p + 1) { + var tmpVal = this.tstack[p + 1]; + this.tstack.splice(p + 1, 1); + this.tstack[p].push(tmpVal); + } + + this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + }, + + writeBool: function(value) { + this.tstack.push(value ? 1 : 0); + }, + + writeByte: function(i8) { + this.tstack.push(i8); + }, + + writeI16: function(i16) { + this.tstack.push(i16); + }, + + writeI32: function(i32) { + this.tstack.push(i32); + }, + + writeI64: function(i64) { + this.tstack.push(i64); + }, + + writeDouble: function(dbl) { + this.tstack.push(dbl); + }, + + writeString: function(str) { + // We do not encode uri components for wire transfer: + if (str === null) { + this.tstack.push(null); + } else { + // concat may be slower than building a byte buffer + var escapedString = ''; + for (var i = 0; i < str.length; i++) { + var ch = str.charAt(i); // a single double quote: " + if (ch === '\"') { + escapedString += '\\\"'; // write out as: \" + } else if (ch === '\\') { // a single backslash: \ + escapedString += '\\\\'; // write out as: \\ + /* Currently escaped forward slashes break TJSONProtocol. + * As it stands, we can simply pass forward slashes into + * our strings across the wire without being escaped. + * I think this is the protocol's bug, not thrift.js + * } else if(ch === '/') { // a single forward slash: / + * escapedString += '\\/'; // write out as \/ + * } + */ + } else if (ch === '\b') { // a single backspace: invisible + escapedString += '\\b'; // write out as: \b" + } else if (ch === '\f') { // a single formfeed: invisible + escapedString += '\\f'; // write out as: \f" + } else if (ch === '\n') { // a single newline: invisible + escapedString += '\\n'; // write out as: \n" + } else if (ch === '\r') { // a single return: invisible + escapedString += '\\r'; // write out as: \r" + } else if (ch === '\t') { // a single tab: invisible + escapedString += '\\t'; // write out as: \t" + } else { + escapedString += ch; // Else it need not be escaped + } + } + this.tstack.push('"' + escapedString + '"'); + } + }, + + writeBinary: function(str) { + this.writeString(str); + }, + + + + // Reading functions + readMessageBegin: function(name, messageType, seqid) { + this.rstack = []; + this.rpos = []; + + if (typeof jQuery !== 'undefined') { + this.robj = jQuery.parseJSON(this.transport.readAll()); + } else { + this.robj = eval(this.transport.readAll()); + } + + var r = {}; + var version = this.robj.shift(); + + if (version != Thrift.Protocol.Version) { + throw 'Wrong thrift protocol version: ' + version; + } + + r.fname = this.robj.shift(); + r.mtype = this.robj.shift(); + r.rseqid = this.robj.shift(); + + + //get to the main obj + this.rstack.push(this.robj.shift()); + + return r; + }, + + readMessageEnd: function() { + }, + + readStructBegin: function(name) { + var r = {}; + r.fname = ''; + + //incase this is an array of structs + if (this.rstack[this.rstack.length - 1] instanceof Array) { + this.rstack.push(this.rstack[this.rstack.length - 1].shift()); + } + + return r; + }, + + readStructEnd: function() { + if (this.rstack[this.rstack.length - 2] instanceof Array) { + this.rstack.pop(); + } + }, + + readFieldBegin: function() { + var r = {}; + + var fid = -1; + var ftype = Thrift.Type.STOP; + + //get a fieldId + for (var f in (this.rstack[this.rstack.length - 1])) { + if (f === null) { + continue; + } + + fid = parseInt(f, 10); + this.rpos.push(this.rstack.length); + + var field = this.rstack[this.rstack.length - 1][fid]; + + //remove so we don't see it again + delete this.rstack[this.rstack.length - 1][fid]; + + this.rstack.push(field); + + break; + } + + if (fid != -1) { + + //should only be 1 of these but this is the only + //way to match a key + for (var i in (this.rstack[this.rstack.length - 1])) { + if (Thrift.Protocol.RType[i] === null) { + continue; + } + + ftype = Thrift.Protocol.RType[i]; + this.rstack[this.rstack.length - 1] = + this.rstack[this.rstack.length - 1][i]; + } + } + + r.fname = ''; + r.ftype = ftype; + r.fid = fid; + + return r; + }, + + readFieldEnd: function() { + var pos = this.rpos.pop(); + + //get back to the right place in the stack + while (this.rstack.length > pos) { + this.rstack.pop(); + } + + }, + + readMapBegin: function(keyType, valType, size) { + var map = this.rstack.pop(); + + var r = {}; + r.ktype = Thrift.Protocol.RType[map.shift()]; + r.vtype = Thrift.Protocol.RType[map.shift()]; + r.size = map.shift(); + + + this.rpos.push(this.rstack.length); + this.rstack.push(map.shift()); + + return r; + }, + + readMapEnd: function() { + this.readFieldEnd(); + }, + + readListBegin: function(elemType, size) { + var list = this.rstack[this.rstack.length - 1]; + + var r = {}; + r.etype = Thrift.Protocol.RType[list.shift()]; + r.size = list.shift(); + + this.rpos.push(this.rstack.length); + this.rstack.push(list); + + return r; + }, + + readListEnd: function() { + this.readFieldEnd(); + }, + + readSetBegin: function(elemType, size) { + return this.readListBegin(elemType, size); + }, + + readSetEnd: function() { + return this.readListEnd(); + }, + + readBool: function() { + var r = this.readI32(); + + if (r !== null && r.value == '1') { + r.value = true; + } else { + r.value = false; + } + + return r; + }, + + readByte: function() { + return this.readI32(); + }, + + readI16: function() { + return this.readI32(); + }, + + readI32: function(f) { + if (f === undefined) { + f = this.rstack[this.rstack.length - 1]; + } + + var r = {}; + + if (f instanceof Array) { + if (f.length === 0) { + r.value = undefined; + } else { + r.value = f.shift(); + } + } else if (f instanceof Object) { + for (var i in f) { + if (i === null) { + continue; + } + this.rstack.push(f[i]); + delete f[i]; + + r.value = i; + break; + } + } else { + r.value = f; + this.rstack.pop(); + } + + return r; + }, + + readI64: function() { + return this.readI32(); + }, + + readDouble: function() { + return this.readI32(); + }, + + readString: function() { + var r = this.readI32(); + return r; + }, + + readBinary: function() { + return this.readString(); + }, + + + //Method to arbitrarily skip over data. + skip: function(type) { + throw 'skip not supported yet'; + } +}; http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/02f4f70f/src/blur-gui/src/main/webapp/thrift_prototype.html ---------------------------------------------------------------------- diff --git a/src/blur-gui/src/main/webapp/thrift_prototype.html b/src/blur-gui/src/main/webapp/thrift_prototype.html new file mode 100644 index 0000000..c56a1b2 --- /dev/null +++ b/src/blur-gui/src/main/webapp/thrift_prototype.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> +<head> +<title>Blur</title> +<meta charset="utf-8"> +<link href="css/bootstrap.min.css" rel="stylesheet"> +</head> + +<script src="js/jquery-1.9.1.min.js"></script> +<script src="js/thrift.js"></script> +<script src="js/Blur.js"></script> +<script src="js/Blur_types.js"></script> +<body> + +<table> +<thead> +<tr> +<th>Table Name</th> +<th>ReadOnly</th> +<th>Cluster</th> +<th>Enabled</th> +<th>Shard Count</th> +<th>Table Uri</th> +</tr> +</thead> +<tbody id="blurtables_tbody"> + +</tbody> +</table> +</body> +<script> +function go() { + var transport = new Thrift.Transport("/blur"); + var protocol = new Thrift.Protocol(transport); + var client = new BlurClient(protocol); + + try { + var result = client.tableList(); + for (var i = 0; i < result.length; i++) { + var tableName = result[i]; + var tableDescriptor = client.describe(tableName) + $("#blurtables_tbody").append( + "<tr>"+ + "<td>"+tableDescriptor.name+"</td>"+ + "<td>"+tableDescriptor.readOnly+"</td>"+ + "<td>"+tableDescriptor.cluster+"</td>"+ + "<td>"+tableDescriptor.isEnabled+"</td>"+ + "<td>"+tableDescriptor.shardCount+"</td>"+ + "<td>"+tableDescriptor.tableUri+"</td>"+ + "</tr>"); + } + } catch(ouch){ +alert (ouch); + } +} + +go(); +</script> +</html> \ No newline at end of file
