blob: b335bc11b708e4d72ffc8eecc2359e3d7d6fb380 [file] [log] [blame]
Mark Slee89e2bb82007-03-01 00:20:36 +00001#
David Reissea2cba82009-03-30 21:35:00 +00002# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
Mark Slee89e2bb82007-03-01 00:20:36 +000019
David Reissc548b3d2010-03-09 05:19:18 +000020import sys
21
Bryan Duxbury69720412012-01-03 17:32:30 +000022
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090023class TType(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090024 STOP = 0
25 VOID = 1
26 BOOL = 2
27 BYTE = 3
28 I08 = 3
29 DOUBLE = 4
30 I16 = 6
31 I32 = 8
32 I64 = 10
33 STRING = 11
34 UTF7 = 11
35 STRUCT = 12
36 MAP = 13
37 SET = 14
38 LIST = 15
39 UTF8 = 16
40 UTF16 = 17
Mark Sleee74306a2007-02-21 05:38:12 +000041
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090042 _VALUES_TO_NAMES = (
43 'STOP',
44 'VOID',
45 'BOOL',
46 'BYTE',
47 'DOUBLE',
48 None,
49 'I16',
50 None,
51 'I32',
52 None,
53 'I64',
54 'STRING',
55 'STRUCT',
56 'MAP',
57 'SET',
58 'LIST',
59 'UTF8',
60 'UTF16',
61 )
Bryan Duxbury69720412012-01-03 17:32:30 +000062
Roger Meierf4eec7a2011-09-11 18:16:21 +000063
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090064class TMessageType(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090065 CALL = 1
66 REPLY = 2
67 EXCEPTION = 3
68 ONEWAY = 4
Mark Sleee74306a2007-02-21 05:38:12 +000069
Mark Sleec9676562006-09-05 17:34:52 +000070
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090071class TProcessor(object):
James E. King, IIIe7611d02017-10-23 16:44:45 -040072 """Base class for processor, which works on two streams."""
Mark Sleec9676562006-09-05 17:34:52 +000073
James E. King, IIIe7611d02017-10-23 16:44:45 -040074 def process(self, iprot, oprot):
James E. King III393f6c92019-02-09 10:35:44 -050075 """
76 Process a request. The normal behvaior is to have the
77 processor invoke the correct handler and then it is the
78 server's responsibility to write the response to oprot.
79 """
80 pass
81
82 def on_message_begin(self, func):
83 """
84 Install a callback that receives (name, type, seqid)
85 after the message header is read.
86 """
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090087 pass
Mark Slee92195ae2007-02-21 05:16:30 +000088
Mark Slee92195ae2007-02-21 05:16:30 +000089
Bryan Duxbury69720412012-01-03 17:32:30 +000090class TException(Exception):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090091 """Base class for all thrift exceptions."""
Mark Slee92195ae2007-02-21 05:16:30 +000092
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090093 def __init__(self, message=None):
94 Exception.__init__(self, message)
95 self.message = message
Mark Slee92195ae2007-02-21 05:16:30 +000096
Mark Slee92195ae2007-02-21 05:16:30 +000097
Bryan Duxbury69720412012-01-03 17:32:30 +000098class TApplicationException(TException):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090099 """Application level thrift exceptions."""
Mark Slee92195ae2007-02-21 05:16:30 +0000100
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900101 UNKNOWN = 0
102 UNKNOWN_METHOD = 1
103 INVALID_MESSAGE_TYPE = 2
104 WRONG_METHOD_NAME = 3
105 BAD_SEQUENCE_ID = 4
106 MISSING_RESULT = 5
107 INTERNAL_ERROR = 6
108 PROTOCOL_ERROR = 7
109 INVALID_TRANSFORM = 8
110 INVALID_PROTOCOL = 9
111 UNSUPPORTED_CLIENT_TYPE = 10
Mark Slee92195ae2007-02-21 05:16:30 +0000112
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900113 def __init__(self, type=UNKNOWN, message=None):
114 TException.__init__(self, message)
115 self.type = type
Mark Slee92195ae2007-02-21 05:16:30 +0000116
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900117 def __str__(self):
118 if self.message:
119 return self.message
120 elif self.type == self.UNKNOWN_METHOD:
121 return 'Unknown method'
122 elif self.type == self.INVALID_MESSAGE_TYPE:
123 return 'Invalid message type'
124 elif self.type == self.WRONG_METHOD_NAME:
125 return 'Wrong method name'
126 elif self.type == self.BAD_SEQUENCE_ID:
127 return 'Bad sequence ID'
128 elif self.type == self.MISSING_RESULT:
129 return 'Missing result'
130 elif self.type == self.INTERNAL_ERROR:
131 return 'Internal error'
132 elif self.type == self.PROTOCOL_ERROR:
133 return 'Protocol error'
134 elif self.type == self.INVALID_TRANSFORM:
135 return 'Invalid transform'
136 elif self.type == self.INVALID_PROTOCOL:
137 return 'Invalid protocol'
138 elif self.type == self.UNSUPPORTED_CLIENT_TYPE:
139 return 'Unsupported client type'
Mark Slee92195ae2007-02-21 05:16:30 +0000140 else:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900141 return 'Default (unknown) TApplicationException'
Mark Slee92195ae2007-02-21 05:16:30 +0000142
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900143 def read(self, iprot):
144 iprot.readStructBegin()
145 while True:
146 (fname, ftype, fid) = iprot.readFieldBegin()
147 if ftype == TType.STOP:
148 break
149 if fid == 1:
150 if ftype == TType.STRING:
151 self.message = iprot.readString()
152 else:
153 iprot.skip(ftype)
154 elif fid == 2:
155 if ftype == TType.I32:
156 self.type = iprot.readI32()
157 else:
158 iprot.skip(ftype)
159 else:
160 iprot.skip(ftype)
161 iprot.readFieldEnd()
162 iprot.readStructEnd()
163
164 def write(self, oprot):
165 oprot.writeStructBegin('TApplicationException')
166 if self.message is not None:
167 oprot.writeFieldBegin('message', TType.STRING, 1)
168 oprot.writeString(self.message)
169 oprot.writeFieldEnd()
170 if self.type is not None:
171 oprot.writeFieldBegin('type', TType.I32, 2)
172 oprot.writeI32(self.type)
173 oprot.writeFieldEnd()
174 oprot.writeFieldStop()
175 oprot.writeStructEnd()
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900176
177
178class TFrozenDict(dict):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900179 """A dictionary that is "frozen" like a frozenset"""
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900180
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900181 def __init__(self, *args, **kwargs):
182 super(TFrozenDict, self).__init__(*args, **kwargs)
183 # Sort the items so they will be in a consistent order.
184 # XOR in the hash of the class so we don't collide with
185 # the hash of a list of tuples.
186 self.__hashval = hash(TFrozenDict) ^ hash(tuple(sorted(self.items())))
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900187
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900188 def __setitem__(self, *args):
189 raise TypeError("Can't modify frozen TFreezableDict")
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900190
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900191 def __delitem__(self, *args):
192 raise TypeError("Can't modify frozen TFreezableDict")
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900193
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900194 def __hash__(self):
195 return self.__hashval