#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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

from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
from thrift.protocol.TProtocol import TProtocolException
from thrift.TRecursive import fix_spec

import sys
import logging
from .ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport
all_structs = []


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

        """
        pass

    def submitTopologyWithOpts(self, name, uploadedJarLocation, jsonConf, topology, options):
        """
        Parameters:
         - name
         - uploadedJarLocation
         - jsonConf
         - topology
         - options

        """
        pass

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

        """
        pass

    def killTopologyWithOpts(self, name, options):
        """
        Parameters:
         - name
         - options

        """
        pass

    def activate(self, name):
        """
        Parameters:
         - name

        """
        pass

    def deactivate(self, name):
        """
        Parameters:
         - name

        """
        pass

    def rebalance(self, name, options):
        """
        Parameters:
         - name
         - options

        """
        pass

    def setLogConfig(self, name, config):
        """
        Parameters:
         - name
         - config

        """
        pass

    def getLogConfig(self, name):
        """
        Parameters:
         - name

        """
        pass

    def debug(self, name, component, enable, samplingPercentage):
        """
        Enable/disable logging the tuples generated in topology via an internal EventLogger bolt. The component name is optional
        and if null or empty, the debug flag will apply to the entire topology.

        The 'samplingPercentage' will limit loggging to a percentage of generated tuples.


        Parameters:
         - name
         - component
         - enable
         - samplingPercentage

        """
        pass

    def setWorkerProfiler(self, id, profileRequest):
        """
        Parameters:
         - id
         - profileRequest

        """
        pass

    def getComponentPendingProfileActions(self, id, component_id, action):
        """
        Parameters:
         - id
         - component_id
         - action

        """
        pass

    def uploadNewCredentials(self, name, creds):
        """
        Parameters:
         - name
         - creds

        """
        pass

    def beginCreateBlob(self, key, meta):
        """
        Parameters:
         - key
         - meta

        """
        pass

    def beginUpdateBlob(self, key):
        """
        Parameters:
         - key

        """
        pass

    def uploadBlobChunk(self, session, chunk):
        """
        Parameters:
         - session
         - chunk

        """
        pass

    def finishBlobUpload(self, session):
        """
        Parameters:
         - session

        """
        pass

    def cancelBlobUpload(self, session):
        """
        Parameters:
         - session

        """
        pass

    def getBlobMeta(self, key):
        """
        Parameters:
         - key

        """
        pass

    def setBlobMeta(self, key, meta):
        """
        Parameters:
         - key
         - meta

        """
        pass

    def beginBlobDownload(self, key):
        """
        Parameters:
         - key

        """
        pass

    def downloadBlobChunk(self, session):
        """
        Parameters:
         - session

        """
        pass

    def deleteBlob(self, key):
        """
        Parameters:
         - key

        """
        pass

    def listBlobs(self, session):
        """
        Parameters:
         - session

        """
        pass

    def getBlobReplication(self, key):
        """
        Parameters:
         - key

        """
        pass

    def updateBlobReplication(self, key, replication):
        """
        Parameters:
         - key
         - replication

        """
        pass

    def createStateInZookeeper(self, key):
        """
        Parameters:
         - key

        """
        pass

    def beginFileUpload(self):
        pass

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

        """
        pass

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

        """
        pass

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

        """
        pass

    def getNimbusConf(self):
        pass

    def getClusterInfo(self):
        pass

    def getLeader(self):
        pass

    def isTopologyNameAllowed(self, name):
        """
        Parameters:
         - name

        """
        pass

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

        """
        pass

    def getTopologyInfoWithOpts(self, id, options):
        """
        Parameters:
         - id
         - options

        """
        pass

    def getTopologyPageInfo(self, id, window, is_include_sys):
        """
        Parameters:
         - id
         - window
         - is_include_sys

        """
        pass

    def getSupervisorPageInfo(self, id, host, is_include_sys):
        """
        Parameters:
         - id
         - host
         - is_include_sys

        """
        pass

    def getComponentPageInfo(self, topology_id, component_id, window, is_include_sys):
        """
        Parameters:
         - topology_id
         - component_id
         - window
         - is_include_sys

        """
        pass

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

        """
        pass

    def getTopology(self, id):
        """
        Returns the compiled topology that contains ackers and metrics consumsers. Compare {@link #getUserTopology(String id)}.

        Parameters:
         - id

        """
        pass

    def getUserTopology(self, id):
        """
        Returns the user specified topology as submitted originally. Compare {@link #getTopology(String id)}.

        Parameters:
         - id

        """
        pass

    def getTopologyHistory(self, user):
        """
        Parameters:
         - user

        """
        pass

    def getOwnerResourceSummaries(self, owner):
        """
        Parameters:
         - owner

        """
        pass

    def getSupervisorAssignments(self, node):
        """
        Get assigned assignments for a specific supervisor

        Parameters:
         - node

        """
        pass

    def sendSupervisorWorkerHeartbeats(self, heartbeats):
        """
        Send supervisor worker heartbeats for a specific supervisor

        Parameters:
         - heartbeats

        """
        pass

    def sendSupervisorWorkerHeartbeat(self, heatbeat):
        """
        Send supervisor local worker heartbeat when a supervisor is unreachable

        Parameters:
         - heatbeat

        """
        pass

    def processWorkerMetrics(self, metrics):
        """
        Parameters:
         - metrics

        """
        pass

    def isRemoteBlobExists(self, blobKey):
        """
        Decide if the blob is removed from cluster.

        Parameters:
         - blobKey

        """
        pass


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

    def 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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = submitTopology_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.ite is not None:
            raise result.ite
        if result.aze is not None:
            raise result.aze
        return

    def submitTopologyWithOpts(self, name, uploadedJarLocation, jsonConf, topology, options):
        """
        Parameters:
         - name
         - uploadedJarLocation
         - jsonConf
         - topology
         - options

        """
        self.send_submitTopologyWithOpts(name, uploadedJarLocation, jsonConf, topology, options)
        self.recv_submitTopologyWithOpts()

    def send_submitTopologyWithOpts(self, name, uploadedJarLocation, jsonConf, topology, options):
        self._oprot.writeMessageBegin('submitTopologyWithOpts', TMessageType.CALL, self._seqid)
        args = submitTopologyWithOpts_args()
        args.name = name
        args.uploadedJarLocation = uploadedJarLocation
        args.jsonConf = jsonConf
        args.topology = topology
        args.options = options
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_submitTopologyWithOpts(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = submitTopologyWithOpts_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.ite is not None:
            raise result.ite
        if result.aze is not None:
            raise result.aze
        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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = killTopology_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        return

    def killTopologyWithOpts(self, name, options):
        """
        Parameters:
         - name
         - options

        """
        self.send_killTopologyWithOpts(name, options)
        self.recv_killTopologyWithOpts()

    def send_killTopologyWithOpts(self, name, options):
        self._oprot.writeMessageBegin('killTopologyWithOpts', TMessageType.CALL, self._seqid)
        args = killTopologyWithOpts_args()
        args.name = name
        args.options = options
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_killTopologyWithOpts(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = killTopologyWithOpts_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        return

    def activate(self, name):
        """
        Parameters:
         - name

        """
        self.send_activate(name)
        self.recv_activate()

    def send_activate(self, name):
        self._oprot.writeMessageBegin('activate', TMessageType.CALL, self._seqid)
        args = activate_args()
        args.name = name
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_activate(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = activate_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        return

    def deactivate(self, name):
        """
        Parameters:
         - name

        """
        self.send_deactivate(name)
        self.recv_deactivate()

    def send_deactivate(self, name):
        self._oprot.writeMessageBegin('deactivate', TMessageType.CALL, self._seqid)
        args = deactivate_args()
        args.name = name
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_deactivate(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = deactivate_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        return

    def rebalance(self, name, options):
        """
        Parameters:
         - name
         - options

        """
        self.send_rebalance(name, options)
        self.recv_rebalance()

    def send_rebalance(self, name, options):
        self._oprot.writeMessageBegin('rebalance', TMessageType.CALL, self._seqid)
        args = rebalance_args()
        args.name = name
        args.options = options
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_rebalance(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = rebalance_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.ite is not None:
            raise result.ite
        if result.aze is not None:
            raise result.aze
        return

    def setLogConfig(self, name, config):
        """
        Parameters:
         - name
         - config

        """
        self.send_setLogConfig(name, config)
        self.recv_setLogConfig()

    def send_setLogConfig(self, name, config):
        self._oprot.writeMessageBegin('setLogConfig', TMessageType.CALL, self._seqid)
        args = setLogConfig_args()
        args.name = name
        args.config = config
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

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

    def getLogConfig(self, name):
        """
        Parameters:
         - name

        """
        self.send_getLogConfig(name)
        return self.recv_getLogConfig()

    def send_getLogConfig(self, name):
        self._oprot.writeMessageBegin('getLogConfig', TMessageType.CALL, self._seqid)
        args = getLogConfig_args()
        args.name = name
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getLogConfig(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getLogConfig_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getLogConfig failed: unknown result")

    def debug(self, name, component, enable, samplingPercentage):
        """
        Enable/disable logging the tuples generated in topology via an internal EventLogger bolt. The component name is optional
        and if null or empty, the debug flag will apply to the entire topology.

        The 'samplingPercentage' will limit loggging to a percentage of generated tuples.


        Parameters:
         - name
         - component
         - enable
         - samplingPercentage

        """
        self.send_debug(name, component, enable, samplingPercentage)
        self.recv_debug()

    def send_debug(self, name, component, enable, samplingPercentage):
        self._oprot.writeMessageBegin('debug', TMessageType.CALL, self._seqid)
        args = debug_args()
        args.name = name
        args.component = component
        args.enable = enable
        args.samplingPercentage = samplingPercentage
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_debug(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = debug_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        return

    def setWorkerProfiler(self, id, profileRequest):
        """
        Parameters:
         - id
         - profileRequest

        """
        self.send_setWorkerProfiler(id, profileRequest)
        self.recv_setWorkerProfiler()

    def send_setWorkerProfiler(self, id, profileRequest):
        self._oprot.writeMessageBegin('setWorkerProfiler', TMessageType.CALL, self._seqid)
        args = setWorkerProfiler_args()
        args.id = id
        args.profileRequest = profileRequest
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

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

    def getComponentPendingProfileActions(self, id, component_id, action):
        """
        Parameters:
         - id
         - component_id
         - action

        """
        self.send_getComponentPendingProfileActions(id, component_id, action)
        return self.recv_getComponentPendingProfileActions()

    def send_getComponentPendingProfileActions(self, id, component_id, action):
        self._oprot.writeMessageBegin('getComponentPendingProfileActions', TMessageType.CALL, self._seqid)
        args = getComponentPendingProfileActions_args()
        args.id = id
        args.component_id = component_id
        args.action = action
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getComponentPendingProfileActions(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getComponentPendingProfileActions_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getComponentPendingProfileActions failed: unknown result")

    def uploadNewCredentials(self, name, creds):
        """
        Parameters:
         - name
         - creds

        """
        self.send_uploadNewCredentials(name, creds)
        self.recv_uploadNewCredentials()

    def send_uploadNewCredentials(self, name, creds):
        self._oprot.writeMessageBegin('uploadNewCredentials', TMessageType.CALL, self._seqid)
        args = uploadNewCredentials_args()
        args.name = name
        args.creds = creds
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_uploadNewCredentials(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = uploadNewCredentials_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.e is not None:
            raise result.e
        if result.ite is not None:
            raise result.ite
        if result.aze is not None:
            raise result.aze
        return

    def beginCreateBlob(self, key, meta):
        """
        Parameters:
         - key
         - meta

        """
        self.send_beginCreateBlob(key, meta)
        return self.recv_beginCreateBlob()

    def send_beginCreateBlob(self, key, meta):
        self._oprot.writeMessageBegin('beginCreateBlob', TMessageType.CALL, self._seqid)
        args = beginCreateBlob_args()
        args.key = key
        args.meta = meta
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_beginCreateBlob(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = beginCreateBlob_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        if result.kae is not None:
            raise result.kae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "beginCreateBlob failed: unknown result")

    def beginUpdateBlob(self, key):
        """
        Parameters:
         - key

        """
        self.send_beginUpdateBlob(key)
        return self.recv_beginUpdateBlob()

    def send_beginUpdateBlob(self, key):
        self._oprot.writeMessageBegin('beginUpdateBlob', TMessageType.CALL, self._seqid)
        args = beginUpdateBlob_args()
        args.key = key
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_beginUpdateBlob(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = beginUpdateBlob_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        raise TApplicationException(TApplicationException.MISSING_RESULT, "beginUpdateBlob failed: unknown result")

    def uploadBlobChunk(self, session, chunk):
        """
        Parameters:
         - session
         - chunk

        """
        self.send_uploadBlobChunk(session, chunk)
        self.recv_uploadBlobChunk()

    def send_uploadBlobChunk(self, session, chunk):
        self._oprot.writeMessageBegin('uploadBlobChunk', TMessageType.CALL, self._seqid)
        args = uploadBlobChunk_args()
        args.session = session
        args.chunk = chunk
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_uploadBlobChunk(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = uploadBlobChunk_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        return

    def finishBlobUpload(self, session):
        """
        Parameters:
         - session

        """
        self.send_finishBlobUpload(session)
        self.recv_finishBlobUpload()

    def send_finishBlobUpload(self, session):
        self._oprot.writeMessageBegin('finishBlobUpload', TMessageType.CALL, self._seqid)
        args = finishBlobUpload_args()
        args.session = session
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_finishBlobUpload(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = finishBlobUpload_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        return

    def cancelBlobUpload(self, session):
        """
        Parameters:
         - session

        """
        self.send_cancelBlobUpload(session)
        self.recv_cancelBlobUpload()

    def send_cancelBlobUpload(self, session):
        self._oprot.writeMessageBegin('cancelBlobUpload', TMessageType.CALL, self._seqid)
        args = cancelBlobUpload_args()
        args.session = session
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_cancelBlobUpload(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = cancelBlobUpload_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        return

    def getBlobMeta(self, key):
        """
        Parameters:
         - key

        """
        self.send_getBlobMeta(key)
        return self.recv_getBlobMeta()

    def send_getBlobMeta(self, key):
        self._oprot.writeMessageBegin('getBlobMeta', TMessageType.CALL, self._seqid)
        args = getBlobMeta_args()
        args.key = key
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getBlobMeta(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getBlobMeta_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getBlobMeta failed: unknown result")

    def setBlobMeta(self, key, meta):
        """
        Parameters:
         - key
         - meta

        """
        self.send_setBlobMeta(key, meta)
        self.recv_setBlobMeta()

    def send_setBlobMeta(self, key, meta):
        self._oprot.writeMessageBegin('setBlobMeta', TMessageType.CALL, self._seqid)
        args = setBlobMeta_args()
        args.key = key
        args.meta = meta
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_setBlobMeta(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = setBlobMeta_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        return

    def beginBlobDownload(self, key):
        """
        Parameters:
         - key

        """
        self.send_beginBlobDownload(key)
        return self.recv_beginBlobDownload()

    def send_beginBlobDownload(self, key):
        self._oprot.writeMessageBegin('beginBlobDownload', TMessageType.CALL, self._seqid)
        args = beginBlobDownload_args()
        args.key = key
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_beginBlobDownload(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = beginBlobDownload_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        raise TApplicationException(TApplicationException.MISSING_RESULT, "beginBlobDownload failed: unknown result")

    def downloadBlobChunk(self, session):
        """
        Parameters:
         - session

        """
        self.send_downloadBlobChunk(session)
        return self.recv_downloadBlobChunk()

    def send_downloadBlobChunk(self, session):
        self._oprot.writeMessageBegin('downloadBlobChunk', TMessageType.CALL, self._seqid)
        args = downloadBlobChunk_args()
        args.session = session
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_downloadBlobChunk(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = downloadBlobChunk_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "downloadBlobChunk failed: unknown result")

    def deleteBlob(self, key):
        """
        Parameters:
         - key

        """
        self.send_deleteBlob(key)
        self.recv_deleteBlob()

    def send_deleteBlob(self, key):
        self._oprot.writeMessageBegin('deleteBlob', TMessageType.CALL, self._seqid)
        args = deleteBlob_args()
        args.key = key
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_deleteBlob(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = deleteBlob_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        if result.ise is not None:
            raise result.ise
        return

    def listBlobs(self, session):
        """
        Parameters:
         - session

        """
        self.send_listBlobs(session)
        return self.recv_listBlobs()

    def send_listBlobs(self, session):
        self._oprot.writeMessageBegin('listBlobs', TMessageType.CALL, self._seqid)
        args = listBlobs_args()
        args.session = session
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_listBlobs(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = listBlobs_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        raise TApplicationException(TApplicationException.MISSING_RESULT, "listBlobs failed: unknown result")

    def getBlobReplication(self, key):
        """
        Parameters:
         - key

        """
        self.send_getBlobReplication(key)
        return self.recv_getBlobReplication()

    def send_getBlobReplication(self, key):
        self._oprot.writeMessageBegin('getBlobReplication', TMessageType.CALL, self._seqid)
        args = getBlobReplication_args()
        args.key = key
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getBlobReplication(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getBlobReplication_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getBlobReplication failed: unknown result")

    def updateBlobReplication(self, key, replication):
        """
        Parameters:
         - key
         - replication

        """
        self.send_updateBlobReplication(key, replication)
        return self.recv_updateBlobReplication()

    def send_updateBlobReplication(self, key, replication):
        self._oprot.writeMessageBegin('updateBlobReplication', TMessageType.CALL, self._seqid)
        args = updateBlobReplication_args()
        args.key = key
        args.replication = replication
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_updateBlobReplication(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = updateBlobReplication_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        if result.knf is not None:
            raise result.knf
        raise TApplicationException(TApplicationException.MISSING_RESULT, "updateBlobReplication failed: unknown result")

    def createStateInZookeeper(self, key):
        """
        Parameters:
         - key

        """
        self.send_createStateInZookeeper(key)
        self.recv_createStateInZookeeper()

    def send_createStateInZookeeper(self, key):
        self._oprot.writeMessageBegin('createStateInZookeeper', TMessageType.CALL, self._seqid)
        args = createStateInZookeeper_args()
        args.key = key
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_createStateInZookeeper(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = createStateInZookeeper_result()
        result.read(iprot)
        iprot.readMessageEnd()
        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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = beginFileUpload_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = uploadChunk_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = finishFileUpload_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        return

    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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = downloadChunk_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "downloadChunk failed: unknown result")

    def getNimbusConf(self):
        self.send_getNimbusConf()
        return self.recv_getNimbusConf()

    def send_getNimbusConf(self):
        self._oprot.writeMessageBegin('getNimbusConf', TMessageType.CALL, self._seqid)
        args = getNimbusConf_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getNimbusConf(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getNimbusConf_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getNimbusConf 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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getClusterInfo_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getClusterInfo failed: unknown result")

    def getLeader(self):
        self.send_getLeader()
        return self.recv_getLeader()

    def send_getLeader(self):
        self._oprot.writeMessageBegin('getLeader', TMessageType.CALL, self._seqid)
        args = getLeader_args()
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getLeader(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getLeader_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getLeader failed: unknown result")

    def isTopologyNameAllowed(self, name):
        """
        Parameters:
         - name

        """
        self.send_isTopologyNameAllowed(name)
        return self.recv_isTopologyNameAllowed()

    def send_isTopologyNameAllowed(self, name):
        self._oprot.writeMessageBegin('isTopologyNameAllowed', TMessageType.CALL, self._seqid)
        args = isTopologyNameAllowed_args()
        args.name = name
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_isTopologyNameAllowed(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = isTopologyNameAllowed_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "isTopologyNameAllowed 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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getTopologyInfo_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyInfo failed: unknown result")

    def getTopologyInfoWithOpts(self, id, options):
        """
        Parameters:
         - id
         - options

        """
        self.send_getTopologyInfoWithOpts(id, options)
        return self.recv_getTopologyInfoWithOpts()

    def send_getTopologyInfoWithOpts(self, id, options):
        self._oprot.writeMessageBegin('getTopologyInfoWithOpts', TMessageType.CALL, self._seqid)
        args = getTopologyInfoWithOpts_args()
        args.id = id
        args.options = options
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getTopologyInfoWithOpts(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getTopologyInfoWithOpts_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyInfoWithOpts failed: unknown result")

    def getTopologyPageInfo(self, id, window, is_include_sys):
        """
        Parameters:
         - id
         - window
         - is_include_sys

        """
        self.send_getTopologyPageInfo(id, window, is_include_sys)
        return self.recv_getTopologyPageInfo()

    def send_getTopologyPageInfo(self, id, window, is_include_sys):
        self._oprot.writeMessageBegin('getTopologyPageInfo', TMessageType.CALL, self._seqid)
        args = getTopologyPageInfo_args()
        args.id = id
        args.window = window
        args.is_include_sys = is_include_sys
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getTopologyPageInfo(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getTopologyPageInfo_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyPageInfo failed: unknown result")

    def getSupervisorPageInfo(self, id, host, is_include_sys):
        """
        Parameters:
         - id
         - host
         - is_include_sys

        """
        self.send_getSupervisorPageInfo(id, host, is_include_sys)
        return self.recv_getSupervisorPageInfo()

    def send_getSupervisorPageInfo(self, id, host, is_include_sys):
        self._oprot.writeMessageBegin('getSupervisorPageInfo', TMessageType.CALL, self._seqid)
        args = getSupervisorPageInfo_args()
        args.id = id
        args.host = host
        args.is_include_sys = is_include_sys
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getSupervisorPageInfo(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getSupervisorPageInfo_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getSupervisorPageInfo failed: unknown result")

    def getComponentPageInfo(self, topology_id, component_id, window, is_include_sys):
        """
        Parameters:
         - topology_id
         - component_id
         - window
         - is_include_sys

        """
        self.send_getComponentPageInfo(topology_id, component_id, window, is_include_sys)
        return self.recv_getComponentPageInfo()

    def send_getComponentPageInfo(self, topology_id, component_id, window, is_include_sys):
        self._oprot.writeMessageBegin('getComponentPageInfo', TMessageType.CALL, self._seqid)
        args = getComponentPageInfo_args()
        args.topology_id = topology_id
        args.component_id = component_id
        args.window = window
        args.is_include_sys = is_include_sys
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getComponentPageInfo(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getComponentPageInfo_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getComponentPageInfo 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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getTopologyConf_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyConf failed: unknown result")

    def getTopology(self, id):
        """
        Returns the compiled topology that contains ackers and metrics consumsers. Compare {@link #getUserTopology(String 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):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getTopology_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopology failed: unknown result")

    def getUserTopology(self, id):
        """
        Returns the user specified topology as submitted originally. Compare {@link #getTopology(String id)}.

        Parameters:
         - id

        """
        self.send_getUserTopology(id)
        return self.recv_getUserTopology()

    def send_getUserTopology(self, id):
        self._oprot.writeMessageBegin('getUserTopology', TMessageType.CALL, self._seqid)
        args = getUserTopology_args()
        args.id = id
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getUserTopology(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getUserTopology_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.e is not None:
            raise result.e
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getUserTopology failed: unknown result")

    def getTopologyHistory(self, user):
        """
        Parameters:
         - user

        """
        self.send_getTopologyHistory(user)
        return self.recv_getTopologyHistory()

    def send_getTopologyHistory(self, user):
        self._oprot.writeMessageBegin('getTopologyHistory', TMessageType.CALL, self._seqid)
        args = getTopologyHistory_args()
        args.user = user
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getTopologyHistory(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getTopologyHistory_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getTopologyHistory failed: unknown result")

    def getOwnerResourceSummaries(self, owner):
        """
        Parameters:
         - owner

        """
        self.send_getOwnerResourceSummaries(owner)
        return self.recv_getOwnerResourceSummaries()

    def send_getOwnerResourceSummaries(self, owner):
        self._oprot.writeMessageBegin('getOwnerResourceSummaries', TMessageType.CALL, self._seqid)
        args = getOwnerResourceSummaries_args()
        args.owner = owner
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getOwnerResourceSummaries(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getOwnerResourceSummaries_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getOwnerResourceSummaries failed: unknown result")

    def getSupervisorAssignments(self, node):
        """
        Get assigned assignments for a specific supervisor

        Parameters:
         - node

        """
        self.send_getSupervisorAssignments(node)
        return self.recv_getSupervisorAssignments()

    def send_getSupervisorAssignments(self, node):
        self._oprot.writeMessageBegin('getSupervisorAssignments', TMessageType.CALL, self._seqid)
        args = getSupervisorAssignments_args()
        args.node = node
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getSupervisorAssignments(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getSupervisorAssignments_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getSupervisorAssignments failed: unknown result")

    def sendSupervisorWorkerHeartbeats(self, heartbeats):
        """
        Send supervisor worker heartbeats for a specific supervisor

        Parameters:
         - heartbeats

        """
        self.send_sendSupervisorWorkerHeartbeats(heartbeats)
        self.recv_sendSupervisorWorkerHeartbeats()

    def send_sendSupervisorWorkerHeartbeats(self, heartbeats):
        self._oprot.writeMessageBegin('sendSupervisorWorkerHeartbeats', TMessageType.CALL, self._seqid)
        args = sendSupervisorWorkerHeartbeats_args()
        args.heartbeats = heartbeats
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_sendSupervisorWorkerHeartbeats(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = sendSupervisorWorkerHeartbeats_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        return

    def sendSupervisorWorkerHeartbeat(self, heatbeat):
        """
        Send supervisor local worker heartbeat when a supervisor is unreachable

        Parameters:
         - heatbeat

        """
        self.send_sendSupervisorWorkerHeartbeat(heatbeat)
        self.recv_sendSupervisorWorkerHeartbeat()

    def send_sendSupervisorWorkerHeartbeat(self, heatbeat):
        self._oprot.writeMessageBegin('sendSupervisorWorkerHeartbeat', TMessageType.CALL, self._seqid)
        args = sendSupervisorWorkerHeartbeat_args()
        args.heatbeat = heatbeat
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_sendSupervisorWorkerHeartbeat(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = sendSupervisorWorkerHeartbeat_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.aze is not None:
            raise result.aze
        if result.e is not None:
            raise result.e
        return

    def processWorkerMetrics(self, metrics):
        """
        Parameters:
         - metrics

        """
        self.send_processWorkerMetrics(metrics)
        self.recv_processWorkerMetrics()

    def send_processWorkerMetrics(self, metrics):
        self._oprot.writeMessageBegin('processWorkerMetrics', TMessageType.CALL, self._seqid)
        args = processWorkerMetrics_args()
        args.metrics = metrics
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

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

    def isRemoteBlobExists(self, blobKey):
        """
        Decide if the blob is removed from cluster.

        Parameters:
         - blobKey

        """
        self.send_isRemoteBlobExists(blobKey)
        return self.recv_isRemoteBlobExists()

    def send_isRemoteBlobExists(self, blobKey):
        self._oprot.writeMessageBegin('isRemoteBlobExists', TMessageType.CALL, self._seqid)
        args = isRemoteBlobExists_args()
        args.blobKey = blobKey
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_isRemoteBlobExists(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = isRemoteBlobExists_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.aze is not None:
            raise result.aze
        raise TApplicationException(TApplicationException.MISSING_RESULT, "isRemoteBlobExists failed: unknown result")


class Processor(Iface, TProcessor):
    def __init__(self, handler):
        self._handler = handler
        self._processMap = {}
        self._processMap["submitTopology"] = Processor.process_submitTopology
        self._processMap["submitTopologyWithOpts"] = Processor.process_submitTopologyWithOpts
        self._processMap["killTopology"] = Processor.process_killTopology
        self._processMap["killTopologyWithOpts"] = Processor.process_killTopologyWithOpts
        self._processMap["activate"] = Processor.process_activate
        self._processMap["deactivate"] = Processor.process_deactivate
        self._processMap["rebalance"] = Processor.process_rebalance
        self._processMap["setLogConfig"] = Processor.process_setLogConfig
        self._processMap["getLogConfig"] = Processor.process_getLogConfig
        self._processMap["debug"] = Processor.process_debug
        self._processMap["setWorkerProfiler"] = Processor.process_setWorkerProfiler
        self._processMap["getComponentPendingProfileActions"] = Processor.process_getComponentPendingProfileActions
        self._processMap["uploadNewCredentials"] = Processor.process_uploadNewCredentials
        self._processMap["beginCreateBlob"] = Processor.process_beginCreateBlob
        self._processMap["beginUpdateBlob"] = Processor.process_beginUpdateBlob
        self._processMap["uploadBlobChunk"] = Processor.process_uploadBlobChunk
        self._processMap["finishBlobUpload"] = Processor.process_finishBlobUpload
        self._processMap["cancelBlobUpload"] = Processor.process_cancelBlobUpload
        self._processMap["getBlobMeta"] = Processor.process_getBlobMeta
        self._processMap["setBlobMeta"] = Processor.process_setBlobMeta
        self._processMap["beginBlobDownload"] = Processor.process_beginBlobDownload
        self._processMap["downloadBlobChunk"] = Processor.process_downloadBlobChunk
        self._processMap["deleteBlob"] = Processor.process_deleteBlob
        self._processMap["listBlobs"] = Processor.process_listBlobs
        self._processMap["getBlobReplication"] = Processor.process_getBlobReplication
        self._processMap["updateBlobReplication"] = Processor.process_updateBlobReplication
        self._processMap["createStateInZookeeper"] = Processor.process_createStateInZookeeper
        self._processMap["beginFileUpload"] = Processor.process_beginFileUpload
        self._processMap["uploadChunk"] = Processor.process_uploadChunk
        self._processMap["finishFileUpload"] = Processor.process_finishFileUpload
        self._processMap["downloadChunk"] = Processor.process_downloadChunk
        self._processMap["getNimbusConf"] = Processor.process_getNimbusConf
        self._processMap["getClusterInfo"] = Processor.process_getClusterInfo
        self._processMap["getLeader"] = Processor.process_getLeader
        self._processMap["isTopologyNameAllowed"] = Processor.process_isTopologyNameAllowed
        self._processMap["getTopologyInfo"] = Processor.process_getTopologyInfo
        self._processMap["getTopologyInfoWithOpts"] = Processor.process_getTopologyInfoWithOpts
        self._processMap["getTopologyPageInfo"] = Processor.process_getTopologyPageInfo
        self._processMap["getSupervisorPageInfo"] = Processor.process_getSupervisorPageInfo
        self._processMap["getComponentPageInfo"] = Processor.process_getComponentPageInfo
        self._processMap["getTopologyConf"] = Processor.process_getTopologyConf
        self._processMap["getTopology"] = Processor.process_getTopology
        self._processMap["getUserTopology"] = Processor.process_getUserTopology
        self._processMap["getTopologyHistory"] = Processor.process_getTopologyHistory
        self._processMap["getOwnerResourceSummaries"] = Processor.process_getOwnerResourceSummaries
        self._processMap["getSupervisorAssignments"] = Processor.process_getSupervisorAssignments
        self._processMap["sendSupervisorWorkerHeartbeats"] = Processor.process_sendSupervisorWorkerHeartbeats
        self._processMap["sendSupervisorWorkerHeartbeat"] = Processor.process_sendSupervisorWorkerHeartbeat
        self._processMap["processWorkerMetrics"] = Processor.process_processWorkerMetrics
        self._processMap["isRemoteBlobExists"] = Processor.process_isRemoteBlobExists

    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)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AlreadyAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except InvalidTopologyException as ite:
            msg_type = TMessageType.REPLY
            result.ite = ite
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("submitTopology", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_submitTopologyWithOpts(self, seqid, iprot, oprot):
        args = submitTopologyWithOpts_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = submitTopologyWithOpts_result()
        try:
            self._handler.submitTopologyWithOpts(args.name, args.uploadedJarLocation, args.jsonConf, args.topology, args.options)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AlreadyAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except InvalidTopologyException as ite:
            msg_type = TMessageType.REPLY
            result.ite = ite
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("submitTopologyWithOpts", msg_type, 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)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("killTopology", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_killTopologyWithOpts(self, seqid, iprot, oprot):
        args = killTopologyWithOpts_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = killTopologyWithOpts_result()
        try:
            self._handler.killTopologyWithOpts(args.name, args.options)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("killTopologyWithOpts", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_activate(self, seqid, iprot, oprot):
        args = activate_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = activate_result()
        try:
            self._handler.activate(args.name)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("activate", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_deactivate(self, seqid, iprot, oprot):
        args = deactivate_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = deactivate_result()
        try:
            self._handler.deactivate(args.name)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("deactivate", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_rebalance(self, seqid, iprot, oprot):
        args = rebalance_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = rebalance_result()
        try:
            self._handler.rebalance(args.name, args.options)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except InvalidTopologyException as ite:
            msg_type = TMessageType.REPLY
            result.ite = ite
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("rebalance", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_setLogConfig(self, seqid, iprot, oprot):
        args = setLogConfig_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = setLogConfig_result()
        try:
            self._handler.setLogConfig(args.name, args.config)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("setLogConfig", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getLogConfig(self, seqid, iprot, oprot):
        args = getLogConfig_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getLogConfig_result()
        try:
            result.success = self._handler.getLogConfig(args.name)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getLogConfig", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_debug(self, seqid, iprot, oprot):
        args = debug_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = debug_result()
        try:
            self._handler.debug(args.name, args.component, args.enable, args.samplingPercentage)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("debug", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_setWorkerProfiler(self, seqid, iprot, oprot):
        args = setWorkerProfiler_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = setWorkerProfiler_result()
        try:
            self._handler.setWorkerProfiler(args.id, args.profileRequest)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("setWorkerProfiler", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getComponentPendingProfileActions(self, seqid, iprot, oprot):
        args = getComponentPendingProfileActions_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getComponentPendingProfileActions_result()
        try:
            result.success = self._handler.getComponentPendingProfileActions(args.id, args.component_id, args.action)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getComponentPendingProfileActions", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_uploadNewCredentials(self, seqid, iprot, oprot):
        args = uploadNewCredentials_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = uploadNewCredentials_result()
        try:
            self._handler.uploadNewCredentials(args.name, args.creds)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except InvalidTopologyException as ite:
            msg_type = TMessageType.REPLY
            result.ite = ite
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("uploadNewCredentials", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_beginCreateBlob(self, seqid, iprot, oprot):
        args = beginCreateBlob_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = beginCreateBlob_result()
        try:
            result.success = self._handler.beginCreateBlob(args.key, args.meta)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyAlreadyExistsException as kae:
            msg_type = TMessageType.REPLY
            result.kae = kae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("beginCreateBlob", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_beginUpdateBlob(self, seqid, iprot, oprot):
        args = beginUpdateBlob_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = beginUpdateBlob_result()
        try:
            result.success = self._handler.beginUpdateBlob(args.key)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("beginUpdateBlob", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_uploadBlobChunk(self, seqid, iprot, oprot):
        args = uploadBlobChunk_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = uploadBlobChunk_result()
        try:
            self._handler.uploadBlobChunk(args.session, args.chunk)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("uploadBlobChunk", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_finishBlobUpload(self, seqid, iprot, oprot):
        args = finishBlobUpload_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = finishBlobUpload_result()
        try:
            self._handler.finishBlobUpload(args.session)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("finishBlobUpload", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_cancelBlobUpload(self, seqid, iprot, oprot):
        args = cancelBlobUpload_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = cancelBlobUpload_result()
        try:
            self._handler.cancelBlobUpload(args.session)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("cancelBlobUpload", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getBlobMeta(self, seqid, iprot, oprot):
        args = getBlobMeta_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getBlobMeta_result()
        try:
            result.success = self._handler.getBlobMeta(args.key)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getBlobMeta", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_setBlobMeta(self, seqid, iprot, oprot):
        args = setBlobMeta_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = setBlobMeta_result()
        try:
            self._handler.setBlobMeta(args.key, args.meta)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("setBlobMeta", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_beginBlobDownload(self, seqid, iprot, oprot):
        args = beginBlobDownload_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = beginBlobDownload_result()
        try:
            result.success = self._handler.beginBlobDownload(args.key)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("beginBlobDownload", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_downloadBlobChunk(self, seqid, iprot, oprot):
        args = downloadBlobChunk_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = downloadBlobChunk_result()
        try:
            result.success = self._handler.downloadBlobChunk(args.session)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("downloadBlobChunk", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_deleteBlob(self, seqid, iprot, oprot):
        args = deleteBlob_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = deleteBlob_result()
        try:
            self._handler.deleteBlob(args.key)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except IllegalStateException as ise:
            msg_type = TMessageType.REPLY
            result.ise = ise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("deleteBlob", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_listBlobs(self, seqid, iprot, oprot):
        args = listBlobs_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = listBlobs_result()
        try:
            result.success = self._handler.listBlobs(args.session)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("listBlobs", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getBlobReplication(self, seqid, iprot, oprot):
        args = getBlobReplication_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getBlobReplication_result()
        try:
            result.success = self._handler.getBlobReplication(args.key)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getBlobReplication", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_updateBlobReplication(self, seqid, iprot, oprot):
        args = updateBlobReplication_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = updateBlobReplication_result()
        try:
            result.success = self._handler.updateBlobReplication(args.key, args.replication)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except KeyNotFoundException as knf:
            msg_type = TMessageType.REPLY
            result.knf = knf
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("updateBlobReplication", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_createStateInZookeeper(self, seqid, iprot, oprot):
        args = createStateInZookeeper_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = createStateInZookeeper_result()
        try:
            self._handler.createStateInZookeeper(args.key)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("createStateInZookeeper", msg_type, 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()
        try:
            result.success = self._handler.beginFileUpload()
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("beginFileUpload", msg_type, 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()
        try:
            self._handler.uploadChunk(args.location, args.chunk)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("uploadChunk", msg_type, 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()
        try:
            self._handler.finishFileUpload(args.location)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("finishFileUpload", msg_type, 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()
        try:
            result.success = self._handler.downloadChunk(args.id)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("downloadChunk", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getNimbusConf(self, seqid, iprot, oprot):
        args = getNimbusConf_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getNimbusConf_result()
        try:
            result.success = self._handler.getNimbusConf()
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getNimbusConf", msg_type, 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()
        try:
            result.success = self._handler.getClusterInfo()
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getClusterInfo", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getLeader(self, seqid, iprot, oprot):
        args = getLeader_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getLeader_result()
        try:
            result.success = self._handler.getLeader()
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getLeader", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_isTopologyNameAllowed(self, seqid, iprot, oprot):
        args = isTopologyNameAllowed_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = isTopologyNameAllowed_result()
        try:
            result.success = self._handler.isTopologyNameAllowed(args.name)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("isTopologyNameAllowed", msg_type, 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)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getTopologyInfo", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getTopologyInfoWithOpts(self, seqid, iprot, oprot):
        args = getTopologyInfoWithOpts_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getTopologyInfoWithOpts_result()
        try:
            result.success = self._handler.getTopologyInfoWithOpts(args.id, args.options)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getTopologyInfoWithOpts", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getTopologyPageInfo(self, seqid, iprot, oprot):
        args = getTopologyPageInfo_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getTopologyPageInfo_result()
        try:
            result.success = self._handler.getTopologyPageInfo(args.id, args.window, args.is_include_sys)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getTopologyPageInfo", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getSupervisorPageInfo(self, seqid, iprot, oprot):
        args = getSupervisorPageInfo_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getSupervisorPageInfo_result()
        try:
            result.success = self._handler.getSupervisorPageInfo(args.id, args.host, args.is_include_sys)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getSupervisorPageInfo", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getComponentPageInfo(self, seqid, iprot, oprot):
        args = getComponentPageInfo_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getComponentPageInfo_result()
        try:
            result.success = self._handler.getComponentPageInfo(args.topology_id, args.component_id, args.window, args.is_include_sys)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getComponentPageInfo", msg_type, 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)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getTopologyConf", msg_type, 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)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getTopology", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getUserTopology(self, seqid, iprot, oprot):
        args = getUserTopology_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getUserTopology_result()
        try:
            result.success = self._handler.getUserTopology(args.id)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getUserTopology", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getTopologyHistory(self, seqid, iprot, oprot):
        args = getTopologyHistory_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getTopologyHistory_result()
        try:
            result.success = self._handler.getTopologyHistory(args.user)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getTopologyHistory", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getOwnerResourceSummaries(self, seqid, iprot, oprot):
        args = getOwnerResourceSummaries_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getOwnerResourceSummaries_result()
        try:
            result.success = self._handler.getOwnerResourceSummaries(args.owner)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getOwnerResourceSummaries", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getSupervisorAssignments(self, seqid, iprot, oprot):
        args = getSupervisorAssignments_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getSupervisorAssignments_result()
        try:
            result.success = self._handler.getSupervisorAssignments(args.node)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getSupervisorAssignments", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_sendSupervisorWorkerHeartbeats(self, seqid, iprot, oprot):
        args = sendSupervisorWorkerHeartbeats_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = sendSupervisorWorkerHeartbeats_result()
        try:
            self._handler.sendSupervisorWorkerHeartbeats(args.heartbeats)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("sendSupervisorWorkerHeartbeats", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_sendSupervisorWorkerHeartbeat(self, seqid, iprot, oprot):
        args = sendSupervisorWorkerHeartbeat_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = sendSupervisorWorkerHeartbeat_result()
        try:
            self._handler.sendSupervisorWorkerHeartbeat(args.heatbeat)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except NotAliveException as e:
            msg_type = TMessageType.REPLY
            result.e = e
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("sendSupervisorWorkerHeartbeat", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_processWorkerMetrics(self, seqid, iprot, oprot):
        args = processWorkerMetrics_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = processWorkerMetrics_result()
        try:
            self._handler.processWorkerMetrics(args.metrics)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("processWorkerMetrics", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_isRemoteBlobExists(self, seqid, iprot, oprot):
        args = isRemoteBlobExists_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = isRemoteBlobExists_result()
        try:
            result.success = self._handler.isRemoteBlobExists(args.blobKey)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except AuthorizationException as aze:
            msg_type = TMessageType.REPLY
            result.aze = aze
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("isRemoteBlobExists", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

# HELPER FUNCTIONS AND STRUCTURES


class submitTopology_args(object):
    """
    Attributes:
     - name
     - uploadedJarLocation
     - jsonConf
     - topology

    """


    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._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.uploadedJarLocation = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.jsonConf = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('submitTopology_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.uploadedJarLocation is not None:
            oprot.writeFieldBegin('uploadedJarLocation', TType.STRING, 2)
            oprot.writeString(self.uploadedJarLocation.encode('utf-8') if sys.version_info[0] == 2 else self.uploadedJarLocation)
            oprot.writeFieldEnd()
        if self.jsonConf is not None:
            oprot.writeFieldBegin('jsonConf', TType.STRING, 3)
            oprot.writeString(self.jsonConf.encode('utf-8') if sys.version_info[0] == 2 else self.jsonConf)
            oprot.writeFieldEnd()
        if self.topology is not None:
            oprot.writeFieldBegin('topology', TType.STRUCT, 4)
            self.topology.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(submitTopology_args)
submitTopology_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'uploadedJarLocation', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'jsonConf', 'UTF8', None, ),  # 3
    (4, TType.STRUCT, 'topology', [StormTopology, None], None, ),  # 4
)


class submitTopology_result(object):
    """
    Attributes:
     - e
     - ite
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('submitTopology_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.ite is not None:
            oprot.writeFieldBegin('ite', TType.STRUCT, 2)
            self.ite.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 3)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(submitTopology_result)
submitTopology_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [AlreadyAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'ite', [InvalidTopologyException, None], None, ),  # 2
    (3, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 3
)


class submitTopologyWithOpts_args(object):
    """
    Attributes:
     - name
     - uploadedJarLocation
     - jsonConf
     - topology
     - options

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.uploadedJarLocation = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.jsonConf = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRUCT:
                    self.topology = StormTopology()
                    self.topology.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 5:
                if ftype == TType.STRUCT:
                    self.options = SubmitOptions()
                    self.options.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('submitTopologyWithOpts_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.uploadedJarLocation is not None:
            oprot.writeFieldBegin('uploadedJarLocation', TType.STRING, 2)
            oprot.writeString(self.uploadedJarLocation.encode('utf-8') if sys.version_info[0] == 2 else self.uploadedJarLocation)
            oprot.writeFieldEnd()
        if self.jsonConf is not None:
            oprot.writeFieldBegin('jsonConf', TType.STRING, 3)
            oprot.writeString(self.jsonConf.encode('utf-8') if sys.version_info[0] == 2 else self.jsonConf)
            oprot.writeFieldEnd()
        if self.topology is not None:
            oprot.writeFieldBegin('topology', TType.STRUCT, 4)
            self.topology.write(oprot)
            oprot.writeFieldEnd()
        if self.options is not None:
            oprot.writeFieldBegin('options', TType.STRUCT, 5)
            self.options.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(submitTopologyWithOpts_args)
submitTopologyWithOpts_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'uploadedJarLocation', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'jsonConf', 'UTF8', None, ),  # 3
    (4, TType.STRUCT, 'topology', [StormTopology, None], None, ),  # 4
    (5, TType.STRUCT, 'options', [SubmitOptions, None], None, ),  # 5
)


class submitTopologyWithOpts_result(object):
    """
    Attributes:
     - e
     - ite
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('submitTopologyWithOpts_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.ite is not None:
            oprot.writeFieldBegin('ite', TType.STRUCT, 2)
            self.ite.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 3)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(submitTopologyWithOpts_result)
submitTopologyWithOpts_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [AlreadyAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'ite', [InvalidTopologyException, None], None, ),  # 2
    (3, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 3
)


class killTopology_args(object):
    """
    Attributes:
     - name

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('killTopology_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(killTopology_args)
killTopology_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
)


class killTopology_result(object):
    """
    Attributes:
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('killTopology_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(killTopology_result)
killTopology_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class killTopologyWithOpts_args(object):
    """
    Attributes:
     - name
     - options

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.options = KillOptions()
                    self.options.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('killTopologyWithOpts_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.options is not None:
            oprot.writeFieldBegin('options', TType.STRUCT, 2)
            self.options.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(killTopologyWithOpts_args)
killTopologyWithOpts_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'options', [KillOptions, None], None, ),  # 2
)


class killTopologyWithOpts_result(object):
    """
    Attributes:
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('killTopologyWithOpts_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(killTopologyWithOpts_result)
killTopologyWithOpts_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class activate_args(object):
    """
    Attributes:
     - name

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('activate_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(activate_args)
activate_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
)


class activate_result(object):
    """
    Attributes:
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('activate_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(activate_result)
activate_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class deactivate_args(object):
    """
    Attributes:
     - name

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('deactivate_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(deactivate_args)
deactivate_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
)


class deactivate_result(object):
    """
    Attributes:
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('deactivate_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(deactivate_result)
deactivate_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class rebalance_args(object):
    """
    Attributes:
     - name
     - options

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.options = RebalanceOptions()
                    self.options.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('rebalance_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.options is not None:
            oprot.writeFieldBegin('options', TType.STRUCT, 2)
            self.options.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(rebalance_args)
rebalance_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'options', [RebalanceOptions, None], None, ),  # 2
)


class rebalance_result(object):
    """
    Attributes:
     - e
     - ite
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ite = InvalidTopologyException()
                    self.ite.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('rebalance_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.ite is not None:
            oprot.writeFieldBegin('ite', TType.STRUCT, 2)
            self.ite.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 3)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(rebalance_result)
rebalance_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'ite', [InvalidTopologyException, None], None, ),  # 2
    (3, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 3
)


class setLogConfig_args(object):
    """
    Attributes:
     - name
     - config

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.config = LogConfig()
                    self.config.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setLogConfig_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.config is not None:
            oprot.writeFieldBegin('config', TType.STRUCT, 2)
            self.config.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(setLogConfig_args)
setLogConfig_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'config', [LogConfig, None], None, ),  # 2
)


class setLogConfig_result(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setLogConfig_result')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(setLogConfig_result)
setLogConfig_result.thrift_spec = (
)


class getLogConfig_args(object):
    """
    Attributes:
     - name

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getLogConfig_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getLogConfig_args)
getLogConfig_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
)


class getLogConfig_result(object):
    """
    Attributes:
     - success

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = LogConfig()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getLogConfig_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getLogConfig_result)
getLogConfig_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [LogConfig, None], None, ),  # 0
)


class debug_args(object):
    """
    Attributes:
     - name
     - component
     - enable
     - samplingPercentage

    """


    def __init__(self, name=None, component=None, enable=None, samplingPercentage=None,):
        self.name = name
        self.component = component
        self.enable = enable
        self.samplingPercentage = samplingPercentage

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.component = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.BOOL:
                    self.enable = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.DOUBLE:
                    self.samplingPercentage = iprot.readDouble()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('debug_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        if self.component is not None:
            oprot.writeFieldBegin('component', TType.STRING, 2)
            oprot.writeString(self.component.encode('utf-8') if sys.version_info[0] == 2 else self.component)
            oprot.writeFieldEnd()
        if self.enable is not None:
            oprot.writeFieldBegin('enable', TType.BOOL, 3)
            oprot.writeBool(self.enable)
            oprot.writeFieldEnd()
        if self.samplingPercentage is not None:
            oprot.writeFieldBegin('samplingPercentage', TType.DOUBLE, 4)
            oprot.writeDouble(self.samplingPercentage)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(debug_args)
debug_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'component', 'UTF8', None, ),  # 2
    (3, TType.BOOL, 'enable', None, None, ),  # 3
    (4, TType.DOUBLE, 'samplingPercentage', None, None, ),  # 4
)


class debug_result(object):
    """
    Attributes:
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('debug_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(debug_result)
debug_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class setWorkerProfiler_args(object):
    """
    Attributes:
     - id
     - profileRequest

    """


    def __init__(self, id=None, profileRequest=None,):
        self.id = id
        self.profileRequest = profileRequest

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.profileRequest = ProfileRequest()
                    self.profileRequest.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setWorkerProfiler_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        if self.profileRequest is not None:
            oprot.writeFieldBegin('profileRequest', TType.STRUCT, 2)
            self.profileRequest.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(setWorkerProfiler_args)
setWorkerProfiler_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'profileRequest', [ProfileRequest, None], None, ),  # 2
)


class setWorkerProfiler_result(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setWorkerProfiler_result')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(setWorkerProfiler_result)
setWorkerProfiler_result.thrift_spec = (
)


class getComponentPendingProfileActions_args(object):
    """
    Attributes:
     - id
     - component_id
     - action

    """


    def __init__(self, id=None, component_id=None, action=None,):
        self.id = id
        self.component_id = component_id
        self.action = action

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.component_id = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.action = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getComponentPendingProfileActions_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        if self.component_id is not None:
            oprot.writeFieldBegin('component_id', TType.STRING, 2)
            oprot.writeString(self.component_id.encode('utf-8') if sys.version_info[0] == 2 else self.component_id)
            oprot.writeFieldEnd()
        if self.action is not None:
            oprot.writeFieldBegin('action', TType.I32, 3)
            oprot.writeI32(self.action)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getComponentPendingProfileActions_args)
getComponentPendingProfileActions_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'component_id', 'UTF8', None, ),  # 2
    (3, TType.I32, 'action', None, None, ),  # 3
)


class getComponentPendingProfileActions_result(object):
    """
    Attributes:
     - success

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.LIST:
                    self.success = []
                    (_etype869, _size866) = iprot.readListBegin()
                    for _i870 in range(_size866):
                        _elem871 = ProfileRequest()
                        _elem871.read(iprot)
                        self.success.append(_elem871)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getComponentPendingProfileActions_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter872 in self.success:
                iter872.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getComponentPendingProfileActions_result)
getComponentPendingProfileActions_result.thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT, [ProfileRequest, None], False), None, ),  # 0
)


class uploadNewCredentials_args(object):
    """
    Attributes:
     - name
     - creds

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('uploadNewCredentials_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            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):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(uploadNewCredentials_args)
uploadNewCredentials_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'creds', [Credentials, None], None, ),  # 2
)


class uploadNewCredentials_result(object):
    """
    Attributes:
     - e
     - ite
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ite = InvalidTopologyException()
                    self.ite.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('uploadNewCredentials_result')
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.ite is not None:
            oprot.writeFieldBegin('ite', TType.STRUCT, 2)
            self.ite.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 3)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(uploadNewCredentials_result)
uploadNewCredentials_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'ite', [InvalidTopologyException, None], None, ),  # 2
    (3, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 3
)


class beginCreateBlob_args(object):
    """
    Attributes:
     - key
     - meta

    """


    def __init__(self, key=None, meta=None,):
        self.key = key
        self.meta = meta

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.meta = SettableBlobMeta()
                    self.meta.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginCreateBlob_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        if self.meta is not None:
            oprot.writeFieldBegin('meta', TType.STRUCT, 2)
            self.meta.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginCreateBlob_args)
beginCreateBlob_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'meta', [SettableBlobMeta, None], None, ),  # 2
)


class beginCreateBlob_result(object):
    """
    Attributes:
     - success
     - aze
     - kae

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.kae = KeyAlreadyExistsException()
                    self.kae.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginCreateBlob_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.kae is not None:
            oprot.writeFieldBegin('kae', TType.STRUCT, 2)
            self.kae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginCreateBlob_result)
beginCreateBlob_result.thrift_spec = (
    (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'kae', [KeyAlreadyExistsException, None], None, ),  # 2
)


class beginUpdateBlob_args(object):
    """
    Attributes:
     - key

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginUpdateBlob_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginUpdateBlob_args)
beginUpdateBlob_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
)


class beginUpdateBlob_result(object):
    """
    Attributes:
     - success
     - aze
     - knf

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginUpdateBlob_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginUpdateBlob_result)
beginUpdateBlob_result.thrift_spec = (
    (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
)


class uploadBlobChunk_args(object):
    """
    Attributes:
     - session
     - chunk

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.session = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.chunk = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('uploadBlobChunk_args')
        if self.session is not None:
            oprot.writeFieldBegin('session', TType.STRING, 1)
            oprot.writeString(self.session.encode('utf-8') if sys.version_info[0] == 2 else self.session)
            oprot.writeFieldEnd()
        if self.chunk is not None:
            oprot.writeFieldBegin('chunk', TType.STRING, 2)
            oprot.writeBinary(self.chunk)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(uploadBlobChunk_args)
uploadBlobChunk_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'session', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'chunk', 'BINARY', None, ),  # 2
)


class uploadBlobChunk_result(object):
    """
    Attributes:
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('uploadBlobChunk_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(uploadBlobChunk_result)
uploadBlobChunk_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class finishBlobUpload_args(object):
    """
    Attributes:
     - session

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.session = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('finishBlobUpload_args')
        if self.session is not None:
            oprot.writeFieldBegin('session', TType.STRING, 1)
            oprot.writeString(self.session.encode('utf-8') if sys.version_info[0] == 2 else self.session)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(finishBlobUpload_args)
finishBlobUpload_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'session', 'UTF8', None, ),  # 1
)


class finishBlobUpload_result(object):
    """
    Attributes:
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('finishBlobUpload_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(finishBlobUpload_result)
finishBlobUpload_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class cancelBlobUpload_args(object):
    """
    Attributes:
     - session

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.session = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('cancelBlobUpload_args')
        if self.session is not None:
            oprot.writeFieldBegin('session', TType.STRING, 1)
            oprot.writeString(self.session.encode('utf-8') if sys.version_info[0] == 2 else self.session)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(cancelBlobUpload_args)
cancelBlobUpload_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'session', 'UTF8', None, ),  # 1
)


class cancelBlobUpload_result(object):
    """
    Attributes:
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('cancelBlobUpload_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(cancelBlobUpload_result)
cancelBlobUpload_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getBlobMeta_args(object):
    """
    Attributes:
     - key

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getBlobMeta_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getBlobMeta_args)
getBlobMeta_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
)


class getBlobMeta_result(object):
    """
    Attributes:
     - success
     - aze
     - knf

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = ReadableBlobMeta()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getBlobMeta_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getBlobMeta_result)
getBlobMeta_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [ReadableBlobMeta, None], None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
)


class setBlobMeta_args(object):
    """
    Attributes:
     - key
     - meta

    """


    def __init__(self, key=None, meta=None,):
        self.key = key
        self.meta = meta

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.meta = SettableBlobMeta()
                    self.meta.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setBlobMeta_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        if self.meta is not None:
            oprot.writeFieldBegin('meta', TType.STRUCT, 2)
            self.meta.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(setBlobMeta_args)
setBlobMeta_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'meta', [SettableBlobMeta, None], None, ),  # 2
)


class setBlobMeta_result(object):
    """
    Attributes:
     - aze
     - knf

    """


    def __init__(self, aze=None, knf=None,):
        self.aze = aze
        self.knf = knf

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setBlobMeta_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(setBlobMeta_result)
setBlobMeta_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
)


class beginBlobDownload_args(object):
    """
    Attributes:
     - key

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginBlobDownload_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginBlobDownload_args)
beginBlobDownload_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
)


class beginBlobDownload_result(object):
    """
    Attributes:
     - success
     - aze
     - knf

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = BeginDownloadResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginBlobDownload_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginBlobDownload_result)
beginBlobDownload_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [BeginDownloadResult, None], None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
)


class downloadBlobChunk_args(object):
    """
    Attributes:
     - session

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.session = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('downloadBlobChunk_args')
        if self.session is not None:
            oprot.writeFieldBegin('session', TType.STRING, 1)
            oprot.writeString(self.session.encode('utf-8') if sys.version_info[0] == 2 else self.session)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(downloadBlobChunk_args)
downloadBlobChunk_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'session', 'UTF8', None, ),  # 1
)


class downloadBlobChunk_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('downloadBlobChunk_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeBinary(self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(downloadBlobChunk_result)
downloadBlobChunk_result.thrift_spec = (
    (0, TType.STRING, 'success', 'BINARY', None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class deleteBlob_args(object):
    """
    Attributes:
     - key

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('deleteBlob_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(deleteBlob_args)
deleteBlob_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
)


class deleteBlob_result(object):
    """
    Attributes:
     - aze
     - knf
     - ise

    """


    def __init__(self, aze=None, knf=None, ise=None,):
        self.aze = aze
        self.knf = knf
        self.ise = ise

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRUCT:
                    self.ise = IllegalStateException()
                    self.ise.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('deleteBlob_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        if self.ise is not None:
            oprot.writeFieldBegin('ise', TType.STRUCT, 3)
            self.ise.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(deleteBlob_result)
deleteBlob_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
    (3, TType.STRUCT, 'ise', [IllegalStateException, None], None, ),  # 3
)


class listBlobs_args(object):
    """
    Attributes:
     - session

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.session = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('listBlobs_args')
        if self.session is not None:
            oprot.writeFieldBegin('session', TType.STRING, 1)
            oprot.writeString(self.session.encode('utf-8') if sys.version_info[0] == 2 else self.session)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(listBlobs_args)
listBlobs_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'session', 'UTF8', None, ),  # 1
)


class listBlobs_result(object):
    """
    Attributes:
     - success

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = ListBlobsResult()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('listBlobs_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(listBlobs_result)
listBlobs_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [ListBlobsResult, None], None, ),  # 0
)


class getBlobReplication_args(object):
    """
    Attributes:
     - key

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getBlobReplication_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getBlobReplication_args)
getBlobReplication_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
)


class getBlobReplication_result(object):
    """
    Attributes:
     - success
     - aze
     - knf

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.I32:
                    self.success = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getBlobReplication_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.I32, 0)
            oprot.writeI32(self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getBlobReplication_result)
getBlobReplication_result.thrift_spec = (
    (0, TType.I32, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
)


class updateBlobReplication_args(object):
    """
    Attributes:
     - key
     - replication

    """


    def __init__(self, key=None, replication=None,):
        self.key = key
        self.replication = replication

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.replication = iprot.readI32()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('updateBlobReplication_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        if self.replication is not None:
            oprot.writeFieldBegin('replication', TType.I32, 2)
            oprot.writeI32(self.replication)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(updateBlobReplication_args)
updateBlobReplication_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
    (2, TType.I32, 'replication', None, None, ),  # 2
)


class updateBlobReplication_result(object):
    """
    Attributes:
     - success
     - aze
     - knf

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.I32:
                    self.success = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.knf = KeyNotFoundException()
                    self.knf.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('updateBlobReplication_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.I32, 0)
            oprot.writeI32(self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.knf is not None:
            oprot.writeFieldBegin('knf', TType.STRUCT, 2)
            self.knf.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(updateBlobReplication_result)
updateBlobReplication_result.thrift_spec = (
    (0, TType.I32, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'knf', [KeyNotFoundException, None], None, ),  # 2
)


class createStateInZookeeper_args(object):
    """
    Attributes:
     - key

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.key = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('createStateInZookeeper_args')
        if self.key is not None:
            oprot.writeFieldBegin('key', TType.STRING, 1)
            oprot.writeString(self.key.encode('utf-8') if sys.version_info[0] == 2 else self.key)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(createStateInZookeeper_args)
createStateInZookeeper_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'key', 'UTF8', None, ),  # 1
)


class createStateInZookeeper_result(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('createStateInZookeeper_result')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(createStateInZookeeper_result)
createStateInZookeeper_result.thrift_spec = (
)


class beginFileUpload_args(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginFileUpload_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginFileUpload_args)
beginFileUpload_args.thrift_spec = (
)


class beginFileUpload_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('beginFileUpload_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(beginFileUpload_result)
beginFileUpload_result.thrift_spec = (
    (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class uploadChunk_args(object):
    """
    Attributes:
     - location
     - chunk

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.chunk = iprot.readBinary()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('uploadChunk_args')
        if self.location is not None:
            oprot.writeFieldBegin('location', TType.STRING, 1)
            oprot.writeString(self.location.encode('utf-8') if sys.version_info[0] == 2 else self.location)
            oprot.writeFieldEnd()
        if self.chunk is not None:
            oprot.writeFieldBegin('chunk', TType.STRING, 2)
            oprot.writeBinary(self.chunk)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(uploadChunk_args)
uploadChunk_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'location', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'chunk', 'BINARY', None, ),  # 2
)


class uploadChunk_result(object):
    """
    Attributes:
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('uploadChunk_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(uploadChunk_result)
uploadChunk_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class finishFileUpload_args(object):
    """
    Attributes:
     - location

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('finishFileUpload_args')
        if self.location is not None:
            oprot.writeFieldBegin('location', TType.STRING, 1)
            oprot.writeString(self.location.encode('utf-8') if sys.version_info[0] == 2 else self.location)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(finishFileUpload_args)
finishFileUpload_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'location', 'UTF8', None, ),  # 1
)


class finishFileUpload_result(object):
    """
    Attributes:
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('finishFileUpload_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(finishFileUpload_result)
finishFileUpload_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class downloadChunk_args(object):
    """
    Attributes:
     - id

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('downloadChunk_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(downloadChunk_args)
downloadChunk_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
)


class downloadChunk_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.readBinary()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('downloadChunk_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeBinary(self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(downloadChunk_result)
downloadChunk_result.thrift_spec = (
    (0, TType.STRING, 'success', 'BINARY', None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getNimbusConf_args(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getNimbusConf_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getNimbusConf_args)
getNimbusConf_args.thrift_spec = (
)


class getNimbusConf_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getNimbusConf_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getNimbusConf_result)
getNimbusConf_result.thrift_spec = (
    (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getClusterInfo_args(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getClusterInfo_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getClusterInfo_args)
getClusterInfo_args.thrift_spec = (
)


class getClusterInfo_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getClusterInfo_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getClusterInfo_result)
getClusterInfo_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [ClusterSummary, None], None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getLeader_args(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getLeader_args')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getLeader_args)
getLeader_args.thrift_spec = (
)


class getLeader_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = NimbusSummary()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getLeader_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getLeader_result)
getLeader_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [NimbusSummary, None], None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class isTopologyNameAllowed_args(object):
    """
    Attributes:
     - name

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isTopologyNameAllowed_args')
        if self.name is not None:
            oprot.writeFieldBegin('name', TType.STRING, 1)
            oprot.writeString(self.name.encode('utf-8') if sys.version_info[0] == 2 else self.name)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(isTopologyNameAllowed_args)
isTopologyNameAllowed_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'name', 'UTF8', None, ),  # 1
)


class isTopologyNameAllowed_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isTopologyNameAllowed_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(isTopologyNameAllowed_result)
isTopologyNameAllowed_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getTopologyInfo_args(object):
    """
    Attributes:
     - id

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyInfo_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyInfo_args)
getTopologyInfo_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
)


class getTopologyInfo_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyInfo_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyInfo_result)
getTopologyInfo_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [TopologyInfo, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getTopologyInfoWithOpts_args(object):
    """
    Attributes:
     - id
     - options

    """


    def __init__(self, id=None, options=None,):
        self.id = id
        self.options = options

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.options = GetInfoOptions()
                    self.options.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyInfoWithOpts_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        if self.options is not None:
            oprot.writeFieldBegin('options', TType.STRUCT, 2)
            self.options.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyInfoWithOpts_args)
getTopologyInfoWithOpts_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
    (2, TType.STRUCT, 'options', [GetInfoOptions, None], None, ),  # 2
)


class getTopologyInfoWithOpts_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyInfoWithOpts_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyInfoWithOpts_result)
getTopologyInfoWithOpts_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [TopologyInfo, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getTopologyPageInfo_args(object):
    """
    Attributes:
     - id
     - window
     - is_include_sys

    """


    def __init__(self, id=None, window=None, is_include_sys=None,):
        self.id = id
        self.window = window
        self.is_include_sys = is_include_sys

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.window = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.BOOL:
                    self.is_include_sys = iprot.readBool()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyPageInfo_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        if self.window is not None:
            oprot.writeFieldBegin('window', TType.STRING, 2)
            oprot.writeString(self.window.encode('utf-8') if sys.version_info[0] == 2 else self.window)
            oprot.writeFieldEnd()
        if self.is_include_sys is not None:
            oprot.writeFieldBegin('is_include_sys', TType.BOOL, 3)
            oprot.writeBool(self.is_include_sys)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyPageInfo_args)
getTopologyPageInfo_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'window', 'UTF8', None, ),  # 2
    (3, TType.BOOL, 'is_include_sys', None, None, ),  # 3
)


class getTopologyPageInfo_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = TopologyPageInfo()
                    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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyPageInfo_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyPageInfo_result)
getTopologyPageInfo_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [TopologyPageInfo, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getSupervisorPageInfo_args(object):
    """
    Attributes:
     - id
     - host
     - is_include_sys

    """


    def __init__(self, id=None, host=None, is_include_sys=None,):
        self.id = id
        self.host = host
        self.is_include_sys = is_include_sys

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.host = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.BOOL:
                    self.is_include_sys = iprot.readBool()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getSupervisorPageInfo_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        if self.host is not None:
            oprot.writeFieldBegin('host', TType.STRING, 2)
            oprot.writeString(self.host.encode('utf-8') if sys.version_info[0] == 2 else self.host)
            oprot.writeFieldEnd()
        if self.is_include_sys is not None:
            oprot.writeFieldBegin('is_include_sys', TType.BOOL, 3)
            oprot.writeBool(self.is_include_sys)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getSupervisorPageInfo_args)
getSupervisorPageInfo_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'host', 'UTF8', None, ),  # 2
    (3, TType.BOOL, 'is_include_sys', None, None, ),  # 3
)


class getSupervisorPageInfo_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = SupervisorPageInfo()
                    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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getSupervisorPageInfo_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getSupervisorPageInfo_result)
getSupervisorPageInfo_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [SupervisorPageInfo, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getComponentPageInfo_args(object):
    """
    Attributes:
     - topology_id
     - component_id
     - window
     - is_include_sys

    """


    def __init__(self, topology_id=None, component_id=None, window=None, is_include_sys=None,):
        self.topology_id = topology_id
        self.component_id = component_id
        self.window = window
        self.is_include_sys = is_include_sys

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.topology_id = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.component_id = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.window = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.BOOL:
                    self.is_include_sys = iprot.readBool()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getComponentPageInfo_args')
        if self.topology_id is not None:
            oprot.writeFieldBegin('topology_id', TType.STRING, 1)
            oprot.writeString(self.topology_id.encode('utf-8') if sys.version_info[0] == 2 else self.topology_id)
            oprot.writeFieldEnd()
        if self.component_id is not None:
            oprot.writeFieldBegin('component_id', TType.STRING, 2)
            oprot.writeString(self.component_id.encode('utf-8') if sys.version_info[0] == 2 else self.component_id)
            oprot.writeFieldEnd()
        if self.window is not None:
            oprot.writeFieldBegin('window', TType.STRING, 3)
            oprot.writeString(self.window.encode('utf-8') if sys.version_info[0] == 2 else self.window)
            oprot.writeFieldEnd()
        if self.is_include_sys is not None:
            oprot.writeFieldBegin('is_include_sys', TType.BOOL, 4)
            oprot.writeBool(self.is_include_sys)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getComponentPageInfo_args)
getComponentPageInfo_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'topology_id', 'UTF8', None, ),  # 1
    (2, TType.STRING, 'component_id', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'window', 'UTF8', None, ),  # 3
    (4, TType.BOOL, 'is_include_sys', None, None, ),  # 4
)


class getComponentPageInfo_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = ComponentPageInfo()
                    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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getComponentPageInfo_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getComponentPageInfo_result)
getComponentPageInfo_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [ComponentPageInfo, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getTopologyConf_args(object):
    """
    Attributes:
     - id

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyConf_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyConf_args)
getTopologyConf_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
)


class getTopologyConf_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.e = NotAliveException()
                    self.e.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyConf_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRING, 0)
            oprot.writeString(self.success.encode('utf-8') if sys.version_info[0] == 2 else self.success)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyConf_result)
getTopologyConf_result.thrift_spec = (
    (0, TType.STRING, 'success', 'UTF8', None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getTopology_args(object):
    """
    Attributes:
     - id

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopology_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopology_args)
getTopology_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
)


class getTopology_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopology_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopology_result)
getTopology_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [StormTopology, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getUserTopology_args(object):
    """
    Attributes:
     - id

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUserTopology_args')
        if self.id is not None:
            oprot.writeFieldBegin('id', TType.STRING, 1)
            oprot.writeString(self.id.encode('utf-8') if sys.version_info[0] == 2 else self.id)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getUserTopology_args)
getUserTopology_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'id', 'UTF8', None, ),  # 1
)


class getUserTopology_result(object):
    """
    Attributes:
     - success
     - e
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUserTopology_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 1)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 2)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getUserTopology_result)
getUserTopology_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [StormTopology, None], None, ),  # 0
    (1, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 1
    (2, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 2
)


class getTopologyHistory_args(object):
    """
    Attributes:
     - user

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.user = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyHistory_args')
        if self.user is not None:
            oprot.writeFieldBegin('user', TType.STRING, 1)
            oprot.writeString(self.user.encode('utf-8') if sys.version_info[0] == 2 else self.user)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyHistory_args)
getTopologyHistory_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'user', 'UTF8', None, ),  # 1
)


class getTopologyHistory_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = TopologyHistoryInfo()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getTopologyHistory_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getTopologyHistory_result)
getTopologyHistory_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [TopologyHistoryInfo, None], None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getOwnerResourceSummaries_args(object):
    """
    Attributes:
     - owner

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.owner = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getOwnerResourceSummaries_args')
        if self.owner is not None:
            oprot.writeFieldBegin('owner', TType.STRING, 1)
            oprot.writeString(self.owner.encode('utf-8') if sys.version_info[0] == 2 else self.owner)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getOwnerResourceSummaries_args)
getOwnerResourceSummaries_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'owner', 'UTF8', None, ),  # 1
)


class getOwnerResourceSummaries_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.LIST:
                    self.success = []
                    (_etype876, _size873) = iprot.readListBegin()
                    for _i877 in range(_size873):
                        _elem878 = OwnerResourceSummary()
                        _elem878.read(iprot)
                        self.success.append(_elem878)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getOwnerResourceSummaries_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter879 in self.success:
                iter879.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getOwnerResourceSummaries_result)
getOwnerResourceSummaries_result.thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT, [OwnerResourceSummary, None], False), None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class getSupervisorAssignments_args(object):
    """
    Attributes:
     - node

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.node = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getSupervisorAssignments_args')
        if self.node is not None:
            oprot.writeFieldBegin('node', TType.STRING, 1)
            oprot.writeString(self.node.encode('utf-8') if sys.version_info[0] == 2 else self.node)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getSupervisorAssignments_args)
getSupervisorAssignments_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'node', 'UTF8', None, ),  # 1
)


class getSupervisorAssignments_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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 = SupervisorAssignments()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getSupervisorAssignments_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(getSupervisorAssignments_result)
getSupervisorAssignments_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [SupervisorAssignments, None], None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class sendSupervisorWorkerHeartbeats_args(object):
    """
    Attributes:
     - heartbeats

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.heartbeats = SupervisorWorkerHeartbeats()
                    self.heartbeats.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('sendSupervisorWorkerHeartbeats_args')
        if self.heartbeats is not None:
            oprot.writeFieldBegin('heartbeats', TType.STRUCT, 1)
            self.heartbeats.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(sendSupervisorWorkerHeartbeats_args)
sendSupervisorWorkerHeartbeats_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'heartbeats', [SupervisorWorkerHeartbeats, None], None, ),  # 1
)


class sendSupervisorWorkerHeartbeats_result(object):
    """
    Attributes:
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('sendSupervisorWorkerHeartbeats_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(sendSupervisorWorkerHeartbeats_result)
sendSupervisorWorkerHeartbeats_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)


class sendSupervisorWorkerHeartbeat_args(object):
    """
    Attributes:
     - heatbeat

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.heatbeat = SupervisorWorkerHeartbeat()
                    self.heatbeat.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('sendSupervisorWorkerHeartbeat_args')
        if self.heatbeat is not None:
            oprot.writeFieldBegin('heatbeat', TType.STRUCT, 1)
            self.heatbeat.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(sendSupervisorWorkerHeartbeat_args)
sendSupervisorWorkerHeartbeat_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'heatbeat', [SupervisorWorkerHeartbeat, None], None, ),  # 1
)


class sendSupervisorWorkerHeartbeat_result(object):
    """
    Attributes:
     - aze
     - e

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('sendSupervisorWorkerHeartbeat_result')
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        if self.e is not None:
            oprot.writeFieldBegin('e', TType.STRUCT, 2)
            self.e.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(sendSupervisorWorkerHeartbeat_result)
sendSupervisorWorkerHeartbeat_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
    (2, TType.STRUCT, 'e', [NotAliveException, None], None, ),  # 2
)


class processWorkerMetrics_args(object):
    """
    Attributes:
     - metrics

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.metrics = WorkerMetrics()
                    self.metrics.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('processWorkerMetrics_args')
        if self.metrics is not None:
            oprot.writeFieldBegin('metrics', TType.STRUCT, 1)
            self.metrics.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(processWorkerMetrics_args)
processWorkerMetrics_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'metrics', [WorkerMetrics, None], None, ),  # 1
)


class processWorkerMetrics_result(object):


    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('processWorkerMetrics_result')
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(processWorkerMetrics_result)
processWorkerMetrics_result.thrift_spec = (
)


class isRemoteBlobExists_args(object):
    """
    Attributes:
     - blobKey

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.blobKey = iprot.readString().decode('utf-8') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isRemoteBlobExists_args')
        if self.blobKey is not None:
            oprot.writeFieldBegin('blobKey', TType.STRING, 1)
            oprot.writeString(self.blobKey.encode('utf-8') if sys.version_info[0] == 2 else self.blobKey)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(isRemoteBlobExists_args)
isRemoteBlobExists_args.thrift_spec = (
    None,  # 0
    (1, TType.STRING, 'blobKey', 'UTF8', None, ),  # 1
)


class isRemoteBlobExists_result(object):
    """
    Attributes:
     - success
     - aze

    """


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

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [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.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.aze = AuthorizationException()
                    self.aze.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isRemoteBlobExists_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.aze is not None:
            oprot.writeFieldBegin('aze', TType.STRUCT, 1)
            self.aze.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        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)
all_structs.append(isRemoteBlobExists_result)
isRemoteBlobExists_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'aze', [AuthorizationException, None], None, ),  # 1
)
fix_spec(all_structs)
del all_structs

