#
# Autogenerated by Thrift
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#

from thrift.Thrift import *
import sys
from ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
try:
  from thrift.protocol import fastbinary
except:
  fastbinary = None


class Iface:
  def submitTopology(self, name, uploadedJarLocation, jsonConf, topology):
    """
    Parameters:
     - name
     - uploadedJarLocation
     - jsonConf
     - topology
    """
    pass

  def killTopology(self, name):
    """
    Parameters:
     - name
    """
    pass

  def beginFileUpload(self, ):
    pass

  def uploadChunk(self, location, chunk):
    """
    Parameters:
     - location
     - chunk
    """
    pass

  def finishFileUpload(self, location):
    """
    Parameters:
     - location
    """
    pass

  def beginFileDownload(self, file):
    """
    Parameters:
     - file
    """
    pass

  def downloadChunk(self, id):
    """
    Parameters:
     - id
    """
    pass

  def getClusterInfo(self, ):
    pass

  def getTopologyInfo(self, id):
    """
    Parameters:
     - id
    """
    pass

  def getTopologyConf(self, id):
    """
    Parameters:
     - id
    """
    pass

  def getTopology(self, id):
    """
    Parameters:
     - id
    """
    pass


class Client(Iface):
  def __init__(self, iprot, oprot=None):
    self._iprot = self._oprot = iprot
    if oprot != None:
      self._oprot = oprot
    self._seqid = 0

  def submitTopology(self, name, uploadedJarLocation, jsonConf, topology):
    """
    Parameters:
     - name
     - uploadedJarLocation
     - jsonConf
     - topology
    """
    self.send_submitTopology(name, uploadedJarLocation, jsonConf, topology)
    self.recv_submitTopology()

  def send_submitTopology(self, name, uploadedJarLocation, jsonConf, topology):
    self._oprot.writeMessageBegin('submitTopology', TMessageType.CALL, self._seqid)
    args = submitTopology_args()
    args.name = name
    args.uploadedJarLocation = uploadedJarLocation
    args.jsonConf = jsonConf
    args.topology = topology
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_submitTopology(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = submitTopology_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.e != None:
      raise result.e
    if result.ite != None:
      raise result.ite
    return

  def killTopology(self, name):
    """
    Parameters:
     - name
    """
    self.send_killTopology(name)
    self.recv_killTopology()

  def send_killTopology(self, name):
    self._oprot.writeMessageBegin('killTopology', TMessageType.CALL, self._seqid)
    args = killTopology_args()
    args.name = name
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_killTopology(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = killTopology_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.e != None:
      raise result.e
    return

  def beginFileUpload(self, ):
    self.send_beginFileUpload()
    return self.recv_beginFileUpload()

  def send_beginFileUpload(self, ):
    self._oprot.writeMessageBegin('beginFileUpload', TMessageType.CALL, self._seqid)
    args = beginFileUpload_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_beginFileUpload(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = beginFileUpload_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "beginFileUpload failed: unknown result");

  def uploadChunk(self, location, chunk):
    """
    Parameters:
     - location
     - chunk
    """
    self.send_uploadChunk(location, chunk)
    self.recv_uploadChunk()

  def send_uploadChunk(self, location, chunk):
    self._oprot.writeMessageBegin('uploadChunk', TMessageType.CALL, self._seqid)
    args = uploadChunk_args()
    args.location = location
    args.chunk = chunk
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_uploadChunk(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = uploadChunk_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    return

  def finishFileUpload(self, location):
    """
    Parameters:
     - location
    """
    self.send_finishFileUpload(location)
    self.recv_finishFileUpload()

  def send_finishFileUpload(self, location):
    self._oprot.writeMessageBegin('finishFileUpload', TMessageType.CALL, self._seqid)
    args = finishFileUpload_args()
    args.location = location
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_finishFileUpload(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = finishFileUpload_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    return

  def beginFileDownload(self, file):
    """
    Parameters:
     - file
    """
    self.send_beginFileDownload(file)
    return self.recv_beginFileDownload()

  def send_beginFileDownload(self, file):
    self._oprot.writeMessageBegin('beginFileDownload', TMessageType.CALL, self._seqid)
    args = beginFileDownload_args()
    args.file = file
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_beginFileDownload(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = beginFileDownload_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "beginFileDownload failed: unknown result");

  def downloadChunk(self, id):
    """
    Parameters:
     - id
    """
    self.send_downloadChunk(id)
    return self.recv_downloadChunk()

  def send_downloadChunk(self, id):
    self._oprot.writeMessageBegin('downloadChunk', TMessageType.CALL, self._seqid)
    args = downloadChunk_args()
    args.id = id
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_downloadChunk(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = downloadChunk_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "downloadChunk failed: unknown result");

  def getClusterInfo(self, ):
    self.send_getClusterInfo()
    return self.recv_getClusterInfo()

  def send_getClusterInfo(self, ):
    self._oprot.writeMessageBegin('getClusterInfo', TMessageType.CALL, self._seqid)
    args = getClusterInfo_args()
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_getClusterInfo(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = getClusterInfo_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    raise TApplicationException(TApplicationException.MISSING_RESULT, "getClusterInfo failed: unknown result");

  def getTopologyInfo(self, id):
    """
    Parameters:
     - id
    """
    self.send_getTopologyInfo(id)
    return self.recv_getTopologyInfo()

  def send_getTopologyInfo(self, id):
    self._oprot.writeMessageBegin('getTopologyInfo', TMessageType.CALL, self._seqid)
    args = getTopologyInfo_args()
    args.id = id
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_getTopologyInfo(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = getTopologyInfo_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.e != None:
      raise result.e
    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyInfo failed: unknown result");

  def getTopologyConf(self, id):
    """
    Parameters:
     - id
    """
    self.send_getTopologyConf(id)
    return self.recv_getTopologyConf()

  def send_getTopologyConf(self, id):
    self._oprot.writeMessageBegin('getTopologyConf', TMessageType.CALL, self._seqid)
    args = getTopologyConf_args()
    args.id = id
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_getTopologyConf(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = getTopologyConf_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.e != None:
      raise result.e
    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyConf failed: unknown result");

  def getTopology(self, id):
    """
    Parameters:
     - id
    """
    self.send_getTopology(id)
    return self.recv_getTopology()

  def send_getTopology(self, id):
    self._oprot.writeMessageBegin('getTopology', TMessageType.CALL, self._seqid)
    args = getTopology_args()
    args.id = id
    args.write(self._oprot)
    self._oprot.writeMessageEnd()
    self._oprot.trans.flush()

  def recv_getTopology(self, ):
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
    if mtype == TMessageType.EXCEPTION:
      x = TApplicationException()
      x.read(self._iprot)
      self._iprot.readMessageEnd()
      raise x
    result = getTopology_result()
    result.read(self._iprot)
    self._iprot.readMessageEnd()
    if result.success != None:
      return result.success
    if result.e != None:
      raise result.e
    raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopology failed: unknown result");


class Processor(Iface, TProcessor):
  def __init__(self, handler):
    self._handler = handler
    self._processMap = {}
    self._processMap["submitTopology"] = Processor.process_submitTopology
    self._processMap["killTopology"] = Processor.process_killTopology
    self._processMap["beginFileUpload"] = Processor.process_beginFileUpload
    self._processMap["uploadChunk"] = Processor.process_uploadChunk
    self._processMap["finishFileUpload"] = Processor.process_finishFileUpload
    self._processMap["beginFileDownload"] = Processor.process_beginFileDownload
    self._processMap["downloadChunk"] = Processor.process_downloadChunk
    self._processMap["getClusterInfo"] = Processor.process_getClusterInfo
    self._processMap["getTopologyInfo"] = Processor.process_getTopologyInfo
    self._processMap["getTopologyConf"] = Processor.process_getTopologyConf
    self._processMap["getTopology"] = Processor.process_getTopology

  def process(self, iprot, oprot):
    (name, type, seqid) = iprot.readMessageBegin()
    if name not in self._processMap:
      iprot.skip(TType.STRUCT)
      iprot.readMessageEnd()
      x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
      oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
      x.write(oprot)
      oprot.writeMessageEnd()
      oprot.trans.flush()
      return
    else:
      self._processMap[name](self, seqid, iprot, oprot)
    return True

  def process_submitTopology(self, seqid, iprot, oprot):
    args = submitTopology_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = submitTopology_result()
    try:
      self._handler.submitTopology(args.name, args.uploadedJarLocation, args.jsonConf, args.topology)
    except AlreadyAliveException, e:
      result.e = e
    except InvalidTopologyException, ite:
      result.ite = ite
    oprot.writeMessageBegin("submitTopology", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_killTopology(self, seqid, iprot, oprot):
    args = killTopology_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = killTopology_result()
    try:
      self._handler.killTopology(args.name)
    except NotAliveException, e:
      result.e = e
    oprot.writeMessageBegin("killTopology", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_beginFileUpload(self, seqid, iprot, oprot):
    args = beginFileUpload_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = beginFileUpload_result()
    result.success = self._handler.beginFileUpload()
    oprot.writeMessageBegin("beginFileUpload", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_uploadChunk(self, seqid, iprot, oprot):
    args = uploadChunk_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = uploadChunk_result()
    self._handler.uploadChunk(args.location, args.chunk)
    oprot.writeMessageBegin("uploadChunk", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_finishFileUpload(self, seqid, iprot, oprot):
    args = finishFileUpload_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = finishFileUpload_result()
    self._handler.finishFileUpload(args.location)
    oprot.writeMessageBegin("finishFileUpload", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_beginFileDownload(self, seqid, iprot, oprot):
    args = beginFileDownload_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = beginFileDownload_result()
    result.success = self._handler.beginFileDownload(args.file)
    oprot.writeMessageBegin("beginFileDownload", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_downloadChunk(self, seqid, iprot, oprot):
    args = downloadChunk_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = downloadChunk_result()
    result.success = self._handler.downloadChunk(args.id)
    oprot.writeMessageBegin("downloadChunk", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_getClusterInfo(self, seqid, iprot, oprot):
    args = getClusterInfo_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = getClusterInfo_result()
    result.success = self._handler.getClusterInfo()
    oprot.writeMessageBegin("getClusterInfo", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_getTopologyInfo(self, seqid, iprot, oprot):
    args = getTopologyInfo_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = getTopologyInfo_result()
    try:
      result.success = self._handler.getTopologyInfo(args.id)
    except NotAliveException, e:
      result.e = e
    oprot.writeMessageBegin("getTopologyInfo", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_getTopologyConf(self, seqid, iprot, oprot):
    args = getTopologyConf_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = getTopologyConf_result()
    try:
      result.success = self._handler.getTopologyConf(args.id)
    except NotAliveException, e:
      result.e = e
    oprot.writeMessageBegin("getTopologyConf", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()

  def process_getTopology(self, seqid, iprot, oprot):
    args = getTopology_args()
    args.read(iprot)
    iprot.readMessageEnd()
    result = getTopology_result()
    try:
      result.success = self._handler.getTopology(args.id)
    except NotAliveException, e:
      result.e = e
    oprot.writeMessageBegin("getTopology", TMessageType.REPLY, seqid)
    result.write(oprot)
    oprot.writeMessageEnd()
    oprot.trans.flush()


# HELPER FUNCTIONS AND STRUCTURES

class submitTopology_args:
  """
  Attributes:
   - name
   - uploadedJarLocation
   - jsonConf
   - topology
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'name', None, None, ), # 1
    (2, TType.STRING, 'uploadedJarLocation', None, None, ), # 2
    (3, TType.STRING, 'jsonConf', None, None, ), # 3
    (4, TType.STRUCT, 'topology', (StormTopology, StormTopology.thrift_spec), None, ), # 4
  )

  def __init__(self, name=None, uploadedJarLocation=None, jsonConf=None, topology=None,):
    self.name = name
    self.uploadedJarLocation = uploadedJarLocation
    self.jsonConf = jsonConf
    self.topology = topology

  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.uploadedJarLocation = iprot.readString().decode('utf-8');
        else:
          iprot.skip(ftype)
      elif fid == 3:
        if ftype == TType.STRING:
          self.jsonConf = iprot.readString().decode('utf-8');
        else:
          iprot.skip(ftype)
      elif fid == 4:
        if ftype == TType.STRUCT:
          self.topology = StormTopology()
          self.topology.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('submitTopology_args')
    if self.name != None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name.encode('utf-8'));
      oprot.writeFieldEnd()
    if self.uploadedJarLocation != None:
      oprot.writeFieldBegin('uploadedJarLocation', TType.STRING, 2)
      oprot.writeString(self.uploadedJarLocation.encode('utf-8'));
      oprot.writeFieldEnd()
    if self.jsonConf != None:
      oprot.writeFieldBegin('jsonConf', TType.STRING, 3)
      oprot.writeString(self.jsonConf.encode('utf-8'));
      oprot.writeFieldEnd()
    if self.topology != None:
      oprot.writeFieldBegin('topology', TType.STRUCT, 4)
      self.topology.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class submitTopology_result:
  """
  Attributes:
   - e
   - ite
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'e', (AlreadyAliveException, AlreadyAliveException.thrift_spec), None, ), # 1
    (2, TType.STRUCT, 'ite', (InvalidTopologyException, InvalidTopologyException.thrift_spec), None, ), # 2
  )

  def __init__(self, e=None, ite=None,):
    self.e = e
    self.ite = ite

  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.e = AlreadyAliveException()
          self.e.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 2:
        if ftype == TType.STRUCT:
          self.ite = InvalidTopologyException()
          self.ite.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('submitTopology_result')
    if self.e != None:
      oprot.writeFieldBegin('e', TType.STRUCT, 1)
      self.e.write(oprot)
      oprot.writeFieldEnd()
    if self.ite != None:
      oprot.writeFieldBegin('ite', TType.STRUCT, 2)
      self.ite.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class killTopology_args:
  """
  Attributes:
   - name
  """

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

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

  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)
      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('killTopology_args')
    if self.name != None:
      oprot.writeFieldBegin('name', TType.STRING, 1)
      oprot.writeString(self.name.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class killTopology_result:
  """
  Attributes:
   - e
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRUCT, 'e', (NotAliveException, NotAliveException.thrift_spec), None, ), # 1
  )

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

  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.e = NotAliveException()
          self.e.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('killTopology_result')
    if self.e != None:
      oprot.writeFieldBegin('e', TType.STRUCT, 1)
      self.e.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class beginFileUpload_args:

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

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class beginFileUpload_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

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

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = 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('beginFileUpload_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class uploadChunk_args:
  """
  Attributes:
   - location
   - chunk
  """

  thrift_spec = (
    None, # 0
    (1, TType.STRING, 'location', None, None, ), # 1
    (2, TType.STRING, 'chunk', None, None, ), # 2
  )

  def __init__(self, location=None, chunk=None,):
    self.location = location
    self.chunk = chunk

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

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class uploadChunk_result:

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

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class finishFileUpload_args:
  """
  Attributes:
   - location
  """

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

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

  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.location = 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('finishFileUpload_args')
    if self.location != None:
      oprot.writeFieldBegin('location', TType.STRING, 1)
      oprot.writeString(self.location.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class finishFileUpload_result:

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

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class beginFileDownload_args:
  """
  Attributes:
   - file
  """

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

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

  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.file = 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('beginFileDownload_args')
    if self.file != None:
      oprot.writeFieldBegin('file', TType.STRING, 1)
      oprot.writeString(self.file.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class beginFileDownload_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

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

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = 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('beginFileDownload_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class downloadChunk_args:
  """
  Attributes:
   - id
  """

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

  def __init__(self, id=None,):
    self.id = 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.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('downloadChunk_args')
    if self.id != None:
      oprot.writeFieldBegin('id', TType.STRING, 1)
      oprot.writeString(self.id.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class downloadChunk_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
  )

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

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = 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('downloadChunk_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success);
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getClusterInfo_args:

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

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getClusterInfo_result:
  """
  Attributes:
   - success
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (ClusterSummary, ClusterSummary.thrift_spec), None, ), # 0
  )

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

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = ClusterSummary()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      else:
        iprot.skip(ftype)
      iprot.readFieldEnd()
    iprot.readStructEnd()

  def write(self, oprot):
    if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
      oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
      return
    oprot.writeStructBegin('getClusterInfo_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getTopologyInfo_args:
  """
  Attributes:
   - id
  """

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

  def __init__(self, id=None,):
    self.id = 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.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('getTopologyInfo_args')
    if self.id != None:
      oprot.writeFieldBegin('id', TType.STRING, 1)
      oprot.writeString(self.id.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getTopologyInfo_result:
  """
  Attributes:
   - success
   - e
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (TopologyInfo, TopologyInfo.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'e', (NotAliveException, NotAliveException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, e=None,):
    self.success = success
    self.e = e

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = TopologyInfo()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.e = NotAliveException()
          self.e.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('getTopologyInfo_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.e != None:
      oprot.writeFieldBegin('e', TType.STRUCT, 1)
      self.e.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getTopologyConf_args:
  """
  Attributes:
   - id
  """

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

  def __init__(self, id=None,):
    self.id = 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.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('getTopologyConf_args')
    if self.id != None:
      oprot.writeFieldBegin('id', TType.STRING, 1)
      oprot.writeString(self.id.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getTopologyConf_result:
  """
  Attributes:
   - success
   - e
  """

  thrift_spec = (
    (0, TType.STRING, 'success', None, None, ), # 0
    (1, TType.STRUCT, 'e', (NotAliveException, NotAliveException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, e=None,):
    self.success = success
    self.e = e

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRING:
          self.success = iprot.readString().decode('utf-8');
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.e = NotAliveException()
          self.e.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('getTopologyConf_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRING, 0)
      oprot.writeString(self.success.encode('utf-8'));
      oprot.writeFieldEnd()
    if self.e != None:
      oprot.writeFieldBegin('e', TType.STRUCT, 1)
      self.e.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getTopology_args:
  """
  Attributes:
   - id
  """

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

  def __init__(self, id=None,):
    self.id = 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.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('getTopology_args')
    if self.id != None:
      oprot.writeFieldBegin('id', TType.STRING, 1)
      oprot.writeString(self.id.encode('utf-8'));
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx

class getTopology_result:
  """
  Attributes:
   - success
   - e
  """

  thrift_spec = (
    (0, TType.STRUCT, 'success', (StormTopology, StormTopology.thrift_spec), None, ), # 0
    (1, TType.STRUCT, 'e', (NotAliveException, NotAliveException.thrift_spec), None, ), # 1
  )

  def __init__(self, success=None, e=None,):
    self.success = success
    self.e = e

  def read(self, iprot):
    if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
      fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
      return
    iprot.readStructBegin()
    while True:
      (fname, ftype, fid) = iprot.readFieldBegin()
      if ftype == TType.STOP:
        break
      if fid == 0:
        if ftype == TType.STRUCT:
          self.success = StormTopology()
          self.success.read(iprot)
        else:
          iprot.skip(ftype)
      elif fid == 1:
        if ftype == TType.STRUCT:
          self.e = NotAliveException()
          self.e.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('getTopology_result')
    if self.success != None:
      oprot.writeFieldBegin('success', TType.STRUCT, 0)
      self.success.write(oprot)
      oprot.writeFieldEnd()
    if self.e != None:
      oprot.writeFieldBegin('e', TType.STRUCT, 1)
      self.e.write(oprot)
      oprot.writeFieldEnd()
    oprot.writeFieldStop()
    oprot.writeStructEnd()

  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)

  def union_value(self):
    d = self.__dict__
    for key in d:
      val = d[key]
      if not val is None:
        return val

  def get_set_field(self):
    for attr in self.__dict__:
      if not self.__dict__[attr] is None:
        return attr

  def get_set_field_id(self):
    for idx, tup in enumerate(self.__class__.thrift_spec):
      if tup:
        key = tup[2]
        if not self.__dict__[key] is None:
          return idx


