python/thrift/appengine-ssl-gateway/appengine/bigtable.py (71 lines of code) (raw):

# Copyright 2016 Google Inc. # # Licensed 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. """Google App Engine application which connects to Google Cloud Bigtable via the HBase Thrift proxy servers.""" # Standard Python libraries. import os import happybase from happybase.hbase import Hbase from happybase.hbase import ttypes import jinja2 # Provided by App Engine. from thrift.transport.TSSLSocket import TSSLSocket import webapp2 # Provided by App Engine. JINJA_ENVIRONMENT = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), autoescape=True, extensions=['jinja2.ext.autoescape']) KEY_FILE = 'stunnel.pem' class SecureConnection(happybase.Connection): def _refresh_thrift_client(self): """Refresh the Thrift socket, transport, and client.""" socket = TSSLSocket( self.host, self.port, False, KEY_FILE, KEY_FILE, KEY_FILE) if self.timeout is not None: socket.setTimeout(self.timeout) self.transport = self._transport_class(socket) protocol = self._protocol_class(self.transport) self.client = Hbase.Client(protocol) def CreateConnection(): # Change this to be your load balancer's IP address. # TODO: add automatic lookup, via Compute APIs? Cache results. return SecureConnection('<Thrift gateway load balancer IP>', 1090) class IndexHandler(webapp2.RequestHandler): def get(self): connection = CreateConnection() tables = connection.tables() variables = {'tables': tables} template = JINJA_ENVIRONMENT.get_template('web/index.jinja') self.response.write(template.render(variables)) class CreateTableHandler(webapp2.RequestHandler): def get(self): connection = CreateConnection() table = 'mytable' status = 'does not exist' try: connection.create_table( 'mytable', { 'cf1': dict(max_versions=10), 'cf2': dict(max_versions=1, block_cache_enabled=False), 'cf3': dict(), # use defaults }) status = 'was created' except ttypes.AlreadyExists: status = 'already exists' variables = {'table': table, 'status': status} template = JINJA_ENVIRONMENT.get_template('web/create.jinja') self.response.write(template.render(variables)) class DeleteTableHandler(webapp2.RequestHandler): def get(self): connection = CreateConnection() table = 'mytable' status = 'invalid' try: connection.delete_table(table, disable=True) status = 'deleted' except Exception as e: # FIXME(mbrukman): the actual exception thrown is IOError, but # trying to catch it specifically does not seem to work. notFound = 'TableNotFoundException: %s' % table if notFound in repr(e): status = 'not found' variables = {'table': table, 'status': status} template = JINJA_ENVIRONMENT.get_template('web/delete.jinja') self.response.write(template.render(variables)) app = webapp2.WSGIApplication( [ webapp2.Route('/', IndexHandler), webapp2.Route('/create', CreateTableHandler), webapp2.Route('/delete', DeleteTableHandler), ], debug=True)