From 7893dd02c15f2a727eb50887c9ddb829fc71f556 Mon Sep 17 00:00:00 2001 From: Ulas Kozat Date: Sun, 15 May 2016 21:31:15 -0700 Subject: [PATCH] Simple mapper/scheduler/partitioner functions implemented Change-Id: I553b196943022451d8dc4984fe37b2b228c8f4cf Signed-off-by: Ulas C. Kozat --- DominoClient.py | 302 ++++++ DominoServer.py | 287 ++++++ README.md | 28 + buildpy | 1 + domino.thrift | 214 ++++ lib/__init__.py | 0 lib/dominoRPC/Communication-remote | 129 +++ lib/dominoRPC/Communication.py | 1196 ++++++++++++++++++++++ lib/dominoRPC/Communication.pyc | Bin 0 -> 41494 bytes lib/dominoRPC/__init__.py | 1 + lib/dominoRPC/__init__.pyc | Bin 0 -> 181 bytes lib/dominoRPC/constants.py | 27 + lib/dominoRPC/constants.pyc | Bin 0 -> 719 bytes lib/dominoRPC/ttypes.py | 1435 +++++++++++++++++++++++++++ lib/dominoRPC/ttypes.pyc | Bin 0 -> 42261 bytes lib/mapper/__init__.py | 1 + lib/mapper/__init__.pyc | Bin 0 -> 142 bytes lib/mapper/label.py | 85 ++ lib/mapper/label.pyc | Bin 0 -> 1764 bytes lib/partitioner/__init__.py | 1 + lib/partitioner/__init__.pyc | Bin 0 -> 154 bytes lib/partitioner/constants.py | 7 + lib/partitioner/constants.pyc | Bin 0 -> 261 bytes lib/partitioner/partitioner.py | 112 +++ lib/partitioner/partitioner.pyc | Bin 0 -> 2745 bytes lib/thrift/TMultiplexedProcessor.py | 58 ++ lib/thrift/TSCons.py | 35 + lib/thrift/TSerialization.py | 38 + lib/thrift/TTornado.py | 182 ++++ lib/thrift/Thrift.py | 170 ++++ lib/thrift/Thrift.pyc | Bin 0 -> 4970 bytes lib/thrift/__init__.py | 20 + lib/thrift/__init__.pyc | Bin 0 -> 157 bytes lib/thrift/protocol/TBase.py | 81 ++ lib/thrift/protocol/TBinaryProtocol.py | 260 +++++ lib/thrift/protocol/TBinaryProtocol.pyc | Bin 0 -> 10720 bytes lib/thrift/protocol/TCompactProtocol.py | 405 ++++++++ lib/thrift/protocol/TJSONProtocol.py | 569 +++++++++++ lib/thrift/protocol/TMultiplexedProtocol.py | 39 + lib/thrift/protocol/TProtocol.py | 421 ++++++++ lib/thrift/protocol/TProtocol.pyc | Bin 0 -> 14621 bytes lib/thrift/protocol/TProtocolDecorator.py | 42 + lib/thrift/protocol/__init__.py | 20 + lib/thrift/protocol/__init__.pyc | Bin 0 -> 254 bytes lib/thrift/protocol/fastbinary.so | Bin 0 -> 49272 bytes lib/thrift/server/THttpServer.py | 87 ++ lib/thrift/server/TNonblockingServer.py | 348 +++++++ lib/thrift/server/TProcessPoolServer.py | 122 +++ lib/thrift/server/TServer.py | 279 ++++++ lib/thrift/server/TServer.pyc | Bin 0 -> 8801 bytes lib/thrift/server/__init__.py | 20 + lib/thrift/server/__init__.pyc | Bin 0 -> 177 bytes lib/thrift/transport/THttpClient.py | 151 +++ lib/thrift/transport/TSSLSocket.py | 227 +++++ lib/thrift/transport/TSocket.py | 180 ++++ lib/thrift/transport/TSocket.pyc | Bin 0 -> 5822 bytes lib/thrift/transport/TTransport.py | 446 +++++++++ lib/thrift/transport/TTransport.pyc | Bin 0 -> 17217 bytes lib/thrift/transport/TTwisted.py | 324 ++++++ lib/thrift/transport/TZlibTransport.py | 248 +++++ lib/thrift/transport/__init__.py | 20 + lib/thrift/transport/__init__.pyc | Bin 0 -> 213 bytes lib/util/__init__.py | 1 + lib/util/__init__.pyc | Bin 0 -> 158 bytes lib/util/miscutil.py | 12 + lib/util/miscutil.pyc | Bin 0 -> 345 bytes lib/util/netutil.py | 18 + lib/util/netutil.pyc | Bin 0 -> 516 bytes requirements.txt | 10 + tosca-templates/tosca_helloworld_nfv.yaml | 46 + 70 files changed, 8705 insertions(+) create mode 100755 DominoClient.py create mode 100755 DominoServer.py create mode 100644 README.md create mode 100755 buildpy create mode 100644 domino.thrift create mode 100644 lib/__init__.py create mode 100755 lib/dominoRPC/Communication-remote create mode 100644 lib/dominoRPC/Communication.py create mode 100644 lib/dominoRPC/Communication.pyc create mode 100644 lib/dominoRPC/__init__.py create mode 100644 lib/dominoRPC/__init__.pyc create mode 100644 lib/dominoRPC/constants.py create mode 100644 lib/dominoRPC/constants.pyc create mode 100644 lib/dominoRPC/ttypes.py create mode 100644 lib/dominoRPC/ttypes.pyc create mode 100644 lib/mapper/__init__.py create mode 100644 lib/mapper/__init__.pyc create mode 100644 lib/mapper/label.py create mode 100644 lib/mapper/label.pyc create mode 100644 lib/partitioner/__init__.py create mode 100644 lib/partitioner/__init__.pyc create mode 100644 lib/partitioner/constants.py create mode 100644 lib/partitioner/constants.pyc create mode 100644 lib/partitioner/partitioner.py create mode 100644 lib/partitioner/partitioner.pyc create mode 100644 lib/thrift/TMultiplexedProcessor.py create mode 100644 lib/thrift/TSCons.py create mode 100644 lib/thrift/TSerialization.py create mode 100644 lib/thrift/TTornado.py create mode 100644 lib/thrift/Thrift.py create mode 100644 lib/thrift/Thrift.pyc create mode 100644 lib/thrift/__init__.py create mode 100644 lib/thrift/__init__.pyc create mode 100644 lib/thrift/protocol/TBase.py create mode 100644 lib/thrift/protocol/TBinaryProtocol.py create mode 100644 lib/thrift/protocol/TBinaryProtocol.pyc create mode 100644 lib/thrift/protocol/TCompactProtocol.py create mode 100644 lib/thrift/protocol/TJSONProtocol.py create mode 100644 lib/thrift/protocol/TMultiplexedProtocol.py create mode 100644 lib/thrift/protocol/TProtocol.py create mode 100644 lib/thrift/protocol/TProtocol.pyc create mode 100644 lib/thrift/protocol/TProtocolDecorator.py create mode 100644 lib/thrift/protocol/__init__.py create mode 100644 lib/thrift/protocol/__init__.pyc create mode 100755 lib/thrift/protocol/fastbinary.so create mode 100644 lib/thrift/server/THttpServer.py create mode 100644 lib/thrift/server/TNonblockingServer.py create mode 100644 lib/thrift/server/TProcessPoolServer.py create mode 100644 lib/thrift/server/TServer.py create mode 100644 lib/thrift/server/TServer.pyc create mode 100644 lib/thrift/server/__init__.py create mode 100644 lib/thrift/server/__init__.pyc create mode 100644 lib/thrift/transport/THttpClient.py create mode 100644 lib/thrift/transport/TSSLSocket.py create mode 100644 lib/thrift/transport/TSocket.py create mode 100644 lib/thrift/transport/TSocket.pyc create mode 100644 lib/thrift/transport/TTransport.py create mode 100644 lib/thrift/transport/TTransport.pyc create mode 100644 lib/thrift/transport/TTwisted.py create mode 100644 lib/thrift/transport/TZlibTransport.py create mode 100644 lib/thrift/transport/__init__.py create mode 100644 lib/thrift/transport/__init__.pyc create mode 100644 lib/util/__init__.py create mode 100644 lib/util/__init__.pyc create mode 100644 lib/util/miscutil.py create mode 100644 lib/util/miscutil.pyc create mode 100644 lib/util/netutil.py create mode 100644 lib/util/netutil.pyc create mode 100644 requirements.txt create mode 100644 tosca-templates/tosca_helloworld_nfv.yaml diff --git a/DominoClient.py b/DominoClient.py new file mode 100755 index 0000000..a705288 --- /dev/null +++ b/DominoClient.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python + +# +# Licence statement goes here +# + +import sys, glob, threading +import getopt + +#sys.path.append('gen-py') +#sys.path.insert(0, glob.glob('./lib/py/build/lib.*')[0]) +sys.path.insert(0, glob.glob('./lib')[0]) + +from dominoRPC import Communication +from dominoRPC.ttypes import * +from dominoRPC.constants import * + +from thrift import Thrift +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol +from thrift.server import TServer + +from util import * + +CLIENT_UDID = 1 +CLIENT_SEQNO = 0 + +DOMINO_SERVER_IP = 'localhost' +DOMINO_SERVER_PORT = 9090 + +UDID_DESIRED = 12467 +LIST_SUPPORTED_TEMPLATES = ['tosca-nfv-v1.0'] +#DEFAULT_TOSCA_PUBFILE = './tosca-templates/tosca_simpleVNF.yaml' +DEFAULT_TOSCA_PUBFILE = './tosca-templates/tosca_helloworld_nfv.yaml' + +class CommunicationHandler: + def __init__(self): + self.log = {} + + def __init__(self, dominoclient): + global DOMINO_SERVER_IP, DOMINO_SERVER_PORT + self.log = {} + self.dominoClient = dominoclient + try: + # Make socket + transport = TSocket.TSocket(DOMINO_SERVER_IP, DOMINO_SERVER_PORT) + # Add buffering to compensate for slow raw sockets + self.transport = TTransport.TBufferedTransport(transport) + # Wrap in a protocol + self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport) + # Create a client to use the protocol encoder + self.sender = Communication.Client(self.protocol) + except Thrift.TException, tx: + print '%s' % (tx.message) + + # Template Push from Domino Server is received + # Actions: + # - Depending on Controller Domain, call API + # - Respond Back with Push Response + def d_push(self, push_msg): + print 'Received Template File' + # Retrieve the template file + + ## End of retrieval + + # Any inspection code goes here + + ## End of inspection + + # Call NB API + # If heat client, call heat command + + # If ONOS client, run as shell script + + + ## End of NB API call + + # Marshall the response message for the Domino Server Fill + push_r = PushResponseMessage() + # Fill response message fields + push_r.domino_udid = self.dominoClient.UDID + push_r.seq_no = self.dominoClient.seqno + push_r.responseCode = SUCCESS + ## End of filling + + self.dominoClient.seqno = self.dominoClient.seqno + 1 + + return push_r + + + def openconnection(self): + self.transport.open() + + def closeconnection(): + self.transport.close() + +def read_templatefile(temp_filename): + f = open(temp_filename, 'r') + lines = f.read().splitlines() + + return lines + +class DominoClientCLIService(threading.Thread): + def __init__(self, dominoclient, communicationhandler): + threading.Thread.__init__(self) + self.dominoclient = dominoclient + self.communicationhandler = communicationhandler + + def run(self): + global DEFAULT_TOSCA_PUBFILE + while True: + sys.stdout.write('>>') + input_string = raw_input() + args = input_string.split() + if len(args) == 0: + continue + + labels = [] + templateTypes = [] + + #process input arguments + try: + sys.stdout.write('>>') + if args[0] == 'heartbeat': + print '\nSending heatbeat' + hbm = HeartBeatMessage() + hbm.domino_udid = self.dominoclient.UDID + hbm.seq_no = self.dominoclient.seqno + hbm_r = self.communicationhandler.sender.d_heartbeat(hbm) + print 'heart beat received from: %d ,sequence number: %d' % (hbm_r.domino_udid, hbm_r.seq_no) + self.dominoclient.seqno = self.dominoclient.seqno + 1 + + elif args[0] == 'publish': + opts, args = getopt.getopt(args[1:],"t:",["tosca-file="]) + if len(opts) == 0: + print '\nUsage: publish -t ' + continue + + #toscafile = DEFAULT_TOSCA_PUBFILE + for opt, arg in opts: + if opt in ('-t', '--tosca-file'): + toscafile = arg + + pub_msg = PublishMessage() + pub_msg.domino_udid = self.dominoclient.UDID + pub_msg.seq_no = self.dominoclient.seqno + pub_msg.template_type = 'tosca-nfv-v1.0' + try: + pub_msg.template = read_templatefile(toscafile) + except IOError as e: + print "I/O error({0}): {1}".format(e.errno, e.strerror) + continue + print '\nPublishing the template file: ' + toscafile + pub_msg_r = self.communicationhandler.sender.d_publish(pub_msg) + print 'Publish Response is received from: %d ,sequence number: %d' % (pub_msg_r.domino_udid, pub_msg_r.seq_no) + self.dominoclient.seqno = self.dominoclient.seqno + 1 + + elif args[0] == 'subscribe': + opts, args = getopt.getopt(args[1:],"l:t:",["labels=","ttype="]) + for opt, arg in opts: + if opt in ('-l', '--labels'): + labels = labels + arg.split(',') + elif opt in ('-t', '--ttype'): + templateTypes = templateTypes + arg.split(',') + + except getopt.GetoptError: + print 'Command is misentered or not supported!' + + + #check if labels or supported templates are nonempty + if labels != [] or templateTypes != []: + #send subscription message + sub_msg = SubscribeMessage() + sub_msg.domino_udid = self.dominoclient.UDID + sub_msg.seq_no = self.dominoclient.seqno + sub_msg.template_op = APPEND + sub_msg.supported_template_types = templateTypes + sub_msg.label_op = APPEND + sub_msg.labels = labels + print 'subscribing labels %s and templates %s' % (labels,templateTypes) + sub_msg_r = self.communicationhandler.sender.d_subscribe(sub_msg) + print 'Subscribe Response is received from: %d ,sequence number: %d' % (sub_msg_r.domino_udid,sub_msg_r.seq_no) + self.dominoclient.seqno = self.dominoclient.seqno + 1 + +class DominoClient: + def __init__(self): + self.log = {} + self.communicationHandler = CommunicationHandler(self) + self.processor = None + self.transport = None + self.tfactory = None + self.pfactory = None + self.communicationServer = None + + self.CLIservice = DominoClientCLIService(self, self.communicationHandler) + + self.serviceport = 9091 + self.dominoserver_IP = 'localhost' + + #Start from UNREGISTERED STATE + #TO BE DONE: initialize from a saved state + self.state = 'UNREGISTERED' + self.seqno = 0 + self.UDID = 1 + + def start_communicationService(self): + self.processor = Communication.Processor(self.communicationHandler) + self.transport = TSocket.TServerSocket(port=int(self.serviceport)) + self.tfactory = TTransport.TBufferedTransportFactory() + self.pfactory = TBinaryProtocol.TBinaryProtocolFactory() + #Use TThreadedServer or TThreadPoolServer for a multithreaded server + #self.communicationServer = TServer.TThreadedServer(self.processor, self.transport, self.tfactory, self.pfactory) + self.communicationServer = TServer.TThreadPoolServer(self.processor, self.transport, self.tfactory, self.pfactory) + + self.communicationServer.serve() + + def start(self): + try: + self.communicationHandler.openconnection() + except Thrift.TException, tx: + print '%s' % (tx.message) + + if self.state == 'UNREGISTERED': + #prepare registration message + reg_msg = RegisterMessage() + reg_msg.domino_udid_desired = UDID_DESIRED + reg_msg.seq_no = self.seqno + reg_msg.ipaddr = netutil.get_ip() + reg_msg.tcpport = self.serviceport + reg_msg.supported_templates = LIST_SUPPORTED_TEMPLATES + + reg_msg_r = self.sender().d_register(reg_msg) + print 'Registration Response:\n' + print 'Response Code: %d' % (reg_msg_r.responseCode) + print 'Response Comments:' + if reg_msg_r.comments: + print reg_msg_r.comments + + if reg_msg_r.responseCode == SUCCESS: + self.state = 'REGISTERED' + self.UDID = reg_msg_r.domino_udid_assigned + else: + #Handle registration failure here (possibly based on reponse comments) + pass + + self.seqno = self.seqno + 1 + + def stop(self): + try: + self.communicationHandler.closeconnection() + except Thrift.TException, tx: + print '%s' % (tx.message) + + def sender(self): + return self.communicationHandler.sender + + def startCLI(self): + print 'CLI Service is starting' + self.CLIservice.start() + #to wait until CLI service is finished + #self.CLIservice.join() + + def set_serviceport(self, port): + self.serviceport = port + print 'port: ' + print self.serviceport + + def set_dominoserver_ipaddr(self, ipaddr): + self.dominoserver_IP = ipaddr + print 'ip addr: ' + print self.dominoserver_IP + +def main(argv): + client = DominoClient() + + #process input arguments + try: + opts, args = getopt.getopt(argv,"hc:p:i:",["conf=","port=","ipaddr="]) + except getopt.GetoptError: + print 'DominoClient.py -c/--conf -p/--port -i/--ipaddr ' + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + print 'DominoClient.py -c/--conf -p/--port -i/--ipaddr ' + sys.exit() + elif opt in ("-c", "--conf"): + configfile = arg + elif opt in ("-p", "--port"): + client.set_serviceport(int(arg)) + elif opt in ("-i", "--ipaddr"): + client.set_dominoserver_ipaddr(arg) + + #The client is starting + print 'Starting the client...' + client.start() + client.startCLI() + client.start_communicationService() + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/DominoServer.py b/DominoServer.py new file mode 100755 index 0000000..7d7a977 --- /dev/null +++ b/DominoServer.py @@ -0,0 +1,287 @@ +#!/usr/bin/env python + +# +# Licence statement goes here +# + + +import sys, os, glob, random, errno +#sys.path.append('gen-py') +#sys.path.insert(0, glob.glob('./lib/py/build/lib.*')[0]) +sys.path.insert(0, glob.glob('./lib')[0]) + + +from dominoRPC import Communication +from dominoRPC.ttypes import * +from dominoRPC.constants import * + +from thrift import Thrift +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol +from thrift.server import TServer + +from toscaparser.tosca_template import ToscaTemplate +#from toscaparser.utils.gettextutils import _ +#import toscaparser.utils.urlutils + +from mapper import * +from partitioner import * +from util import miscutil + +SERVER_UDID = 0 +DOMINO_CLIENT_IP = 'localhost' +DOMINO_CLIENT_PORT = 9091 +TOSCADIR = './toscafiles/' +TOSCA_DEFAULT_FNAME = 'template1.yaml' + +class CommunicationHandler: + def __init__(self): + self.log = {} + + def __init__(self, dominoserver): + self.log = {} + self.dominoServer = dominoserver + self.seqno = 0; + + def openconnection(self, ipaddr, tcpport): + try: + # Make socket + transport = TSocket.TSocket(ipaddr, tcpport) + # Add buffering to compensate for slow raw sockets + self.transport = TTransport.TBufferedTransport(transport) + # Wrap in a protocol + self.protocol = TBinaryProtocol.TBinaryProtocol(self.transport) + # Create a client to use the protocol encoder + self.sender = Communication.Client(self.protocol) + self.transport.open() + except Thrift.TException, tx: + print '%s' % (tx.message) + + + def closeconnection(self): + self.transport.close() + + def push_template(self,template,ipaddr,tcpport): + global SERVER_UDID + self.openconnection(ipaddr,tcpport) + pushm = PushMessage() + pushm.domino_udid = SERVER_UDID + pushm.seq_no = self.seqno + pushm.template_type = 'tosca-nfv-v1.0' + pushm.template = template + + push_r = self.sender.d_push(pushm) + + print 'Push Response received from %d' % push_r.domino_udid + self.seqno = self.seqno + 1 + + self.closeconnection() + + #Heartbeat from Domino Client is received + #Actions: + # - Respond Back with a heartbeat + + def d_heartbeat(self, hb_msg): + global SERVER_UDID + print 'heart beat received from %d' % hb_msg.domino_udid + + hb_r = HeartBeatMessage() + hb_r.domino_udid = SERVER_UDID + hb_r.seq_no = self.seqno + + self.seqno = self.seqno + 1 + + return hb_r + + #Registration from Domino Client is received + #Actions: + # + # - Respond Back with Registration Response + def d_register(self, reg_msg): + global SERVER_UDID + + #Prepare and send Registration Response + reg_r = RegisterResponseMessage() + print 'Registration Request received for UDID %d from IP: %s port: %d ' % (reg_msg.domino_udid_desired, reg_msg.ipaddr, reg_msg.tcpport) + + + reg_r.domino_udid_assigned = self.dominoServer.assign_udid(reg_msg.domino_udid_desired) + reg_r.seq_no = self.seqno + reg_r.domino_udid = SERVER_UDID + #return unconditional success + #To be implemented: + #Define conditions for unsuccessful registration (e.g., unsupported mapping) + reg_r.responseCode = SUCCESS + #no need to send comments + #To be implemented: + #Logic for a new UDID assignment + + self.seqno = self.seqno + 1 + + # Store the Domino Client info + # TBD: check the sequence number to ensure the most recent record is saved + self.dominoServer.registration_record[reg_r.domino_udid_assigned] = reg_msg + return reg_r + + + #Subscription from Domino Client is received + #Actions: + # - Save the templates & labels + # - Respond Back with Subscription Response + def d_subscribe(self, sub_msg): + global SERVER_UDID, SERVER_SEQNO + print 'Subscribe Request received from %d' % sub_msg.domino_udid + + if sub_msg.template_op == APPEND: + if self.dominoServer.subscribed_templateformats.has_key(sub_msg.domino_udid): + self.dominoServer.subscribed_templateformats[sub_msg.domino_udid].update(set(sub_msg.supported_template_types)) + else: + self.dominoServer.subscribed_templateformats[sub_msg.domino_udid] = set(sub_msg.supported_template_types) + elif sub_msg.template_op == OVERWRITE: + self.dominoServer.subscribed_templateformats[sub_msg.domino_udid] = set(sub_msg.supported_template_types) + elif sub_msg.template_op == DELETE: + self.dominoServer.subscribed_templateformats[sub_msg.domino_udid].difference_update(set(sub_msg.supported_template_types)) + + if sub_msg.labels != []: + if sub_msg.label_op == APPEND: + if self.dominoServer.subscribed_labels.has_key(sub_msg.domino_udid): + self.dominoServer.subscribed_labels[sub_msg.domino_udid].update(set(sub_msg.labels)) + else: + self.dominoServer.subscribed_labels[sub_msg.domino_udid] = set(sub_msg.labels) + elif sub_msg.label_op == OVERWRITE: + self.dominoServer.subscribed_labels[sub_msg.domino_udid] = set(sub_msg.labels) + elif sub_msg.label_op == DELETE: + self.dominoServer.subscribed_labels[sub_msg.domino_udid].difference_update(set(sub_msg.labels)) + + print 'Supported Template: %s' % self.dominoServer.subscribed_templateformats[sub_msg.domino_udid] + print 'Supported Labels: %s' % self.dominoServer.subscribed_labels[sub_msg.domino_udid] + #Fill in the details + sub_r = SubscribeResponseMessage() + sub_r.domino_udid = SERVER_UDID + sub_r.seq_no = self.seqno + sub_r.responseCode = SUCCESS + self.seqno = self.seqno + 1 + + return sub_r + + #Template Publication from Domino Client is received + #Actions: + # - Parse the template, perform mapping, partition the template + # - Launch Push service + # - Respond Back with Publication Response + def d_publish(self, pub_msg): + global SERVER_UDID, SERVER_SEQNO, TOSCADIR, TOSCA_DEFAULT_FNAME + print 'Publish Request received from %d' % pub_msg.domino_udid + print pub_msg.template + + # Save as file + try: + os.makedirs(TOSCADIR) + except OSError as exception: + if exception.errno == errno.EEXIST: + print TOSCADIR, ' exists. Creating: ' , TOSCADIR+TOSCA_DEFAULT_FNAME + else: + print 'Error occurred in creating the directory. Err no: ', exception.errno + + #Risking a race condition if another process is attempting to write to same file + f = open(TOSCADIR+TOSCA_DEFAULT_FNAME, 'w') + for item in pub_msg.template: + print>>f, item + f.close() + + # Load tosca object from file into memory + tosca = ToscaTemplate( TOSCADIR+TOSCA_DEFAULT_FNAME ) + + # Extract Labels + node_labels = label.extract_labels( tosca ) + print '\nNode Labels: \n', node_labels + + # Map nodes in the template to resource domains + site_map = label.map_nodes( self.dominoServer.subscribed_labels , node_labels ) + print '\nSite Maps: \n' , site_map + + # Select a site for each VNF + node_site = label.select_site( site_map ) + print '\nSelected Sites:\n' , node_site , '\n' + + # Create per-domain Tosca files + file_paths = partitioner.partition_tosca('./toscafiles/template1.yaml',node_site,tosca.tpl) + + # Create list of translated template files + + # Create work-flow + + # Send domain templates to each domain agent/client + # FOR NOW: send untranslated but partitioned tosca files to scheduled sites + # TBD: read from work-flow + for site in file_paths: + domino_client_ip = self.dominoServer.registration_record[site].ipaddr + domino_client_port = self.dominoServer.registration_record[site].tcpport + self.push_template(miscutil.read_templatefile(file_paths[site]), domino_client_ip, domino_client_port) + # self.push_template(pub_msg.template, DOMINO_CLIENT_IP, DOMINO_CLIENT_PORT) + + #Fill in the details + pub_r = PublishResponseMessage() + pub_r.domino_udid = SERVER_UDID + pub_r.seq_no = self.seqno + pub_r.responseCode = SUCCESS + self.seqno = self.seqno + 1 + return pub_r + + #Query from Domino Client is received + #Actions: + # + # - Respond Back with Query Response + def d_query(self, qu_msg): + #Fill in the details + qu_r = QueryResponseMessage() + + return qu_r + + +class DominoServer: + def __init__(self): + self.log = {} + self.assignedUUIDs = list() + self.subscribed_labels = dict() + self.subscribed_templateformats = dict() + self.registration_record = dict() + self.communicationHandler = CommunicationHandler(self) + self.processor = Communication.Processor(self.communicationHandler) + self.transport = TSocket.TServerSocket(port=9090) + self.tfactory = TTransport.TBufferedTransportFactory() + self.pfactory = TBinaryProtocol.TBinaryProtocolFactory() + #Use TThreadedServer or TThreadPoolServer for a multithreaded server + #self.communicationServer = TServer.TThreadedServer(self.processor, self.transport, self.tfactory, self.pfactory) + self.communicationServer = TServer.TThreadPoolServer(self.processor, self.transport, self.tfactory, self.pfactory) + + def start_communicationService(self): + self.communicationServer.serve() + + #For now assign the desired UDID + #To be implemented: + #Check if ID is already assigned and in use + #If not assigned, assign it + #If assigned, offer a new random id + def assign_udid(self, udid_desired): + if udid_desired in self.assignedUUIDs: + new_udid = random.getrandbits(64) + while new_udid in self.assignedUUIDs: + new_udid = random.getrandbits(64) + + self.assignedUUIDs.append(new_udid) + return new_udid + else: + self.assignedUUIDs.append(udid_desired) + return udid_desired + + +def main(argv): + server = DominoServer() + print 'Starting the server...' + server.start_communicationService() + print 'done.' + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/README.md b/README.md new file mode 100644 index 0000000..ed133a0 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# Domino + +##Quick Start on the same machine: + +Tested on Ubuntu 14.04 and OS X El Capitan + +###Prerequisite: + sudo pip install tosca-parser + +###Start Domino Server: + ./DominoServer.py + +###Start the first Domino Client: + ./DominoClient.py -p 9091 + +###Start the second Domino Client: + ./DominoClient.py -p 9092 + +##CLI at the Domino Client: + +###send heartbeat + heartbeat + +###subscribe for policy labels + subscribe -l/--labels :properties:key:value + +###publish default template file under tosca-templates + publish --tosca-file diff --git a/buildpy b/buildpy new file mode 100755 index 0000000..64d0855 --- /dev/null +++ b/buildpy @@ -0,0 +1 @@ +thrift -r --gen py domino.thrift diff --git a/domino.thrift b/domino.thrift new file mode 100644 index 0000000..72fb37f --- /dev/null +++ b/domino.thrift @@ -0,0 +1,214 @@ +/** + * Thrift types: + * + * bool Boolean, one byte + * byte Signed byte + * i16 Signed 16-bit integer + * i32 Signed 32-bit integer + * i64 Signed 64-bit integer + * double 64-bit floating point value + * string String + * binary Blob (byte array) + * map Map from one type to another + * list Ordered list of one type + * set Set of unique elements of one type + * + */ + + +/** + * Thrift files can reference other Thrift files to include common struct + * and service definitions. These are found using the current path, or by + * searching relative to any paths specified with the -I compiler flag. + * + * Included objects are accessed using the name of the .thrift file as a + * prefix. i.e. shared.SharedObject + */ +//include "shared.thrift" + +/** + * Thrift files can namespace, package, or prefix their output in various + * target languages. + */ +namespace cpp domino +namespace py domino +namespace java domino + +/** + * Thrift also lets you define constants for use across languages. Complex + * types and structs are specified using JSON notation. + */ +/* +const i32 INT32CONSTANT = 9853 +const map MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} +*/ + +typedef byte MessageType + +const MessageType HEART_BEAT = 1 +const MessageType REGISTER = 2 +const MessageType REGISTER_RESPONSE = 3 +const MessageType SUBSCRIBE = 4 +const MessageType SUBSCRIBE_RESPONSE = 5 +const MessageType PUBLISH = 6 +const MessageType PUBLISH_RESPONSE = 7 +const MessageType PUSH = 8 +const MessageType PUSH_RESPONSE = 9 +const MessageType QUERY = 10 +const MessageType QUERY_RESPONSE = 11 + +typedef byte ResponseCode + +const ResponseCode SUCCESS = 1 +const ResponseCode FAILED = 2 + +const byte APPEND = 0 +const byte OVERWRITE = 1 +const byte DELETE = 2 + +/** + * Structs are the basic complex data structures. They are comprised of fields + * which each have an integer identifier, a type, a symbolic name, and an + * optional default value. + * + * Fields can be declared "optional", which ensures they will not be included + * in the serialized output if they aren't set. Note that this requires some + * manual management in some languages. + */ +/* +struct Work { + 1: i32 num1 = 0, + 2: i32 num2, + 3: Operation op, + 4: optional string comment, +} +*/ + +/** + * Structs can also be exceptions, if they are nasty. + */ +/* +exception InvalidOperation { + 1: i32 whatOp, + 2: string why +} +*/ + +/** +* Domino sends periodic heartbeats from +* Domino Clients and Domino Server echos +*/ +struct HeartBeatMessage { + 1: MessageType messageType = HEART_BEAT, + 2: i64 domino_udid, + 3: i64 seq_no +} + +/** +* Domino Clients must first register with +* Domino Server. Clients can ask for a specific +* Unique Domino ID (UDID) +*/ + +struct RegisterMessage { + 1: MessageType messageType = REGISTER, + 2: i64 domino_udid_desired, + 3: i64 seq_no, + 4: string ipaddr, + 5: i16 tcpport, + 6: list supported_templates +} + +struct RegisterResponseMessage { + 1: MessageType messageType = REGISTER_RESPONSE, + 2: i64 domino_udid, + 3: i64 domino_udid_assigned, + 4: i64 seq_no, + 5: ResponseCode responseCode, + 6: optional list comments +} + +struct SubscribeMessage { + 1: MessageType messageType = SUBSCRIBE, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: byte template_op, + 5: list supported_template_types, + 6: optional byte label_op, + 7: optional list labels +} + +struct SubscribeResponseMessage { + 1: MessageType messageType = SUBSCRIBE_RESPONSE, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: ResponseCode responseCode, + 5: optional list comments +} + +struct PublishMessage { + 1: MessageType messageType = PUBLISH, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: string template_type, + 5: list template +} + +struct PublishResponseMessage { + 1: MessageType messageType = PUBLISH_RESPONSE, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: ResponseCode responseCode, + 5: optional list comments +} + +struct PushMessage { + 1: MessageType messageType = PUSH, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: string template_type, + 5: list template +} + +struct PushResponseMessage { + 1: MessageType messageType = PUSH_RESPONSE, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: ResponseCode responseCode, + 5: optional list comments +} + +struct QueryMessage{ + 1: MessageType messageType = QUERY, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: list queryString +} + +struct QueryResponseMessage{ + 1: MessageType messageType = QUERY_RESPONSE, + 2: i64 domino_udid, + 3: i64 seq_no, + 4: ResponseCode responseCode, + 5: optional list queryResponse, +} + +service Communication { + + /** + * A method definition looks like C code. It has a return type, arguments, + * and optionally a list of exceptions that it may throw. Note that argument + * lists and exception lists are specified using the exact same syntax as + * field lists in struct or exception definitions. + */ + + //void ping(), + + + HeartBeatMessage d_heartbeat(1:HeartBeatMessage msg), + RegisterResponseMessage d_register(1:RegisterMessage msg), + SubscribeResponseMessage d_subscribe(1:SubscribeMessage msg), + PublishResponseMessage d_publish(1:PublishMessage msg), + PushResponseMessage d_push(1:PushMessage msg), + QueryResponseMessage d_query(1:QueryMessage msg) +} diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/dominoRPC/Communication-remote b/lib/dominoRPC/Communication-remote new file mode 100755 index 0000000..77a96d7 --- /dev/null +++ b/lib/dominoRPC/Communication-remote @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# +# Autogenerated by Thrift Compiler (0.9.3) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +import sys +import pprint +from urlparse import urlparse +from thrift.transport import TTransport +from thrift.transport import TSocket +from thrift.transport import TSSLSocket +from thrift.transport import THttpClient +from thrift.protocol import TBinaryProtocol + +from domino import Communication +from domino.ttypes import * + +if len(sys.argv) <= 1 or sys.argv[1] == '--help': + print('') + print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] function [arg1 [arg2...]]') + print('') + print('Functions:') + print(' HeartBeatMessage d_heartbeat(HeartBeatMessage msg)') + print(' RegisterResponseMessage d_register(RegisterMessage msg)') + print(' SubscribeResponseMessage d_subscribe(SubscribeMessage msg)') + print(' PublishResponseMessage d_publish(PublishMessage msg)') + print(' PushResponseMessage d_push(PushMessage msg)') + print(' QueryResponseMessage d_query(QueryMessage msg)') + print('') + sys.exit(0) + +pp = pprint.PrettyPrinter(indent = 2) +host = 'localhost' +port = 9090 +uri = '' +framed = False +ssl = False +http = False +argi = 1 + +if sys.argv[argi] == '-h': + parts = sys.argv[argi+1].split(':') + host = parts[0] + if len(parts) > 1: + port = int(parts[1]) + argi += 2 + +if sys.argv[argi] == '-u': + url = urlparse(sys.argv[argi+1]) + parts = url[1].split(':') + host = parts[0] + if len(parts) > 1: + port = int(parts[1]) + else: + port = 80 + uri = url[2] + if url[4]: + uri += '?%s' % url[4] + http = True + argi += 2 + +if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed': + framed = True + argi += 1 + +if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl': + ssl = True + argi += 1 + +cmd = sys.argv[argi] +args = sys.argv[argi+1:] + +if http: + transport = THttpClient.THttpClient(host, port, uri) +else: + socket = TSSLSocket.TSSLSocket(host, port, validate=False) if ssl else TSocket.TSocket(host, port) + if framed: + transport = TTransport.TFramedTransport(socket) + else: + transport = TTransport.TBufferedTransport(socket) +protocol = TBinaryProtocol.TBinaryProtocol(transport) +client = Communication.Client(protocol) +transport.open() + +if cmd == 'd_heartbeat': + if len(args) != 1: + print('d_heartbeat requires 1 args') + sys.exit(1) + pp.pprint(client.d_heartbeat(eval(args[0]),)) + +elif cmd == 'd_register': + if len(args) != 1: + print('d_register requires 1 args') + sys.exit(1) + pp.pprint(client.d_register(eval(args[0]),)) + +elif cmd == 'd_subscribe': + if len(args) != 1: + print('d_subscribe requires 1 args') + sys.exit(1) + pp.pprint(client.d_subscribe(eval(args[0]),)) + +elif cmd == 'd_publish': + if len(args) != 1: + print('d_publish requires 1 args') + sys.exit(1) + pp.pprint(client.d_publish(eval(args[0]),)) + +elif cmd == 'd_push': + if len(args) != 1: + print('d_push requires 1 args') + sys.exit(1) + pp.pprint(client.d_push(eval(args[0]),)) + +elif cmd == 'd_query': + if len(args) != 1: + print('d_query requires 1 args') + sys.exit(1) + pp.pprint(client.d_query(eval(args[0]),)) + +else: + print('Unrecognized method %s' % cmd) + sys.exit(1) + +transport.close() diff --git a/lib/dominoRPC/Communication.py b/lib/dominoRPC/Communication.py new file mode 100644 index 0000000..2252bf7 --- /dev/null +++ b/lib/dominoRPC/Communication.py @@ -0,0 +1,1196 @@ +# +# Autogenerated by Thrift Compiler (0.9.3) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TException, TApplicationException +import logging +from ttypes import * +from thrift.Thrift import TProcessor +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol, TProtocol +try: + from thrift.protocol import fastbinary +except: + fastbinary = None + + +class Iface: + def d_heartbeat(self, msg): + """ + A method definition looks like C code. It has a return type, arguments, + and optionally a list of exceptions that it may throw. Note that argument + lists and exception lists are specified using the exact same syntax as + field lists in struct or exception definitions. + + Parameters: + - msg + """ + pass + + def d_register(self, msg): + """ + Parameters: + - msg + """ + pass + + def d_subscribe(self, msg): + """ + Parameters: + - msg + """ + pass + + def d_publish(self, msg): + """ + Parameters: + - msg + """ + pass + + def d_push(self, msg): + """ + Parameters: + - msg + """ + pass + + def d_query(self, msg): + """ + Parameters: + - msg + """ + pass + + +class Client(Iface): + def __init__(self, iprot, oprot=None): + self._iprot = self._oprot = iprot + if oprot is not None: + self._oprot = oprot + self._seqid = 0 + + def d_heartbeat(self, msg): + """ + A method definition looks like C code. It has a return type, arguments, + and optionally a list of exceptions that it may throw. Note that argument + lists and exception lists are specified using the exact same syntax as + field lists in struct or exception definitions. + + Parameters: + - msg + """ + self.send_d_heartbeat(msg) + return self.recv_d_heartbeat() + + def send_d_heartbeat(self, msg): + self._oprot.writeMessageBegin('d_heartbeat', TMessageType.CALL, self._seqid) + args = d_heartbeat_args() + args.msg = msg + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_d_heartbeat(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = d_heartbeat_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "d_heartbeat failed: unknown result") + + def d_register(self, msg): + """ + Parameters: + - msg + """ + self.send_d_register(msg) + return self.recv_d_register() + + def send_d_register(self, msg): + self._oprot.writeMessageBegin('d_register', TMessageType.CALL, self._seqid) + args = d_register_args() + args.msg = msg + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_d_register(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = d_register_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "d_register failed: unknown result") + + def d_subscribe(self, msg): + """ + Parameters: + - msg + """ + self.send_d_subscribe(msg) + return self.recv_d_subscribe() + + def send_d_subscribe(self, msg): + self._oprot.writeMessageBegin('d_subscribe', TMessageType.CALL, self._seqid) + args = d_subscribe_args() + args.msg = msg + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_d_subscribe(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = d_subscribe_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "d_subscribe failed: unknown result") + + def d_publish(self, msg): + """ + Parameters: + - msg + """ + self.send_d_publish(msg) + return self.recv_d_publish() + + def send_d_publish(self, msg): + self._oprot.writeMessageBegin('d_publish', TMessageType.CALL, self._seqid) + args = d_publish_args() + args.msg = msg + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_d_publish(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = d_publish_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "d_publish failed: unknown result") + + def d_push(self, msg): + """ + Parameters: + - msg + """ + self.send_d_push(msg) + return self.recv_d_push() + + def send_d_push(self, msg): + self._oprot.writeMessageBegin('d_push', TMessageType.CALL, self._seqid) + args = d_push_args() + args.msg = msg + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_d_push(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = d_push_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "d_push failed: unknown result") + + def d_query(self, msg): + """ + Parameters: + - msg + """ + self.send_d_query(msg) + return self.recv_d_query() + + def send_d_query(self, msg): + self._oprot.writeMessageBegin('d_query', TMessageType.CALL, self._seqid) + args = d_query_args() + args.msg = msg + args.write(self._oprot) + self._oprot.writeMessageEnd() + self._oprot.trans.flush() + + def recv_d_query(self): + iprot = self._iprot + (fname, mtype, rseqid) = iprot.readMessageBegin() + if mtype == TMessageType.EXCEPTION: + x = TApplicationException() + x.read(iprot) + iprot.readMessageEnd() + raise x + result = d_query_result() + result.read(iprot) + iprot.readMessageEnd() + if result.success is not None: + return result.success + raise TApplicationException(TApplicationException.MISSING_RESULT, "d_query failed: unknown result") + + +class Processor(Iface, TProcessor): + def __init__(self, handler): + self._handler = handler + self._processMap = {} + self._processMap["d_heartbeat"] = Processor.process_d_heartbeat + self._processMap["d_register"] = Processor.process_d_register + self._processMap["d_subscribe"] = Processor.process_d_subscribe + self._processMap["d_publish"] = Processor.process_d_publish + self._processMap["d_push"] = Processor.process_d_push + self._processMap["d_query"] = Processor.process_d_query + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin() + if name not in self._processMap: + iprot.skip(TType.STRUCT) + iprot.readMessageEnd() + x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name)) + oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid) + x.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + return + else: + self._processMap[name](self, seqid, iprot, oprot) + return True + + def process_d_heartbeat(self, seqid, iprot, oprot): + args = d_heartbeat_args() + args.read(iprot) + iprot.readMessageEnd() + result = d_heartbeat_result() + try: + result.success = self._handler.d_heartbeat(args.msg) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("d_heartbeat", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_d_register(self, seqid, iprot, oprot): + args = d_register_args() + args.read(iprot) + iprot.readMessageEnd() + result = d_register_result() + try: + result.success = self._handler.d_register(args.msg) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("d_register", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_d_subscribe(self, seqid, iprot, oprot): + args = d_subscribe_args() + args.read(iprot) + iprot.readMessageEnd() + result = d_subscribe_result() + try: + result.success = self._handler.d_subscribe(args.msg) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("d_subscribe", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_d_publish(self, seqid, iprot, oprot): + args = d_publish_args() + args.read(iprot) + iprot.readMessageEnd() + result = d_publish_result() + try: + result.success = self._handler.d_publish(args.msg) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("d_publish", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_d_push(self, seqid, iprot, oprot): + args = d_push_args() + args.read(iprot) + iprot.readMessageEnd() + result = d_push_result() + try: + result.success = self._handler.d_push(args.msg) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("d_push", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + def process_d_query(self, seqid, iprot, oprot): + args = d_query_args() + args.read(iprot) + iprot.readMessageEnd() + result = d_query_result() + try: + result.success = self._handler.d_query(args.msg) + msg_type = TMessageType.REPLY + except (TTransport.TTransportException, KeyboardInterrupt, SystemExit): + raise + except Exception as ex: + msg_type = TMessageType.EXCEPTION + logging.exception(ex) + result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error') + oprot.writeMessageBegin("d_query", msg_type, seqid) + result.write(oprot) + oprot.writeMessageEnd() + oprot.trans.flush() + + +# HELPER FUNCTIONS AND STRUCTURES + +class d_heartbeat_args: + """ + Attributes: + - msg + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRUCT, 'msg', (HeartBeatMessage, HeartBeatMessage.thrift_spec), None, ), # 1 + ) + + def __init__(self, msg=None,): + self.msg = msg + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRUCT: + self.msg = HeartBeatMessage() + self.msg.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_heartbeat_args') + if self.msg is not None: + oprot.writeFieldBegin('msg', TType.STRUCT, 1) + self.msg.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.msg) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_heartbeat_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (HeartBeatMessage, HeartBeatMessage.thrift_spec), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = HeartBeatMessage() + self.success.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_heartbeat_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.success) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_register_args: + """ + Attributes: + - msg + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRUCT, 'msg', (RegisterMessage, RegisterMessage.thrift_spec), None, ), # 1 + ) + + def __init__(self, msg=None,): + self.msg = msg + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRUCT: + self.msg = RegisterMessage() + self.msg.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_register_args') + if self.msg is not None: + oprot.writeFieldBegin('msg', TType.STRUCT, 1) + self.msg.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.msg) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_register_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (RegisterResponseMessage, RegisterResponseMessage.thrift_spec), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = RegisterResponseMessage() + self.success.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_register_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.success) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_subscribe_args: + """ + Attributes: + - msg + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRUCT, 'msg', (SubscribeMessage, SubscribeMessage.thrift_spec), None, ), # 1 + ) + + def __init__(self, msg=None,): + self.msg = msg + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRUCT: + self.msg = SubscribeMessage() + self.msg.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_subscribe_args') + if self.msg is not None: + oprot.writeFieldBegin('msg', TType.STRUCT, 1) + self.msg.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.msg) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_subscribe_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (SubscribeResponseMessage, SubscribeResponseMessage.thrift_spec), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = SubscribeResponseMessage() + self.success.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_subscribe_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.success) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_publish_args: + """ + Attributes: + - msg + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRUCT, 'msg', (PublishMessage, PublishMessage.thrift_spec), None, ), # 1 + ) + + def __init__(self, msg=None,): + self.msg = msg + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRUCT: + self.msg = PublishMessage() + self.msg.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_publish_args') + if self.msg is not None: + oprot.writeFieldBegin('msg', TType.STRUCT, 1) + self.msg.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.msg) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_publish_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (PublishResponseMessage, PublishResponseMessage.thrift_spec), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = PublishResponseMessage() + self.success.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_publish_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.success) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_push_args: + """ + Attributes: + - msg + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRUCT, 'msg', (PushMessage, PushMessage.thrift_spec), None, ), # 1 + ) + + def __init__(self, msg=None,): + self.msg = msg + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRUCT: + self.msg = PushMessage() + self.msg.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_push_args') + if self.msg is not None: + oprot.writeFieldBegin('msg', TType.STRUCT, 1) + self.msg.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.msg) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_push_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (PushResponseMessage, PushResponseMessage.thrift_spec), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = PushResponseMessage() + self.success.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_push_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.success) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_query_args: + """ + Attributes: + - msg + """ + + thrift_spec = ( + None, # 0 + (1, TType.STRUCT, 'msg', (QueryMessage, QueryMessage.thrift_spec), None, ), # 1 + ) + + def __init__(self, msg=None,): + self.msg = msg + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRUCT: + self.msg = QueryMessage() + self.msg.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_query_args') + if self.msg is not None: + oprot.writeFieldBegin('msg', TType.STRUCT, 1) + self.msg.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.msg) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class d_query_result: + """ + Attributes: + - success + """ + + thrift_spec = ( + (0, TType.STRUCT, 'success', (QueryResponseMessage, QueryResponseMessage.thrift_spec), None, ), # 0 + ) + + def __init__(self, success=None,): + self.success = success + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 0: + if ftype == TType.STRUCT: + self.success = QueryResponseMessage() + self.success.read(iprot) + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('d_query_result') + if self.success is not None: + oprot.writeFieldBegin('success', TType.STRUCT, 0) + self.success.write(oprot) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.success) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/lib/dominoRPC/Communication.pyc b/lib/dominoRPC/Communication.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b697bc29fa9bb5ab9606f460e5efe2663cb6a1df GIT binary patch literal 41494 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 literal 0 HcmV?d00001 diff --git a/lib/dominoRPC/constants.py b/lib/dominoRPC/constants.py new file mode 100644 index 0000000..5687d91 --- /dev/null +++ b/lib/dominoRPC/constants.py @@ -0,0 +1,27 @@ +# +# Autogenerated by Thrift Compiler (0.9.3) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TException, TApplicationException +from ttypes import * + +HEART_BEAT = 1 +REGISTER = 2 +REGISTER_RESPONSE = 3 +SUBSCRIBE = 4 +SUBSCRIBE_RESPONSE = 5 +PUBLISH = 6 +PUBLISH_RESPONSE = 7 +PUSH = 8 +PUSH_RESPONSE = 9 +QUERY = 10 +QUERY_RESPONSE = 11 +SUCCESS = 1 +FAILED = 2 +APPEND = 0 +OVERWRITE = 1 +DELETE = 2 diff --git a/lib/dominoRPC/constants.pyc b/lib/dominoRPC/constants.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a494a7829a0216a4845c7b612d0396d3135488b GIT binary patch literal 719 zcmaJ-%Wl*#6g|njGmk!?NNl@`Sj_wYRL#s78flmYJ1N4OY8VHwluROGB>ETpC(C|7 z@wE!+iX=Y1_Z;Wkd)>L825%O>Z}xb6e7j%T)%>!c?B}5XN)OUQ=|lP`JCGfeUC1sx zI^m<}Ayt;{Ls@zN)q@;D^&v-41IPes2swrtK~A6o$SKqqat1YlJc61+9)lcCoWm*9 z4Dy*{o;&6Y>Ifn{woT~=`-EK^nVy9-y{mIGq3C_yG`p|4BLX7W&wXAST^-CBrBPiM zdcPy$pAvdjF$AwPp{5Ja9Rez$sf6wm3n~=Wx{Z^_ z$(WNdCu2i)#@MzSLoQb=;_2;@MX4cs&fdi$W!#)RNp3k4$@Nw+L&Zh56e}JtnK^x$ zwTGzJBwKD`ab@Vv9^>`^&6Z?VrH(0RC7Sp{#`q^Q`x~_)8H;SSVnVnv-bV3;tz8%; z3EQq+f7dsRf8=q>oUmpama@?Pi58ldHk~gD{du9PQXi_tzB)8!cQDPozH=Axx~$ZX TBEO)Cn{x~2Uf}n=|Gj?z)|ZH^ literal 0 HcmV?d00001 diff --git a/lib/dominoRPC/ttypes.py b/lib/dominoRPC/ttypes.py new file mode 100644 index 0000000..8a80d5f --- /dev/null +++ b/lib/dominoRPC/ttypes.py @@ -0,0 +1,1435 @@ +# +# Autogenerated by Thrift Compiler (0.9.3) +# +# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING +# +# options string: py +# + +from thrift.Thrift import TType, TMessageType, TException, TApplicationException + +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol, TProtocol +try: + from thrift.protocol import fastbinary +except: + fastbinary = None + + + +class HeartBeatMessage: + """ + Domino sends periodic heartbeats from + Domino Clients and Domino Server echos + + Attributes: + - messageType + - domino_udid + - seq_no + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 1, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 1 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('HeartBeatMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class RegisterMessage: + """ + Domino Clients must first register with + Domino Server. Clients can ask for a specific + Unique Domino ID (UDID) + + Attributes: + - messageType + - domino_udid_desired + - seq_no + - ipaddr + - tcpport + - supported_templates + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 2, ), # 1 + (2, TType.I64, 'domino_udid_desired', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.STRING, 'ipaddr', None, None, ), # 4 + (5, TType.I16, 'tcpport', None, None, ), # 5 + (6, TType.LIST, 'supported_templates', (TType.STRING,None), None, ), # 6 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid_desired=None, seq_no=None, ipaddr=None, tcpport=None, supported_templates=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 2 + self.messageType = messageType + self.domino_udid_desired = domino_udid_desired + self.seq_no = seq_no + self.ipaddr = ipaddr + self.tcpport = tcpport + self.supported_templates = supported_templates + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid_desired = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.STRING: + self.ipaddr = iprot.readString() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.I16: + self.tcpport = iprot.readI16() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.LIST: + self.supported_templates = [] + (_etype3, _size0) = iprot.readListBegin() + for _i4 in xrange(_size0): + _elem5 = iprot.readString() + self.supported_templates.append(_elem5) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('RegisterMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid_desired is not None: + oprot.writeFieldBegin('domino_udid_desired', TType.I64, 2) + oprot.writeI64(self.domino_udid_desired) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.ipaddr is not None: + oprot.writeFieldBegin('ipaddr', TType.STRING, 4) + oprot.writeString(self.ipaddr) + oprot.writeFieldEnd() + if self.tcpport is not None: + oprot.writeFieldBegin('tcpport', TType.I16, 5) + oprot.writeI16(self.tcpport) + oprot.writeFieldEnd() + if self.supported_templates is not None: + oprot.writeFieldBegin('supported_templates', TType.LIST, 6) + oprot.writeListBegin(TType.STRING, len(self.supported_templates)) + for iter6 in self.supported_templates: + oprot.writeString(iter6) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid_desired) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.ipaddr) + value = (value * 31) ^ hash(self.tcpport) + value = (value * 31) ^ hash(self.supported_templates) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class RegisterResponseMessage: + """ + Attributes: + - messageType + - domino_udid + - domino_udid_assigned + - seq_no + - responseCode + - comments + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 3, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'domino_udid_assigned', None, None, ), # 3 + (4, TType.I64, 'seq_no', None, None, ), # 4 + (5, TType.BYTE, 'responseCode', None, None, ), # 5 + (6, TType.LIST, 'comments', (TType.STRING,None), None, ), # 6 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, domino_udid_assigned=None, seq_no=None, responseCode=None, comments=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 3 + self.messageType = messageType + self.domino_udid = domino_udid + self.domino_udid_assigned = domino_udid_assigned + self.seq_no = seq_no + self.responseCode = responseCode + self.comments = comments + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.domino_udid_assigned = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.BYTE: + self.responseCode = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.LIST: + self.comments = [] + (_etype10, _size7) = iprot.readListBegin() + for _i11 in xrange(_size7): + _elem12 = iprot.readString() + self.comments.append(_elem12) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('RegisterResponseMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.domino_udid_assigned is not None: + oprot.writeFieldBegin('domino_udid_assigned', TType.I64, 3) + oprot.writeI64(self.domino_udid_assigned) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 4) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.responseCode is not None: + oprot.writeFieldBegin('responseCode', TType.BYTE, 5) + oprot.writeByte(self.responseCode) + oprot.writeFieldEnd() + if self.comments is not None: + oprot.writeFieldBegin('comments', TType.LIST, 6) + oprot.writeListBegin(TType.STRING, len(self.comments)) + for iter13 in self.comments: + oprot.writeString(iter13) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.domino_udid_assigned) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.responseCode) + value = (value * 31) ^ hash(self.comments) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class SubscribeMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - template_op + - supported_template_types + - label_op + - labels + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 4, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.BYTE, 'template_op', None, None, ), # 4 + (5, TType.LIST, 'supported_template_types', (TType.STRING,None), None, ), # 5 + (6, TType.BYTE, 'label_op', None, None, ), # 6 + (7, TType.LIST, 'labels', (TType.STRING,None), None, ), # 7 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, template_op=None, supported_template_types=None, label_op=None, labels=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 4 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.template_op = template_op + self.supported_template_types = supported_template_types + self.label_op = label_op + self.labels = labels + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.BYTE: + self.template_op = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.supported_template_types = [] + (_etype17, _size14) = iprot.readListBegin() + for _i18 in xrange(_size14): + _elem19 = iprot.readString() + self.supported_template_types.append(_elem19) + iprot.readListEnd() + else: + iprot.skip(ftype) + elif fid == 6: + if ftype == TType.BYTE: + self.label_op = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 7: + if ftype == TType.LIST: + self.labels = [] + (_etype23, _size20) = iprot.readListBegin() + for _i24 in xrange(_size20): + _elem25 = iprot.readString() + self.labels.append(_elem25) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('SubscribeMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.template_op is not None: + oprot.writeFieldBegin('template_op', TType.BYTE, 4) + oprot.writeByte(self.template_op) + oprot.writeFieldEnd() + if self.supported_template_types is not None: + oprot.writeFieldBegin('supported_template_types', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.supported_template_types)) + for iter26 in self.supported_template_types: + oprot.writeString(iter26) + oprot.writeListEnd() + oprot.writeFieldEnd() + if self.label_op is not None: + oprot.writeFieldBegin('label_op', TType.BYTE, 6) + oprot.writeByte(self.label_op) + oprot.writeFieldEnd() + if self.labels is not None: + oprot.writeFieldBegin('labels', TType.LIST, 7) + oprot.writeListBegin(TType.STRING, len(self.labels)) + for iter27 in self.labels: + oprot.writeString(iter27) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.template_op) + value = (value * 31) ^ hash(self.supported_template_types) + value = (value * 31) ^ hash(self.label_op) + value = (value * 31) ^ hash(self.labels) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class SubscribeResponseMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - responseCode + - comments + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 5, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.BYTE, 'responseCode', None, None, ), # 4 + (5, TType.LIST, 'comments', (TType.STRING,None), None, ), # 5 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, responseCode=None, comments=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 5 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.responseCode = responseCode + self.comments = comments + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.BYTE: + self.responseCode = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.comments = [] + (_etype31, _size28) = iprot.readListBegin() + for _i32 in xrange(_size28): + _elem33 = iprot.readString() + self.comments.append(_elem33) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('SubscribeResponseMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.responseCode is not None: + oprot.writeFieldBegin('responseCode', TType.BYTE, 4) + oprot.writeByte(self.responseCode) + oprot.writeFieldEnd() + if self.comments is not None: + oprot.writeFieldBegin('comments', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.comments)) + for iter34 in self.comments: + oprot.writeString(iter34) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.responseCode) + value = (value * 31) ^ hash(self.comments) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class PublishMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - template_type + - template + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 6, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.STRING, 'template_type', None, None, ), # 4 + (5, TType.LIST, 'template', (TType.STRING,None), None, ), # 5 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, template_type=None, template=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 6 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.template_type = template_type + self.template = template + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.STRING: + self.template_type = iprot.readString() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.template = [] + (_etype38, _size35) = iprot.readListBegin() + for _i39 in xrange(_size35): + _elem40 = iprot.readString() + self.template.append(_elem40) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('PublishMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.template_type is not None: + oprot.writeFieldBegin('template_type', TType.STRING, 4) + oprot.writeString(self.template_type) + oprot.writeFieldEnd() + if self.template is not None: + oprot.writeFieldBegin('template', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.template)) + for iter41 in self.template: + oprot.writeString(iter41) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.template_type) + value = (value * 31) ^ hash(self.template) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class PublishResponseMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - responseCode + - comments + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 7, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.BYTE, 'responseCode', None, None, ), # 4 + (5, TType.LIST, 'comments', (TType.STRING,None), None, ), # 5 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, responseCode=None, comments=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 7 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.responseCode = responseCode + self.comments = comments + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.BYTE: + self.responseCode = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.comments = [] + (_etype45, _size42) = iprot.readListBegin() + for _i46 in xrange(_size42): + _elem47 = iprot.readString() + self.comments.append(_elem47) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('PublishResponseMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.responseCode is not None: + oprot.writeFieldBegin('responseCode', TType.BYTE, 4) + oprot.writeByte(self.responseCode) + oprot.writeFieldEnd() + if self.comments is not None: + oprot.writeFieldBegin('comments', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.comments)) + for iter48 in self.comments: + oprot.writeString(iter48) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.responseCode) + value = (value * 31) ^ hash(self.comments) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class PushMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - template_type + - template + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 8, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.STRING, 'template_type', None, None, ), # 4 + (5, TType.LIST, 'template', (TType.STRING,None), None, ), # 5 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, template_type=None, template=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 8 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.template_type = template_type + self.template = template + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.STRING: + self.template_type = iprot.readString() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.template = [] + (_etype52, _size49) = iprot.readListBegin() + for _i53 in xrange(_size49): + _elem54 = iprot.readString() + self.template.append(_elem54) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('PushMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.template_type is not None: + oprot.writeFieldBegin('template_type', TType.STRING, 4) + oprot.writeString(self.template_type) + oprot.writeFieldEnd() + if self.template is not None: + oprot.writeFieldBegin('template', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.template)) + for iter55 in self.template: + oprot.writeString(iter55) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.template_type) + value = (value * 31) ^ hash(self.template) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class PushResponseMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - responseCode + - comments + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 9, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.BYTE, 'responseCode', None, None, ), # 4 + (5, TType.LIST, 'comments', (TType.STRING,None), None, ), # 5 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, responseCode=None, comments=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 9 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.responseCode = responseCode + self.comments = comments + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.BYTE: + self.responseCode = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.comments = [] + (_etype59, _size56) = iprot.readListBegin() + for _i60 in xrange(_size56): + _elem61 = iprot.readString() + self.comments.append(_elem61) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('PushResponseMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.responseCode is not None: + oprot.writeFieldBegin('responseCode', TType.BYTE, 4) + oprot.writeByte(self.responseCode) + oprot.writeFieldEnd() + if self.comments is not None: + oprot.writeFieldBegin('comments', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.comments)) + for iter62 in self.comments: + oprot.writeString(iter62) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.responseCode) + value = (value * 31) ^ hash(self.comments) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class QueryMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - queryString + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 10, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.LIST, 'queryString', (TType.STRING,None), None, ), # 4 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, queryString=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 10 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.queryString = queryString + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.LIST: + self.queryString = [] + (_etype66, _size63) = iprot.readListBegin() + for _i67 in xrange(_size63): + _elem68 = iprot.readString() + self.queryString.append(_elem68) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('QueryMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.queryString is not None: + oprot.writeFieldBegin('queryString', TType.LIST, 4) + oprot.writeListBegin(TType.STRING, len(self.queryString)) + for iter69 in self.queryString: + oprot.writeString(iter69) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.queryString) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) + +class QueryResponseMessage: + """ + Attributes: + - messageType + - domino_udid + - seq_no + - responseCode + - queryResponse + """ + + thrift_spec = ( + None, # 0 + (1, TType.BYTE, 'messageType', None, 11, ), # 1 + (2, TType.I64, 'domino_udid', None, None, ), # 2 + (3, TType.I64, 'seq_no', None, None, ), # 3 + (4, TType.BYTE, 'responseCode', None, None, ), # 4 + (5, TType.LIST, 'queryResponse', (TType.STRING,None), None, ), # 5 + ) + + def __init__(self, messageType=thrift_spec[1][4], domino_udid=None, seq_no=None, responseCode=None, queryResponse=None,): + if messageType is self.thrift_spec[1][4]: + messageType = 11 + self.messageType = messageType + self.domino_udid = domino_udid + self.seq_no = seq_no + self.responseCode = responseCode + self.queryResponse = queryResponse + + def read(self, iprot): + if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: + fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) + return + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.BYTE: + self.messageType = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I64: + self.domino_udid = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 3: + if ftype == TType.I64: + self.seq_no = iprot.readI64() + else: + iprot.skip(ftype) + elif fid == 4: + if ftype == TType.BYTE: + self.responseCode = iprot.readByte() + else: + iprot.skip(ftype) + elif fid == 5: + if ftype == TType.LIST: + self.queryResponse = [] + (_etype73, _size70) = iprot.readListBegin() + for _i74 in xrange(_size70): + _elem75 = iprot.readString() + self.queryResponse.append(_elem75) + iprot.readListEnd() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: + oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStructBegin('QueryResponseMessage') + if self.messageType is not None: + oprot.writeFieldBegin('messageType', TType.BYTE, 1) + oprot.writeByte(self.messageType) + oprot.writeFieldEnd() + if self.domino_udid is not None: + oprot.writeFieldBegin('domino_udid', TType.I64, 2) + oprot.writeI64(self.domino_udid) + oprot.writeFieldEnd() + if self.seq_no is not None: + oprot.writeFieldBegin('seq_no', TType.I64, 3) + oprot.writeI64(self.seq_no) + oprot.writeFieldEnd() + if self.responseCode is not None: + oprot.writeFieldBegin('responseCode', TType.BYTE, 4) + oprot.writeByte(self.responseCode) + oprot.writeFieldEnd() + if self.queryResponse is not None: + oprot.writeFieldBegin('queryResponse', TType.LIST, 5) + oprot.writeListBegin(TType.STRING, len(self.queryResponse)) + for iter76 in self.queryResponse: + oprot.writeString(iter76) + oprot.writeListEnd() + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() + + def validate(self): + return + + + def __hash__(self): + value = 17 + value = (value * 31) ^ hash(self.messageType) + value = (value * 31) ^ hash(self.domino_udid) + value = (value * 31) ^ hash(self.seq_no) + value = (value * 31) ^ hash(self.responseCode) + value = (value * 31) ^ hash(self.queryResponse) + return value + + def __repr__(self): + L = ['%s=%r' % (key, value) + for key, value in self.__dict__.iteritems()] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not (self == other) diff --git a/lib/dominoRPC/ttypes.pyc b/lib/dominoRPC/ttypes.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be548d11f8d5f66897b9d896ab98d37fccf60873 GIT binary patch literal 42261 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 NPO2Tqpkg3q004558R-B3 literal 0 HcmV?d00001 diff --git a/lib/mapper/label.py b/lib/mapper/label.py new file mode 100644 index 0000000..8591d7c --- /dev/null +++ b/lib/mapper/label.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + +# +# Licence statement goes here +# + +#from toscaparser.tosca_template import ToscaTemplate + +#Current version: +#Parses policy rules, extracts targets, extracts policy properties +#Returns set of policy properties for each target in a dictionary object +#e.g., node_labels['VNF1'] = {label1, label2, ..., labeln} +def extract_labels(tosca): + node_labels = dict() #stores labels for each node + + if tosca.tpl.has_key('topology_template'): + if tosca.tpl['topology_template'].has_key('policies'): + policies = tosca.tpl['topology_template']['policies'] + else: + return node_labels + else: + return node_labels + + #extract label sets for each policy target + for p in policies: + for rule in p: + targetlist = p[rule]['targets'] + for props in p[rule]['properties']: + prop_list = p[rule]['properties'][props] + for values in prop_list: + labelkey = p[rule]['type']+ ':properties:' + props + ":" + values + for target in targetlist: + if node_labels.has_key(target): + node_labels[target].update(set([labelkey])) + else: + node_labels[target] = set([labelkey]) + return node_labels + +# Returns a map from nodes to regions based on label matching +def map_nodes(site_labels,node_labels): + sitemap = dict() #stores mapping + + #for each target find a map of sites + for node in node_labels: + sitemap[node] = set() + for site in site_labels: + if node_labels[node].issubset(site_labels[site]): + sitemap[node].add(site) + + return sitemap + +# Selects sites for nodes if multiple candidates exist +# First iterate for nodes with single candidate site +# Rank sites with most nodes higher +def select_site( site_map ): + node_site = dict() + counter = dict() + #SHALL I CHECK IF ANY KEY HAS AN EMPTY SET TO THROW EXCEPTION? + #For now, I assume input as safe + + for node in site_map: + node_site[node] = [] + if len(site_map[node]) == 1: + for site in site_map[node]: + node_site[node] = site + if counter.has_key(site): + counter[site] = counter[site] + 1 + else: + counter[site] = 1 + + for node in site_map: + if len(site_map[node]) > 1: + maxval = 0 + maxkey = '-1' + for site in site_map[node]: + if counter.has_key(site) and counter[site] >= maxval: + maxval = counter[site] + maxkey = site + elif counter.has_key(site) == False: + counter[site] = 1 + if maxval == 0: + maxval = 1 + maxkey = site + node_site[node] = maxkey + return node_site diff --git a/lib/mapper/label.pyc b/lib/mapper/label.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a223fe78ab136d69f1bbaff34e258226906b943 GIT binary patch literal 1764 zcma)6U27Xh6uq;n4@-^WIMfwt(gsSP!cd#^rNo#}5~UBNb&K*KXc1zqUEH{inbPAuv<%DU9>f5-(U#4cjAjfAT2r8JK~yV{`Xr@weSGwX#N`Q7qk#%z3hd-Gx^N9(i!|h+oVJncGqFxRXLcGm4$o&{G)aP^D6vECtlOu$ zbGAq#4XX+GN8YDq>R}!4 z$ENB%hOtzyC;5meAB?}F>~K+N8Zw0B4)Xhy>|lIPH3%I*f0PCmKzLO8&T=W`0Zdh~ zBl8`k{RYzRA?>8^P^)N2I)==svJqRmI0FBghae2A0wDK*i+6rrfY6{Q-(_Mt$6wo$g0ZMggvWhc}l`SC4~>RKpmL@N1y?v zf9grr)6%NY!T5plsKrhP&_gzrwhVi!-GgVhG7siobD#BKH17$1qx_F5fZvuGd;8d$ zWUu(<;HAKWfu|vVei_(cywDJ?9$YuegYg2K)+Jkw;g8thKYzm*R-qzayxN;9vB4Dw z5`Ab8@!IpDfir$1JUC05=C1_5>PcXw9>%0SMiWb+es*sy7L`U4oewuKp;h)(kl3iN zF9b1F3RS`UYS9u=y-a6|a~Ea94>2>mMSsfgEXYximnLfQoz$bEjFJfT$Nj&+M)q@b z(2r@=I;M>Z+(N%;w!LkygHZ$jTjmb17V5EWu3>xw$YGza&XBb}yv>e9ypBPw|9J^` U=Yz9Zh&Skgz5!&gb*r`cAD)g*>Hq)$ literal 0 HcmV?d00001 diff --git a/lib/partitioner/__init__.py b/lib/partitioner/__init__.py new file mode 100644 index 0000000..15b0269 --- /dev/null +++ b/lib/partitioner/__init__.py @@ -0,0 +1 @@ +__all__ = ['partitioner'] diff --git a/lib/partitioner/__init__.pyc b/lib/partitioner/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f38019521226d3a15e197b287a13a4952acb2c5c GIT binary patch literal 154 zcmZSn%*&-R*El?x0SXv_v;zQ9KSd~a6#DysQkO*oIC=w2;rHaVf>`sz(Hs1Bl zq;svkzOWey!U59NUR{e~7yU?4=uJv8Qw`~gy2&Lhy_@AS}HC9{Sa%os5Tcj>*9M;I@C@a%i z{~Kx#{$eldTYvBx2fyV8zpw%Pu#+;m`?Hij8X39Bg^LWin0_nA5fN68bn(g`s==41 zlndmpZynLFLW6{|3Y_iHa9;2$l+6RK2p=U%KUSC>3%YQh$J`_0*rrqP63o#49Hlqa zi6y|l%T|>E6yz((2hhN@3m0{ODvNN$OoYIl zr{f|i#5%IgV;|vG^URKMYZBoUxB4_(7XBaZg5dr>#$6KJ>CzUS0b)@gZWKn#UOoe{ z_zVzAAi^=kg);j@1WA-`ApOY$}Q|OeNJ1(hz%9hL-d?@pe}fHsYQZ1wV?7ZgRu| zyc0$`@$8-qczX@o^BQat;RF-01~$;{83Edfyj{U(MKKUD_avg8Y_<^Y87L2Dma<+KgW)BUi z5`PLcwWt=#RaO_(73UnJ7t|%EcBVI$ zOn(;~pX1`anUu0$aoo8!$)&{Ew+^!}g4`(*lk|r&D`f;ZU=n_;z>6SWR0inhhINz( z;ko`})%#RU0VlkT@`_Seru3^5fO8|s2vEE*Cl20GQl&npVezy&{Qt?k%*2mET>x=o z4N?c|s4F?wg6Ab7$X(#D;tZz1xBaiD#?NNR{GA)Nd*7YN6qYWzVD^;Up@=|Yl2Py& zx*-0iWc1r<{*ifck#s1-FGylkGXZC3c+wz4Adsc44P854q z=C|WGzdAwa+ZIz&>%!PJ3XN?s)3k(D_}rx$OzrC?pF{DtBPjl1nv+D5>ifbp=pIorL+Yw?-nr(SS66YRYU;dt36jg|I;3x4d|fV^{Ph!J@Im#~ n>sixcB5J+D4aYKF#B<#LIT)@T!~t04ZBB#X_^Ybwlt1_vMg$w$ literal 0 HcmV?d00001 diff --git a/lib/thrift/TMultiplexedProcessor.py b/lib/thrift/TMultiplexedProcessor.py new file mode 100644 index 0000000..a8d5565 --- /dev/null +++ b/lib/thrift/TMultiplexedProcessor.py @@ -0,0 +1,58 @@ +# +# 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. +# + +from thrift.Thrift import TProcessor, TMessageType, TException +from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol + +class TMultiplexedProcessor(TProcessor): + def __init__(self): + self.services = {} + + def registerProcessor(self, serviceName, processor): + self.services[serviceName] = processor + + def process(self, iprot, oprot): + (name, type, seqid) = iprot.readMessageBegin(); + if type != TMessageType.CALL & type != TMessageType.ONEWAY: + raise TException("TMultiplex protocol only supports CALL & ONEWAY") + + index = name.find(TMultiplexedProtocol.SEPARATOR) + if index < 0: + raise TException("Service name not found in message name: " + name + ". Did you forget to use TMultiplexProtocol in your client?") + + serviceName = name[0:index] + call = name[index+len(TMultiplexedProtocol.SEPARATOR):] + if not serviceName in self.services: + raise TException("Service name not found: " + serviceName + ". Did you forget to call registerProcessor()?") + + standardMessage = ( + call, + type, + seqid + ) + return self.services[serviceName].process(StoredMessageProtocol(iprot, standardMessage), oprot) + + +class StoredMessageProtocol(TProtocolDecorator.TProtocolDecorator): + def __init__(self, protocol, messageBegin): + TProtocolDecorator.TProtocolDecorator.__init__(self, protocol) + self.messageBegin = messageBegin + + def readMessageBegin(self): + return self.messageBegin diff --git a/lib/thrift/TSCons.py b/lib/thrift/TSCons.py new file mode 100644 index 0000000..da8d283 --- /dev/null +++ b/lib/thrift/TSCons.py @@ -0,0 +1,35 @@ +# +# 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. +# + +from os import path +from SCons.Builder import Builder + + +def scons_env(env, add=''): + opath = path.dirname(path.abspath('$TARGET')) + lstr = 'thrift --gen cpp -o ' + opath + ' ' + add + ' $SOURCE' + cppbuild = Builder(action=lstr) + env.Append(BUILDERS={'ThriftCpp': cppbuild}) + + +def gen_cpp(env, dir, file): + scons_env(env) + suffixes = ['_types.h', '_types.cpp'] + targets = map(lambda s: 'gen-cpp/' + file + s, suffixes) + return env.ThriftCpp(targets, dir + file + '.thrift') diff --git a/lib/thrift/TSerialization.py b/lib/thrift/TSerialization.py new file mode 100644 index 0000000..8a58d89 --- /dev/null +++ b/lib/thrift/TSerialization.py @@ -0,0 +1,38 @@ +# +# 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. +# + +from protocol import TBinaryProtocol +from transport import TTransport + + +def serialize(thrift_object, + protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()): + transport = TTransport.TMemoryBuffer() + protocol = protocol_factory.getProtocol(transport) + thrift_object.write(protocol) + return transport.getvalue() + + +def deserialize(base, + buf, + protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()): + transport = TTransport.TMemoryBuffer(buf) + protocol = protocol_factory.getProtocol(transport) + base.read(protocol) + return base diff --git a/lib/thrift/TTornado.py b/lib/thrift/TTornado.py new file mode 100644 index 0000000..ef3e0f2 --- /dev/null +++ b/lib/thrift/TTornado.py @@ -0,0 +1,182 @@ +# +# 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. +# + +from __future__ import absolute_import +import socket +import struct + +import logging +logger = logging.getLogger(__name__) + +from thrift.transport.TTransport import TTransportException, TTransportBase, TMemoryBuffer + +from io import BytesIO +from collections import deque +from contextlib import contextmanager +from tornado import gen, iostream, ioloop, tcpserver, concurrent + +__all__ = ['TTornadoServer', 'TTornadoStreamTransport'] + + +class _Lock(object): + def __init__(self): + self._waiters = deque() + + def acquired(self): + return len(self._waiters) > 0 + + @gen.coroutine + def acquire(self): + blocker = self._waiters[-1] if self.acquired() else None + future = concurrent.Future() + self._waiters.append(future) + if blocker: + yield blocker + + raise gen.Return(self._lock_context()) + + def release(self): + assert self.acquired(), 'Lock not aquired' + future = self._waiters.popleft() + future.set_result(None) + + @contextmanager + def _lock_context(self): + try: + yield + finally: + self.release() + + +class TTornadoStreamTransport(TTransportBase): + """a framed, buffered transport over a Tornado stream""" + def __init__(self, host, port, stream=None, io_loop=None): + self.host = host + self.port = port + self.io_loop = io_loop or ioloop.IOLoop.current() + self.__wbuf = BytesIO() + self._read_lock = _Lock() + + # servers provide a ready-to-go stream + self.stream = stream + + def with_timeout(self, timeout, future): + return gen.with_timeout(timeout, future, self.io_loop) + + @gen.coroutine + def open(self, timeout=None): + logger.debug('socket connecting') + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) + self.stream = iostream.IOStream(sock) + + try: + connect = self.stream.connect((self.host, self.port)) + if timeout is not None: + yield self.with_timeout(timeout, connect) + else: + yield connect + except (socket.error, IOError, ioloop.TimeoutError) as e: + message = 'could not connect to {}:{} ({})'.format(self.host, self.port, e) + raise TTransportException( + type=TTransportException.NOT_OPEN, + message=message) + + raise gen.Return(self) + + def set_close_callback(self, callback): + """ + Should be called only after open() returns + """ + self.stream.set_close_callback(callback) + + def close(self): + # don't raise if we intend to close + self.stream.set_close_callback(None) + self.stream.close() + + def read(self, _): + # The generated code for Tornado shouldn't do individual reads -- only + # frames at a time + assert False, "you're doing it wrong" + + @contextmanager + def io_exception_context(self): + try: + yield + except (socket.error, IOError) as e: + raise TTransportException( + type=TTransportException.END_OF_FILE, + message=str(e)) + except iostream.StreamBufferFullError as e: + raise TTransportException( + type=TTransportException.UNKNOWN, + message=str(e)) + + @gen.coroutine + def readFrame(self): + # IOStream processes reads one at a time + with (yield self._read_lock.acquire()): + with self.io_exception_context(): + frame_header = yield self.stream.read_bytes(4) + if len(frame_header) == 0: + raise iostream.StreamClosedError('Read zero bytes from stream') + frame_length, = struct.unpack('!i', frame_header) + frame = yield self.stream.read_bytes(frame_length) + raise gen.Return(frame) + + def write(self, buf): + self.__wbuf.write(buf) + + def flush(self): + frame = self.__wbuf.getvalue() + # reset wbuf before write/flush to preserve state on underlying failure + frame_length = struct.pack('!i', len(frame)) + self.__wbuf = BytesIO() + with self.io_exception_context(): + return self.stream.write(frame_length + frame) + + +class TTornadoServer(tcpserver.TCPServer): + def __init__(self, processor, iprot_factory, oprot_factory=None, + *args, **kwargs): + super(TTornadoServer, self).__init__(*args, **kwargs) + + self._processor = processor + self._iprot_factory = iprot_factory + self._oprot_factory = (oprot_factory if oprot_factory is not None + else iprot_factory) + + @gen.coroutine + def handle_stream(self, stream, address): + host, port = address + trans = TTornadoStreamTransport(host=host, port=port, stream=stream, + io_loop=self.io_loop) + oprot = self._oprot_factory.getProtocol(trans) + + try: + while not trans.stream.closed(): + frame = yield trans.readFrame() + tr = TMemoryBuffer(frame) + iprot = self._iprot_factory.getProtocol(tr) + yield self._processor.process(iprot, oprot) + except Exception: + logger.exception('thrift exception in handle_stream') + trans.close() + + logger.info('client disconnected %s:%d', host, port) diff --git a/lib/thrift/Thrift.py b/lib/thrift/Thrift.py new file mode 100644 index 0000000..9890af7 --- /dev/null +++ b/lib/thrift/Thrift.py @@ -0,0 +1,170 @@ +# +# 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. +# + +import sys + + +class TType: + 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 + + _VALUES_TO_NAMES = ('STOP', + 'VOID', + 'BOOL', + 'BYTE', + 'DOUBLE', + None, + 'I16', + None, + 'I32', + None, + 'I64', + 'STRING', + 'STRUCT', + 'MAP', + 'SET', + 'LIST', + 'UTF8', + 'UTF16') + + +class TMessageType: + CALL = 1 + REPLY = 2 + EXCEPTION = 3 + ONEWAY = 4 + + +class TProcessor: + """Base class for procsessor, which works on two streams.""" + + def process(iprot, oprot): + pass + + +class TException(Exception): + """Base class for all thrift exceptions.""" + + # BaseException.message is deprecated in Python v[2.6,3.0) + if (2, 6, 0) <= sys.version_info < (3, 0): + def _get_message(self): + return self._message + + def _set_message(self, message): + self._message = message + message = property(_get_message, _set_message) + + def __init__(self, message=None): + Exception.__init__(self, message) + self.message = message + + +class TApplicationException(TException): + """Application level thrift exceptions.""" + + 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 + INVALID_TRANSFORM = 8 + INVALID_PROTOCOL = 9 + UNSUPPORTED_CLIENT_TYPE = 10 + + def __init__(self, type=UNKNOWN, message=None): + TException.__init__(self, message) + self.type = type + + def __str__(self): + if self.message: + return self.message + elif self.type == self.UNKNOWN_METHOD: + return 'Unknown method' + elif self.type == self.INVALID_MESSAGE_TYPE: + return 'Invalid message type' + elif self.type == self.WRONG_METHOD_NAME: + return 'Wrong method name' + elif self.type == self.BAD_SEQUENCE_ID: + return 'Bad sequence ID' + elif self.type == self.MISSING_RESULT: + return 'Missing result' + elif self.type == self.INTERNAL_ERROR: + return 'Internal error' + elif self.type == self.PROTOCOL_ERROR: + return 'Protocol error' + elif self.type == self.INVALID_TRANSFORM: + return 'Invalid transform' + elif self.type == self.INVALID_PROTOCOL: + return 'Invalid protocol' + elif self.type == self.UNSUPPORTED_CLIENT_TYPE: + return 'Unsupported client type' + else: + return 'Default (unknown) TApplicationException' + + def read(self, iprot): + iprot.readStructBegin() + while True: + (fname, ftype, fid) = iprot.readFieldBegin() + if ftype == TType.STOP: + break + if fid == 1: + if ftype == TType.STRING: + self.message = iprot.readString() + else: + iprot.skip(ftype) + elif fid == 2: + if ftype == TType.I32: + self.type = iprot.readI32() + else: + iprot.skip(ftype) + else: + iprot.skip(ftype) + iprot.readFieldEnd() + iprot.readStructEnd() + + def write(self, oprot): + oprot.writeStructBegin('TApplicationException') + if self.message is not None: + oprot.writeFieldBegin('message', TType.STRING, 1) + oprot.writeString(self.message) + oprot.writeFieldEnd() + if self.type is not None: + oprot.writeFieldBegin('type', TType.I32, 2) + oprot.writeI32(self.type) + oprot.writeFieldEnd() + oprot.writeFieldStop() + oprot.writeStructEnd() diff --git a/lib/thrift/Thrift.pyc b/lib/thrift/Thrift.pyc new file mode 100644 index 0000000000000000000000000000000000000000..941bb7733347828244c5daaeb9ba440874f80a0b GIT binary patch literal 4970 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 literal 0 HcmV?d00001 diff --git a/lib/thrift/protocol/TBase.py b/lib/thrift/protocol/TBase.py new file mode 100644 index 0000000..6cbd5f3 --- /dev/null +++ b/lib/thrift/protocol/TBase.py @@ -0,0 +1,81 @@ +# +# 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. +# + +from thrift.Thrift import * +from thrift.protocol import TBinaryProtocol +from thrift.transport import TTransport + +try: + from thrift.protocol import fastbinary +except: + fastbinary = None + + +class TBase(object): + __slots__ = [] + + def __repr__(self): + L = ['%s=%r' % (key, getattr(self, key)) + for key in self.__slots__] + return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + for attr in self.__slots__: + my_val = getattr(self, attr) + other_val = getattr(other, attr) + if my_val != other_val: + return False + return True + + def __ne__(self, other): + return not (self == other) + + def read(self, iprot): + if (iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and + isinstance(iprot.trans, TTransport.CReadableTransport) and + self.thrift_spec is not None and + fastbinary is not None): + fastbinary.decode_binary(self, + iprot.trans, + (self.__class__, self.thrift_spec)) + return + iprot.readStruct(self, self.thrift_spec) + + def write(self, oprot): + if (oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and + self.thrift_spec is not None and + fastbinary is not None): + oprot.trans.write( + fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) + return + oprot.writeStruct(self, self.thrift_spec) + + +class TExceptionBase(Exception): + # old style class so python2.4 can raise exceptions derived from this + # This can't inherit from TBase because of that limitation. + __slots__ = [] + + __repr__ = TBase.__repr__.im_func + __eq__ = TBase.__eq__.im_func + __ne__ = TBase.__ne__.im_func + read = TBase.read.im_func + write = TBase.write.im_func diff --git a/lib/thrift/protocol/TBinaryProtocol.py b/lib/thrift/protocol/TBinaryProtocol.py new file mode 100644 index 0000000..6fdd08c --- /dev/null +++ b/lib/thrift/protocol/TBinaryProtocol.py @@ -0,0 +1,260 @@ +# +# 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. +# + +from TProtocol import * +from struct import pack, unpack + + +class TBinaryProtocol(TProtocolBase): + """Binary implementation of the Thrift protocol driver.""" + + # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be + # positive, converting this into a long. If we hardcode the int value + # instead it'll stay in 32 bit-land. + + # VERSION_MASK = 0xffff0000 + VERSION_MASK = -65536 + + # VERSION_1 = 0x80010000 + VERSION_1 = -2147418112 + + TYPE_MASK = 0x000000ff + + def __init__(self, trans, strictRead=False, strictWrite=True): + TProtocolBase.__init__(self, trans) + self.strictRead = strictRead + self.strictWrite = strictWrite + + def writeMessageBegin(self, name, type, seqid): + if self.strictWrite: + self.writeI32(TBinaryProtocol.VERSION_1 | type) + self.writeString(name) + self.writeI32(seqid) + else: + self.writeString(name) + self.writeByte(type) + self.writeI32(seqid) + + def writeMessageEnd(self): + pass + + def writeStructBegin(self, name): + pass + + def writeStructEnd(self): + pass + + def writeFieldBegin(self, name, type, id): + self.writeByte(type) + self.writeI16(id) + + def writeFieldEnd(self): + pass + + def writeFieldStop(self): + self.writeByte(TType.STOP) + + def writeMapBegin(self, ktype, vtype, size): + self.writeByte(ktype) + self.writeByte(vtype) + self.writeI32(size) + + def writeMapEnd(self): + pass + + def writeListBegin(self, etype, size): + self.writeByte(etype) + self.writeI32(size) + + def writeListEnd(self): + pass + + def writeSetBegin(self, etype, size): + self.writeByte(etype) + self.writeI32(size) + + def writeSetEnd(self): + pass + + def writeBool(self, bool): + if bool: + self.writeByte(1) + else: + self.writeByte(0) + + def writeByte(self, byte): + buff = pack("!b", byte) + self.trans.write(buff) + + def writeI16(self, i16): + buff = pack("!h", i16) + self.trans.write(buff) + + def writeI32(self, i32): + buff = pack("!i", i32) + self.trans.write(buff) + + def writeI64(self, i64): + buff = pack("!q", i64) + self.trans.write(buff) + + def writeDouble(self, dub): + buff = pack("!d", dub) + self.trans.write(buff) + + def writeString(self, str): + self.writeI32(len(str)) + self.trans.write(str) + + def readMessageBegin(self): + sz = self.readI32() + if sz < 0: + version = sz & TBinaryProtocol.VERSION_MASK + if version != TBinaryProtocol.VERSION_1: + raise TProtocolException( + type=TProtocolException.BAD_VERSION, + message='Bad version in readMessageBegin: %d' % (sz)) + type = sz & TBinaryProtocol.TYPE_MASK + name = self.readString() + seqid = self.readI32() + else: + if self.strictRead: + raise TProtocolException(type=TProtocolException.BAD_VERSION, + message='No protocol version header') + name = self.trans.readAll(sz) + type = self.readByte() + seqid = self.readI32() + return (name, type, seqid) + + def readMessageEnd(self): + pass + + def readStructBegin(self): + pass + + def readStructEnd(self): + pass + + def readFieldBegin(self): + type = self.readByte() + if type == TType.STOP: + return (None, type, 0) + id = self.readI16() + return (None, type, id) + + def readFieldEnd(self): + pass + + def readMapBegin(self): + ktype = self.readByte() + vtype = self.readByte() + size = self.readI32() + return (ktype, vtype, size) + + def readMapEnd(self): + pass + + def readListBegin(self): + etype = self.readByte() + size = self.readI32() + return (etype, size) + + def readListEnd(self): + pass + + def readSetBegin(self): + etype = self.readByte() + size = self.readI32() + return (etype, size) + + def readSetEnd(self): + pass + + def readBool(self): + byte = self.readByte() + if byte == 0: + return False + return True + + def readByte(self): + buff = self.trans.readAll(1) + val, = unpack('!b', buff) + return val + + def readI16(self): + buff = self.trans.readAll(2) + val, = unpack('!h', buff) + return val + + def readI32(self): + buff = self.trans.readAll(4) + val, = unpack('!i', buff) + return val + + def readI64(self): + buff = self.trans.readAll(8) + val, = unpack('!q', buff) + return val + + def readDouble(self): + buff = self.trans.readAll(8) + val, = unpack('!d', buff) + return val + + def readString(self): + len = self.readI32() + str = self.trans.readAll(len) + return str + + +class TBinaryProtocolFactory: + def __init__(self, strictRead=False, strictWrite=True): + self.strictRead = strictRead + self.strictWrite = strictWrite + + def getProtocol(self, trans): + prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite) + return prot + + +class TBinaryProtocolAccelerated(TBinaryProtocol): + """C-Accelerated version of TBinaryProtocol. + + This class does not override any of TBinaryProtocol's methods, + but the generated code recognizes it directly and will call into + our C module to do the encoding, bypassing this object entirely. + We inherit from TBinaryProtocol so that the normal TBinaryProtocol + encoding can happen if the fastbinary module doesn't work for some + reason. (TODO(dreiss): Make this happen sanely in more cases.) + + In order to take advantage of the C module, just use + TBinaryProtocolAccelerated instead of TBinaryProtocol. + + NOTE: This code was contributed by an external developer. + The internal Thrift team has reviewed and tested it, + but we cannot guarantee that it is production-ready. + Please feel free to report bugs and/or success stories + to the public mailing list. + """ + pass + + +class TBinaryProtocolAcceleratedFactory: + def getProtocol(self, trans): + return TBinaryProtocolAccelerated(trans) diff --git a/lib/thrift/protocol/TBinaryProtocol.pyc b/lib/thrift/protocol/TBinaryProtocol.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c895567464dfbe70f1cbeddcff947b4578cad7c GIT binary patch literal 10720 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 literal 0 HcmV?d00001 diff --git a/lib/thrift/protocol/TCompactProtocol.py b/lib/thrift/protocol/TCompactProtocol.py new file mode 100644 index 0000000..7054ab0 --- /dev/null +++ b/lib/thrift/protocol/TCompactProtocol.py @@ -0,0 +1,405 @@ +# +# 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. +# + +from TProtocol import * +from struct import pack, unpack + +__all__ = ['TCompactProtocol', 'TCompactProtocolFactory'] + +CLEAR = 0 +FIELD_WRITE = 1 +VALUE_WRITE = 2 +CONTAINER_WRITE = 3 +BOOL_WRITE = 4 +FIELD_READ = 5 +CONTAINER_READ = 6 +VALUE_READ = 7 +BOOL_READ = 8 + + +def make_helper(v_from, container): + def helper(func): + def nested(self, *args, **kwargs): + assert self.state in (v_from, container), (self.state, v_from, container) + return func(self, *args, **kwargs) + return nested + return helper +writer = make_helper(VALUE_WRITE, CONTAINER_WRITE) +reader = make_helper(VALUE_READ, CONTAINER_READ) + + +def makeZigZag(n, bits): + checkIntegerLimits(n, bits) + return (n << 1) ^ (n >> (bits - 1)) + + +def fromZigZag(n): + return (n >> 1) ^ -(n & 1) + + +def writeVarint(trans, n): + out = [] + while True: + if n & ~0x7f == 0: + out.append(n) + break + else: + out.append((n & 0xff) | 0x80) + n = n >> 7 + trans.write(''.join(map(chr, out))) + + +def readVarint(trans): + result = 0 + shift = 0 + while True: + x = trans.readAll(1) + byte = ord(x) + result |= (byte & 0x7f) << shift + if byte >> 7 == 0: + return result + shift += 7 + + +class CompactType: + STOP = 0x00 + TRUE = 0x01 + FALSE = 0x02 + BYTE = 0x03 + I16 = 0x04 + I32 = 0x05 + I64 = 0x06 + DOUBLE = 0x07 + BINARY = 0x08 + LIST = 0x09 + SET = 0x0A + MAP = 0x0B + STRUCT = 0x0C + +CTYPES = {TType.STOP: CompactType.STOP, + TType.BOOL: CompactType.TRUE, # used for collection + TType.BYTE: CompactType.BYTE, + TType.I16: CompactType.I16, + TType.I32: CompactType.I32, + TType.I64: CompactType.I64, + TType.DOUBLE: CompactType.DOUBLE, + TType.STRING: CompactType.BINARY, + TType.STRUCT: CompactType.STRUCT, + TType.LIST: CompactType.LIST, + TType.SET: CompactType.SET, + TType.MAP: CompactType.MAP + } + +TTYPES = {} +for k, v in CTYPES.items(): + TTYPES[v] = k +TTYPES[CompactType.FALSE] = TType.BOOL +del k +del v + + +class TCompactProtocol(TProtocolBase): + """Compact implementation of the Thrift protocol driver.""" + + PROTOCOL_ID = 0x82 + VERSION = 1 + VERSION_MASK = 0x1f + TYPE_MASK = 0xe0 + TYPE_BITS = 0x07 + TYPE_SHIFT_AMOUNT = 5 + + def __init__(self, trans): + TProtocolBase.__init__(self, trans) + self.state = CLEAR + self.__last_fid = 0 + self.__bool_fid = None + self.__bool_value = None + self.__structs = [] + self.__containers = [] + + def __writeVarint(self, n): + writeVarint(self.trans, n) + + def writeMessageBegin(self, name, type, seqid): + assert self.state == CLEAR + self.__writeUByte(self.PROTOCOL_ID) + self.__writeUByte(self.VERSION | (type << self.TYPE_SHIFT_AMOUNT)) + self.__writeVarint(seqid) + self.__writeString(name) + self.state = VALUE_WRITE + + def writeMessageEnd(self): + assert self.state == VALUE_WRITE + self.state = CLEAR + + def writeStructBegin(self, name): + assert self.state in (CLEAR, CONTAINER_WRITE, VALUE_WRITE), self.state + self.__structs.append((self.state, self.__last_fid)) + self.state = FIELD_WRITE + self.__last_fid = 0 + + def writeStructEnd(self): + assert self.state == FIELD_WRITE + self.state, self.__last_fid = self.__structs.pop() + + def writeFieldStop(self): + self.__writeByte(0) + + def __writeFieldHeader(self, type, fid): + delta = fid - self.__last_fid + if 0 < delta <= 15: + self.__writeUByte(delta << 4 | type) + else: + self.__writeByte(type) + self.__writeI16(fid) + self.__last_fid = fid + + def writeFieldBegin(self, name, type, fid): + assert self.state == FIELD_WRITE, self.state + if type == TType.BOOL: + self.state = BOOL_WRITE + self.__bool_fid = fid + else: + self.state = VALUE_WRITE + self.__writeFieldHeader(CTYPES[type], fid) + + def writeFieldEnd(self): + assert self.state in (VALUE_WRITE, BOOL_WRITE), self.state + self.state = FIELD_WRITE + + def __writeUByte(self, byte): + self.trans.write(pack('!B', byte)) + + def __writeByte(self, byte): + self.trans.write(pack('!b', byte)) + + def __writeI16(self, i16): + self.__writeVarint(makeZigZag(i16, 16)) + + def __writeSize(self, i32): + self.__writeVarint(i32) + + def writeCollectionBegin(self, etype, size): + assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state + if size <= 14: + self.__writeUByte(size << 4 | CTYPES[etype]) + else: + self.__writeUByte(0xf0 | CTYPES[etype]) + self.__writeSize(size) + self.__containers.append(self.state) + self.state = CONTAINER_WRITE + writeSetBegin = writeCollectionBegin + writeListBegin = writeCollectionBegin + + def writeMapBegin(self, ktype, vtype, size): + assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state + if size == 0: + self.__writeByte(0) + else: + self.__writeSize(size) + self.__writeUByte(CTYPES[ktype] << 4 | CTYPES[vtype]) + self.__containers.append(self.state) + self.state = CONTAINER_WRITE + + def writeCollectionEnd(self): + assert self.state == CONTAINER_WRITE, self.state + self.state = self.__containers.pop() + writeMapEnd = writeCollectionEnd + writeSetEnd = writeCollectionEnd + writeListEnd = writeCollectionEnd + + def writeBool(self, bool): + if self.state == BOOL_WRITE: + if bool: + ctype = CompactType.TRUE + else: + ctype = CompactType.FALSE + self.__writeFieldHeader(ctype, self.__bool_fid) + elif self.state == CONTAINER_WRITE: + if bool: + self.__writeByte(CompactType.TRUE) + else: + self.__writeByte(CompactType.FALSE) + else: + raise AssertionError("Invalid state in compact protocol") + + writeByte = writer(__writeByte) + writeI16 = writer(__writeI16) + + @writer + def writeI32(self, i32): + self.__writeVarint(makeZigZag(i32, 32)) + + @writer + def writeI64(self, i64): + self.__writeVarint(makeZigZag(i64, 64)) + + @writer + def writeDouble(self, dub): + self.trans.write(pack('> 4 + if delta == 0: + fid = self.__readI16() + else: + fid = self.__last_fid + delta + self.__last_fid = fid + type = type & 0x0f + if type == CompactType.TRUE: + self.state = BOOL_READ + self.__bool_value = True + elif type == CompactType.FALSE: + self.state = BOOL_READ + self.__bool_value = False + else: + self.state = VALUE_READ + return (None, self.__getTType(type), fid) + + def readFieldEnd(self): + assert self.state in (VALUE_READ, BOOL_READ), self.state + self.state = FIELD_READ + + def __readUByte(self): + result, = unpack('!B', self.trans.readAll(1)) + return result + + def __readByte(self): + result, = unpack('!b', self.trans.readAll(1)) + return result + + def __readVarint(self): + return readVarint(self.trans) + + def __readZigZag(self): + return fromZigZag(self.__readVarint()) + + def __readSize(self): + result = self.__readVarint() + if result < 0: + raise TException("Length < 0") + return result + + def readMessageBegin(self): + assert self.state == CLEAR + proto_id = self.__readUByte() + if proto_id != self.PROTOCOL_ID: + raise TProtocolException(TProtocolException.BAD_VERSION, + 'Bad protocol id in the message: %d' % proto_id) + ver_type = self.__readUByte() + type = (ver_type >> self.TYPE_SHIFT_AMOUNT) & self.TYPE_BITS + version = ver_type & self.VERSION_MASK + if version != self.VERSION: + raise TProtocolException(TProtocolException.BAD_VERSION, + 'Bad version: %d (expect %d)' % (version, self.VERSION)) + seqid = self.__readVarint() + name = self.__readString() + return (name, type, seqid) + + def readMessageEnd(self): + assert self.state == CLEAR + assert len(self.__structs) == 0 + + def readStructBegin(self): + assert self.state in (CLEAR, CONTAINER_READ, VALUE_READ), self.state + self.__structs.append((self.state, self.__last_fid)) + self.state = FIELD_READ + self.__last_fid = 0 + + def readStructEnd(self): + assert self.state == FIELD_READ + self.state, self.__last_fid = self.__structs.pop() + + def readCollectionBegin(self): + assert self.state in (VALUE_READ, CONTAINER_READ), self.state + size_type = self.__readUByte() + size = size_type >> 4 + type = self.__getTType(size_type) + if size == 15: + size = self.__readSize() + self.__containers.append(self.state) + self.state = CONTAINER_READ + return type, size + readSetBegin = readCollectionBegin + readListBegin = readCollectionBegin + + def readMapBegin(self): + assert self.state in (VALUE_READ, CONTAINER_READ), self.state + size = self.__readSize() + types = 0 + if size > 0: + types = self.__readUByte() + vtype = self.__getTType(types) + ktype = self.__getTType(types >> 4) + self.__containers.append(self.state) + self.state = CONTAINER_READ + return (ktype, vtype, size) + + def readCollectionEnd(self): + assert self.state == CONTAINER_READ, self.state + self.state = self.__containers.pop() + readSetEnd = readCollectionEnd + readListEnd = readCollectionEnd + readMapEnd = readCollectionEnd + + def readBool(self): + if self.state == BOOL_READ: + return self.__bool_value == CompactType.TRUE + elif self.state == CONTAINER_READ: + return self.__readByte() == CompactType.TRUE + else: + raise AssertionError("Invalid state in compact protocol: %d" % + self.state) + + readByte = reader(__readByte) + __readI16 = __readZigZag + readI16 = reader(__readZigZag) + readI32 = reader(__readZigZag) + readI64 = reader(__readZigZag) + + @reader + def readDouble(self): + buff = self.trans.readAll(8) + val, = unpack(' 127): + raise TProtocolException(TProtocolException.INVALID_DATA, + "i8 requires -128 <= number <= 127") + elif bits == 16 and (i < -32768 or i > 32767): + raise TProtocolException(TProtocolException.INVALID_DATA, + "i16 requires -32768 <= number <= 32767") + elif bits == 32 and (i < -2147483648 or i > 2147483647): + raise TProtocolException(TProtocolException.INVALID_DATA, + "i32 requires -2147483648 <= number <= 2147483647") + elif bits == 64 and (i < -9223372036854775808 or i > 9223372036854775807): + raise TProtocolException(TProtocolException.INVALID_DATA, + "i64 requires -9223372036854775808 <= number <= 9223372036854775807") + +class TProtocolFactory: + def getProtocol(self, trans): + pass diff --git a/lib/thrift/protocol/TProtocol.pyc b/lib/thrift/protocol/TProtocol.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ec8411aea978ca7c14d7bb03e4011477f4a4d76 GIT binary patch literal 14621 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 F{{kIeSCjw% literal 0 HcmV?d00001 diff --git a/lib/thrift/protocol/TProtocolDecorator.py b/lib/thrift/protocol/TProtocolDecorator.py new file mode 100644 index 0000000..3e9e500 --- /dev/null +++ b/lib/thrift/protocol/TProtocolDecorator.py @@ -0,0 +1,42 @@ +# +# 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. +# + +from thrift.protocol.TProtocol import TProtocolBase +from types import * + +class TProtocolDecorator(): + def __init__(self, protocol): + TProtocolBase(protocol) + self.protocol = protocol + + def __getattr__(self, name): + if hasattr(self.protocol, name): + member = getattr(self.protocol, name) + if type(member) in [MethodType, UnboundMethodType, FunctionType, LambdaType, BuiltinFunctionType, BuiltinMethodType]: + return lambda *args, **kwargs: self._wrap(member, args, kwargs) + else: + return member + raise AttributeError(name) + + def _wrap(self, func, args, kwargs): + if type(func) == MethodType: + result = func(*args, **kwargs) + else: + result = func(self.protocol, *args, **kwargs) + return result diff --git a/lib/thrift/protocol/__init__.py b/lib/thrift/protocol/__init__.py new file mode 100644 index 0000000..7eefb45 --- /dev/null +++ b/lib/thrift/protocol/__init__.py @@ -0,0 +1,20 @@ +# +# 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. +# + +__all__ = ['fastbinary', 'TBase', 'TBinaryProtocol', 'TCompactProtocol', 'TJSONProtocol', 'TProtocol'] diff --git a/lib/thrift/protocol/__init__.pyc b/lib/thrift/protocol/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a259bbd3fd3b31a7f4ca5ed11ef22f275ebc41a3 GIT binary patch literal 254 zcmYL?!3u&v5QfK0D?#eeu}e2k`T`MAw+QpP7G;E`bil^8?zk%C$zw5}TA-}W>EQ;7XV~i`sSU?v3V&)XXNXaC^ gTP<^ps`g*Rm@FkS7FG`&($%8S;;ypgl)RyV5B79C1ONa4 literal 0 HcmV?d00001 diff --git a/lib/thrift/protocol/fastbinary.so b/lib/thrift/protocol/fastbinary.so new file mode 100755 index 0000000000000000000000000000000000000000..e9e73e3e7ca35635311a92a02045d58f2f46b146 GIT binary patch literal 49272 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 SSLgBYe3p3a-#_m;{{I5OS;`#% literal 0 HcmV?d00001 diff --git a/lib/thrift/server/THttpServer.py b/lib/thrift/server/THttpServer.py new file mode 100644 index 0000000..6f92173 --- /dev/null +++ b/lib/thrift/server/THttpServer.py @@ -0,0 +1,87 @@ +# +# 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. +# + +import BaseHTTPServer + +from thrift.server import TServer +from thrift.transport import TTransport + + +class ResponseException(Exception): + """Allows handlers to override the HTTP response + + Normally, THttpServer always sends a 200 response. If a handler wants + to override this behavior (e.g., to simulate a misconfigured or + overloaded web server during testing), it can raise a ResponseException. + The function passed to the constructor will be called with the + RequestHandler as its only argument. + """ + def __init__(self, handler): + self.handler = handler + + +class THttpServer(TServer.TServer): + """A simple HTTP-based Thrift server + + This class is not very performant, but it is useful (for example) for + acting as a mock version of an Apache-based PHP Thrift endpoint. + """ + def __init__(self, + processor, + server_address, + inputProtocolFactory, + outputProtocolFactory=None, + server_class=BaseHTTPServer.HTTPServer): + """Set up protocol factories and HTTP server. + + See BaseHTTPServer for server_address. + See TServer for protocol factories. + """ + if outputProtocolFactory is None: + outputProtocolFactory = inputProtocolFactory + + TServer.TServer.__init__(self, processor, None, None, None, + inputProtocolFactory, outputProtocolFactory) + + thttpserver = self + + class RequestHander(BaseHTTPServer.BaseHTTPRequestHandler): + def do_POST(self): + # Don't care about the request path. + itrans = TTransport.TFileObjectTransport(self.rfile) + otrans = TTransport.TFileObjectTransport(self.wfile) + itrans = TTransport.TBufferedTransport( + itrans, int(self.headers['Content-Length'])) + otrans = TTransport.TMemoryBuffer() + iprot = thttpserver.inputProtocolFactory.getProtocol(itrans) + oprot = thttpserver.outputProtocolFactory.getProtocol(otrans) + try: + thttpserver.processor.process(iprot, oprot) + except ResponseException as exn: + exn.handler(self) + else: + self.send_response(200) + self.send_header("content-type", "application/x-thrift") + self.end_headers() + self.wfile.write(otrans.getvalue()) + + self.httpd = server_class(server_address, RequestHander) + + def serve(self): + self.httpd.serve_forever() diff --git a/lib/thrift/server/TNonblockingServer.py b/lib/thrift/server/TNonblockingServer.py new file mode 100644 index 0000000..39486cd --- /dev/null +++ b/lib/thrift/server/TNonblockingServer.py @@ -0,0 +1,348 @@ +# +# 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. +# +"""Implementation of non-blocking server. + +The main idea of the server is to receive and send requests +only from the main thread. + +The thread poool should be sized for concurrent tasks, not +maximum connections +""" +import threading +import socket +import Queue +import select +import struct + +import logging +logger = logging.getLogger(__name__) + +from thrift.transport import TTransport +from thrift.protocol.TBinaryProtocol import TBinaryProtocolFactory + +__all__ = ['TNonblockingServer'] + + +class Worker(threading.Thread): + """Worker is a small helper to process incoming connection.""" + + def __init__(self, queue): + threading.Thread.__init__(self) + self.queue = queue + + def run(self): + """Process queries from task queue, stop if processor is None.""" + while True: + try: + processor, iprot, oprot, otrans, callback = self.queue.get() + if processor is None: + break + processor.process(iprot, oprot) + callback(True, otrans.getvalue()) + except Exception: + logger.exception("Exception while processing request") + callback(False, '') + +WAIT_LEN = 0 +WAIT_MESSAGE = 1 +WAIT_PROCESS = 2 +SEND_ANSWER = 3 +CLOSED = 4 + + +def locked(func): + """Decorator which locks self.lock.""" + def nested(self, *args, **kwargs): + self.lock.acquire() + try: + return func(self, *args, **kwargs) + finally: + self.lock.release() + return nested + + +def socket_exception(func): + """Decorator close object on socket.error.""" + def read(self, *args, **kwargs): + try: + return func(self, *args, **kwargs) + except socket.error: + self.close() + return read + + +class Connection: + """Basic class is represented connection. + + It can be in state: + WAIT_LEN --- connection is reading request len. + WAIT_MESSAGE --- connection is reading request. + WAIT_PROCESS --- connection has just read whole request and + waits for call ready routine. + SEND_ANSWER --- connection is sending answer string (including length + of answer). + CLOSED --- socket was closed and connection should be deleted. + """ + def __init__(self, new_socket, wake_up): + self.socket = new_socket + self.socket.setblocking(False) + self.status = WAIT_LEN + self.len = 0 + self.message = '' + self.lock = threading.Lock() + self.wake_up = wake_up + + def _read_len(self): + """Reads length of request. + + It's a safer alternative to self.socket.recv(4) + """ + read = self.socket.recv(4 - len(self.message)) + if len(read) == 0: + # if we read 0 bytes and self.message is empty, then + # the client closed the connection + if len(self.message) != 0: + logger.error("can't read frame size from socket") + self.close() + return + self.message += read + if len(self.message) == 4: + self.len, = struct.unpack('!i', self.message) + if self.len < 0: + logger.error("negative frame size, it seems client " + "doesn't use FramedTransport") + self.close() + elif self.len == 0: + logger.error("empty frame, it's really strange") + self.close() + else: + self.message = '' + self.status = WAIT_MESSAGE + + @socket_exception + def read(self): + """Reads data from stream and switch state.""" + assert self.status in (WAIT_LEN, WAIT_MESSAGE) + if self.status == WAIT_LEN: + self._read_len() + # go back to the main loop here for simplicity instead of + # falling through, even though there is a good chance that + # the message is already available + elif self.status == WAIT_MESSAGE: + read = self.socket.recv(self.len - len(self.message)) + if len(read) == 0: + logger.error("can't read frame from socket (get %d of " + "%d bytes)" % (len(self.message), self.len)) + self.close() + return + self.message += read + if len(self.message) == self.len: + self.status = WAIT_PROCESS + + @socket_exception + def write(self): + """Writes data from socket and switch state.""" + assert self.status == SEND_ANSWER + sent = self.socket.send(self.message) + if sent == len(self.message): + self.status = WAIT_LEN + self.message = '' + self.len = 0 + else: + self.message = self.message[sent:] + + @locked + def ready(self, all_ok, message): + """Callback function for switching state and waking up main thread. + + This function is the only function witch can be called asynchronous. + + The ready can switch Connection to three states: + WAIT_LEN if request was oneway. + SEND_ANSWER if request was processed in normal way. + CLOSED if request throws unexpected exception. + + The one wakes up main thread. + """ + assert self.status == WAIT_PROCESS + if not all_ok: + self.close() + self.wake_up() + return + self.len = '' + if len(message) == 0: + # it was a oneway request, do not write answer + self.message = '' + self.status = WAIT_LEN + else: + self.message = struct.pack('!i', len(message)) + message + self.status = SEND_ANSWER + self.wake_up() + + @locked + def is_writeable(self): + """Return True if connection should be added to write list of select""" + return self.status == SEND_ANSWER + + # it's not necessary, but... + @locked + def is_readable(self): + """Return True if connection should be added to read list of select""" + return self.status in (WAIT_LEN, WAIT_MESSAGE) + + @locked + def is_closed(self): + """Returns True if connection is closed.""" + return self.status == CLOSED + + def fileno(self): + """Returns the file descriptor of the associated socket.""" + return self.socket.fileno() + + def close(self): + """Closes connection""" + self.status = CLOSED + self.socket.close() + + +class TNonblockingServer: + """Non-blocking server.""" + + def __init__(self, + processor, + lsocket, + inputProtocolFactory=None, + outputProtocolFactory=None, + threads=10): + self.processor = processor + self.socket = lsocket + self.in_protocol = inputProtocolFactory or TBinaryProtocolFactory() + self.out_protocol = outputProtocolFactory or self.in_protocol + self.threads = int(threads) + self.clients = {} + self.tasks = Queue.Queue() + self._read, self._write = socket.socketpair() + self.prepared = False + self._stop = False + + def setNumThreads(self, num): + """Set the number of worker threads that should be created.""" + # implement ThreadPool interface + assert not self.prepared, "Can't change number of threads after start" + self.threads = num + + def prepare(self): + """Prepares server for serve requests.""" + if self.prepared: + return + self.socket.listen() + for _ in xrange(self.threads): + thread = Worker(self.tasks) + thread.setDaemon(True) + thread.start() + self.prepared = True + + def wake_up(self): + """Wake up main thread. + + The server usually waits in select call in we should terminate one. + The simplest way is using socketpair. + + Select always wait to read from the first socket of socketpair. + + In this case, we can just write anything to the second socket from + socketpair. + """ + self._write.send('1') + + def stop(self): + """Stop the server. + + This method causes the serve() method to return. stop() may be invoked + from within your handler, or from another thread. + + After stop() is called, serve() will return but the server will still + be listening on the socket. serve() may then be called again to resume + processing requests. Alternatively, close() may be called after + serve() returns to close the server socket and shutdown all worker + threads. + """ + self._stop = True + self.wake_up() + + def _select(self): + """Does select on open connections.""" + readable = [self.socket.handle.fileno(), self._read.fileno()] + writable = [] + for i, connection in self.clients.items(): + if connection.is_readable(): + readable.append(connection.fileno()) + if connection.is_writeable(): + writable.append(connection.fileno()) + if connection.is_closed(): + del self.clients[i] + return select.select(readable, writable, readable) + + def handle(self): + """Handle requests. + + WARNING! You must call prepare() BEFORE calling handle() + """ + assert self.prepared, "You have to call prepare before handle" + rset, wset, xset = self._select() + for readable in rset: + if readable == self._read.fileno(): + # don't care i just need to clean readable flag + self._read.recv(1024) + elif readable == self.socket.handle.fileno(): + client = self.socket.accept().handle + self.clients[client.fileno()] = Connection(client, + self.wake_up) + else: + connection = self.clients[readable] + connection.read() + if connection.status == WAIT_PROCESS: + itransport = TTransport.TMemoryBuffer(connection.message) + otransport = TTransport.TMemoryBuffer() + iprot = self.in_protocol.getProtocol(itransport) + oprot = self.out_protocol.getProtocol(otransport) + self.tasks.put([self.processor, iprot, oprot, + otransport, connection.ready]) + for writeable in wset: + self.clients[writeable].write() + for oob in xset: + self.clients[oob].close() + del self.clients[oob] + + def close(self): + """Closes the server.""" + for _ in xrange(self.threads): + self.tasks.put([None, None, None, None, None]) + self.socket.close() + self.prepared = False + + def serve(self): + """Serve requests. + + Serve requests forever, or until stop() is called. + """ + self._stop = False + self.prepare() + while not self._stop: + self.handle() diff --git a/lib/thrift/server/TProcessPoolServer.py b/lib/thrift/server/TProcessPoolServer.py new file mode 100644 index 0000000..ae7fe1c --- /dev/null +++ b/lib/thrift/server/TProcessPoolServer.py @@ -0,0 +1,122 @@ +# +# 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. +# + + +import logging +logger = logging.getLogger(__name__) + +from multiprocessing import Process, Value, Condition, reduction + +from TServer import TServer +from thrift.transport.TTransport import TTransportException + + +class TProcessPoolServer(TServer): + """Server with a fixed size pool of worker subprocesses to service requests + + Note that if you need shared state between the handlers - it's up to you! + Written by Dvir Volk, doat.com + """ + def __init__(self, *args): + TServer.__init__(self, *args) + self.numWorkers = 10 + self.workers = [] + self.isRunning = Value('b', False) + self.stopCondition = Condition() + self.postForkCallback = None + + def setPostForkCallback(self, callback): + if not callable(callback): + raise TypeError("This is not a callback!") + self.postForkCallback = callback + + def setNumWorkers(self, num): + """Set the number of worker threads that should be created""" + self.numWorkers = num + + def workerProcess(self): + """Loop getting clients from the shared queue and process them""" + if self.postForkCallback: + self.postForkCallback() + + while self.isRunning.value: + try: + client = self.serverTransport.accept() + if not client: + continue + self.serveClient(client) + except (KeyboardInterrupt, SystemExit): + return 0 + except Exception as x: + logger.exception(x) + + def serveClient(self, client): + """Process input/output from a client for as long as possible""" + itrans = self.inputTransportFactory.getTransport(client) + otrans = self.outputTransportFactory.getTransport(client) + iprot = self.inputProtocolFactory.getProtocol(itrans) + oprot = self.outputProtocolFactory.getProtocol(otrans) + + try: + while True: + self.processor.process(iprot, oprot) + except TTransportException as tx: + pass + except Exception as x: + logger.exception(x) + + itrans.close() + otrans.close() + + def serve(self): + """Start workers and put into queue""" + # this is a shared state that can tell the workers to exit when False + self.isRunning.value = True + + # first bind and listen to the port + self.serverTransport.listen() + + # fork the children + for i in range(self.numWorkers): + try: + w = Process(target=self.workerProcess) + w.daemon = True + w.start() + self.workers.append(w) + except Exception as x: + logger.exception(x) + + # wait until the condition is set by stop() + while True: + self.stopCondition.acquire() + try: + self.stopCondition.wait() + break + except (SystemExit, KeyboardInterrupt): + break + except Exception as x: + logger.exception(x) + + self.isRunning.value = False + + def stop(self): + self.isRunning.value = False + self.stopCondition.acquire() + self.stopCondition.notify() + self.stopCondition.release() diff --git a/lib/thrift/server/TServer.py b/lib/thrift/server/TServer.py new file mode 100644 index 0000000..8c58e39 --- /dev/null +++ b/lib/thrift/server/TServer.py @@ -0,0 +1,279 @@ +# +# 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. +# + +import Queue +import os +import sys +import threading +import traceback + +import logging +logger = logging.getLogger(__name__) + +from thrift.Thrift import TProcessor +from thrift.protocol import TBinaryProtocol +from thrift.transport import TTransport + + +class TServer: + """Base interface for a server, which must have a serve() method. + + Three constructors for all servers: + 1) (processor, serverTransport) + 2) (processor, serverTransport, transportFactory, protocolFactory) + 3) (processor, serverTransport, + inputTransportFactory, outputTransportFactory, + inputProtocolFactory, outputProtocolFactory) + """ + def __init__(self, *args): + if (len(args) == 2): + self.__initArgs__(args[0], args[1], + TTransport.TTransportFactoryBase(), + TTransport.TTransportFactoryBase(), + TBinaryProtocol.TBinaryProtocolFactory(), + TBinaryProtocol.TBinaryProtocolFactory()) + elif (len(args) == 4): + self.__initArgs__(args[0], args[1], args[2], args[2], args[3], args[3]) + elif (len(args) == 6): + self.__initArgs__(args[0], args[1], args[2], args[3], args[4], args[5]) + + def __initArgs__(self, processor, serverTransport, + inputTransportFactory, outputTransportFactory, + inputProtocolFactory, outputProtocolFactory): + self.processor = processor + self.serverTransport = serverTransport + self.inputTransportFactory = inputTransportFactory + self.outputTransportFactory = outputTransportFactory + self.inputProtocolFactory = inputProtocolFactory + self.outputProtocolFactory = outputProtocolFactory + + def serve(self): + pass + + +class TSimpleServer(TServer): + """Simple single-threaded server that just pumps around one transport.""" + + def __init__(self, *args): + TServer.__init__(self, *args) + + def serve(self): + self.serverTransport.listen() + while True: + client = self.serverTransport.accept() + if not client: + continue + itrans = self.inputTransportFactory.getTransport(client) + otrans = self.outputTransportFactory.getTransport(client) + iprot = self.inputProtocolFactory.getProtocol(itrans) + oprot = self.outputProtocolFactory.getProtocol(otrans) + try: + while True: + self.processor.process(iprot, oprot) + except TTransport.TTransportException as tx: + pass + except Exception as x: + logger.exception(x) + + itrans.close() + otrans.close() + + +class TThreadedServer(TServer): + """Threaded server that spawns a new thread per each connection.""" + + def __init__(self, *args, **kwargs): + TServer.__init__(self, *args) + self.daemon = kwargs.get("daemon", False) + + def serve(self): + self.serverTransport.listen() + while True: + try: + client = self.serverTransport.accept() + if not client: + continue + t = threading.Thread(target=self.handle, args=(client,)) + t.setDaemon(self.daemon) + t.start() + except KeyboardInterrupt: + raise + except Exception as x: + logger.exception(x) + + def handle(self, client): + itrans = self.inputTransportFactory.getTransport(client) + otrans = self.outputTransportFactory.getTransport(client) + iprot = self.inputProtocolFactory.getProtocol(itrans) + oprot = self.outputProtocolFactory.getProtocol(otrans) + try: + while True: + self.processor.process(iprot, oprot) + except TTransport.TTransportException as tx: + pass + except Exception as x: + logger.exception(x) + + itrans.close() + otrans.close() + + +class TThreadPoolServer(TServer): + """Server with a fixed size pool of threads which service requests.""" + + def __init__(self, *args, **kwargs): + TServer.__init__(self, *args) + self.clients = Queue.Queue() + self.threads = 10 + self.daemon = kwargs.get("daemon", False) + + def setNumThreads(self, num): + """Set the number of worker threads that should be created""" + self.threads = num + + def serveThread(self): + """Loop around getting clients from the shared queue and process them.""" + while True: + try: + client = self.clients.get() + self.serveClient(client) + except Exception as x: + logger.exception(x) + + def serveClient(self, client): + """Process input/output from a client for as long as possible""" + itrans = self.inputTransportFactory.getTransport(client) + otrans = self.outputTransportFactory.getTransport(client) + iprot = self.inputProtocolFactory.getProtocol(itrans) + oprot = self.outputProtocolFactory.getProtocol(otrans) + try: + while True: + self.processor.process(iprot, oprot) + except TTransport.TTransportException as tx: + pass + except Exception as x: + logger.exception(x) + + itrans.close() + otrans.close() + + def serve(self): + """Start a fixed number of worker threads and put client into a queue""" + for i in range(self.threads): + try: + t = threading.Thread(target=self.serveThread) + t.setDaemon(self.daemon) + t.start() + except Exception as x: + logger.exception(x) + + # Pump the socket for clients + self.serverTransport.listen() + while True: + try: + client = self.serverTransport.accept() + if not client: + continue + self.clients.put(client) + except Exception as x: + logger.exception(x) + + +class TForkingServer(TServer): + """A Thrift server that forks a new process for each request + + This is more scalable than the threaded server as it does not cause + GIL contention. + + Note that this has different semantics from the threading server. + Specifically, updates to shared variables will no longer be shared. + It will also not work on windows. + + This code is heavily inspired by SocketServer.ForkingMixIn in the + Python stdlib. + """ + def __init__(self, *args): + TServer.__init__(self, *args) + self.children = [] + + def serve(self): + def try_close(file): + try: + file.close() + except IOError as e: + logger.warning(e, exc_info=True) + + self.serverTransport.listen() + while True: + client = self.serverTransport.accept() + if not client: + continue + try: + pid = os.fork() + + if pid: # parent + # add before collect, otherwise you race w/ waitpid + self.children.append(pid) + self.collect_children() + + # Parent must close socket or the connection may not get + # closed promptly + itrans = self.inputTransportFactory.getTransport(client) + otrans = self.outputTransportFactory.getTransport(client) + try_close(itrans) + try_close(otrans) + else: + itrans = self.inputTransportFactory.getTransport(client) + otrans = self.outputTransportFactory.getTransport(client) + + iprot = self.inputProtocolFactory.getProtocol(itrans) + oprot = self.outputProtocolFactory.getProtocol(otrans) + + ecode = 0 + try: + try: + while True: + self.processor.process(iprot, oprot) + except TTransport.TTransportException as tx: + pass + except Exception as e: + logger.exception(e) + ecode = 1 + finally: + try_close(itrans) + try_close(otrans) + + os._exit(ecode) + + except TTransport.TTransportException as tx: + pass + except Exception as x: + logger.exception(x) + + def collect_children(self): + while self.children: + try: + pid, status = os.waitpid(0, os.WNOHANG) + except os.error: + pid = None + + if pid: + self.children.remove(pid) + else: + break diff --git a/lib/thrift/server/TServer.pyc b/lib/thrift/server/TServer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a9174df87f10a207ee73221a786a96e5edc9297 GIT binary patch literal 8801 zcmds7%Wot{8Lyrhk9WqeeTU7n2_czav1KQAZeVYf ztE;=ds{S6o@6lWQ=T!CY-}&^drpkVb_3u?KLkBe%# zn2$?pxs;E`)bg0pW2#kFdR%Q|`4PEQQ0f3KlrKF91PPcy2Tqw+|vnXy9tX44s_QPUCtADBI5KI{Yo>8xER}XU zqhnscQ|HgRwQl~}=dwG4S38R*p8Cuu&bevMhbumJ>7R2!PneZWkjT@YO$1NyCycti zbg=n=UffIfnjc-1%V*b`UDG^ClaeW*9YMQFcK;P!s?;5astfUK6jbu2x}#Lf;UwgA zhJT9cOj=N_BGq#^D5=(%%;baZvT~vyj1Vjd!4LN&NV<+CpZyuLSNJ1@=0^yXh0v#; zM<}CEvV_JnLSoztHNJE`G@Tw5YcpsivoSd#Cke(y7UEQFYy3O*!yEw}!t;I`c3_vvcimWiDM$!qs%n zYW`eiWwYIW$~UoRYBbJaY)+z6&T;3YQ<2}J7(b8JqY)=xs!wIApp z17SB^_fxk;kni?7UE}&m+=~J?j`R?7X9sXbqE|_n$^$qfc!`?7?})d}^_KjU_Y*FO zDO$auE)Q9C5H69;^Jtljef*e z*#!coFi`;VU9nGu7QoqTMhvwzu3ATEy?jP2wpEcC(8SD`>OZEo9+K^TB->S0YeH-r zcwJD=t?#O(rRZ5z0=l)P)J9b$A1miB(c8u3w9Nb-GvmsEWw(y1I}+PCk)v*6+tx9{ zz5~?AMmYV_hy@(SyNem7gwl3sQUEEfWHIS!ne&@X-A%Tg1!*7#A^r ztWb4o+}{&s^X)xqzqS7_X!`VOSI`XEgq;hOq5%6M<0+cwex`pG&+EeldM{&1PIiaY zo36hZ!Q$OWZvqFnvD?*&t9`_M2o+zJ?ZRaXa7-DRg>sHsx55hw z^)j0I1-hLG@7|uBCs^z1!5~ME;EJ$b|975Rs{kI7&0!mju0#y zURT7Nmte&uxE8{}wsIWjdy24Bf)#S=r@(_E@IW8~rq9K=eRE*@WSwPb3V!I+qv_Se z2a8K)P~_dm?n~&z{;YW60)&rN9b~xfM?qW5Ge)Pch=7Fu)TSI|$r!uMo}L&t+npv_e|v!w}vyX3Ds3 z()xF}fnQ@{AjBQ04!#Tc6R|C-15N?vqo|I&5;MC{y{wX!(6n9v4`irb&ru!Dz>4v` z5mdKQ{8@(TR*E}OeR_cEb`%UFJ_({EraFTc8X~kueppx*$w~nB0O!QlKFHBdiFhvN zh9K)vEZ(E+zQT^!=Y5skhT)i4_M1J82!Zjeb-YH#7AB1MH7@u%yFH-TJBJ%0Dd`R(E*|B5 zG!Yj;c!u#kH8*dUd6#+*(}fu$XTp10-(jA|^ny;oP3=a#&I)`Kc)J-V8yICr#$N=o zWyH z7h7*omdSP1cLheAOpc62;W2I9y0_s^dVfBeOJF|70(FvfC$s%`&1*xj~ zvV>&2U}eNF3!)qvIEM5sA3wmxHuo!3Y{d2dhwlSbW>w%uCIU&m=WM2JCFW-Wv^6y2 zwqwZDH-Hmk!j-nJ*Zz0h13~u36s*9R*`g z{-pYIVyCzvZkh>TNtut-=Dj?Hv?&|TfnAqw-Gdd|y*}A%uY0iKd$8gHaE(}DE}>gs zgyrVWV_$R=)9t0XexPO>W09D(_aw;FYYdzO*^xV~X+b=17IWSlyO-FVXGcKyo?^Ev zT-YOY^au)qmMD$du$`_%g1gXrhD2!o5?UMzOr>P8p z`c482Y!I_o`bBfH??!d|qJ@}evG)6Df9>8L16^PwsBeAZ zu*d@l2~#(SwQ-{uO62#9MwR;N{59rztQj!RBjI|S3LQFI&|k;OAY5J537)}8J3bz5 zqQ;;57rPT(k9dq^7Bm*Rx*4v9I8_^U`d&AHBZk9?;hn`9-S(4^=S5f);yXbU3(mon z!)@C~NM$~?w~-LWa%%c})TJ;R1@WfIK0n})%{ahU3>;Sbx5IWH1%A^F>Gf9n?n2z$ z(5V&OY$nJz!marTPmxvF=tdu3Ga}cd0ZPH#Ss;miokn^U&CpVIM`dd^9+U4@dD)8# zM&c~mN^?DI2jJc?`mos=ZXG-+V)*nsw4FID4R#Q3{01roSbR?rC<$j4JAr{)KXF(N z`<0W;+DukZ6GiGr}KE}+%V3P^i1h;RZaR>WZu0BvcN_K%VC$jaY zGntb6OLB62LPEIs92^Z8Yd;m?kWc}fY8y2Lo?OUMlk4&&14TG|Us;VUlDn9fpnv}Q zt4R_klFQ2ksw@#qT1p6_w;-w1YKS@k<6M0xsJG>Zq~DOD-yg6(O9F~W=4YG`6ZQ*H zO~TMUybxYaso2;<00g{?xR&CD-|gxsNcqhHpH17SS2c2bv)?85&7nU(eHLHZ&|6_z zlQYqnJ)(hlJL?p~V6TK)R%)V>O|7qR5&h($_$JQm6Ra|?p;Jz!Jgid|oykJEaMY=m z7*c)ypYo8uiPG!ZF;XOBMAZObvhoK%uspnR+E!^&g>s&q{e1!1fF3 z9ax)G$(N%0q2-vi*~(Q`ub^ePDHUr+C4NSV>5ENokhyd2a4HA*mJoVF_IUKWJ$Koj{x1la6 zXA;bM1o23Tm_p%Yy* zeIwyqW={BAzv4GHgi&pj*C8aC@moCc*y#sPKXLly{{q4RsO$g$ literal 0 HcmV?d00001 diff --git a/lib/thrift/server/__init__.py b/lib/thrift/server/__init__.py new file mode 100644 index 0000000..1bf6e25 --- /dev/null +++ b/lib/thrift/server/__init__.py @@ -0,0 +1,20 @@ +# +# 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. +# + +__all__ = ['TServer', 'TNonblockingServer'] diff --git a/lib/thrift/server/__init__.pyc b/lib/thrift/server/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a11045d62a6c8979b5cf2c6da3177c23d0cad85 GIT binary patch literal 177 zcmZSn%**v5?r~T$0~9a;X$K%K761|{K*Y$9&cqM}WH2!VYcK-^OW1)#NN{RVS!z*< z5Qy!UpO=)ApPZeUmkts3(_n-tjE_&u$%&8G0P-0SM6o=OtEZonnWSHmQIwfhqF)R) jPd`3BGcU6wK3=b&vV;Su#wIsEr8FniP6Ws<24V&PT4^SH literal 0 HcmV?d00001 diff --git a/lib/thrift/transport/THttpClient.py b/lib/thrift/transport/THttpClient.py new file mode 100644 index 0000000..5851fa2 --- /dev/null +++ b/lib/thrift/transport/THttpClient.py @@ -0,0 +1,151 @@ +# +# 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. +# + +import httplib +import os +import socket +import sys +import urllib +import urlparse +import warnings + +from cStringIO import StringIO + +from TTransport import * + + +class THttpClient(TTransportBase): + """Http implementation of TTransport base.""" + + def __init__(self, uri_or_host, port=None, path=None): + """THttpClient supports two different types constructor parameters. + + THttpClient(host, port, path) - deprecated + THttpClient(uri) + + Only the second supports https. + """ + if port is not None: + warnings.warn( + "Please use the THttpClient('http://host:port/path') syntax", + DeprecationWarning, + stacklevel=2) + self.host = uri_or_host + self.port = port + assert path + self.path = path + self.scheme = 'http' + else: + parsed = urlparse.urlparse(uri_or_host) + self.scheme = parsed.scheme + assert self.scheme in ('http', 'https') + if self.scheme == 'http': + self.port = parsed.port or httplib.HTTP_PORT + elif self.scheme == 'https': + self.port = parsed.port or httplib.HTTPS_PORT + self.host = parsed.hostname + self.path = parsed.path + if parsed.query: + self.path += '?%s' % parsed.query + self.__wbuf = StringIO() + self.__http = None + self.__timeout = None + self.__custom_headers = None + + def open(self): + if self.scheme == 'http': + self.__http = httplib.HTTP(self.host, self.port) + else: + self.__http = httplib.HTTPS(self.host, self.port) + + def close(self): + self.__http.close() + self.__http = None + + def isOpen(self): + return self.__http is not None + + def setTimeout(self, ms): + if not hasattr(socket, 'getdefaulttimeout'): + raise NotImplementedError + + if ms is None: + self.__timeout = None + else: + self.__timeout = ms / 1000.0 + + def setCustomHeaders(self, headers): + self.__custom_headers = headers + + def read(self, sz): + return self.__http.file.read(sz) + + def write(self, buf): + self.__wbuf.write(buf) + + def __withTimeout(f): + def _f(*args, **kwargs): + orig_timeout = socket.getdefaulttimeout() + socket.setdefaulttimeout(args[0].__timeout) + try: + result = f(*args, **kwargs) + finally: + socket.setdefaulttimeout(orig_timeout) + return result + return _f + + def flush(self): + if self.isOpen(): + self.close() + self.open() + + # Pull data out of buffer + data = self.__wbuf.getvalue() + self.__wbuf = StringIO() + + # HTTP request + self.__http.putrequest('POST', self.path) + + # Write headers + self.__http.putheader('Host', self.host) + self.__http.putheader('Content-Type', 'application/x-thrift') + self.__http.putheader('Content-Length', str(len(data))) + + if not self.__custom_headers or 'User-Agent' not in self.__custom_headers: + user_agent = 'Python/THttpClient' + script = os.path.basename(sys.argv[0]) + if script: + user_agent = '%s (%s)' % (user_agent, urllib.quote(script)) + self.__http.putheader('User-Agent', user_agent) + + if self.__custom_headers: + for key, val in self.__custom_headers.iteritems(): + self.__http.putheader(key, val) + + self.__http.endheaders() + + # Write payload + self.__http.send(data) + + # Get reply to flush the request + self.code, self.message, self.headers = self.__http.getreply() + + # Decorate if we know how to timeout + if hasattr(socket, 'getdefaulttimeout'): + flush = __withTimeout(flush) diff --git a/lib/thrift/transport/TSSLSocket.py b/lib/thrift/transport/TSSLSocket.py new file mode 100644 index 0000000..6ad8d50 --- /dev/null +++ b/lib/thrift/transport/TSSLSocket.py @@ -0,0 +1,227 @@ +# +# 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. +# + +import os +import socket +import ssl + +from thrift.transport import TSocket +from thrift.transport.TTransport import TTransportException + + +class TSSLSocket(TSocket.TSocket): + """ + SSL implementation of client-side TSocket + + This class creates outbound sockets wrapped using the + python standard ssl module for encrypted connections. + + The protocol used is set using the class variable + SSL_VERSION, which must be one of ssl.PROTOCOL_* and + defaults to ssl.PROTOCOL_TLSv1 for greatest security. + """ + SSL_VERSION = ssl.PROTOCOL_TLSv1 + + def __init__(self, + host='localhost', + port=9090, + validate=True, + ca_certs=None, + keyfile=None, + certfile=None, + unix_socket=None, + ciphers=None): + """Create SSL TSocket + + @param validate: Set to False to disable SSL certificate validation + @type validate: bool + @param ca_certs: Filename to the Certificate Authority pem file, possibly a + file downloaded from: http://curl.haxx.se/ca/cacert.pem This is passed to + the ssl_wrap function as the 'ca_certs' parameter. + @type ca_certs: str + @param keyfile: The private key + @type keyfile: str + @param certfile: The cert file + @type certfile: str + @param ciphers: The cipher suites to allow. This is passed to + the ssl_wrap function as the 'ciphers' parameter. + @type ciphers: str + + Raises an IOError exception if validate is True and the ca_certs file is + None, not present or unreadable. + """ + self.validate = validate + self.is_valid = False + self.peercert = None + if not validate: + self.cert_reqs = ssl.CERT_NONE + else: + self.cert_reqs = ssl.CERT_REQUIRED + self.ca_certs = ca_certs + self.keyfile = keyfile + self.certfile = certfile + self.ciphers = ciphers + if validate: + if ca_certs is None or not os.access(ca_certs, os.R_OK): + raise IOError('Certificate Authority ca_certs file "%s" ' + 'is not readable, cannot validate SSL ' + 'certificates.' % (ca_certs)) + TSocket.TSocket.__init__(self, host, port, unix_socket) + + def open(self): + try: + res0 = self._resolveAddr() + for res in res0: + sock_family, sock_type = res[0:2] + ip_port = res[4] + plain_sock = socket.socket(sock_family, sock_type) + self.handle = ssl.wrap_socket(plain_sock, + ssl_version=self.SSL_VERSION, + do_handshake_on_connect=True, + ca_certs=self.ca_certs, + keyfile=self.keyfile, + certfile=self.certfile, + cert_reqs=self.cert_reqs, + ciphers=self.ciphers) + self.handle.settimeout(self._timeout) + try: + self.handle.connect(ip_port) + except socket.error as e: + if res is not res0[-1]: + continue + else: + raise e + break + except socket.error as e: + if self._unix_socket: + message = 'Could not connect to secure socket %s: %s' \ + % (self._unix_socket, e) + else: + message = 'Could not connect to %s:%d: %s' % (self.host, self.port, e) + raise TTransportException(type=TTransportException.NOT_OPEN, + message=message) + if self.validate: + self._validate_cert() + + def _validate_cert(self): + """internal method to validate the peer's SSL certificate, and to check the + commonName of the certificate to ensure it matches the hostname we + used to make this connection. Does not support subjectAltName records + in certificates. + + raises TTransportException if the certificate fails validation. + """ + cert = self.handle.getpeercert() + self.peercert = cert + if 'subject' not in cert: + raise TTransportException( + type=TTransportException.NOT_OPEN, + message='No SSL certificate found from %s:%s' % (self.host, self.port)) + fields = cert['subject'] + for field in fields: + # ensure structure we get back is what we expect + if not isinstance(field, tuple): + continue + cert_pair = field[0] + if len(cert_pair) < 2: + continue + cert_key, cert_value = cert_pair[0:2] + if cert_key != 'commonName': + continue + certhost = cert_value + # this check should be performed by some sort of Access Manager + if certhost == self.host: + # success, cert commonName matches desired hostname + self.is_valid = True + return + else: + raise TTransportException( + type=TTransportException.UNKNOWN, + message='Hostname we connected to "%s" doesn\'t match certificate ' + 'provided commonName "%s"' % (self.host, certhost)) + raise TTransportException( + type=TTransportException.UNKNOWN, + message='Could not validate SSL certificate from ' + 'host "%s". Cert=%s' % (self.host, cert)) + + +class TSSLServerSocket(TSocket.TServerSocket): + """SSL implementation of TServerSocket + + This uses the ssl module's wrap_socket() method to provide SSL + negotiated encryption. + """ + SSL_VERSION = ssl.PROTOCOL_TLSv1 + + def __init__(self, + host=None, + port=9090, + certfile='cert.pem', + unix_socket=None, + ciphers=None): + """Initialize a TSSLServerSocket + + @param certfile: filename of the server certificate, defaults to cert.pem + @type certfile: str + @param host: The hostname or IP to bind the listen socket to, + i.e. 'localhost' for only allowing local network connections. + Pass None to bind to all interfaces. + @type host: str + @param port: The port to listen on for inbound connections. + @type port: int + @param ciphers: The cipher suites to allow. This is passed to + the ssl_wrap function as the 'ciphers' parameter. + @type ciphers: str + + """ + self.setCertfile(certfile) + TSocket.TServerSocket.__init__(self, host, port) + self.ciphers = ciphers + + def setCertfile(self, certfile): + """Set or change the server certificate file used to wrap new connections. + + @param certfile: The filename of the server certificate, + i.e. '/etc/certs/server.pem' + @type certfile: str + + Raises an IOError exception if the certfile is not present or unreadable. + """ + if not os.access(certfile, os.R_OK): + raise IOError('No such certfile found: %s' % (certfile)) + self.certfile = certfile + + def accept(self): + plain_client, addr = self.handle.accept() + try: + client = ssl.wrap_socket(plain_client, certfile=self.certfile, + server_side=True, ssl_version=self.SSL_VERSION, + ciphers=self.ciphers) + except ssl.SSLError as ssl_exc: + # failed handshake/ssl wrap, close socket to client + plain_client.close() + # raise ssl_exc + # We can't raise the exception, because it kills most TServer derived + # serve() methods. + # Instead, return None, and let the TServer instance deal with it in + # other exception handling. (but TSimpleServer dies anyway) + return None + result = TSocket.TSocket() + result.setHandle(client) + return result diff --git a/lib/thrift/transport/TSocket.py b/lib/thrift/transport/TSocket.py new file mode 100644 index 0000000..7b564aa --- /dev/null +++ b/lib/thrift/transport/TSocket.py @@ -0,0 +1,180 @@ +# +# 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. +# + +import errno +import os +import socket +import sys + +from TTransport import * + + +class TSocketBase(TTransportBase): + def _resolveAddr(self): + if self._unix_socket is not None: + return [(socket.AF_UNIX, socket.SOCK_STREAM, None, None, + self._unix_socket)] + else: + return socket.getaddrinfo(self.host, + self.port, + self._socket_family, + socket.SOCK_STREAM, + 0, + socket.AI_PASSIVE | socket.AI_ADDRCONFIG) + + def close(self): + if self.handle: + self.handle.close() + self.handle = None + + +class TSocket(TSocketBase): + """Socket implementation of TTransport base.""" + + def __init__(self, host='localhost', port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC): + """Initialize a TSocket + + @param host(str) The host to connect to. + @param port(int) The (TCP) port to connect to. + @param unix_socket(str) The filename of a unix socket to connect to. + (host and port will be ignored.) + @param socket_family(int) The socket family to use with this socket. + """ + self.host = host + self.port = port + self.handle = None + self._unix_socket = unix_socket + self._timeout = None + self._socket_family = socket_family + + def setHandle(self, h): + self.handle = h + + def isOpen(self): + return self.handle is not None + + def setTimeout(self, ms): + if ms is None: + self._timeout = None + else: + self._timeout = ms / 1000.0 + + if self.handle is not None: + self.handle.settimeout(self._timeout) + + def open(self): + try: + res0 = self._resolveAddr() + for res in res0: + self.handle = socket.socket(res[0], res[1]) + self.handle.settimeout(self._timeout) + try: + self.handle.connect(res[4]) + except socket.error as e: + if res is not res0[-1]: + continue + else: + raise e + break + except socket.error as e: + if self._unix_socket: + message = 'Could not connect to socket %s' % self._unix_socket + else: + message = 'Could not connect to %s:%d' % (self.host, self.port) + raise TTransportException(type=TTransportException.NOT_OPEN, + message=message) + + def read(self, sz): + try: + buff = self.handle.recv(sz) + except socket.error as e: + if (e.args[0] == errno.ECONNRESET and + (sys.platform == 'darwin' or sys.platform.startswith('freebsd'))): + # freebsd and Mach don't follow POSIX semantic of recv + # and fail with ECONNRESET if peer performed shutdown. + # See corresponding comment and code in TSocket::read() + # in lib/cpp/src/transport/TSocket.cpp. + self.close() + # Trigger the check to raise the END_OF_FILE exception below. + buff = '' + else: + raise + if len(buff) == 0: + raise TTransportException(type=TTransportException.END_OF_FILE, + message='TSocket read 0 bytes') + return buff + + def write(self, buff): + if not self.handle: + raise TTransportException(type=TTransportException.NOT_OPEN, + message='Transport not open') + sent = 0 + have = len(buff) + while sent < have: + plus = self.handle.send(buff) + if plus == 0: + raise TTransportException(type=TTransportException.END_OF_FILE, + message='TSocket sent 0 bytes') + sent += plus + buff = buff[plus:] + + def flush(self): + pass + + +class TServerSocket(TSocketBase, TServerTransportBase): + """Socket implementation of TServerTransport base.""" + + def __init__(self, host=None, port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC): + self.host = host + self.port = port + self._unix_socket = unix_socket + self._socket_family = socket_family + self.handle = None + + def listen(self): + res0 = self._resolveAddr() + socket_family = self._socket_family == socket.AF_UNSPEC and socket.AF_INET6 or self._socket_family + for res in res0: + if res[0] is socket_family or res is res0[-1]: + break + + # We need remove the old unix socket if the file exists and + # nobody is listening on it. + if self._unix_socket: + tmp = socket.socket(res[0], res[1]) + try: + tmp.connect(res[4]) + except socket.error as err: + eno, message = err.args + if eno == errno.ECONNREFUSED: + os.unlink(res[4]) + + self.handle = socket.socket(res[0], res[1]) + self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if hasattr(self.handle, 'settimeout'): + self.handle.settimeout(None) + self.handle.bind(res[4]) + self.handle.listen(128) + + def accept(self): + client, addr = self.handle.accept() + result = TSocket() + result.setHandle(client) + return result diff --git a/lib/thrift/transport/TSocket.pyc b/lib/thrift/transport/TSocket.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff141f31e12ecf74b17ecb8e648b39c638f7770c GIT binary patch literal 5822 zcmbVQTW=f36`oyE6iG{#;|psicC$|6gbondb&I$S($u=pjnb4-mrUdeb%+(YlvY~p zQadBtO6;Pr{ZgPs`cm}r(&s)D=pX5?=tBeKr9j`?e&3np#eiB^rnIwXW@pcwIp;f< z*}}hOtN;A$@1J&6{wv^q3zvR^riXt=#Y%0AXh&^0!*N$_xI?<2HVQ(!DlV#aub{#y z)yLGLda4wd{dA+GdQ&Pa$!KXbI<0!s91Y8=4{qhrg9_Jf)hm!A`VW51x&zX%dE1;o z+is=Z-OwxsIvk15r;E7s%V6ZCpnl=M@1 ze>>Gih(VeebCOF~PMvzjyA8E?JVk>YbFa4&1J6TMwuTR+D&DlPUCyw0tCB6MyJWenR8A%v+j&j zlD~p8G6n4-rg#&CHAVJXPV6|ukpl(dK}V@X%+wMooAm--5N&M-NiPn~6#Csb)uGQP zGRfx-kGl>36kfWDOVbp}sW`JvojNguO{bFtdts*|y6klJ(%wOgu1{^to8#q3Wu%&W;Km8ntH{WV>Q#l9rQZ;!n%c0w=S6#iINS>p6PPGXytMDN+e0jPoAAte zLkEu2ZV(fX(c{-)77EU5WbOCRdFbSJedr1S&$S~3^$`EiH9XLcz~hQCf-NydkdJOc zX)8%&q9Bew552(4)m5!}_}v-=S+M6(hPpP{RnKd0htl;->UGm33A+a5{N!vRx*jDa zpIvV+tzGpv_MO#Ul zg}wQ!ld?bK>JyvDm$e~)s~_mlyC0ct&um9Jm&$6PStsgz;@qbd#gqIwQq;J002A$n z>4EVXOzJeMc-iSiZ{HLID?)) z0vIC5Flx}zWJiJ_5nVFO_SkQqGulx>Iy4_j^jTzw0;nTGo5(VeWrnhFzSV94)Qd+f ziGq<{9fU~(jD~Uy^})O7qzM8#fi`x_DmzbtUgoG|R>mE5&i2vnNTO#-{D_m#MOGw% znCvKL7>dcexrGKr#Fw`uOj^*K!-(un0wwg6!)8M5e0NVDTkpgj__ZwzKV*+X%9(Ly z+*xN3as{NYU{{ti3V<_HH zch)elzMkBjeD&Y?tI+qf%KpaiP2Eqc+M}XMYK-FSm!+++j^YET8c`kX4uUzJL0IMH ztB4B_vbG9|=m$}e4NEQkO{ywAhs)fqfI5$w=9E)%s|Z4;ah-B& zsB)vxE{rlLG|- z!9}PnLt={)2`#-KyN{&E+|bX$a8vgTNaerE#zUjeqRF$bmxV#kyY6isno!rJEMfx5 z4b#2n3ld%%4h7kk9vUCeqbD~|j5hs7tI-xC>O(EY9>js^r`etjC??2^W)_p8OC}=W z`md8OE9^#dxwCq^b9?3EhK))L!q7E@{aj?(Jm~lRx6pqfSa6dJd-^;Y!lDKU)SSyx zRkz|!gPsFW1PX+~2nv5hhlUb70h+J~VTGF~J%3Luac9mnLpdQ?%X%IDb0qfrm z!Gxm7f(ZmLQxyCDoIG>Rs0G1%YRs8Tis~i+f;U0EideY+J+Tt%k*0+P$rn0F2(J6s!uBu0B2UXr z>k}`LDfKIE)#>!oE=~~zj#36GqUG$@T5Bx%M48VMuKx-fMr)tK`8V0T&*uAR#!wdO z`3f1I5%wA`IjZ4+=AJ)QDd4YCsa4KaPD=gOZiU&sFl)(SwTsE}qox;e>F=Tmhlg*T zM}RwE5T}289&v}~5gbe~4d)SiFe&qhLBMDVV7VW4#IUQ6p(qE9|8cbV7B~^xa%3dj zrNqfk6oP(^$hQj;kaS!f3Uw z{AolJ2`;R3SPb4&Yx_49{@2NPN@ZUQKd38z4L4Rfu0ox0c#e?+sfiDZdF`|RwasPI zQv3V^xoirx4>DL;{S0rF)FXTecl+JuQDdwYbt0ww}u|4mSmQ_bE$?kLUdJxO1vmhwLW$KT=7WX)Rr4b)MdQ!ZAV zmytftNy?maUU4ru7eSwK&f4f)#B92uL}vyG+DWhvKOnHAl7iCc7J_n~Q|uuH@Ejhs z$j0iCdJVd)A|>!iRGp|0__!NKNNA!geqR%1p_Dv`&9VKv33h+QrRmHH+vL}zrhMb{ zM=8Mn0MEv;-zR!($fwqP@)$2H)N@9cTX^%=xMX#S?9-JCb%80d=ToT`u-8EerpBeV zd_Wv`7x8V!msH4nVQj@GNnsS0Wy&o)eIaSZU*5ML)IK14eG&~0b^LRyh1!|gXa5BP CU`7-G literal 0 HcmV?d00001 diff --git a/lib/thrift/transport/TTransport.py b/lib/thrift/transport/TTransport.py new file mode 100644 index 0000000..5914aca --- /dev/null +++ b/lib/thrift/transport/TTransport.py @@ -0,0 +1,446 @@ +# +# 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. +# + +from cStringIO import StringIO +from struct import pack, unpack +from thrift.Thrift import TException + + +class TTransportException(TException): + """Custom Transport Exception class""" + + UNKNOWN = 0 + NOT_OPEN = 1 + ALREADY_OPEN = 2 + TIMED_OUT = 3 + END_OF_FILE = 4 + + def __init__(self, type=UNKNOWN, message=None): + TException.__init__(self, message) + self.type = type + + +class TTransportBase: + """Base class for Thrift transport layer.""" + + def isOpen(self): + pass + + def open(self): + pass + + def close(self): + pass + + def read(self, sz): + pass + + def readAll(self, sz): + buff = '' + have = 0 + while (have < sz): + chunk = self.read(sz - have) + have += len(chunk) + buff += chunk + + if len(chunk) == 0: + raise EOFError() + + return buff + + def write(self, buf): + pass + + def flush(self): + pass + + +# This class should be thought of as an interface. +class CReadableTransport: + """base class for transports that are readable from C""" + + # TODO(dreiss): Think about changing this interface to allow us to use + # a (Python, not c) StringIO instead, because it allows + # you to write after reading. + + # NOTE: This is a classic class, so properties will NOT work + # correctly for setting. + @property + def cstringio_buf(self): + """A cStringIO buffer that contains the current chunk we are reading.""" + pass + + def cstringio_refill(self, partialread, reqlen): + """Refills cstringio_buf. + + Returns the currently used buffer (which can but need not be the same as + the old cstringio_buf). partialread is what the C code has read from the + buffer, and should be inserted into the buffer before any more reads. The + return value must be a new, not borrowed reference. Something along the + lines of self._buf should be fine. + + If reqlen bytes can't be read, throw EOFError. + """ + pass + + +class TServerTransportBase: + """Base class for Thrift server transports.""" + + def listen(self): + pass + + def accept(self): + pass + + def close(self): + pass + + +class TTransportFactoryBase: + """Base class for a Transport Factory""" + + def getTransport(self, trans): + return trans + + +class TBufferedTransportFactory: + """Factory transport that builds buffered transports""" + + def getTransport(self, trans): + buffered = TBufferedTransport(trans) + return buffered + + +class TBufferedTransport(TTransportBase, CReadableTransport): + """Class that wraps another transport and buffers its I/O. + + The implementation uses a (configurable) fixed-size read buffer + but buffers all writes until a flush is performed. + """ + DEFAULT_BUFFER = 4096 + + def __init__(self, trans, rbuf_size=DEFAULT_BUFFER): + self.__trans = trans + self.__wbuf = StringIO() + self.__rbuf = StringIO("") + self.__rbuf_size = rbuf_size + + def isOpen(self): + return self.__trans.isOpen() + + def open(self): + return self.__trans.open() + + def close(self): + return self.__trans.close() + + def read(self, sz): + ret = self.__rbuf.read(sz) + if len(ret) != 0: + return ret + + self.__rbuf = StringIO(self.__trans.read(max(sz, self.__rbuf_size))) + return self.__rbuf.read(sz) + + def write(self, buf): + try: + self.__wbuf.write(buf) + except Exception as e: + # on exception reset wbuf so it doesn't contain a partial function call + self.__wbuf = StringIO() + raise e + + def flush(self): + out = self.__wbuf.getvalue() + # reset wbuf before write/flush to preserve state on underlying failure + self.__wbuf = StringIO() + self.__trans.write(out) + self.__trans.flush() + + # Implement the CReadableTransport interface. + @property + def cstringio_buf(self): + return self.__rbuf + + def cstringio_refill(self, partialread, reqlen): + retstring = partialread + if reqlen < self.__rbuf_size: + # try to make a read of as much as we can. + retstring += self.__trans.read(self.__rbuf_size) + + # but make sure we do read reqlen bytes. + if len(retstring) < reqlen: + retstring += self.__trans.readAll(reqlen - len(retstring)) + + self.__rbuf = StringIO(retstring) + return self.__rbuf + + +class TMemoryBuffer(TTransportBase, CReadableTransport): + """Wraps a cStringIO object as a TTransport. + + NOTE: Unlike the C++ version of this class, you cannot write to it + then immediately read from it. If you want to read from a + TMemoryBuffer, you must either pass a string to the constructor. + TODO(dreiss): Make this work like the C++ version. + """ + + def __init__(self, value=None): + """value -- a value to read from for stringio + + If value is set, this will be a transport for reading, + otherwise, it is for writing""" + if value is not None: + self._buffer = StringIO(value) + else: + self._buffer = StringIO() + + def isOpen(self): + return not self._buffer.closed + + def open(self): + pass + + def close(self): + self._buffer.close() + + def read(self, sz): + return self._buffer.read(sz) + + def write(self, buf): + self._buffer.write(buf) + + def flush(self): + pass + + def getvalue(self): + return self._buffer.getvalue() + + # Implement the CReadableTransport interface. + @property + def cstringio_buf(self): + return self._buffer + + def cstringio_refill(self, partialread, reqlen): + # only one shot at reading... + raise EOFError() + + +class TFramedTransportFactory: + """Factory transport that builds framed transports""" + + def getTransport(self, trans): + framed = TFramedTransport(trans) + return framed + + +class TFramedTransport(TTransportBase, CReadableTransport): + """Class that wraps another transport and frames its I/O when writing.""" + + def __init__(self, trans,): + self.__trans = trans + self.__rbuf = StringIO() + self.__wbuf = StringIO() + + def isOpen(self): + return self.__trans.isOpen() + + def open(self): + return self.__trans.open() + + def close(self): + return self.__trans.close() + + def read(self, sz): + ret = self.__rbuf.read(sz) + if len(ret) != 0: + return ret + + self.readFrame() + return self.__rbuf.read(sz) + + def readFrame(self): + buff = self.__trans.readAll(4) + sz, = unpack('!i', buff) + self.__rbuf = StringIO(self.__trans.readAll(sz)) + + def write(self, buf): + self.__wbuf.write(buf) + + def flush(self): + wout = self.__wbuf.getvalue() + wsz = len(wout) + # reset wbuf before write/flush to preserve state on underlying failure + self.__wbuf = StringIO() + # N.B.: Doing this string concatenation is WAY cheaper than making + # two separate calls to the underlying socket object. Socket writes in + # Python turn out to be REALLY expensive, but it seems to do a pretty + # good job of managing string buffer operations without excessive copies + buf = pack("!i", wsz) + wout + self.__trans.write(buf) + self.__trans.flush() + + # Implement the CReadableTransport interface. + @property + def cstringio_buf(self): + return self.__rbuf + + def cstringio_refill(self, prefix, reqlen): + # self.__rbuf will already be empty here because fastbinary doesn't + # ask for a refill until the previous buffer is empty. Therefore, + # we can start reading new frames immediately. + while len(prefix) < reqlen: + self.readFrame() + prefix += self.__rbuf.getvalue() + self.__rbuf = StringIO(prefix) + return self.__rbuf + + +class TFileObjectTransport(TTransportBase): + """Wraps a file-like object to make it work as a Thrift transport.""" + + def __init__(self, fileobj): + self.fileobj = fileobj + + def isOpen(self): + return True + + def close(self): + self.fileobj.close() + + def read(self, sz): + return self.fileobj.read(sz) + + def write(self, buf): + self.fileobj.write(buf) + + def flush(self): + self.fileobj.flush() + + +class TSaslClientTransport(TTransportBase, CReadableTransport): + """ + SASL transport + """ + + START = 1 + OK = 2 + BAD = 3 + ERROR = 4 + COMPLETE = 5 + + def __init__(self, transport, host, service, mechanism='GSSAPI', + **sasl_kwargs): + """ + transport: an underlying transport to use, typically just a TSocket + host: the name of the server, from a SASL perspective + service: the name of the server's service, from a SASL perspective + mechanism: the name of the preferred mechanism to use + + All other kwargs will be passed to the puresasl.client.SASLClient + constructor. + """ + + from puresasl.client import SASLClient + + self.transport = transport + self.sasl = SASLClient(host, service, mechanism, **sasl_kwargs) + + self.__wbuf = StringIO() + self.__rbuf = StringIO() + + def open(self): + if not self.transport.isOpen(): + self.transport.open() + + self.send_sasl_msg(self.START, self.sasl.mechanism) + self.send_sasl_msg(self.OK, self.sasl.process()) + + while True: + status, challenge = self.recv_sasl_msg() + if status == self.OK: + self.send_sasl_msg(self.OK, self.sasl.process(challenge)) + elif status == self.COMPLETE: + if not self.sasl.complete: + raise TTransportException("The server erroneously indicated " + "that SASL negotiation was complete") + else: + break + else: + raise TTransportException("Bad SASL negotiation status: %d (%s)" + % (status, challenge)) + + def send_sasl_msg(self, status, body): + header = pack(">BI", status, len(body)) + self.transport.write(header + body) + self.transport.flush() + + def recv_sasl_msg(self): + header = self.transport.readAll(5) + status, length = unpack(">BI", header) + if length > 0: + payload = self.transport.readAll(length) + else: + payload = "" + return status, payload + + def write(self, data): + self.__wbuf.write(data) + + def flush(self): + data = self.__wbuf.getvalue() + encoded = self.sasl.wrap(data) + self.transport.write(''.join((pack("!i", len(encoded)), encoded))) + self.transport.flush() + self.__wbuf = StringIO() + + def read(self, sz): + ret = self.__rbuf.read(sz) + if len(ret) != 0: + return ret + + self._read_frame() + return self.__rbuf.read(sz) + + def _read_frame(self): + header = self.transport.readAll(4) + length, = unpack('!i', header) + encoded = self.transport.readAll(length) + self.__rbuf = StringIO(self.sasl.unwrap(encoded)) + + def close(self): + self.sasl.dispose() + self.transport.close() + + # based on TFramedTransport + @property + def cstringio_buf(self): + return self.__rbuf + + def cstringio_refill(self, prefix, reqlen): + # self.__rbuf will already be empty here because fastbinary doesn't + # ask for a refill until the previous buffer is empty. Therefore, + # we can start reading new frames immediately. + while len(prefix) < reqlen: + self._read_frame() + prefix += self.__rbuf.getvalue() + self.__rbuf = StringIO(prefix) + return self.__rbuf + diff --git a/lib/thrift/transport/TTransport.pyc b/lib/thrift/transport/TTransport.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7cf4cb02beb5c099f545b6135e70aa714c3de2f GIT binary patch literal 17217 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

k zQJ2NHC5#a0#hh#-31WQA$0X#JVUt)TpHGDwq@F4eZ5l;$ck3;;ufvsqFVzpokO^E6 zpg0Q+I7|7n^CSsdjuIF?#7mBiEQ?e{beYG_~&+-Z>H`$#{+=@`~`2;@f=u4<<_s8U# zxD!n3X=~0pl^xe2GlhE#xJWhKzy!yEAbtzY<`6_OsLI{=s(|d7WfNF!APn&jvQe5t zX)%UK3tB{yQBpSPD2@N=p3lb9C3D{B1)!`LRTSMZvlD{PAcxQvUDV*dN_i8Eto0nLqJb$kMc%tpqB zCx_xsy-+tdX|m~4n!y7THLb?~=Yd%(a3-45P{tlp7bHeAAM4MVkHh6Z0+4V_KFf4S zlf%~K8xCiVSKKXjxJm6SFr&qB?la>^a+Kgs9XU{uc<=-Bx&Mchoy2QX);Vjcc<%Jf X)tO5(r)Eyfj9#3-_%8Af&z<{UCP&!M literal 0 HcmV?d00001 diff --git a/lib/thrift/transport/TTwisted.py b/lib/thrift/transport/TTwisted.py new file mode 100644 index 0000000..29bbd4c --- /dev/null +++ b/lib/thrift/transport/TTwisted.py @@ -0,0 +1,324 @@ +# +# 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. +# + +import struct +from cStringIO import StringIO + +from zope.interface import implements, Interface, Attribute +from twisted.internet.protocol import ServerFactory, ClientFactory, \ + connectionDone +from twisted.internet import defer +from twisted.internet.threads import deferToThread +from twisted.protocols import basic +from twisted.web import server, resource, http + +from thrift.transport import TTransport + + +class TMessageSenderTransport(TTransport.TTransportBase): + + def __init__(self): + self.__wbuf = StringIO() + + def write(self, buf): + self.__wbuf.write(buf) + + def flush(self): + msg = self.__wbuf.getvalue() + self.__wbuf = StringIO() + return self.sendMessage(msg) + + def sendMessage(self, message): + raise NotImplementedError + + +class TCallbackTransport(TMessageSenderTransport): + + def __init__(self, func): + TMessageSenderTransport.__init__(self) + self.func = func + + def sendMessage(self, message): + return self.func(message) + + +class ThriftClientProtocol(basic.Int32StringReceiver): + + MAX_LENGTH = 2 ** 31 - 1 + + def __init__(self, client_class, iprot_factory, oprot_factory=None): + self._client_class = client_class + self._iprot_factory = iprot_factory + if oprot_factory is None: + self._oprot_factory = iprot_factory + else: + self._oprot_factory = oprot_factory + + self.recv_map = {} + self.started = defer.Deferred() + + def dispatch(self, msg): + self.sendString(msg) + + def connectionMade(self): + tmo = TCallbackTransport(self.dispatch) + self.client = self._client_class(tmo, self._oprot_factory) + self.started.callback(self.client) + + def connectionLost(self, reason=connectionDone): + for k, v in self.client._reqs.iteritems(): + tex = TTransport.TTransportException( + type=TTransport.TTransportException.END_OF_FILE, + message='Connection closed') + v.errback(tex) + + def stringReceived(self, frame): + tr = TTransport.TMemoryBuffer(frame) + iprot = self._iprot_factory.getProtocol(tr) + (fname, mtype, rseqid) = iprot.readMessageBegin() + + try: + method = self.recv_map[fname] + except KeyError: + method = getattr(self.client, 'recv_' + fname) + self.recv_map[fname] = method + + method(iprot, mtype, rseqid) + + +class ThriftSASLClientProtocol(ThriftClientProtocol): + + START = 1 + OK = 2 + BAD = 3 + ERROR = 4 + COMPLETE = 5 + + MAX_LENGTH = 2 ** 31 - 1 + + def __init__(self, client_class, iprot_factory, oprot_factory=None, + host=None, service=None, mechanism='GSSAPI', **sasl_kwargs): + """ + host: the name of the server, from a SASL perspective + service: the name of the server's service, from a SASL perspective + mechanism: the name of the preferred mechanism to use + + All other kwargs will be passed to the puresasl.client.SASLClient + constructor. + """ + + from puresasl.client import SASLClient + self.SASLCLient = SASLClient + + ThriftClientProtocol.__init__(self, client_class, iprot_factory, oprot_factory) + + self._sasl_negotiation_deferred = None + self._sasl_negotiation_status = None + self.client = None + + if host is not None: + self.createSASLClient(host, service, mechanism, **sasl_kwargs) + + def createSASLClient(self, host, service, mechanism, **kwargs): + self.sasl = self.SASLClient(host, service, mechanism, **kwargs) + + def dispatch(self, msg): + encoded = self.sasl.wrap(msg) + len_and_encoded = ''.join((struct.pack('!i', len(encoded)), encoded)) + ThriftClientProtocol.dispatch(self, len_and_encoded) + + @defer.inlineCallbacks + def connectionMade(self): + self._sendSASLMessage(self.START, self.sasl.mechanism) + initial_message = yield deferToThread(self.sasl.process) + self._sendSASLMessage(self.OK, initial_message) + + while True: + status, challenge = yield self._receiveSASLMessage() + if status == self.OK: + response = yield deferToThread(self.sasl.process, challenge) + self._sendSASLMessage(self.OK, response) + elif status == self.COMPLETE: + if not self.sasl.complete: + msg = "The server erroneously indicated that SASL " \ + "negotiation was complete" + raise TTransport.TTransportException(msg, message=msg) + else: + break + else: + msg = "Bad SASL negotiation status: %d (%s)" % (status, challenge) + raise TTransport.TTransportException(msg, message=msg) + + self._sasl_negotiation_deferred = None + ThriftClientProtocol.connectionMade(self) + + def _sendSASLMessage(self, status, body): + if body is None: + body = "" + header = struct.pack(">BI", status, len(body)) + self.transport.write(header + body) + + def _receiveSASLMessage(self): + self._sasl_negotiation_deferred = defer.Deferred() + self._sasl_negotiation_status = None + return self._sasl_negotiation_deferred + + def connectionLost(self, reason=connectionDone): + if self.client: + ThriftClientProtocol.connectionLost(self, reason) + + def dataReceived(self, data): + if self._sasl_negotiation_deferred: + # we got a sasl challenge in the format (status, length, challenge) + # save the status, let IntNStringReceiver piece the challenge data together + self._sasl_negotiation_status, = struct.unpack("B", data[0]) + ThriftClientProtocol.dataReceived(self, data[1:]) + else: + # normal frame, let IntNStringReceiver piece it together + ThriftClientProtocol.dataReceived(self, data) + + def stringReceived(self, frame): + if self._sasl_negotiation_deferred: + # the frame is just a SASL challenge + response = (self._sasl_negotiation_status, frame) + self._sasl_negotiation_deferred.callback(response) + else: + # there's a second 4 byte length prefix inside the frame + decoded_frame = self.sasl.unwrap(frame[4:]) + ThriftClientProtocol.stringReceived(self, decoded_frame) + + +class ThriftServerProtocol(basic.Int32StringReceiver): + + MAX_LENGTH = 2 ** 31 - 1 + + def dispatch(self, msg): + self.sendString(msg) + + def processError(self, error): + self.transport.loseConnection() + + def processOk(self, _, tmo): + msg = tmo.getvalue() + + if len(msg) > 0: + self.dispatch(msg) + + def stringReceived(self, frame): + tmi = TTransport.TMemoryBuffer(frame) + tmo = TTransport.TMemoryBuffer() + + iprot = self.factory.iprot_factory.getProtocol(tmi) + oprot = self.factory.oprot_factory.getProtocol(tmo) + + d = self.factory.processor.process(iprot, oprot) + d.addCallbacks(self.processOk, self.processError, + callbackArgs=(tmo,)) + + +class IThriftServerFactory(Interface): + + processor = Attribute("Thrift processor") + + iprot_factory = Attribute("Input protocol factory") + + oprot_factory = Attribute("Output protocol factory") + + +class IThriftClientFactory(Interface): + + client_class = Attribute("Thrift client class") + + iprot_factory = Attribute("Input protocol factory") + + oprot_factory = Attribute("Output protocol factory") + + +class ThriftServerFactory(ServerFactory): + + implements(IThriftServerFactory) + + protocol = ThriftServerProtocol + + def __init__(self, processor, iprot_factory, oprot_factory=None): + self.processor = processor + self.iprot_factory = iprot_factory + if oprot_factory is None: + self.oprot_factory = iprot_factory + else: + self.oprot_factory = oprot_factory + + +class ThriftClientFactory(ClientFactory): + + implements(IThriftClientFactory) + + protocol = ThriftClientProtocol + + def __init__(self, client_class, iprot_factory, oprot_factory=None): + self.client_class = client_class + self.iprot_factory = iprot_factory + if oprot_factory is None: + self.oprot_factory = iprot_factory + else: + self.oprot_factory = oprot_factory + + def buildProtocol(self, addr): + p = self.protocol(self.client_class, self.iprot_factory, + self.oprot_factory) + p.factory = self + return p + + +class ThriftResource(resource.Resource): + + allowedMethods = ('POST',) + + def __init__(self, processor, inputProtocolFactory, + outputProtocolFactory=None): + resource.Resource.__init__(self) + self.inputProtocolFactory = inputProtocolFactory + if outputProtocolFactory is None: + self.outputProtocolFactory = inputProtocolFactory + else: + self.outputProtocolFactory = outputProtocolFactory + self.processor = processor + + def getChild(self, path, request): + return self + + def _cbProcess(self, _, request, tmo): + msg = tmo.getvalue() + request.setResponseCode(http.OK) + request.setHeader("content-type", "application/x-thrift") + request.write(msg) + request.finish() + + def render_POST(self, request): + request.content.seek(0, 0) + data = request.content.read() + tmi = TTransport.TMemoryBuffer(data) + tmo = TTransport.TMemoryBuffer() + + iprot = self.inputProtocolFactory.getProtocol(tmi) + oprot = self.outputProtocolFactory.getProtocol(tmo) + + d = self.processor.process(iprot, oprot) + d.addCallback(self._cbProcess, request, tmo) + return server.NOT_DONE_YET diff --git a/lib/thrift/transport/TZlibTransport.py b/lib/thrift/transport/TZlibTransport.py new file mode 100644 index 0000000..a2f42a5 --- /dev/null +++ b/lib/thrift/transport/TZlibTransport.py @@ -0,0 +1,248 @@ +# +# 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. +# + +"""TZlibTransport provides a compressed transport and transport factory +class, using the python standard library zlib module to implement +data compression. +""" + +from __future__ import division +import zlib +from cStringIO import StringIO +from TTransport import TTransportBase, CReadableTransport + + +class TZlibTransportFactory(object): + """Factory transport that builds zlib compressed transports. + + This factory caches the last single client/transport that it was passed + and returns the same TZlibTransport object that was created. + + This caching means the TServer class will get the _same_ transport + object for both input and output transports from this factory. + (For non-threaded scenarios only, since the cache only holds one object) + + The purpose of this caching is to allocate only one TZlibTransport where + only one is really needed (since it must have separate read/write buffers), + and makes the statistics from getCompSavings() and getCompRatio() + easier to understand. + """ + # class scoped cache of last transport given and zlibtransport returned + _last_trans = None + _last_z = None + + def getTransport(self, trans, compresslevel=9): + """Wrap a transport, trans, with the TZlibTransport + compressed transport class, returning a new + transport to the caller. + + @param compresslevel: The zlib compression level, ranging + from 0 (no compression) to 9 (best compression). Defaults to 9. + @type compresslevel: int + + This method returns a TZlibTransport which wraps the + passed C{trans} TTransport derived instance. + """ + if trans == self._last_trans: + return self._last_z + ztrans = TZlibTransport(trans, compresslevel) + self._last_trans = trans + self._last_z = ztrans + return ztrans + + +class TZlibTransport(TTransportBase, CReadableTransport): + """Class that wraps a transport with zlib, compressing writes + and decompresses reads, using the python standard + library zlib module. + """ + # Read buffer size for the python fastbinary C extension, + # the TBinaryProtocolAccelerated class. + DEFAULT_BUFFSIZE = 4096 + + def __init__(self, trans, compresslevel=9): + """Create a new TZlibTransport, wrapping C{trans}, another + TTransport derived object. + + @param trans: A thrift transport object, i.e. a TSocket() object. + @type trans: TTransport + @param compresslevel: The zlib compression level, ranging + from 0 (no compression) to 9 (best compression). Default is 9. + @type compresslevel: int + """ + self.__trans = trans + self.compresslevel = compresslevel + self.__rbuf = StringIO() + self.__wbuf = StringIO() + self._init_zlib() + self._init_stats() + + def _reinit_buffers(self): + """Internal method to initialize/reset the internal StringIO objects + for read and write buffers. + """ + self.__rbuf = StringIO() + self.__wbuf = StringIO() + + def _init_stats(self): + """Internal method to reset the internal statistics counters + for compression ratios and bandwidth savings. + """ + self.bytes_in = 0 + self.bytes_out = 0 + self.bytes_in_comp = 0 + self.bytes_out_comp = 0 + + def _init_zlib(self): + """Internal method for setting up the zlib compression and + decompression objects. + """ + self._zcomp_read = zlib.decompressobj() + self._zcomp_write = zlib.compressobj(self.compresslevel) + + def getCompRatio(self): + """Get the current measured compression ratios (in,out) from + this transport. + + Returns a tuple of: + (inbound_compression_ratio, outbound_compression_ratio) + + The compression ratios are computed as: + compressed / uncompressed + + E.g., data that compresses by 10x will have a ratio of: 0.10 + and data that compresses to half of ts original size will + have a ratio of 0.5 + + None is returned if no bytes have yet been processed in + a particular direction. + """ + r_percent, w_percent = (None, None) + if self.bytes_in > 0: + r_percent = self.bytes_in_comp / self.bytes_in + if self.bytes_out > 0: + w_percent = self.bytes_out_comp / self.bytes_out + return (r_percent, w_percent) + + def getCompSavings(self): + """Get the current count of saved bytes due to data + compression. + + Returns a tuple of: + (inbound_saved_bytes, outbound_saved_bytes) + + Note: if compression is actually expanding your + data (only likely with very tiny thrift objects), then + the values returned will be negative. + """ + r_saved = self.bytes_in - self.bytes_in_comp + w_saved = self.bytes_out - self.bytes_out_comp + return (r_saved, w_saved) + + def isOpen(self): + """Return the underlying transport's open status""" + return self.__trans.isOpen() + + def open(self): + """Open the underlying transport""" + self._init_stats() + return self.__trans.open() + + def listen(self): + """Invoke the underlying transport's listen() method""" + self.__trans.listen() + + def accept(self): + """Accept connections on the underlying transport""" + return self.__trans.accept() + + def close(self): + """Close the underlying transport,""" + self._reinit_buffers() + self._init_zlib() + return self.__trans.close() + + def read(self, sz): + """Read up to sz bytes from the decompressed bytes buffer, and + read from the underlying transport if the decompression + buffer is empty. + """ + ret = self.__rbuf.read(sz) + if len(ret) > 0: + return ret + # keep reading from transport until something comes back + while True: + if self.readComp(sz): + break + ret = self.__rbuf.read(sz) + return ret + + def readComp(self, sz): + """Read compressed data from the underlying transport, then + decompress it and append it to the internal StringIO read buffer + """ + zbuf = self.__trans.read(sz) + zbuf = self._zcomp_read.unconsumed_tail + zbuf + buf = self._zcomp_read.decompress(zbuf) + self.bytes_in += len(zbuf) + self.bytes_in_comp += len(buf) + old = self.__rbuf.read() + self.__rbuf = StringIO(old + buf) + if len(old) + len(buf) == 0: + return False + return True + + def write(self, buf): + """Write some bytes, putting them into the internal write + buffer for eventual compression. + """ + self.__wbuf.write(buf) + + def flush(self): + """Flush any queued up data in the write buffer and ensure the + compression buffer is flushed out to the underlying transport + """ + wout = self.__wbuf.getvalue() + if len(wout) > 0: + zbuf = self._zcomp_write.compress(wout) + self.bytes_out += len(wout) + self.bytes_out_comp += len(zbuf) + else: + zbuf = '' + ztail = self._zcomp_write.flush(zlib.Z_SYNC_FLUSH) + self.bytes_out_comp += len(ztail) + if (len(zbuf) + len(ztail)) > 0: + self.__wbuf = StringIO() + self.__trans.write(zbuf + ztail) + self.__trans.flush() + + @property + def cstringio_buf(self): + """Implement the CReadableTransport interface""" + return self.__rbuf + + def cstringio_refill(self, partialread, reqlen): + """Implement the CReadableTransport interface for refill""" + retstring = partialread + if reqlen < self.DEFAULT_BUFFSIZE: + retstring += self.read(self.DEFAULT_BUFFSIZE) + while len(retstring) < reqlen: + retstring += self.read(reqlen - len(retstring)) + self.__rbuf = StringIO(retstring) + return self.__rbuf diff --git a/lib/thrift/transport/__init__.py b/lib/thrift/transport/__init__.py new file mode 100644 index 0000000..c9596d9 --- /dev/null +++ b/lib/thrift/transport/__init__.py @@ -0,0 +1,20 @@ +# +# 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. +# + +__all__ = ['TTransport', 'TSocket', 'THttpClient', 'TZlibTransport'] diff --git a/lib/thrift/transport/__init__.pyc b/lib/thrift/transport/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcbb0129abb401b20daccb3808aa039e45b2a988 GIT binary patch literal 213 zcmZSn%**v5?r~T$0~D|TX$K%K76TF~K*Y$9!o-lm%#hB)5C!D2Fa&F`0;Nj0fJ8`0 zQDR;`Xw1fnQ0~ZB`~Y>VFSVq!Br~Uk z1IW(JEKUY-{4^M0((&<$IXUt18bCe+f+!XPa`p6cGL!T{>hS8vk8LV$rbn(h`igVx|= za0gCS@n+H5Zhyxba7i?R`vT{N>PRk>6+9LtG~TgyHHD{3Kf+Wshthefvx;Iw$uFWm zZ9n_3oHn+4;0`Ay=|&zW7x}`o=-Ce8!}4LtPpOz)a1|?h^goyQ(qo5B^IY QiG5w2i>s$i43s;50WA1Hg8%>k literal 0 HcmV?d00001 diff --git a/lib/util/netutil.py b/lib/util/netutil.py new file mode 100644 index 0000000..f8cc2d4 --- /dev/null +++ b/lib/util/netutil.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +# +# Licence statement goes here +# + +import socket +def get_ip(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + # doesn't even have to be reachable + s.connect(('192.255.255.255', 1)) + IP = s.getsockname()[0] + except: + IP = '127.0.0.1' + finally: + s.close() + return IP diff --git a/lib/util/netutil.pyc b/lib/util/netutil.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad3953e66aeec92b58fb97e662504e1dde001b00 GIT binary patch literal 516 zcmah^O-sW-5S_`kezaCW6ztJkPpK^w5kxKZgCbUG#TG9?lSQIwQrPXG(w^$S^e1@q z2k4ts@g#0CZ{O~lc{8itONH0Nx0{f@mxuibVak9AKT|?<3*ylW2+K{cqM*hfSRGd> zRXIcpVFG|9di+9m+@rZiGot4PO}1$YRZ*0uITOnvM{{&gRGu;Q(-JXrlp`Ecra>QL zND|VCcrcaz3+T}?YrxuG-LE$qKM^zTVg#9GQR}<@4!&ANM*OqD`B^bFS@@)_T?B2O z2JOztwJm`6E?eip@maTd;iNE2Qyp4cg!G`T6s31VZSy#XNoKTbXJr;+rE~kL0wf1! z6U?tB@qKk{M> QVHS-OeIO4sGT91$0&`SZ8UO$Q literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..62ce629 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,10 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. +pbr>=1.6 # Apache-2.0 +Babel>=1.3 # BSD +cliff!=1.16.0,!=1.17.0,>=1.15.0 # Apache-2.0 +PyYAML>=3.1.0 # MIT +python-dateutil>=2.4.2 # BSD +six>=1.9.0 # MIT +tosca-parser>=0.4.0 # Apache-2.0 diff --git a/tosca-templates/tosca_helloworld_nfv.yaml b/tosca-templates/tosca_helloworld_nfv.yaml new file mode 100644 index 0000000..b7f3100 --- /dev/null +++ b/tosca-templates/tosca_helloworld_nfv.yaml @@ -0,0 +1,46 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: Template for deploying a single server with predefined properties. + +metadata: + template_name: TOSCA NFV Sample Template + +policy_types: + tosca.policies.Placement.Geolocation: + description: Geolocation policy + derived_from: tosca.policies.Placement + +topology_template: + node_templates: + VNF1: + type: tosca.nodes.nfv.VNF + properties: + id: vnf1 + vendor: acmetelco + version: 1.0 + + VNF2: + type: tosca.nodes.nfv.VNF + properties: + id: vnf2 + vendor: ericsson + version: 1.0 + + VNF3: + type: tosca.nodes.nfv.VNF + properties: + id: vnf3 + vendor: huawei + version: 1.0 + + policies: + - rule1: + type: tosca.policies.Placement.Geolocation + targets: [ VNF1 ] + properties: + region: [ us-west-1 ] + - rule2: + type: tosca.policies.Placement.Geolocation + targets: [ VNF2, VNF3 ] + properties: + region: [ us-west-1 , us-west-2 ] -- 2.16.6