blob: 7b28c908c7e2f65e1a7d3c72fd7fb08979d2119d [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
Bryan Duxbury69720412012-01-03 17:32:30 +000020
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090021class TType(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090022 STOP = 0
23 VOID = 1
24 BOOL = 2
25 BYTE = 3
26 I08 = 3
27 DOUBLE = 4
28 I16 = 6
29 I32 = 8
30 I64 = 10
31 STRING = 11
32 UTF7 = 11
33 STRUCT = 12
34 MAP = 13
35 SET = 14
36 LIST = 15
Carel Combrinka715bdf2025-10-30 07:44:21 +010037 UUID = 16
Mark Sleee74306a2007-02-21 05:38:12 +000038
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090039 _VALUES_TO_NAMES = (
40 'STOP',
41 'VOID',
42 'BOOL',
43 'BYTE',
44 'DOUBLE',
45 None,
46 'I16',
47 None,
48 'I32',
49 None,
50 'I64',
51 'STRING',
52 'STRUCT',
53 'MAP',
54 'SET',
55 'LIST',
Carel Combrinka715bdf2025-10-30 07:44:21 +010056 'UUID',
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090057 )
Bryan Duxbury69720412012-01-03 17:32:30 +000058
Roger Meierf4eec7a2011-09-11 18:16:21 +000059
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090060class TMessageType(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090061 CALL = 1
62 REPLY = 2
63 EXCEPTION = 3
64 ONEWAY = 4
Mark Sleee74306a2007-02-21 05:38:12 +000065
Mark Sleec9676562006-09-05 17:34:52 +000066
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090067class TProcessor(object):
James E. King, IIIe7611d02017-10-23 16:44:45 -040068 """Base class for processor, which works on two streams."""
Mark Sleec9676562006-09-05 17:34:52 +000069
James E. King, IIIe7611d02017-10-23 16:44:45 -040070 def process(self, iprot, oprot):
James E. King III393f6c92019-02-09 10:35:44 -050071 """
72 Process a request. The normal behvaior is to have the
73 processor invoke the correct handler and then it is the
74 server's responsibility to write the response to oprot.
75 """
76 pass
77
78 def on_message_begin(self, func):
79 """
80 Install a callback that receives (name, type, seqid)
81 after the message header is read.
82 """
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090083 pass
Mark Slee92195ae2007-02-21 05:16:30 +000084
Mark Slee92195ae2007-02-21 05:16:30 +000085
Bryan Duxbury69720412012-01-03 17:32:30 +000086class TException(Exception):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090087 """Base class for all thrift exceptions."""
Mark Slee92195ae2007-02-21 05:16:30 +000088
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090089 def __init__(self, message=None):
90 Exception.__init__(self, message)
Neil Williams055fe672021-02-16 15:12:15 -080091 super(TException, self).__setattr__("message", message)
Mark Slee92195ae2007-02-21 05:16:30 +000092
Mark Slee92195ae2007-02-21 05:16:30 +000093
Bryan Duxbury69720412012-01-03 17:32:30 +000094class TApplicationException(TException):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090095 """Application level thrift exceptions."""
Mark Slee92195ae2007-02-21 05:16:30 +000096
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090097 UNKNOWN = 0
98 UNKNOWN_METHOD = 1
99 INVALID_MESSAGE_TYPE = 2
100 WRONG_METHOD_NAME = 3
101 BAD_SEQUENCE_ID = 4
102 MISSING_RESULT = 5
103 INTERNAL_ERROR = 6
104 PROTOCOL_ERROR = 7
105 INVALID_TRANSFORM = 8
106 INVALID_PROTOCOL = 9
107 UNSUPPORTED_CLIENT_TYPE = 10
Mark Slee92195ae2007-02-21 05:16:30 +0000108
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900109 def __init__(self, type=UNKNOWN, message=None):
110 TException.__init__(self, message)
111 self.type = type
Mark Slee92195ae2007-02-21 05:16:30 +0000112
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900113 def __str__(self):
114 if self.message:
115 return self.message
116 elif self.type == self.UNKNOWN_METHOD:
117 return 'Unknown method'
118 elif self.type == self.INVALID_MESSAGE_TYPE:
119 return 'Invalid message type'
120 elif self.type == self.WRONG_METHOD_NAME:
121 return 'Wrong method name'
122 elif self.type == self.BAD_SEQUENCE_ID:
123 return 'Bad sequence ID'
124 elif self.type == self.MISSING_RESULT:
125 return 'Missing result'
126 elif self.type == self.INTERNAL_ERROR:
127 return 'Internal error'
128 elif self.type == self.PROTOCOL_ERROR:
129 return 'Protocol error'
130 elif self.type == self.INVALID_TRANSFORM:
131 return 'Invalid transform'
132 elif self.type == self.INVALID_PROTOCOL:
133 return 'Invalid protocol'
134 elif self.type == self.UNSUPPORTED_CLIENT_TYPE:
135 return 'Unsupported client type'
Mark Slee92195ae2007-02-21 05:16:30 +0000136 else:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900137 return 'Default (unknown) TApplicationException'
Mark Slee92195ae2007-02-21 05:16:30 +0000138
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900139 def read(self, iprot):
140 iprot.readStructBegin()
141 while True:
142 (fname, ftype, fid) = iprot.readFieldBegin()
143 if ftype == TType.STOP:
144 break
145 if fid == 1:
146 if ftype == TType.STRING:
147 self.message = iprot.readString()
148 else:
149 iprot.skip(ftype)
150 elif fid == 2:
151 if ftype == TType.I32:
152 self.type = iprot.readI32()
153 else:
154 iprot.skip(ftype)
155 else:
156 iprot.skip(ftype)
157 iprot.readFieldEnd()
158 iprot.readStructEnd()
159
160 def write(self, oprot):
161 oprot.writeStructBegin('TApplicationException')
162 if self.message is not None:
163 oprot.writeFieldBegin('message', TType.STRING, 1)
164 oprot.writeString(self.message)
165 oprot.writeFieldEnd()
166 if self.type is not None:
167 oprot.writeFieldBegin('type', TType.I32, 2)
168 oprot.writeI32(self.type)
169 oprot.writeFieldEnd()
170 oprot.writeFieldStop()
171 oprot.writeStructEnd()
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900172
173
174class TFrozenDict(dict):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900175 """A dictionary that is "frozen" like a frozenset"""
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900176
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900177 def __init__(self, *args, **kwargs):
178 super(TFrozenDict, self).__init__(*args, **kwargs)
179 # Sort the items so they will be in a consistent order.
180 # XOR in the hash of the class so we don't collide with
181 # the hash of a list of tuples.
182 self.__hashval = hash(TFrozenDict) ^ hash(tuple(sorted(self.items())))
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900183
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900184 def __setitem__(self, *args):
185 raise TypeError("Can't modify frozen TFreezableDict")
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900186
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900187 def __delitem__(self, *args):
188 raise TypeError("Can't modify frozen TFreezableDict")
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900189
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900190 def __hash__(self):
191 return self.__hashval