#
# Autogenerated by Thrift Compiler (0.9.2)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py:utf8strings
#

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 TopologyInitialStatus:
  ACTIVE = 1
  INACTIVE = 2

  _VALUES_TO_NAMES = {
    1: "ACTIVE",
    2: "INACTIVE",
  }

  _NAMES_TO_VALUES = {
    "ACTIVE": 1,
    "INACTIVE": 2,
  }


class JavaObjectArg:
  """
  Attributes:
   - int_arg
   - long_arg
   - string_arg
   - bool_arg
   - binary_arg
   - double_arg
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'int_arg', None, None, ), # 1
    (2, TType.I64, 'long_arg', None, None, ), # 2
    (3, TType.STRING, 'string_arg', None, None, ), # 3
    (4, TType.BOOL, 'bool_arg', None, None, ), # 4
    (5, TType.STRING, 'binary_arg', None, None, ), # 5
    (6, TType.DOUBLE, 'double_arg', None, None, ), # 6
  )

  def __init__(self, int_arg=None, long_arg=None, string_arg=None, bool_arg=None, binary_arg=None, double_arg=None,):
    self.int_arg = int_arg
    self.long_arg = long_arg
    self.string_arg = string_arg
    self.bool_arg = bool_arg
    self.binary_arg = binary_arg
    self.double_arg = double_arg

  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.I32:
          self.int_arg = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.long_arg = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.string_arg = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.BOOL:
          self.bool_arg = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.STRING:
          self.binary_arg = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.DOUBLE:
          self.double_arg = iprot.readDouble();
        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('JavaObjectArg')
    if self.int_arg is not None:
      oprot.writeFieldBegin('int_arg', TType.I32, 1)
      oprot.writeI32(self.int_arg)
      oprot.writeFieldEnd()
    if self.long_arg is not None:
      oprot.writeFieldBegin('long_arg', TType.I64, 2)
      oprot.writeI64(self.long_arg)
      oprot.writeFieldEnd()
    if self.string_arg is not None:
      oprot.writeFieldBegin('string_arg', TType.STRING, 3)
      oprot.writeString(self.string_arg.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.bool_arg is not None:
      oprot.writeFieldBegin('bool_arg', TType.BOOL, 4)
      oprot.writeBool(self.bool_arg)
      oprot.writeFieldEnd()
    if self.binary_arg is not None:
      oprot.writeFieldBegin('binary_arg', TType.STRING, 5)
      oprot.writeString(self.binary_arg)
      oprot.writeFieldEnd()
    if self.double_arg is not None:
      oprot.writeFieldBegin('double_arg', TType.DOUBLE, 6)
      oprot.writeDouble(self.double_arg)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.int_arg)
    value = (value * 31) ^ hash(self.long_arg)
    value = (value * 31) ^ hash(self.string_arg)
    value = (value * 31) ^ hash(self.bool_arg)
    value = (value * 31) ^ hash(self.binary_arg)
    value = (value * 31) ^ hash(self.double_arg)
    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 JavaObject:
  """
  Attributes:
   - full_class_name
   - args_list
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'full_class_name', None, None, ), # 1
    (2, TType.LIST, 'args_list', (TType.STRUCT,(JavaObjectArg, JavaObjectArg.thrift_spec)), None, ), # 2
  )

  def __init__(self, full_class_name=None, args_list=None,):
    self.full_class_name = full_class_name
    self.args_list = args_list

  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.STRING:
          self.full_class_name = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.args_list = []
          (_etype3, _size0) = iprot.readListBegin()
          for _i4 in xrange(_size0):
            _elem5 = JavaObjectArg()
            _elem5.read(iprot)
            self.args_list.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('JavaObject')
    if self.full_class_name is not None:
      oprot.writeFieldBegin('full_class_name', TType.STRING, 1)
      oprot.writeString(self.full_class_name.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.args_list is not None:
      oprot.writeFieldBegin('args_list', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.args_list))
      for iter6 in self.args_list:
        iter6.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.full_class_name is None:
      raise TProtocol.TProtocolException(message='Required field full_class_name is unset!')
    if self.args_list is None:
      raise TProtocol.TProtocolException(message='Required field args_list is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.full_class_name)
    value = (value * 31) ^ hash(self.args_list)
    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 NullStruct:

  thrift_spec = (
  )

  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
      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('NullStruct')
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    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 GlobalStreamId:
  """
  Attributes:
   - componentId
   - streamId
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'componentId', None, None, ), # 1
    (2, TType.STRING, 'streamId', None, None, ), # 2
  )

  def __init__(self, componentId=None, streamId=None,):
    self.componentId = componentId
    self.streamId = streamId

  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.STRING:
          self.componentId = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.streamId = iprot.readString().decode('utf-8')
        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('GlobalStreamId')
    if self.componentId is not None:
      oprot.writeFieldBegin('componentId', TType.STRING, 1)
      oprot.writeString(self.componentId.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.streamId is not None:
      oprot.writeFieldBegin('streamId', TType.STRING, 2)
      oprot.writeString(self.streamId.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.componentId is None:
      raise TProtocol.TProtocolException(message='Required field componentId is unset!')
    if self.streamId is None:
      raise TProtocol.TProtocolException(message='Required field streamId is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.componentId)
    value = (value * 31) ^ hash(self.streamId)
    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 Grouping:
  """
  Attributes:
   - fields
   - shuffle
   - all
   - none
   - direct
   - custom_object
   - custom_serialized
   - local_or_shuffle
   - localFirst
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'fields', (TType.STRING,None), None, ), # 1
    (2, TType.STRUCT, 'shuffle', (NullStruct, NullStruct.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'all', (NullStruct, NullStruct.thrift_spec), None, ), # 3
    (4, TType.STRUCT, 'none', (NullStruct, NullStruct.thrift_spec), None, ), # 4
    (5, TType.STRUCT, 'direct', (NullStruct, NullStruct.thrift_spec), None, ), # 5
    (6, TType.STRUCT, 'custom_object', (JavaObject, JavaObject.thrift_spec), None, ), # 6
    (7, TType.STRING, 'custom_serialized', None, None, ), # 7
    (8, TType.STRUCT, 'local_or_shuffle', (NullStruct, NullStruct.thrift_spec), None, ), # 8
    (9, TType.STRUCT, 'localFirst', (NullStruct, NullStruct.thrift_spec), None, ), # 9
  )

  def __init__(self, fields=None, shuffle=None, all=None, none=None, direct=None, custom_object=None, custom_serialized=None, local_or_shuffle=None, localFirst=None,):
    self.fields = fields
    self.shuffle = shuffle
    self.all = all
    self.none = none
    self.direct = direct
    self.custom_object = custom_object
    self.custom_serialized = custom_serialized
    self.local_or_shuffle = local_or_shuffle
    self.localFirst = localFirst

  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.LIST:
          self.fields = []
          (_etype10, _size7) = iprot.readListBegin()
          for _i11 in xrange(_size7):
            _elem12 = iprot.readString().decode('utf-8')
            self.fields.append(_elem12)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.shuffle = NullStruct()
          self.shuffle.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.all = NullStruct()
          self.all.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.none = NullStruct()
          self.none.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.STRUCT:
          self.direct = NullStruct()
          self.direct.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.STRUCT:
          self.custom_object = JavaObject()
          self.custom_object.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 7:
        if ftype == TType.STRING:
          self.custom_serialized = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 8:
        if ftype == TType.STRUCT:
          self.local_or_shuffle = NullStruct()
          self.local_or_shuffle.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 9:
        if ftype == TType.STRUCT:
          self.localFirst = NullStruct()
          self.localFirst.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('Grouping')
    if self.fields is not None:
      oprot.writeFieldBegin('fields', TType.LIST, 1)
      oprot.writeListBegin(TType.STRING, len(self.fields))
      for iter13 in self.fields:
        oprot.writeString(iter13.encode('utf-8'))
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.shuffle is not None:
      oprot.writeFieldBegin('shuffle', TType.STRUCT, 2)
      self.shuffle.write(oprot)
      oprot.writeFieldEnd()
    if self.all is not None:
      oprot.writeFieldBegin('all', TType.STRUCT, 3)
      self.all.write(oprot)
      oprot.writeFieldEnd()
    if self.none is not None:
      oprot.writeFieldBegin('none', TType.STRUCT, 4)
      self.none.write(oprot)
      oprot.writeFieldEnd()
    if self.direct is not None:
      oprot.writeFieldBegin('direct', TType.STRUCT, 5)
      self.direct.write(oprot)
      oprot.writeFieldEnd()
    if self.custom_object is not None:
      oprot.writeFieldBegin('custom_object', TType.STRUCT, 6)
      self.custom_object.write(oprot)
      oprot.writeFieldEnd()
    if self.custom_serialized is not None:
      oprot.writeFieldBegin('custom_serialized', TType.STRING, 7)
      oprot.writeString(self.custom_serialized)
      oprot.writeFieldEnd()
    if self.local_or_shuffle is not None:
      oprot.writeFieldBegin('local_or_shuffle', TType.STRUCT, 8)
      self.local_or_shuffle.write(oprot)
      oprot.writeFieldEnd()
    if self.localFirst is not None:
      oprot.writeFieldBegin('localFirst', TType.STRUCT, 9)
      self.localFirst.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.fields)
    value = (value * 31) ^ hash(self.shuffle)
    value = (value * 31) ^ hash(self.all)
    value = (value * 31) ^ hash(self.none)
    value = (value * 31) ^ hash(self.direct)
    value = (value * 31) ^ hash(self.custom_object)
    value = (value * 31) ^ hash(self.custom_serialized)
    value = (value * 31) ^ hash(self.local_or_shuffle)
    value = (value * 31) ^ hash(self.localFirst)
    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 StreamInfo:
  """
  Attributes:
   - output_fields
   - direct
  """

  thrift_spec = (
    None, # 0
    (1, TType.LIST, 'output_fields', (TType.STRING,None), None, ), # 1
    (2, TType.BOOL, 'direct', None, None, ), # 2
  )

  def __init__(self, output_fields=None, direct=None,):
    self.output_fields = output_fields
    self.direct = direct

  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.LIST:
          self.output_fields = []
          (_etype17, _size14) = iprot.readListBegin()
          for _i18 in xrange(_size14):
            _elem19 = iprot.readString().decode('utf-8')
            self.output_fields.append(_elem19)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.BOOL:
          self.direct = iprot.readBool();
        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('StreamInfo')
    if self.output_fields is not None:
      oprot.writeFieldBegin('output_fields', TType.LIST, 1)
      oprot.writeListBegin(TType.STRING, len(self.output_fields))
      for iter20 in self.output_fields:
        oprot.writeString(iter20.encode('utf-8'))
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.direct is not None:
      oprot.writeFieldBegin('direct', TType.BOOL, 2)
      oprot.writeBool(self.direct)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.output_fields is None:
      raise TProtocol.TProtocolException(message='Required field output_fields is unset!')
    if self.direct is None:
      raise TProtocol.TProtocolException(message='Required field direct is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.output_fields)
    value = (value * 31) ^ hash(self.direct)
    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 ShellComponent:
  """
  Attributes:
   - execution_command
   - script
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'execution_command', None, None, ), # 1
    (2, TType.STRING, 'script', None, None, ), # 2
  )

  def __init__(self, execution_command=None, script=None,):
    self.execution_command = execution_command
    self.script = script

  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.STRING:
          self.execution_command = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.script = iprot.readString().decode('utf-8')
        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('ShellComponent')
    if self.execution_command is not None:
      oprot.writeFieldBegin('execution_command', TType.STRING, 1)
      oprot.writeString(self.execution_command.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.script is not None:
      oprot.writeFieldBegin('script', TType.STRING, 2)
      oprot.writeString(self.script.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.execution_command)
    value = (value * 31) ^ hash(self.script)
    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 ComponentObject:
  """
  Attributes:
   - serialized_java
   - shell
   - java_object
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'serialized_java', None, None, ), # 1
    (2, TType.STRUCT, 'shell', (ShellComponent, ShellComponent.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'java_object', (JavaObject, JavaObject.thrift_spec), None, ), # 3
  )

  def __init__(self, serialized_java=None, shell=None, java_object=None,):
    self.serialized_java = serialized_java
    self.shell = shell
    self.java_object = java_object

  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.STRING:
          self.serialized_java = iprot.readString();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.shell = ShellComponent()
          self.shell.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.java_object = JavaObject()
          self.java_object.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('ComponentObject')
    if self.serialized_java is not None:
      oprot.writeFieldBegin('serialized_java', TType.STRING, 1)
      oprot.writeString(self.serialized_java)
      oprot.writeFieldEnd()
    if self.shell is not None:
      oprot.writeFieldBegin('shell', TType.STRUCT, 2)
      self.shell.write(oprot)
      oprot.writeFieldEnd()
    if self.java_object is not None:
      oprot.writeFieldBegin('java_object', TType.STRUCT, 3)
      self.java_object.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.serialized_java)
    value = (value * 31) ^ hash(self.shell)
    value = (value * 31) ^ hash(self.java_object)
    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 ComponentCommon:
  """
  Attributes:
   - inputs
   - streams
   - parallelism_hint
   - json_conf
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'inputs', (TType.STRUCT,(GlobalStreamId, GlobalStreamId.thrift_spec),TType.STRUCT,(Grouping, Grouping.thrift_spec)), None, ), # 1
    (2, TType.MAP, 'streams', (TType.STRING,None,TType.STRUCT,(StreamInfo, StreamInfo.thrift_spec)), None, ), # 2
    (3, TType.I32, 'parallelism_hint', None, None, ), # 3
    (4, TType.STRING, 'json_conf', None, None, ), # 4
  )

  def __init__(self, inputs=None, streams=None, parallelism_hint=None, json_conf=None,):
    self.inputs = inputs
    self.streams = streams
    self.parallelism_hint = parallelism_hint
    self.json_conf = json_conf

  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.MAP:
          self.inputs = {}
          (_ktype22, _vtype23, _size21 ) = iprot.readMapBegin()
          for _i25 in xrange(_size21):
            _key26 = GlobalStreamId()
            _key26.read(iprot)
            _val27 = Grouping()
            _val27.read(iprot)
            self.inputs[_key26] = _val27
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.MAP:
          self.streams = {}
          (_ktype29, _vtype30, _size28 ) = iprot.readMapBegin()
          for _i32 in xrange(_size28):
            _key33 = iprot.readString().decode('utf-8')
            _val34 = StreamInfo()
            _val34.read(iprot)
            self.streams[_key33] = _val34
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.parallelism_hint = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.json_conf = iprot.readString().decode('utf-8')
        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('ComponentCommon')
    if self.inputs is not None:
      oprot.writeFieldBegin('inputs', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRUCT, TType.STRUCT, len(self.inputs))
      for kiter35,viter36 in self.inputs.items():
        kiter35.write(oprot)
        viter36.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.streams is not None:
      oprot.writeFieldBegin('streams', TType.MAP, 2)
      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.streams))
      for kiter37,viter38 in self.streams.items():
        oprot.writeString(kiter37.encode('utf-8'))
        viter38.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.parallelism_hint is not None:
      oprot.writeFieldBegin('parallelism_hint', TType.I32, 3)
      oprot.writeI32(self.parallelism_hint)
      oprot.writeFieldEnd()
    if self.json_conf is not None:
      oprot.writeFieldBegin('json_conf', TType.STRING, 4)
      oprot.writeString(self.json_conf.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.inputs is None:
      raise TProtocol.TProtocolException(message='Required field inputs is unset!')
    if self.streams is None:
      raise TProtocol.TProtocolException(message='Required field streams is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.inputs)
    value = (value * 31) ^ hash(self.streams)
    value = (value * 31) ^ hash(self.parallelism_hint)
    value = (value * 31) ^ hash(self.json_conf)
    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 SpoutSpec:
  """
  Attributes:
   - spout_object
   - common
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'spout_object', (ComponentObject, ComponentObject.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'common', (ComponentCommon, ComponentCommon.thrift_spec), None, ), # 2
  )

  def __init__(self, spout_object=None, common=None,):
    self.spout_object = spout_object
    self.common = common

  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.spout_object = ComponentObject()
          self.spout_object.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.common = ComponentCommon()
          self.common.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('SpoutSpec')
    if self.spout_object is not None:
      oprot.writeFieldBegin('spout_object', TType.STRUCT, 1)
      self.spout_object.write(oprot)
      oprot.writeFieldEnd()
    if self.common is not None:
      oprot.writeFieldBegin('common', TType.STRUCT, 2)
      self.common.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.spout_object is None:
      raise TProtocol.TProtocolException(message='Required field spout_object is unset!')
    if self.common is None:
      raise TProtocol.TProtocolException(message='Required field common is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.spout_object)
    value = (value * 31) ^ hash(self.common)
    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 Bolt:
  """
  Attributes:
   - bolt_object
   - common
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'bolt_object', (ComponentObject, ComponentObject.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'common', (ComponentCommon, ComponentCommon.thrift_spec), None, ), # 2
  )

  def __init__(self, bolt_object=None, common=None,):
    self.bolt_object = bolt_object
    self.common = common

  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.bolt_object = ComponentObject()
          self.bolt_object.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.common = ComponentCommon()
          self.common.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('Bolt')
    if self.bolt_object is not None:
      oprot.writeFieldBegin('bolt_object', TType.STRUCT, 1)
      self.bolt_object.write(oprot)
      oprot.writeFieldEnd()
    if self.common is not None:
      oprot.writeFieldBegin('common', TType.STRUCT, 2)
      self.common.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.bolt_object is None:
      raise TProtocol.TProtocolException(message='Required field bolt_object is unset!')
    if self.common is None:
      raise TProtocol.TProtocolException(message='Required field common is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.bolt_object)
    value = (value * 31) ^ hash(self.common)
    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 StateSpoutSpec:
  """
  Attributes:
   - state_spout_object
   - common
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'state_spout_object', (ComponentObject, ComponentObject.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'common', (ComponentCommon, ComponentCommon.thrift_spec), None, ), # 2
  )

  def __init__(self, state_spout_object=None, common=None,):
    self.state_spout_object = state_spout_object
    self.common = common

  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.state_spout_object = ComponentObject()
          self.state_spout_object.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.common = ComponentCommon()
          self.common.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('StateSpoutSpec')
    if self.state_spout_object is not None:
      oprot.writeFieldBegin('state_spout_object', TType.STRUCT, 1)
      self.state_spout_object.write(oprot)
      oprot.writeFieldEnd()
    if self.common is not None:
      oprot.writeFieldBegin('common', TType.STRUCT, 2)
      self.common.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.state_spout_object is None:
      raise TProtocol.TProtocolException(message='Required field state_spout_object is unset!')
    if self.common is None:
      raise TProtocol.TProtocolException(message='Required field common is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.state_spout_object)
    value = (value * 31) ^ hash(self.common)
    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 StormTopology:
  """
  Attributes:
   - spouts
   - bolts
   - state_spouts
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'spouts', (TType.STRING,None,TType.STRUCT,(SpoutSpec, SpoutSpec.thrift_spec)), None, ), # 1
    (2, TType.MAP, 'bolts', (TType.STRING,None,TType.STRUCT,(Bolt, Bolt.thrift_spec)), None, ), # 2
    (3, TType.MAP, 'state_spouts', (TType.STRING,None,TType.STRUCT,(StateSpoutSpec, StateSpoutSpec.thrift_spec)), None, ), # 3
  )

  def __init__(self, spouts=None, bolts=None, state_spouts=None,):
    self.spouts = spouts
    self.bolts = bolts
    self.state_spouts = state_spouts

  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.MAP:
          self.spouts = {}
          (_ktype40, _vtype41, _size39 ) = iprot.readMapBegin()
          for _i43 in xrange(_size39):
            _key44 = iprot.readString().decode('utf-8')
            _val45 = SpoutSpec()
            _val45.read(iprot)
            self.spouts[_key44] = _val45
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.MAP:
          self.bolts = {}
          (_ktype47, _vtype48, _size46 ) = iprot.readMapBegin()
          for _i50 in xrange(_size46):
            _key51 = iprot.readString().decode('utf-8')
            _val52 = Bolt()
            _val52.read(iprot)
            self.bolts[_key51] = _val52
          iprot.readMapEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.MAP:
          self.state_spouts = {}
          (_ktype54, _vtype55, _size53 ) = iprot.readMapBegin()
          for _i57 in xrange(_size53):
            _key58 = iprot.readString().decode('utf-8')
            _val59 = StateSpoutSpec()
            _val59.read(iprot)
            self.state_spouts[_key58] = _val59
          iprot.readMapEnd()
        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('StormTopology')
    if self.spouts is not None:
      oprot.writeFieldBegin('spouts', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.spouts))
      for kiter60,viter61 in self.spouts.items():
        oprot.writeString(kiter60.encode('utf-8'))
        viter61.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.bolts is not None:
      oprot.writeFieldBegin('bolts', TType.MAP, 2)
      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.bolts))
      for kiter62,viter63 in self.bolts.items():
        oprot.writeString(kiter62.encode('utf-8'))
        viter63.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    if self.state_spouts is not None:
      oprot.writeFieldBegin('state_spouts', TType.MAP, 3)
      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.state_spouts))
      for kiter64,viter65 in self.state_spouts.items():
        oprot.writeString(kiter64.encode('utf-8'))
        viter65.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.spouts is None:
      raise TProtocol.TProtocolException(message='Required field spouts is unset!')
    if self.bolts is None:
      raise TProtocol.TProtocolException(message='Required field bolts is unset!')
    if self.state_spouts is None:
      raise TProtocol.TProtocolException(message='Required field state_spouts is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.spouts)
    value = (value * 31) ^ hash(self.bolts)
    value = (value * 31) ^ hash(self.state_spouts)
    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 AlreadyAliveException(TException):
  """
  Attributes:
   - msg
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'msg', None, 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.STRING:
          self.msg = iprot.readString().decode('utf-8')
        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('AlreadyAliveException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.msg is None:
      raise TProtocol.TProtocolException(message='Required field msg is unset!')
    return


  def __str__(self):
    return repr(self)

  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 NotAliveException(TException):
  """
  Attributes:
   - msg
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'msg', None, 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.STRING:
          self.msg = iprot.readString().decode('utf-8')
        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('NotAliveException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.msg is None:
      raise TProtocol.TProtocolException(message='Required field msg is unset!')
    return


  def __str__(self):
    return repr(self)

  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 AuthorizationException(TException):
  """
  Attributes:
   - msg
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'msg', None, 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.STRING:
          self.msg = iprot.readString().decode('utf-8')
        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('AuthorizationException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.msg is None:
      raise TProtocol.TProtocolException(message='Required field msg is unset!')
    return


  def __str__(self):
    return repr(self)

  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 InvalidTopologyException(TException):
  """
  Attributes:
   - msg
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'msg', None, 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.STRING:
          self.msg = iprot.readString().decode('utf-8')
        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('InvalidTopologyException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.msg is None:
      raise TProtocol.TProtocolException(message='Required field msg is unset!')
    return


  def __str__(self):
    return repr(self)

  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 TopologyAssignException(TException):
  """
  Attributes:
   - msg
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'msg', None, 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.STRING:
          self.msg = iprot.readString().decode('utf-8')
        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('TopologyAssignException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.msg is None:
      raise TProtocol.TProtocolException(message='Required field msg is unset!')
    return


  def __str__(self):
    return repr(self)

  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 TopologySummary:
  """
  Attributes:
   - id
   - name
   - status
   - uptimeSecs
   - numTasks
   - numWorkers
   - errorInfo
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'id', None, None, ), # 1
    (2, TType.STRING, 'name', None, None, ), # 2
    (3, TType.STRING, 'status', None, None, ), # 3
    (4, TType.I32, 'uptimeSecs', None, None, ), # 4
    (5, TType.I32, 'numTasks', None, None, ), # 5
    (6, TType.I32, 'numWorkers', None, None, ), # 6
    (7, TType.STRING, 'errorInfo', None, None, ), # 7
  )

  def __init__(self, id=None, name=None, status=None, uptimeSecs=None, numTasks=None, numWorkers=None, errorInfo=None,):
    self.id = id
    self.name = name
    self.status = status
    self.uptimeSecs = uptimeSecs
    self.numTasks = numTasks
    self.numWorkers = numWorkers
    self.errorInfo = errorInfo

  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.STRING:
          self.id = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.name = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.status = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.uptimeSecs = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.numTasks = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.I32:
          self.numWorkers = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 7:
        if ftype == TType.STRING:
          self.errorInfo = iprot.readString().decode('utf-8')
        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('TopologySummary')
    if self.id is not None:
      oprot.writeFieldBegin('id', TType.STRING, 1)
      oprot.writeString(self.id.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 2)
      oprot.writeString(self.name.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.status is not None:
      oprot.writeFieldBegin('status', TType.STRING, 3)
      oprot.writeString(self.status.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.uptimeSecs is not None:
      oprot.writeFieldBegin('uptimeSecs', TType.I32, 4)
      oprot.writeI32(self.uptimeSecs)
      oprot.writeFieldEnd()
    if self.numTasks is not None:
      oprot.writeFieldBegin('numTasks', TType.I32, 5)
      oprot.writeI32(self.numTasks)
      oprot.writeFieldEnd()
    if self.numWorkers is not None:
      oprot.writeFieldBegin('numWorkers', TType.I32, 6)
      oprot.writeI32(self.numWorkers)
      oprot.writeFieldEnd()
    if self.errorInfo is not None:
      oprot.writeFieldBegin('errorInfo', TType.STRING, 7)
      oprot.writeString(self.errorInfo.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.id is None:
      raise TProtocol.TProtocolException(message='Required field id is unset!')
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.status is None:
      raise TProtocol.TProtocolException(message='Required field status is unset!')
    if self.uptimeSecs is None:
      raise TProtocol.TProtocolException(message='Required field uptimeSecs is unset!')
    if self.numTasks is None:
      raise TProtocol.TProtocolException(message='Required field numTasks is unset!')
    if self.numWorkers is None:
      raise TProtocol.TProtocolException(message='Required field numWorkers is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.id)
    value = (value * 31) ^ hash(self.name)
    value = (value * 31) ^ hash(self.status)
    value = (value * 31) ^ hash(self.uptimeSecs)
    value = (value * 31) ^ hash(self.numTasks)
    value = (value * 31) ^ hash(self.numWorkers)
    value = (value * 31) ^ hash(self.errorInfo)
    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 SupervisorSummary:
  """
  Attributes:
   - host
   - supervisorId
   - uptimeSecs
   - numWorkers
   - numUsedWorkers
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'host', None, None, ), # 1
    (2, TType.STRING, 'supervisorId', None, None, ), # 2
    (3, TType.I32, 'uptimeSecs', None, None, ), # 3
    (4, TType.I32, 'numWorkers', None, None, ), # 4
    (5, TType.I32, 'numUsedWorkers', None, None, ), # 5
  )

  def __init__(self, host=None, supervisorId=None, uptimeSecs=None, numWorkers=None, numUsedWorkers=None,):
    self.host = host
    self.supervisorId = supervisorId
    self.uptimeSecs = uptimeSecs
    self.numWorkers = numWorkers
    self.numUsedWorkers = numUsedWorkers

  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.STRING:
          self.host = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.supervisorId = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.uptimeSecs = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.numWorkers = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.numUsedWorkers = iprot.readI32();
        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('SupervisorSummary')
    if self.host is not None:
      oprot.writeFieldBegin('host', TType.STRING, 1)
      oprot.writeString(self.host.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.supervisorId is not None:
      oprot.writeFieldBegin('supervisorId', TType.STRING, 2)
      oprot.writeString(self.supervisorId.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.uptimeSecs is not None:
      oprot.writeFieldBegin('uptimeSecs', TType.I32, 3)
      oprot.writeI32(self.uptimeSecs)
      oprot.writeFieldEnd()
    if self.numWorkers is not None:
      oprot.writeFieldBegin('numWorkers', TType.I32, 4)
      oprot.writeI32(self.numWorkers)
      oprot.writeFieldEnd()
    if self.numUsedWorkers is not None:
      oprot.writeFieldBegin('numUsedWorkers', TType.I32, 5)
      oprot.writeI32(self.numUsedWorkers)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.host is None:
      raise TProtocol.TProtocolException(message='Required field host is unset!')
    if self.supervisorId is None:
      raise TProtocol.TProtocolException(message='Required field supervisorId is unset!')
    if self.uptimeSecs is None:
      raise TProtocol.TProtocolException(message='Required field uptimeSecs is unset!')
    if self.numWorkers is None:
      raise TProtocol.TProtocolException(message='Required field numWorkers is unset!')
    if self.numUsedWorkers is None:
      raise TProtocol.TProtocolException(message='Required field numUsedWorkers is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.host)
    value = (value * 31) ^ hash(self.supervisorId)
    value = (value * 31) ^ hash(self.uptimeSecs)
    value = (value * 31) ^ hash(self.numWorkers)
    value = (value * 31) ^ hash(self.numUsedWorkers)
    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 NimbusStat:
  """
  Attributes:
   - host
   - uptimeSecs
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'host', None, None, ), # 1
    (2, TType.STRING, 'uptimeSecs', None, None, ), # 2
  )

  def __init__(self, host=None, uptimeSecs=None,):
    self.host = host
    self.uptimeSecs = uptimeSecs

  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.STRING:
          self.host = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.uptimeSecs = iprot.readString().decode('utf-8')
        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('NimbusStat')
    if self.host is not None:
      oprot.writeFieldBegin('host', TType.STRING, 1)
      oprot.writeString(self.host.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.uptimeSecs is not None:
      oprot.writeFieldBegin('uptimeSecs', TType.STRING, 2)
      oprot.writeString(self.uptimeSecs.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.host is None:
      raise TProtocol.TProtocolException(message='Required field host is unset!')
    if self.uptimeSecs is None:
      raise TProtocol.TProtocolException(message='Required field uptimeSecs is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.host)
    value = (value * 31) ^ hash(self.uptimeSecs)
    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 NimbusSummary:
  """
  Attributes:
   - nimbusMaster
   - nimbusSlaves
   - supervisorNum
   - totalPortNum
   - usedPortNum
   - freePortNum
   - version
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'nimbusMaster', (NimbusStat, NimbusStat.thrift_spec), None, ), # 1
    (2, TType.LIST, 'nimbusSlaves', (TType.STRUCT,(NimbusStat, NimbusStat.thrift_spec)), None, ), # 2
    (3, TType.I32, 'supervisorNum', None, None, ), # 3
    (4, TType.I32, 'totalPortNum', None, None, ), # 4
    (5, TType.I32, 'usedPortNum', None, None, ), # 5
    (6, TType.I32, 'freePortNum', None, None, ), # 6
    (7, TType.STRING, 'version', None, None, ), # 7
  )

  def __init__(self, nimbusMaster=None, nimbusSlaves=None, supervisorNum=None, totalPortNum=None, usedPortNum=None, freePortNum=None, version=None,):
    self.nimbusMaster = nimbusMaster
    self.nimbusSlaves = nimbusSlaves
    self.supervisorNum = supervisorNum
    self.totalPortNum = totalPortNum
    self.usedPortNum = usedPortNum
    self.freePortNum = freePortNum
    self.version = version

  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.nimbusMaster = NimbusStat()
          self.nimbusMaster.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.nimbusSlaves = []
          (_etype69, _size66) = iprot.readListBegin()
          for _i70 in xrange(_size66):
            _elem71 = NimbusStat()
            _elem71.read(iprot)
            self.nimbusSlaves.append(_elem71)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.supervisorNum = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I32:
          self.totalPortNum = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.usedPortNum = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.I32:
          self.freePortNum = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 7:
        if ftype == TType.STRING:
          self.version = iprot.readString().decode('utf-8')
        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('NimbusSummary')
    if self.nimbusMaster is not None:
      oprot.writeFieldBegin('nimbusMaster', TType.STRUCT, 1)
      self.nimbusMaster.write(oprot)
      oprot.writeFieldEnd()
    if self.nimbusSlaves is not None:
      oprot.writeFieldBegin('nimbusSlaves', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.nimbusSlaves))
      for iter72 in self.nimbusSlaves:
        iter72.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.supervisorNum is not None:
      oprot.writeFieldBegin('supervisorNum', TType.I32, 3)
      oprot.writeI32(self.supervisorNum)
      oprot.writeFieldEnd()
    if self.totalPortNum is not None:
      oprot.writeFieldBegin('totalPortNum', TType.I32, 4)
      oprot.writeI32(self.totalPortNum)
      oprot.writeFieldEnd()
    if self.usedPortNum is not None:
      oprot.writeFieldBegin('usedPortNum', TType.I32, 5)
      oprot.writeI32(self.usedPortNum)
      oprot.writeFieldEnd()
    if self.freePortNum is not None:
      oprot.writeFieldBegin('freePortNum', TType.I32, 6)
      oprot.writeI32(self.freePortNum)
      oprot.writeFieldEnd()
    if self.version is not None:
      oprot.writeFieldBegin('version', TType.STRING, 7)
      oprot.writeString(self.version.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.nimbusMaster is None:
      raise TProtocol.TProtocolException(message='Required field nimbusMaster is unset!')
    if self.nimbusSlaves is None:
      raise TProtocol.TProtocolException(message='Required field nimbusSlaves is unset!')
    if self.supervisorNum is None:
      raise TProtocol.TProtocolException(message='Required field supervisorNum is unset!')
    if self.totalPortNum is None:
      raise TProtocol.TProtocolException(message='Required field totalPortNum is unset!')
    if self.usedPortNum is None:
      raise TProtocol.TProtocolException(message='Required field usedPortNum is unset!')
    if self.freePortNum is None:
      raise TProtocol.TProtocolException(message='Required field freePortNum is unset!')
    if self.version is None:
      raise TProtocol.TProtocolException(message='Required field version is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.nimbusMaster)
    value = (value * 31) ^ hash(self.nimbusSlaves)
    value = (value * 31) ^ hash(self.supervisorNum)
    value = (value * 31) ^ hash(self.totalPortNum)
    value = (value * 31) ^ hash(self.usedPortNum)
    value = (value * 31) ^ hash(self.freePortNum)
    value = (value * 31) ^ hash(self.version)
    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 ClusterSummary:
  """
  Attributes:
   - nimbus
   - supervisors
   - topologies
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'nimbus', (NimbusSummary, NimbusSummary.thrift_spec), None, ), # 1
    (2, TType.LIST, 'supervisors', (TType.STRUCT,(SupervisorSummary, SupervisorSummary.thrift_spec)), None, ), # 2
    (3, TType.LIST, 'topologies', (TType.STRUCT,(TopologySummary, TopologySummary.thrift_spec)), None, ), # 3
  )

  def __init__(self, nimbus=None, supervisors=None, topologies=None,):
    self.nimbus = nimbus
    self.supervisors = supervisors
    self.topologies = topologies

  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.nimbus = NimbusSummary()
          self.nimbus.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.supervisors = []
          (_etype76, _size73) = iprot.readListBegin()
          for _i77 in xrange(_size73):
            _elem78 = SupervisorSummary()
            _elem78.read(iprot)
            self.supervisors.append(_elem78)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.topologies = []
          (_etype82, _size79) = iprot.readListBegin()
          for _i83 in xrange(_size79):
            _elem84 = TopologySummary()
            _elem84.read(iprot)
            self.topologies.append(_elem84)
          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('ClusterSummary')
    if self.nimbus is not None:
      oprot.writeFieldBegin('nimbus', TType.STRUCT, 1)
      self.nimbus.write(oprot)
      oprot.writeFieldEnd()
    if self.supervisors is not None:
      oprot.writeFieldBegin('supervisors', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.supervisors))
      for iter85 in self.supervisors:
        iter85.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.topologies is not None:
      oprot.writeFieldBegin('topologies', TType.LIST, 3)
      oprot.writeListBegin(TType.STRUCT, len(self.topologies))
      for iter86 in self.topologies:
        iter86.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.nimbus is None:
      raise TProtocol.TProtocolException(message='Required field nimbus is unset!')
    if self.supervisors is None:
      raise TProtocol.TProtocolException(message='Required field supervisors is unset!')
    if self.topologies is None:
      raise TProtocol.TProtocolException(message='Required field topologies is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.nimbus)
    value = (value * 31) ^ hash(self.supervisors)
    value = (value * 31) ^ hash(self.topologies)
    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 TaskComponent:
  """
  Attributes:
   - taskId
   - component
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'taskId', None, None, ), # 1
    (2, TType.STRING, 'component', None, None, ), # 2
  )

  def __init__(self, taskId=None, component=None,):
    self.taskId = taskId
    self.component = component

  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.I32:
          self.taskId = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.component = iprot.readString().decode('utf-8')
        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('TaskComponent')
    if self.taskId is not None:
      oprot.writeFieldBegin('taskId', TType.I32, 1)
      oprot.writeI32(self.taskId)
      oprot.writeFieldEnd()
    if self.component is not None:
      oprot.writeFieldBegin('component', TType.STRING, 2)
      oprot.writeString(self.component.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.taskId is None:
      raise TProtocol.TProtocolException(message='Required field taskId is unset!')
    if self.component is None:
      raise TProtocol.TProtocolException(message='Required field component is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.taskId)
    value = (value * 31) ^ hash(self.component)
    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 WorkerSummary:
  """
  Attributes:
   - port
   - uptime
   - topology
   - tasks
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'port', None, None, ), # 1
    (2, TType.I32, 'uptime', None, None, ), # 2
    (3, TType.STRING, 'topology', None, None, ), # 3
    (4, TType.LIST, 'tasks', (TType.STRUCT,(TaskComponent, TaskComponent.thrift_spec)), None, ), # 4
  )

  def __init__(self, port=None, uptime=None, topology=None, tasks=None,):
    self.port = port
    self.uptime = uptime
    self.topology = topology
    self.tasks = tasks

  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.I32:
          self.port = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.uptime = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.topology = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.LIST:
          self.tasks = []
          (_etype90, _size87) = iprot.readListBegin()
          for _i91 in xrange(_size87):
            _elem92 = TaskComponent()
            _elem92.read(iprot)
            self.tasks.append(_elem92)
          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('WorkerSummary')
    if self.port is not None:
      oprot.writeFieldBegin('port', TType.I32, 1)
      oprot.writeI32(self.port)
      oprot.writeFieldEnd()
    if self.uptime is not None:
      oprot.writeFieldBegin('uptime', TType.I32, 2)
      oprot.writeI32(self.uptime)
      oprot.writeFieldEnd()
    if self.topology is not None:
      oprot.writeFieldBegin('topology', TType.STRING, 3)
      oprot.writeString(self.topology.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.tasks is not None:
      oprot.writeFieldBegin('tasks', TType.LIST, 4)
      oprot.writeListBegin(TType.STRUCT, len(self.tasks))
      for iter93 in self.tasks:
        iter93.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.port is None:
      raise TProtocol.TProtocolException(message='Required field port is unset!')
    if self.uptime is None:
      raise TProtocol.TProtocolException(message='Required field uptime is unset!')
    if self.topology is None:
      raise TProtocol.TProtocolException(message='Required field topology is unset!')
    if self.tasks is None:
      raise TProtocol.TProtocolException(message='Required field tasks is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.port)
    value = (value * 31) ^ hash(self.uptime)
    value = (value * 31) ^ hash(self.topology)
    value = (value * 31) ^ hash(self.tasks)
    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 MetricWindow:
  """
  Attributes:
   - metricWindow
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'metricWindow', (TType.I32,None,TType.DOUBLE,None), None, ), # 1
  )

  def __init__(self, metricWindow=None,):
    self.metricWindow = metricWindow

  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.MAP:
          self.metricWindow = {}
          (_ktype95, _vtype96, _size94 ) = iprot.readMapBegin()
          for _i98 in xrange(_size94):
            _key99 = iprot.readI32();
            _val100 = iprot.readDouble();
            self.metricWindow[_key99] = _val100
          iprot.readMapEnd()
        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('MetricWindow')
    if self.metricWindow is not None:
      oprot.writeFieldBegin('metricWindow', TType.MAP, 1)
      oprot.writeMapBegin(TType.I32, TType.DOUBLE, len(self.metricWindow))
      for kiter101,viter102 in self.metricWindow.items():
        oprot.writeI32(kiter101)
        oprot.writeDouble(viter102)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.metricWindow is None:
      raise TProtocol.TProtocolException(message='Required field metricWindow is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.metricWindow)
    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 MetricSnapshot:
  """
  Attributes:
   - metricId
   - ts
   - metricType
   - longValue
   - doubleValue
   - m1
   - m5
   - m15
   - mean
   - min
   - max
   - p50
   - p75
   - p95
   - p98
   - p99
   - p999
   - stddev
   - points
  """

  thrift_spec = (
    None, # 0
    (1, TType.I64, 'metricId', None, None, ), # 1
    (2, TType.I64, 'ts', None, None, ), # 2
    (3, TType.I32, 'metricType', None, None, ), # 3
    (4, TType.I64, 'longValue', None, None, ), # 4
    (5, TType.DOUBLE, 'doubleValue', None, None, ), # 5
    (6, TType.DOUBLE, 'm1', None, None, ), # 6
    (7, TType.DOUBLE, 'm5', None, None, ), # 7
    (8, TType.DOUBLE, 'm15', None, None, ), # 8
    (9, TType.DOUBLE, 'mean', None, None, ), # 9
    (10, TType.I64, 'min', None, None, ), # 10
    (11, TType.I64, 'max', None, None, ), # 11
    (12, TType.DOUBLE, 'p50', None, None, ), # 12
    (13, TType.DOUBLE, 'p75', None, None, ), # 13
    (14, TType.DOUBLE, 'p95', None, None, ), # 14
    (15, TType.DOUBLE, 'p98', None, None, ), # 15
    (16, TType.DOUBLE, 'p99', None, None, ), # 16
    (17, TType.DOUBLE, 'p999', None, None, ), # 17
    (18, TType.DOUBLE, 'stddev', None, None, ), # 18
    (19, TType.LIST, 'points', (TType.I64,None), None, ), # 19
  )

  def __init__(self, metricId=None, ts=None, metricType=None, longValue=None, doubleValue=None, m1=None, m5=None, m15=None, mean=None, min=None, max=None, p50=None, p75=None, p95=None, p98=None, p99=None, p999=None, stddev=None, points=None,):
    self.metricId = metricId
    self.ts = ts
    self.metricType = metricType
    self.longValue = longValue
    self.doubleValue = doubleValue
    self.m1 = m1
    self.m5 = m5
    self.m15 = m15
    self.mean = mean
    self.min = min
    self.max = max
    self.p50 = p50
    self.p75 = p75
    self.p95 = p95
    self.p98 = p98
    self.p99 = p99
    self.p999 = p999
    self.stddev = stddev
    self.points = points

  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.I64:
          self.metricId = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I64:
          self.ts = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.metricType = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.I64:
          self.longValue = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.DOUBLE:
          self.doubleValue = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.DOUBLE:
          self.m1 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 7:
        if ftype == TType.DOUBLE:
          self.m5 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 8:
        if ftype == TType.DOUBLE:
          self.m15 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 9:
        if ftype == TType.DOUBLE:
          self.mean = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 10:
        if ftype == TType.I64:
          self.min = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 11:
        if ftype == TType.I64:
          self.max = iprot.readI64();
        else:
          iprot.skip(ftype)
      elif fid == 12:
        if ftype == TType.DOUBLE:
          self.p50 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 13:
        if ftype == TType.DOUBLE:
          self.p75 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 14:
        if ftype == TType.DOUBLE:
          self.p95 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 15:
        if ftype == TType.DOUBLE:
          self.p98 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 16:
        if ftype == TType.DOUBLE:
          self.p99 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 17:
        if ftype == TType.DOUBLE:
          self.p999 = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 18:
        if ftype == TType.DOUBLE:
          self.stddev = iprot.readDouble();
        else:
          iprot.skip(ftype)
      elif fid == 19:
        if ftype == TType.LIST:
          self.points = []
          (_etype106, _size103) = iprot.readListBegin()
          for _i107 in xrange(_size103):
            _elem108 = iprot.readI64();
            self.points.append(_elem108)
          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('MetricSnapshot')
    if self.metricId is not None:
      oprot.writeFieldBegin('metricId', TType.I64, 1)
      oprot.writeI64(self.metricId)
      oprot.writeFieldEnd()
    if self.ts is not None:
      oprot.writeFieldBegin('ts', TType.I64, 2)
      oprot.writeI64(self.ts)
      oprot.writeFieldEnd()
    if self.metricType is not None:
      oprot.writeFieldBegin('metricType', TType.I32, 3)
      oprot.writeI32(self.metricType)
      oprot.writeFieldEnd()
    if self.longValue is not None:
      oprot.writeFieldBegin('longValue', TType.I64, 4)
      oprot.writeI64(self.longValue)
      oprot.writeFieldEnd()
    if self.doubleValue is not None:
      oprot.writeFieldBegin('doubleValue', TType.DOUBLE, 5)
      oprot.writeDouble(self.doubleValue)
      oprot.writeFieldEnd()
    if self.m1 is not None:
      oprot.writeFieldBegin('m1', TType.DOUBLE, 6)
      oprot.writeDouble(self.m1)
      oprot.writeFieldEnd()
    if self.m5 is not None:
      oprot.writeFieldBegin('m5', TType.DOUBLE, 7)
      oprot.writeDouble(self.m5)
      oprot.writeFieldEnd()
    if self.m15 is not None:
      oprot.writeFieldBegin('m15', TType.DOUBLE, 8)
      oprot.writeDouble(self.m15)
      oprot.writeFieldEnd()
    if self.mean is not None:
      oprot.writeFieldBegin('mean', TType.DOUBLE, 9)
      oprot.writeDouble(self.mean)
      oprot.writeFieldEnd()
    if self.min is not None:
      oprot.writeFieldBegin('min', TType.I64, 10)
      oprot.writeI64(self.min)
      oprot.writeFieldEnd()
    if self.max is not None:
      oprot.writeFieldBegin('max', TType.I64, 11)
      oprot.writeI64(self.max)
      oprot.writeFieldEnd()
    if self.p50 is not None:
      oprot.writeFieldBegin('p50', TType.DOUBLE, 12)
      oprot.writeDouble(self.p50)
      oprot.writeFieldEnd()
    if self.p75 is not None:
      oprot.writeFieldBegin('p75', TType.DOUBLE, 13)
      oprot.writeDouble(self.p75)
      oprot.writeFieldEnd()
    if self.p95 is not None:
      oprot.writeFieldBegin('p95', TType.DOUBLE, 14)
      oprot.writeDouble(self.p95)
      oprot.writeFieldEnd()
    if self.p98 is not None:
      oprot.writeFieldBegin('p98', TType.DOUBLE, 15)
      oprot.writeDouble(self.p98)
      oprot.writeFieldEnd()
    if self.p99 is not None:
      oprot.writeFieldBegin('p99', TType.DOUBLE, 16)
      oprot.writeDouble(self.p99)
      oprot.writeFieldEnd()
    if self.p999 is not None:
      oprot.writeFieldBegin('p999', TType.DOUBLE, 17)
      oprot.writeDouble(self.p999)
      oprot.writeFieldEnd()
    if self.stddev is not None:
      oprot.writeFieldBegin('stddev', TType.DOUBLE, 18)
      oprot.writeDouble(self.stddev)
      oprot.writeFieldEnd()
    if self.points is not None:
      oprot.writeFieldBegin('points', TType.LIST, 19)
      oprot.writeListBegin(TType.I64, len(self.points))
      for iter109 in self.points:
        oprot.writeI64(iter109)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.metricId is None:
      raise TProtocol.TProtocolException(message='Required field metricId is unset!')
    if self.ts is None:
      raise TProtocol.TProtocolException(message='Required field ts is unset!')
    if self.metricType is None:
      raise TProtocol.TProtocolException(message='Required field metricType is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.metricId)
    value = (value * 31) ^ hash(self.ts)
    value = (value * 31) ^ hash(self.metricType)
    value = (value * 31) ^ hash(self.longValue)
    value = (value * 31) ^ hash(self.doubleValue)
    value = (value * 31) ^ hash(self.m1)
    value = (value * 31) ^ hash(self.m5)
    value = (value * 31) ^ hash(self.m15)
    value = (value * 31) ^ hash(self.mean)
    value = (value * 31) ^ hash(self.min)
    value = (value * 31) ^ hash(self.max)
    value = (value * 31) ^ hash(self.p50)
    value = (value * 31) ^ hash(self.p75)
    value = (value * 31) ^ hash(self.p95)
    value = (value * 31) ^ hash(self.p98)
    value = (value * 31) ^ hash(self.p99)
    value = (value * 31) ^ hash(self.p999)
    value = (value * 31) ^ hash(self.stddev)
    value = (value * 31) ^ hash(self.points)
    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 MetricInfo:
  """
  Attributes:
   - metrics
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'metrics', (TType.STRING,None,TType.MAP,(TType.I32,None,TType.STRUCT,(MetricSnapshot, MetricSnapshot.thrift_spec))), None, ), # 1
  )

  def __init__(self, metrics=None,):
    self.metrics = metrics

  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.MAP:
          self.metrics = {}
          (_ktype111, _vtype112, _size110 ) = iprot.readMapBegin()
          for _i114 in xrange(_size110):
            _key115 = iprot.readString().decode('utf-8')
            _val116 = {}
            (_ktype118, _vtype119, _size117 ) = iprot.readMapBegin()
            for _i121 in xrange(_size117):
              _key122 = iprot.readI32();
              _val123 = MetricSnapshot()
              _val123.read(iprot)
              _val116[_key122] = _val123
            iprot.readMapEnd()
            self.metrics[_key115] = _val116
          iprot.readMapEnd()
        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('MetricInfo')
    if self.metrics is not None:
      oprot.writeFieldBegin('metrics', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.MAP, len(self.metrics))
      for kiter124,viter125 in self.metrics.items():
        oprot.writeString(kiter124.encode('utf-8'))
        oprot.writeMapBegin(TType.I32, TType.STRUCT, len(viter125))
        for kiter126,viter127 in viter125.items():
          oprot.writeI32(kiter126)
          viter127.write(oprot)
        oprot.writeMapEnd()
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.metrics)
    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 SupervisorWorkers:
  """
  Attributes:
   - supervisor
   - workers
   - workerMetric
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'supervisor', (SupervisorSummary, SupervisorSummary.thrift_spec), None, ), # 1
    (2, TType.LIST, 'workers', (TType.STRUCT,(WorkerSummary, WorkerSummary.thrift_spec)), None, ), # 2
    (3, TType.MAP, 'workerMetric', (TType.STRING,None,TType.STRUCT,(MetricInfo, MetricInfo.thrift_spec)), None, ), # 3
  )

  def __init__(self, supervisor=None, workers=None, workerMetric=None,):
    self.supervisor = supervisor
    self.workers = workers
    self.workerMetric = workerMetric

  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.supervisor = SupervisorSummary()
          self.supervisor.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.workers = []
          (_etype131, _size128) = iprot.readListBegin()
          for _i132 in xrange(_size128):
            _elem133 = WorkerSummary()
            _elem133.read(iprot)
            self.workers.append(_elem133)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.MAP:
          self.workerMetric = {}
          (_ktype135, _vtype136, _size134 ) = iprot.readMapBegin()
          for _i138 in xrange(_size134):
            _key139 = iprot.readString().decode('utf-8')
            _val140 = MetricInfo()
            _val140.read(iprot)
            self.workerMetric[_key139] = _val140
          iprot.readMapEnd()
        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('SupervisorWorkers')
    if self.supervisor is not None:
      oprot.writeFieldBegin('supervisor', TType.STRUCT, 1)
      self.supervisor.write(oprot)
      oprot.writeFieldEnd()
    if self.workers is not None:
      oprot.writeFieldBegin('workers', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.workers))
      for iter141 in self.workers:
        iter141.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.workerMetric is not None:
      oprot.writeFieldBegin('workerMetric', TType.MAP, 3)
      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.workerMetric))
      for kiter142,viter143 in self.workerMetric.items():
        oprot.writeString(kiter142.encode('utf-8'))
        viter143.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.supervisor is None:
      raise TProtocol.TProtocolException(message='Required field supervisor is unset!')
    if self.workers is None:
      raise TProtocol.TProtocolException(message='Required field workers is unset!')
    if self.workerMetric is None:
      raise TProtocol.TProtocolException(message='Required field workerMetric is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.supervisor)
    value = (value * 31) ^ hash(self.workers)
    value = (value * 31) ^ hash(self.workerMetric)
    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 ErrorInfo:
  """
  Attributes:
   - error
   - errorTimeSecs
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'error', None, None, ), # 1
    (2, TType.I32, 'errorTimeSecs', None, None, ), # 2
  )

  def __init__(self, error=None, errorTimeSecs=None,):
    self.error = error
    self.errorTimeSecs = errorTimeSecs

  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.STRING:
          self.error = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.errorTimeSecs = iprot.readI32();
        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('ErrorInfo')
    if self.error is not None:
      oprot.writeFieldBegin('error', TType.STRING, 1)
      oprot.writeString(self.error.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.errorTimeSecs is not None:
      oprot.writeFieldBegin('errorTimeSecs', TType.I32, 2)
      oprot.writeI32(self.errorTimeSecs)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.error is None:
      raise TProtocol.TProtocolException(message='Required field error is unset!')
    if self.errorTimeSecs is None:
      raise TProtocol.TProtocolException(message='Required field errorTimeSecs is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.error)
    value = (value * 31) ^ hash(self.errorTimeSecs)
    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 ComponentSummary:
  """
  Attributes:
   - name
   - parallel
   - type
   - taskIds
   - errors
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.I32, 'parallel', None, None, ), # 2
    (3, TType.STRING, 'type', None, None, ), # 3
    (4, TType.LIST, 'taskIds', (TType.I32,None), None, ), # 4
    (5, TType.LIST, 'errors', (TType.STRUCT,(ErrorInfo, ErrorInfo.thrift_spec)), None, ), # 5
  )

  def __init__(self, name=None, parallel=None, type=None, taskIds=None, errors=None,):
    self.name = name
    self.parallel = parallel
    self.type = type
    self.taskIds = taskIds
    self.errors = errors

  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.STRING:
          self.name = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.parallel = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.type = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.LIST:
          self.taskIds = []
          (_etype147, _size144) = iprot.readListBegin()
          for _i148 in xrange(_size144):
            _elem149 = iprot.readI32();
            self.taskIds.append(_elem149)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.LIST:
          self.errors = []
          (_etype153, _size150) = iprot.readListBegin()
          for _i154 in xrange(_size150):
            _elem155 = ErrorInfo()
            _elem155.read(iprot)
            self.errors.append(_elem155)
          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('ComponentSummary')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.parallel is not None:
      oprot.writeFieldBegin('parallel', TType.I32, 2)
      oprot.writeI32(self.parallel)
      oprot.writeFieldEnd()
    if self.type is not None:
      oprot.writeFieldBegin('type', TType.STRING, 3)
      oprot.writeString(self.type.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.taskIds is not None:
      oprot.writeFieldBegin('taskIds', TType.LIST, 4)
      oprot.writeListBegin(TType.I32, len(self.taskIds))
      for iter156 in self.taskIds:
        oprot.writeI32(iter156)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.errors is not None:
      oprot.writeFieldBegin('errors', TType.LIST, 5)
      oprot.writeListBegin(TType.STRUCT, len(self.errors))
      for iter157 in self.errors:
        iter157.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.parallel is None:
      raise TProtocol.TProtocolException(message='Required field parallel is unset!')
    if self.type is None:
      raise TProtocol.TProtocolException(message='Required field type is unset!')
    if self.taskIds is None:
      raise TProtocol.TProtocolException(message='Required field taskIds is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.name)
    value = (value * 31) ^ hash(self.parallel)
    value = (value * 31) ^ hash(self.type)
    value = (value * 31) ^ hash(self.taskIds)
    value = (value * 31) ^ hash(self.errors)
    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 TaskSummary:
  """
  Attributes:
   - taskId
   - uptime
   - status
   - host
   - port
   - errors
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'taskId', None, None, ), # 1
    (2, TType.I32, 'uptime', None, None, ), # 2
    (3, TType.STRING, 'status', None, None, ), # 3
    (4, TType.STRING, 'host', None, None, ), # 4
    (5, TType.I32, 'port', None, None, ), # 5
    (6, TType.LIST, 'errors', (TType.STRUCT,(ErrorInfo, ErrorInfo.thrift_spec)), None, ), # 6
  )

  def __init__(self, taskId=None, uptime=None, status=None, host=None, port=None, errors=None,):
    self.taskId = taskId
    self.uptime = uptime
    self.status = status
    self.host = host
    self.port = port
    self.errors = errors

  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.I32:
          self.taskId = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.uptime = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.status = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRING:
          self.host = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.I32:
          self.port = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.LIST:
          self.errors = []
          (_etype161, _size158) = iprot.readListBegin()
          for _i162 in xrange(_size158):
            _elem163 = ErrorInfo()
            _elem163.read(iprot)
            self.errors.append(_elem163)
          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('TaskSummary')
    if self.taskId is not None:
      oprot.writeFieldBegin('taskId', TType.I32, 1)
      oprot.writeI32(self.taskId)
      oprot.writeFieldEnd()
    if self.uptime is not None:
      oprot.writeFieldBegin('uptime', TType.I32, 2)
      oprot.writeI32(self.uptime)
      oprot.writeFieldEnd()
    if self.status is not None:
      oprot.writeFieldBegin('status', TType.STRING, 3)
      oprot.writeString(self.status.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.host is not None:
      oprot.writeFieldBegin('host', TType.STRING, 4)
      oprot.writeString(self.host.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.port is not None:
      oprot.writeFieldBegin('port', TType.I32, 5)
      oprot.writeI32(self.port)
      oprot.writeFieldEnd()
    if self.errors is not None:
      oprot.writeFieldBegin('errors', TType.LIST, 6)
      oprot.writeListBegin(TType.STRUCT, len(self.errors))
      for iter164 in self.errors:
        iter164.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.taskId is None:
      raise TProtocol.TProtocolException(message='Required field taskId is unset!')
    if self.uptime is None:
      raise TProtocol.TProtocolException(message='Required field uptime is unset!')
    if self.status is None:
      raise TProtocol.TProtocolException(message='Required field status is unset!')
    if self.host is None:
      raise TProtocol.TProtocolException(message='Required field host is unset!')
    if self.port is None:
      raise TProtocol.TProtocolException(message='Required field port is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.taskId)
    value = (value * 31) ^ hash(self.uptime)
    value = (value * 31) ^ hash(self.status)
    value = (value * 31) ^ hash(self.host)
    value = (value * 31) ^ hash(self.port)
    value = (value * 31) ^ hash(self.errors)
    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 TopologyMetric:
  """
  Attributes:
   - topologyMetric
   - componentMetric
   - workerMetric
   - taskMetric
   - streamMetric
   - nettyMetric
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'topologyMetric', (MetricInfo, MetricInfo.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'componentMetric', (MetricInfo, MetricInfo.thrift_spec), None, ), # 2
    (3, TType.STRUCT, 'workerMetric', (MetricInfo, MetricInfo.thrift_spec), None, ), # 3
    (4, TType.STRUCT, 'taskMetric', (MetricInfo, MetricInfo.thrift_spec), None, ), # 4
    (5, TType.STRUCT, 'streamMetric', (MetricInfo, MetricInfo.thrift_spec), None, ), # 5
    (6, TType.STRUCT, 'nettyMetric', (MetricInfo, MetricInfo.thrift_spec), None, ), # 6
  )

  def __init__(self, topologyMetric=None, componentMetric=None, workerMetric=None, taskMetric=None, streamMetric=None, nettyMetric=None,):
    self.topologyMetric = topologyMetric
    self.componentMetric = componentMetric
    self.workerMetric = workerMetric
    self.taskMetric = taskMetric
    self.streamMetric = streamMetric
    self.nettyMetric = nettyMetric

  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.topologyMetric = MetricInfo()
          self.topologyMetric.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.componentMetric = MetricInfo()
          self.componentMetric.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRUCT:
          self.workerMetric = MetricInfo()
          self.workerMetric.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.taskMetric = MetricInfo()
          self.taskMetric.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 5:
        if ftype == TType.STRUCT:
          self.streamMetric = MetricInfo()
          self.streamMetric.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 6:
        if ftype == TType.STRUCT:
          self.nettyMetric = MetricInfo()
          self.nettyMetric.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('TopologyMetric')
    if self.topologyMetric is not None:
      oprot.writeFieldBegin('topologyMetric', TType.STRUCT, 1)
      self.topologyMetric.write(oprot)
      oprot.writeFieldEnd()
    if self.componentMetric is not None:
      oprot.writeFieldBegin('componentMetric', TType.STRUCT, 2)
      self.componentMetric.write(oprot)
      oprot.writeFieldEnd()
    if self.workerMetric is not None:
      oprot.writeFieldBegin('workerMetric', TType.STRUCT, 3)
      self.workerMetric.write(oprot)
      oprot.writeFieldEnd()
    if self.taskMetric is not None:
      oprot.writeFieldBegin('taskMetric', TType.STRUCT, 4)
      self.taskMetric.write(oprot)
      oprot.writeFieldEnd()
    if self.streamMetric is not None:
      oprot.writeFieldBegin('streamMetric', TType.STRUCT, 5)
      self.streamMetric.write(oprot)
      oprot.writeFieldEnd()
    if self.nettyMetric is not None:
      oprot.writeFieldBegin('nettyMetric', TType.STRUCT, 6)
      self.nettyMetric.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.topologyMetric is None:
      raise TProtocol.TProtocolException(message='Required field topologyMetric is unset!')
    if self.componentMetric is None:
      raise TProtocol.TProtocolException(message='Required field componentMetric is unset!')
    if self.workerMetric is None:
      raise TProtocol.TProtocolException(message='Required field workerMetric is unset!')
    if self.taskMetric is None:
      raise TProtocol.TProtocolException(message='Required field taskMetric is unset!')
    if self.streamMetric is None:
      raise TProtocol.TProtocolException(message='Required field streamMetric is unset!')
    if self.nettyMetric is None:
      raise TProtocol.TProtocolException(message='Required field nettyMetric is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.topologyMetric)
    value = (value * 31) ^ hash(self.componentMetric)
    value = (value * 31) ^ hash(self.workerMetric)
    value = (value * 31) ^ hash(self.taskMetric)
    value = (value * 31) ^ hash(self.streamMetric)
    value = (value * 31) ^ hash(self.nettyMetric)
    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 TopologyInfo:
  """
  Attributes:
   - topology
   - components
   - tasks
   - metrics
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'topology', (TopologySummary, TopologySummary.thrift_spec), None, ), # 1
    (2, TType.LIST, 'components', (TType.STRUCT,(ComponentSummary, ComponentSummary.thrift_spec)), None, ), # 2
    (3, TType.LIST, 'tasks', (TType.STRUCT,(TaskSummary, TaskSummary.thrift_spec)), None, ), # 3
    (4, TType.STRUCT, 'metrics', (TopologyMetric, TopologyMetric.thrift_spec), None, ), # 4
  )

  def __init__(self, topology=None, components=None, tasks=None, metrics=None,):
    self.topology = topology
    self.components = components
    self.tasks = tasks
    self.metrics = metrics

  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.topology = TopologySummary()
          self.topology.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.LIST:
          self.components = []
          (_etype168, _size165) = iprot.readListBegin()
          for _i169 in xrange(_size165):
            _elem170 = ComponentSummary()
            _elem170.read(iprot)
            self.components.append(_elem170)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.LIST:
          self.tasks = []
          (_etype174, _size171) = iprot.readListBegin()
          for _i175 in xrange(_size171):
            _elem176 = TaskSummary()
            _elem176.read(iprot)
            self.tasks.append(_elem176)
          iprot.readListEnd()
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.metrics = TopologyMetric()
          self.metrics.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('TopologyInfo')
    if self.topology is not None:
      oprot.writeFieldBegin('topology', TType.STRUCT, 1)
      self.topology.write(oprot)
      oprot.writeFieldEnd()
    if self.components is not None:
      oprot.writeFieldBegin('components', TType.LIST, 2)
      oprot.writeListBegin(TType.STRUCT, len(self.components))
      for iter177 in self.components:
        iter177.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.tasks is not None:
      oprot.writeFieldBegin('tasks', TType.LIST, 3)
      oprot.writeListBegin(TType.STRUCT, len(self.tasks))
      for iter178 in self.tasks:
        iter178.write(oprot)
      oprot.writeListEnd()
      oprot.writeFieldEnd()
    if self.metrics is not None:
      oprot.writeFieldBegin('metrics', TType.STRUCT, 4)
      self.metrics.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.topology is None:
      raise TProtocol.TProtocolException(message='Required field topology is unset!')
    if self.components is None:
      raise TProtocol.TProtocolException(message='Required field components is unset!')
    if self.tasks is None:
      raise TProtocol.TProtocolException(message='Required field tasks is unset!')
    if self.metrics is None:
      raise TProtocol.TProtocolException(message='Required field metrics is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.topology)
    value = (value * 31) ^ hash(self.components)
    value = (value * 31) ^ hash(self.tasks)
    value = (value * 31) ^ hash(self.metrics)
    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 WorkerUploadMetrics:
  """
  Attributes:
   - topologyId
   - supervisorId
   - port
   - allMetrics
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'topologyId', None, None, ), # 1
    (2, TType.STRING, 'supervisorId', None, None, ), # 2
    (3, TType.I32, 'port', None, None, ), # 3
    (4, TType.STRUCT, 'allMetrics', (MetricInfo, MetricInfo.thrift_spec), None, ), # 4
  )

  def __init__(self, topologyId=None, supervisorId=None, port=None, allMetrics=None,):
    self.topologyId = topologyId
    self.supervisorId = supervisorId
    self.port = port
    self.allMetrics = allMetrics

  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.STRING:
          self.topologyId = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.supervisorId = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.I32:
          self.port = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.allMetrics = MetricInfo()
          self.allMetrics.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('WorkerUploadMetrics')
    if self.topologyId is not None:
      oprot.writeFieldBegin('topologyId', TType.STRING, 1)
      oprot.writeString(self.topologyId.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.supervisorId is not None:
      oprot.writeFieldBegin('supervisorId', TType.STRING, 2)
      oprot.writeString(self.supervisorId.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.port is not None:
      oprot.writeFieldBegin('port', TType.I32, 3)
      oprot.writeI32(self.port)
      oprot.writeFieldEnd()
    if self.allMetrics is not None:
      oprot.writeFieldBegin('allMetrics', TType.STRUCT, 4)
      self.allMetrics.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.topologyId is None:
      raise TProtocol.TProtocolException(message='Required field topologyId is unset!')
    if self.supervisorId is None:
      raise TProtocol.TProtocolException(message='Required field supervisorId is unset!')
    if self.port is None:
      raise TProtocol.TProtocolException(message='Required field port is unset!')
    if self.allMetrics is None:
      raise TProtocol.TProtocolException(message='Required field allMetrics is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.topologyId)
    value = (value * 31) ^ hash(self.supervisorId)
    value = (value * 31) ^ hash(self.port)
    value = (value * 31) ^ hash(self.allMetrics)
    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 KillOptions:
  """
  Attributes:
   - wait_secs
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'wait_secs', None, None, ), # 1
  )

  def __init__(self, wait_secs=None,):
    self.wait_secs = wait_secs

  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.I32:
          self.wait_secs = iprot.readI32();
        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('KillOptions')
    if self.wait_secs is not None:
      oprot.writeFieldBegin('wait_secs', TType.I32, 1)
      oprot.writeI32(self.wait_secs)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.wait_secs)
    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 RebalanceOptions:
  """
  Attributes:
   - wait_secs
   - reassign
   - conf
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'wait_secs', None, None, ), # 1
    (2, TType.BOOL, 'reassign', None, None, ), # 2
    (3, TType.STRING, 'conf', None, None, ), # 3
  )

  def __init__(self, wait_secs=None, reassign=None, conf=None,):
    self.wait_secs = wait_secs
    self.reassign = reassign
    self.conf = conf

  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.I32:
          self.wait_secs = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.BOOL:
          self.reassign = iprot.readBool();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.conf = iprot.readString().decode('utf-8')
        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('RebalanceOptions')
    if self.wait_secs is not None:
      oprot.writeFieldBegin('wait_secs', TType.I32, 1)
      oprot.writeI32(self.wait_secs)
      oprot.writeFieldEnd()
    if self.reassign is not None:
      oprot.writeFieldBegin('reassign', TType.BOOL, 2)
      oprot.writeBool(self.reassign)
      oprot.writeFieldEnd()
    if self.conf is not None:
      oprot.writeFieldBegin('conf', TType.STRING, 3)
      oprot.writeString(self.conf.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.wait_secs)
    value = (value * 31) ^ hash(self.reassign)
    value = (value * 31) ^ hash(self.conf)
    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 Credentials:
  """
  Attributes:
   - creds
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'creds', (TType.STRING,None,TType.STRING,None), None, ), # 1
  )

  def __init__(self, creds=None,):
    self.creds = creds

  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.MAP:
          self.creds = {}
          (_ktype180, _vtype181, _size179 ) = iprot.readMapBegin()
          for _i183 in xrange(_size179):
            _key184 = iprot.readString().decode('utf-8')
            _val185 = iprot.readString().decode('utf-8')
            self.creds[_key184] = _val185
          iprot.readMapEnd()
        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('Credentials')
    if self.creds is not None:
      oprot.writeFieldBegin('creds', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.STRING, len(self.creds))
      for kiter186,viter187 in self.creds.items():
        oprot.writeString(kiter186.encode('utf-8'))
        oprot.writeString(viter187.encode('utf-8'))
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.creds is None:
      raise TProtocol.TProtocolException(message='Required field creds is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.creds)
    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 SubmitOptions:
  """
  Attributes:
   - initial_status
   - creds
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'initial_status', None, None, ), # 1
    (2, TType.STRUCT, 'creds', (Credentials, Credentials.thrift_spec), None, ), # 2
  )

  def __init__(self, initial_status=None, creds=None,):
    self.initial_status = initial_status
    self.creds = creds

  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.I32:
          self.initial_status = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.creds = Credentials()
          self.creds.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('SubmitOptions')
    if self.initial_status is not None:
      oprot.writeFieldBegin('initial_status', TType.I32, 1)
      oprot.writeI32(self.initial_status)
      oprot.writeFieldEnd()
    if self.creds is not None:
      oprot.writeFieldBegin('creds', TType.STRUCT, 2)
      self.creds.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.initial_status is None:
      raise TProtocol.TProtocolException(message='Required field initial_status is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.initial_status)
    value = (value * 31) ^ hash(self.creds)
    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 MonitorOptions:
  """
  Attributes:
   - isEnable
  """

  thrift_spec = (
    None, # 0
    (1, TType.BOOL, 'isEnable', None, None, ), # 1
  )

  def __init__(self, isEnable=None,):
    self.isEnable = isEnable

  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.BOOL:
          self.isEnable = iprot.readBool();
        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('MonitorOptions')
    if self.isEnable is not None:
      oprot.writeFieldBegin('isEnable', TType.BOOL, 1)
      oprot.writeBool(self.isEnable)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.isEnable)
    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 ThriftSerializedObject:
  """
  Attributes:
   - name
   - bits
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.STRING, 'bits', None, None, ), # 2
  )

  def __init__(self, name=None, bits=None,):
    self.name = name
    self.bits = bits

  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.STRING:
          self.name = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.bits = iprot.readString();
        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('ThriftSerializedObject')
    if self.name is not None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.bits is not None:
      oprot.writeFieldBegin('bits', TType.STRING, 2)
      oprot.writeString(self.bits)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.name is None:
      raise TProtocol.TProtocolException(message='Required field name is unset!')
    if self.bits is None:
      raise TProtocol.TProtocolException(message='Required field bits is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.name)
    value = (value * 31) ^ hash(self.bits)
    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 LocalStateData:
  """
  Attributes:
   - serialized_parts
  """

  thrift_spec = (
    None, # 0
    (1, TType.MAP, 'serialized_parts', (TType.STRING,None,TType.STRUCT,(ThriftSerializedObject, ThriftSerializedObject.thrift_spec)), None, ), # 1
  )

  def __init__(self, serialized_parts=None,):
    self.serialized_parts = serialized_parts

  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.MAP:
          self.serialized_parts = {}
          (_ktype189, _vtype190, _size188 ) = iprot.readMapBegin()
          for _i192 in xrange(_size188):
            _key193 = iprot.readString().decode('utf-8')
            _val194 = ThriftSerializedObject()
            _val194.read(iprot)
            self.serialized_parts[_key193] = _val194
          iprot.readMapEnd()
        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('LocalStateData')
    if self.serialized_parts is not None:
      oprot.writeFieldBegin('serialized_parts', TType.MAP, 1)
      oprot.writeMapBegin(TType.STRING, TType.STRUCT, len(self.serialized_parts))
      for kiter195,viter196 in self.serialized_parts.items():
        oprot.writeString(kiter195.encode('utf-8'))
        viter196.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.serialized_parts is None:
      raise TProtocol.TProtocolException(message='Required field serialized_parts is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.serialized_parts)
    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 TaskHeartbeat:
  """
  Attributes:
   - time
   - uptime
  """

  thrift_spec = (
    None, # 0
    (1, TType.I32, 'time', None, None, ), # 1
    (2, TType.I32, 'uptime', None, None, ), # 2
  )

  def __init__(self, time=None, uptime=None,):
    self.time = time
    self.uptime = uptime

  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.I32:
          self.time = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.uptime = iprot.readI32();
        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('TaskHeartbeat')
    if self.time is not None:
      oprot.writeFieldBegin('time', TType.I32, 1)
      oprot.writeI32(self.time)
      oprot.writeFieldEnd()
    if self.uptime is not None:
      oprot.writeFieldBegin('uptime', TType.I32, 2)
      oprot.writeI32(self.uptime)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.time is None:
      raise TProtocol.TProtocolException(message='Required field time is unset!')
    if self.uptime is None:
      raise TProtocol.TProtocolException(message='Required field uptime is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.time)
    value = (value * 31) ^ hash(self.uptime)
    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 TopologyTaskHbInfo:
  """
  Attributes:
   - topologyId
   - topologyMasterId
   - taskHbs
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'topologyId', None, None, ), # 1
    (2, TType.I32, 'topologyMasterId', None, None, ), # 2
    (3, TType.MAP, 'taskHbs', (TType.I32,None,TType.STRUCT,(TaskHeartbeat, TaskHeartbeat.thrift_spec)), None, ), # 3
  )

  def __init__(self, topologyId=None, topologyMasterId=None, taskHbs=None,):
    self.topologyId = topologyId
    self.topologyMasterId = topologyMasterId
    self.taskHbs = taskHbs

  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.STRING:
          self.topologyId = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.I32:
          self.topologyMasterId = iprot.readI32();
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.MAP:
          self.taskHbs = {}
          (_ktype198, _vtype199, _size197 ) = iprot.readMapBegin()
          for _i201 in xrange(_size197):
            _key202 = iprot.readI32();
            _val203 = TaskHeartbeat()
            _val203.read(iprot)
            self.taskHbs[_key202] = _val203
          iprot.readMapEnd()
        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('TopologyTaskHbInfo')
    if self.topologyId is not None:
      oprot.writeFieldBegin('topologyId', TType.STRING, 1)
      oprot.writeString(self.topologyId.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.topologyMasterId is not None:
      oprot.writeFieldBegin('topologyMasterId', TType.I32, 2)
      oprot.writeI32(self.topologyMasterId)
      oprot.writeFieldEnd()
    if self.taskHbs is not None:
      oprot.writeFieldBegin('taskHbs', TType.MAP, 3)
      oprot.writeMapBegin(TType.I32, TType.STRUCT, len(self.taskHbs))
      for kiter204,viter205 in self.taskHbs.items():
        oprot.writeI32(kiter204)
        viter205.write(oprot)
      oprot.writeMapEnd()
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.topologyId is None:
      raise TProtocol.TProtocolException(message='Required field topologyId is unset!')
    if self.topologyMasterId is None:
      raise TProtocol.TProtocolException(message='Required field topologyMasterId is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.topologyId)
    value = (value * 31) ^ hash(self.topologyMasterId)
    value = (value * 31) ^ hash(self.taskHbs)
    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 DRPCRequest:
  """
  Attributes:
   - func_args
   - request_id
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'func_args', None, None, ), # 1
    (2, TType.STRING, 'request_id', None, None, ), # 2
  )

  def __init__(self, func_args=None, request_id=None,):
    self.func_args = func_args
    self.request_id = request_id

  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.STRING:
          self.func_args = iprot.readString().decode('utf-8')
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRING:
          self.request_id = iprot.readString().decode('utf-8')
        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('DRPCRequest')
    if self.func_args is not None:
      oprot.writeFieldBegin('func_args', TType.STRING, 1)
      oprot.writeString(self.func_args.encode('utf-8'))
      oprot.writeFieldEnd()
    if self.request_id is not None:
      oprot.writeFieldBegin('request_id', TType.STRING, 2)
      oprot.writeString(self.request_id.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.func_args is None:
      raise TProtocol.TProtocolException(message='Required field func_args is unset!')
    if self.request_id is None:
      raise TProtocol.TProtocolException(message='Required field request_id is unset!')
    return


  def __hash__(self):
    value = 17
    value = (value * 31) ^ hash(self.func_args)
    value = (value * 31) ^ hash(self.request_id)
    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 DRPCExecutionException(TException):
  """
  Attributes:
   - msg
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'msg', None, 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.STRING:
          self.msg = iprot.readString().decode('utf-8')
        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('DRPCExecutionException')
    if self.msg is not None:
      oprot.writeFieldBegin('msg', TType.STRING, 1)
      oprot.writeString(self.msg.encode('utf-8'))
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  def validate(self):
    if self.msg is None:
      raise TProtocol.TProtocolException(message='Required field msg is unset!')
    return


  def __str__(self):
    return repr(self)

  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)
