#!/usr/bin/env python

import requests
import requests.exceptions
import inspect
import time
import json
import cluster_common
from requests_scripts.requests_helper import *

def cdc_get_endpoint(ipport):
    return "http://"+ipport+"/kunlun_cdc"

def cdc_get_reqbase(job_type):
    return {
            "version": "1.0",
            "job_id": "",
            "job_type": job_type,
            "timestamp": "%s" % str(time.time()),
            "user_name": "super_dba",
            "paras": {}
            }

def cdc_send_request(url, json_obj, asjson=False, maxtry=10, debug=False):
    reqdata = json.dumps(json_obj, indent=4)
    #current_frame = inspect.currentframe()
    #func_name = inspect.getouterframes(current_frame)[1][3]
    i = 0
    while i < maxtry:
        try:
            rep = requests.post(url, data=reqdata)
            if rep.ok:
                #if debug:
                #   print('debug info(%s): ' % func_name + r.text)
                if asjson:
                    return rep.json()
                else:
                    return rep.text
        except requests.exceptions.RequestException as ex:
            pass
        time.sleep(10)
        i += 1
    return None

# The return is like, so the ipport is repobj['attachment']['ipPort']:
'''
'{
    "attachment":{"serverId":"1","ipPort":"192.168.0.15:19701"},
    "version":"1.0","error_code":"0","error_info":"Ok","status":"Done"
}'
'''
def cdc_get_leader(url):
    json_obj = cdc_get_reqbase("get_leader")
    return cdc_send_request(url, json_obj, True)

# return the ip:port if success, and return None if fail or not found primary.
def cdc_get_url_from_seeds(cdcseeds):
    if cdcseeds == "":
        return None
    cdclist=cdcseeds.split(",")
    for u in cdclist:
        u = cdc_get_endpoint(u)
        repobj = cdc_get_leader(u)
        if repobj is None:
            continue
        if repobj['error_code'] == '0':
            return u
    return None

def cdc_get_url_from_config(jscfg):
    if 'cdc' not in jscfg:
        return None
    seedlist = []
    for node in jscfg['cdc']['nodes']:
        seedlist.append("%s:%s" % (node['ip'], str(node['http_port'])))
    return cdc_get_url_from_seeds(",".join(seedlist))

# the return is like
'''
{
    'attachment': 'event_file,event_sql,parallel_sql,event_kafka,event_es,event_mongodb,event_rabbitmq,event_tdengine,event_redis', 
    'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'
}
'''
def cdc_list_support_plugins(url):
    json_obj = cdc_get_reqbase("list_support_plugins")
    return cdc_send_request(url, json_obj, True)

# the return is like:
'''
{
    'attachment': [
        {'dump_db_type': '0', 'metadb': '192.168.0.16:3306', 'meta_user': 'cdcuser', 'meta_passwd': 
        'cdcpasswd', 'dump_tables': 'cdcdb.*', 'is_kunlun': '1', 'cluster_name': 'mysql', 'job_id': '1', 
        'output_plugins': [
            {'plugin_name': 'event_sql', 
                'plugin_param': 
                    '{"hostaddr": "192.168.0.110", "port": "47002", "user": "abc", 
                    "password": "abc", "state_schema": "cdcdb", "state_table": "kunlun_cdc_dump_table", 
                    "log_path": "../log/", "is_kunlun": "1"}', 
                'udf_name': 'event_sql_log_file'
            }
        ]
        }
        ], 
    'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'}
'''
def cdc_list_dump_jobs(url):
    json_obj = cdc_get_reqbase("list_dump_jobs")
    return cdc_send_request(url, json_obj, True)

# the return is like
'''
{
    'attachment': {
        'dump_binlog': {
            'allow_dump_shard_master': '0', 'dump_shard_max_delay': '1800', 'query_shard_state_interval': '10', 
            'report_cdc_sync_state_interval': '5', 'pending_binlog_event_num': '1000', 'dump_mode': 'shard',
            'binlog_event_queue_len': '4096', 'reserve_binlog_log_dir': '../data/reserve_dir'
            }, 
        'cdc_ha': {'group_member': '192.168.0.15:19702', 'data_dir': '../data/paxosdata', 'log_dir': '../data/paxoslog'}
    }, 
    'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'
}
'''
def cdc_list_cdc_conf(url):
    json_obj = cdc_get_reqbase("list_cdc_conf")
    return cdc_send_request(url, json_obj, True)

# this is the running state of the job
# there are threads for the job, and this 
# returns the jobs
def cdc_get_job_state(url, metadb, cluster_name, dump_tables):
    json_obj = cdc_get_reqbase("get_job_state")
    json_obj['paras'] = {
            "meta_db": metadb,
            "cluster_name": cluster_name,
            "dump_tables": dump_tables
            }
    return cdc_send_request(url, json_obj, True)

# this is the state for the job creating, when it is created, and the 
# thread for the job is setup write, it finished.
# The returned repobj is like:
'''
{
    'attachment': {'job_state': 'done', 'err_code': '0', 'err_msg': 'ok'}, 
    'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'
}

{
    'attachment': {'job_state': 'Fail', 'err_code': '80023', 'err_msg': 'cdc server restart to set job failed'}, 
    'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'
}

status can be: creating, ongoing, fail, done, failed
error_info can be: ok, Ok, Done, and the real message
'''
def cdc_get_state(url, job_id):
    json_obj = cdc_get_reqbase("get_state")
    json_obj['job_id'] = str(job_id)
    return cdc_send_request(url, json_obj, True)

def cdc_wait_status_internal(url, job_id, ins, checkNot=False, retry=200):
    cnt=0
    status = None
    while True:
        if cnt > retry:
            print("exceed retry limit %d, quit." % retry)
            return status
        ret = cdc_get_state(url, job_id)
        if 'status' not in ret:
            raise ValueError("bad return:%s" % str(ret))
        status = ret['status']
        if status == 'not_started':
            time.sleep(5)
            cnt=cnt+1
            continue
        if checkNot and status not in ins:
            return status
        if status in ins and not checkNot:
            return status
        time.sleep(5)
        cnt=cnt+1

def cdc_wait_status_until(url, job_id, ins, retries=100):
    return cdc_wait_status_internal(url, job_id, ins, False, retries)

def cdc_wait_status_until_not(url, job_id, ins, retries=100):
    return cdc_wait_status_internal(url, job_id, ins, True, retries)

def cdc_stop_dump_job(url, metadb, cluster_name, dump_tables):
    json_obj = cdc_get_reqbase("stop_dump_job")
    json_obj['paras'] = {
            "meta_db": metadb,
            "cluster_name": cluster_name,
            "dump_tables": dump_tables
            }
    return cdc_send_request(url, json_obj, True)

def cdc_stop_gtid_pos(url, metadb, cluster_name, dump_tables, gtidspos):
    json_obj = cdc_get_reqbase("stop_gtids_pos")
    json_obj['paras'] = {
            "meta_db": metadb,
            "cluster_name": cluster_name,
            "dump_tables": dump_tables,
            "gtids_pos": gtidspos
            }
    return cdc_send_request(url, json_obj, True)

def cdc_start_dispatch_write(url, metadb, cluster_name, dump_tables):
    json_obj = cdc_get_reqbase("start_dispatch_write")
    json_obj['paras'] = {
            "meta_db": metadb,
            "cluster_name": cluster_name,
            "dump_tables": dump_tables
            }
    return cdc_send_request(url, json_obj, True)

def cdc_del_dump_table(url, metadb, cluster_name, dump_tables):
    json_obj = cdc_get_reqbase("del_dump_table")
    json_obj['paras'] = {
            "meta_db": metadb,
            "cluster_name": cluster_name,
            "dump_tables": dump_tables
            }
    return cdc_send_request(url, json_obj, True)

# for various dump adding job, the return is like following:
'''
{'job_id': '1', 'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'}

{'version': '1.0', 'error_code': '80006', 'error_info': 'Http request send follower or learner node, get node state first', 'status': 'Fail'}

'''

# For regular job, the return is like
#   ('0', job_id)
# For error job, the return is like
#   (error_code, error_info)
def cdc_get_jobid(repobj):
    if repobj is None:
        return None
    if repobj['error_code'] == '0':
        return ('0', repobj['job_id'])
    return (repobj['error_code'], repobj['error_info'])

# add_dump_table
# The job state is like:
'''
{   'attachment': [{
        'dump_state': 'all_dump', 'db_type': 'mysql', 
        'sync_state': '{
            "done_dump_tables":"","fail_dump_tables":"","dump_tables":"cdcdb2.*","column_num":"0","sync_sql_num":"0",
            "dump_state":"running","pending_sql_num":"0",
            "dispatch_event_state":[{
                "udf_name":"event_sql_log_file","channel_name":"event_sql",
                "dispatch_result":"error_info_if_there_is_error"}]}'
            }], 
    'version': '1.0', 'error_code': '0', 'error_info': 'Ok', 'status': 'Done'}
'''
def cdc_add_dump_job_mysql_to_kunlun(url, host, port, user,  passwd, tablepat,
        kl_host, kl_port, kl_user, kl_passwd, kl_pgdb, kl_state_schema, kl_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/', is_kunlun="1", need_alldump="1", udf_name="event_sql_log_file"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":"%s:%s" % (host, str(port)),
            "meta_user": user,
            "meta_passwd": passwd,
            "cluster_name": "mysql",
            "dump_db_type": "mysql",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": kl_host,
                        "port": str(kl_port),
                        "user": kl_user,
                        "password": kl_passwd,
                        'database': kl_pgdb,
                        "state_schema": kl_state_schema,
                        "state_table": kl_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": is_kunlun
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

def cdc_add_dump_job_mariadb_to_kunlun(url, host, port, user,  passwd, tablepat,
        kl_host, kl_port, kl_user, kl_passwd, kl_pgdb, kl_state_schema, kl_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/', is_kunlun="1", need_alldump="1", udf_name="event_sql_log_file"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":"%s:%s" % (host, str(port)),
            "meta_user": user,
            "meta_passwd": passwd,
            "cluster_name": "mariadb",
            "dump_db_type": "mariadb",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": kl_host,
                        "port": str(kl_port),
                        "user": kl_user,
                        "password": kl_passwd,
                        'database': kl_pgdb,
                        "state_schema": kl_state_schema,
                        "state_table": kl_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": is_kunlun
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

# The dump list is list of list, the content of sub-list is:
# [full-table-name, condition, first_field_name(timestamp field)], like:
# example:
# cdc_add_dump_job_tdengine_to_kunlun(cdcurl, "192.168.0.21", 6030, "root", "taosdata", 
#     [["device_shenzhen.meter_ef", 'receive_time>=\"2020-01-01 00:00:00.000\"', "receive_time"]],
#   "192.168.0.110", 47002, "abc", "abc", "device_shenzhen")
# notice the time should be query from the db, to select a reasonable range, since it will
# create multiple subscribes from the time specified, one day a subscription.
# The job state is like:
'''
{   'attachment': [{
        'dump_state': 'incr_dump', 'db_type': 'kunlunbase', 'id': 'tdengine',
        'sync_state': '{
            "dump_hostaddr":"192.168.0.21","dump_port":"6030","binlog_file":"","inlog_pos":"0",
            "gtid_set":"device_shenzhen.meter_ef:2025-07-04 14:40:00.000@175161120","sync_sql_num":"84620",
            "dump_state":"running","pending_sql_num":"0","cache_sql_num""0",
            "dispatch_event_states":[
                    [{"udf_name":"event_sql_log_file","channel_name":"event_ql","dispatch_result":"ok"}],
                    [{"udf_name":"event_sql_log_file","channel_name":"event_ql","dispatch_result":"ok"}],
                    [{"udf_name":"event_sql_log_file","channel_name":"event_ql","dispatch_result":"ok"}],
                    [{"udf_name":"event_sql_log_file","channel_name":"event_ql","dispatch_result":"ok"}],
                    [{"udf_name":"event_sql_log_file","channel_name":"event_ql","dispatch_result":"ok"}]
                ]}'
            }], 
    'version': '1.0', 'error_code': '0', 'error_info':'Ok', 'status': 'Done'}
'''
def cdc_add_dump_job_tdengine_to_kunlun(url, host, port, user, passwd, dump_list,
        kl_host, kl_port, kl_user, kl_passwd, kl_pgdb, kl_state_schema, kl_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/', is_kunlun="1", thread_num="5", delay_subscribe_ts="600",
        separator="$$", udf_name="event_sql_log_file"):
    tblist=[]
    shard_params = []
    for item in dump_list:
        tblist.append(item[0])
        shard_params.append({
            "binlog_file": item[0],
            "binlog_pos": item[1],
            "gtid_set": item[2]
            })
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":"%s:%s" % (host, str(port)),
            "meta_user": user,
            "meta_passwd": passwd,
            "cluster_name": "tdengine",
            "dump_db_type": "tdengine",
            "dump_tables": ",".join(tblist),
            "thread_num": "5",
            "delay_subscribe_ts": delay_subscribe_ts,
            "shard_params": shard_params,
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": kl_host,
                        "port": str(kl_port),
                        "user": kl_user,
                        "password": kl_passwd,
                        'database': kl_pgdb,
                        "state_schema": kl_state_schema,
                        "state_table": kl_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": is_kunlun
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

def cdc_add_dump_job_es_to_kunlun(url, host, port, user, passwd, dbname,
        kl_host, kl_port, kl_user, kl_passwd, kl_pgdb, kl_state_schema, kl_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/', is_kunlun="1", separator="$$", udf_name="event_sql_log_file"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":"http://%s:%s" % (host, str(port)),
            "meta_user": user,
            "meta_passwd": passwd,
            "cluster_name": "es_%s" % dbname,
            "dump_db_type": "es",
            "dump_tables": "postgres_%s_%s._doc" % (separator, dbname),
            "shard_params": [
                {
                    "binlog_file": dbname,
                    "binlog_pos": "_doc",
                    "gtid_set": json.dumps({
                            "id":"",
                            "seq_no": 0,
                            "scroll_id": None,
                            "timestamp": int(time.time())
                        })
                    }
                ],
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": kl_host,
                        "port": str(kl_port),
                        "user": kl_user,
                        "password": kl_passwd,
                        'database': kl_pgdb,
                        "state_schema": kl_state_schema,
                        "state_table": kl_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": is_kunlun
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

def cdc_add_dump_job_mongodb_to_kunlun(url, host, port, user, passwd, dbname, tbname,
        kl_host, kl_port, kl_user, kl_passwd, kl_pgdb, kl_state_schema, kl_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/', is_kunlun="1", separator="$$", gtidset="000000000000000000000000",
        udf_name="event_sql_log_file"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":"mongodb://%s:%s" % (host, str(port)),
            "meta_user": user,
            "meta_passwd": passwd,
            "cluster_name": "%s.%s" %(dbname, tbname),
            "dump_db_type": "mongodb",
            "dump_tables": "postgres_%s_%s.%s" % (separator, dbname, tbname),
            "shard_params": [
                {
                    "binlog_file": dbname,
                    "binlog_pos": tbname,
                    "gtid_set": gtidset
                    }
                ],
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": kl_host,
                        "port": str(kl_port),
                        "user": kl_user,
                        "password": kl_passwd,
                        'database': kl_pgdb,
                        "state_schema": kl_state_schema,
                        "state_table": kl_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": is_kunlun
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

def cdc_add_dump_job_kunlun_to_mysql(url, k_metaseeds, k_user,  k_passwd, k_cluster_name, tablepat,
        my_host, my_port, my_user, my_passwd, my_state_schema, my_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/',  need_alldump="1", udf_name="event_sql_log_file"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":str(k_metaseeds),
            "meta_user": k_user,
            "meta_passwd": k_passwd,
            "cluster_name": k_cluster_name,
            "dump_db_type": "kunlunbase",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": my_host,
                        "port": str(my_port),
                        "user": my_user,
                        "password": my_passwd,
                        'database':my_state_schema,
                        "state_schema": my_state_schema,
                        "state_table": my_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": "0"
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

def cdc_add_dump_job_kunlun_to_mariadb(url, k_metaseeds, k_user,  k_passwd, k_cluster_name, tablepat,
        my_host, my_port, my_user, my_passwd, my_state_schema, my_state_table='kunlun_cdc_dump_state',
        cdc_log_path='../log/',  need_alldump="1", udf_name="event_sql_log_file"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":str(k_metaseeds),
            "meta_user": k_user,
            "meta_passwd": k_passwd,
            "cluster_name": k_cluster_name,
            "dump_db_type": "kunlunbase",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_sql",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": my_host,
                        "port": str(my_port),
                        "user": my_user,
                        "password": my_passwd,
                        'database':my_state_schema,
                        "state_schema": my_state_schema,
                        "state_table": my_state_table,
                        "log_path": cdc_log_path,
                        "is_kunlun": "0"
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

## TODO: check udf_name
def cdc_add_dump_job_kunlun_to_tdengine(url, k_metaseeds, k_user,  k_passwd, k_cluster_name, tablepat,
        td_host, td_port, td_user, td_passwd, td_db, sub_tables, remap_rules, cdc_log_path='../log/', need_alldump="1", udf_name="test1"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":str(k_metaseeds),
            "meta_user": k_user,
            "meta_passwd": k_passwd,
            "cluster_name": k_cluster_name,
            "dump_db_type": "kunlunbase",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_tdengine",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "hostaddr": td_host,
                        "port": str(td_port),
                        "user": td_user,
                        "password": td_passwd,
                        "database": td_db,
                        "log_name": "tdengine",
                        "log_path": cdc_log_path,
                        "remap_rules": remap_rules,
                        "sub_tables": sub_tables
                        })
                    }
                ]
            }
    return cdc_send_request(url, json_obj, True)

## TODO: check udf_name
def cdc_add_dump_job_kunlun_to_es(url, k_metaseeds, k_user, k_passwd, k_cluster_name, tablepat,
        es_host, es_port, es_index, es_version,  cdc_log_path='../log/', need_alldump="1", udf_name="test1"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":str(k_metaseeds),
            "meta_user": k_user,
            "meta_passwd": k_passwd,
            "cluster_name": k_cluster_name,
            "dump_db_type": "kunlunbase",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_es",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "es_url": "%s:%s" % (es_host, str(es_port)),
                        "es_index": es_index,
                        "es_version": es_version,
                        "log_path": cdc_log_path,
                        "log_name": "es"
                        })
                    }
                ],
            "hex_blob":"0",
            "skip_escape_str":"1"
            }
    return cdc_send_request(url, json_obj, True)

## TODO: check udf_name
def cdc_add_dump_job_kunlun_to_mongo(url, k_metaseeds, k_user, k_passwd, k_cluster_name, tablepat,
        mg_host, mg_port, mg_user, mg_pass, mg_db, cdc_log_path='../log/', need_alldump="1", udf_name="test1"):
    json_obj = cdc_get_reqbase("add_dump_table")
    json_obj['paras'] = {
            "meta_db":str(k_metaseeds),
            "meta_user": k_user,
            "meta_passwd": k_passwd,
            "cluster_name": k_cluster_name,
            "dump_db_type": "kunlunbase",
            "dump_tables": tablepat,
            "need_alldump": need_alldump,
            "output_plugins": [
                {
                    "plugin_name": "event_mongodb",
                    "udf_name": udf_name,
                    "plugin_param": json.dumps({
                        "mongo_url": "%s:%s" % (mg_host, str(mg_port)),
                        "mongo_user": mg_user,
                        "mongo_passwd": mg_pass,
                        "mongo_database": mg_db,
                        "log_path": cdc_log_path,
                        "log_name": "mongodb"
                        })
                    }
                ],
            "hex_blob":"0",
            "skip_escape_str":"1"
            }
    return cdc_send_request(url, json_obj, True)


##################################################
# util functions
##################################################
def cdc_show_all_jobs(cdcurl):
    repobj = cdc_list_dump_jobs(cdcurl)
    if repobj is None or 'attachment' not in repobj:
        print("jobs can not be shown!")
        return None
    jobs = repobj['attachment']
    for job in jobs:
        print("job: " + str(job))
        jobobj = cdc_get_job_state(cdcurl, job['metadb'], job['cluster_name'], job['dump_tables'])
        print("job state: " + str(jobobj))
    return jobs

def cdc_wait_leader(cdcurl, seconds=30):
    repobj = cdc_get_leader(cdcurl)
    rcode = repobj['error_code']
    if rcode != '0' or 'attachment' not in repobj or 'ipPort' not in repobj['attachment']:
        time.sleep(seconds)
