# -*- coding: utf-8 -*-
# This file is auto-generated, don't edit it. Thanks.
from Tea.model import TeaModel


class ConfigureDtsJobRequest(TeaModel):
    def __init__(self, checkpoint=None, data_check_configure=None, data_initialization=None,
                 data_synchronization=None, db_list=None, dedicated_cluster_id=None, delay_notice=None, delay_phone=None,
                 delay_rule_time=None, destination_endpoint_data_base_name=None, destination_endpoint_engine_name=None,
                 destination_endpoint_ip=None, destination_endpoint_instance_id=None, destination_endpoint_instance_type=None,
                 destination_endpoint_oracle_sid=None, destination_endpoint_owner_id=None, destination_endpoint_password=None,
                 destination_endpoint_port=None, destination_endpoint_region=None, destination_endpoint_role=None,
                 destination_endpoint_user_name=None, disaster_recovery_job=None, dts_bis_label=None, dts_instance_id=None, dts_job_id=None,
                 dts_job_name=None, error_notice=None, error_phone=None, file_oss_url=None, job_type=None, owner_id=None,
                 region_id=None, reserve=None, source_endpoint_database_name=None, source_endpoint_engine_name=None,
                 source_endpoint_ip=None, source_endpoint_instance_id=None, source_endpoint_instance_type=None,
                 source_endpoint_oracle_sid=None, source_endpoint_owner_id=None, source_endpoint_password=None, source_endpoint_port=None,
                 source_endpoint_region=None, source_endpoint_role=None, source_endpoint_user_name=None, source_endpoint_vswitch_id=None,
                 structure_initialization=None, synchronization_direction=None):
        # The type of the task. Valid values:
        # 
        # *   **MIGRATION**: data migration task
        # *   **SYNC**: data synchronization task
        self.checkpoint = checkpoint  # type: str
        # The HTTP status code.
        self.data_check_configure = data_check_configure  # type: str
        # The objects that you want to migrate or synchronize. The value is a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        self.data_initialization = data_initialization  # type: bool
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to add more configurations of the source or destination instance to the DTS task. For example, you can specify the data storage format of the destination Kafka database and the ID of the CEN instance. For more information, see [Reserve](~~273111~~).
        self.data_synchronization = data_synchronization  # type: bool
        # The start offset of incremental data migration or synchronization. The value is a UNIX timestamp. Unit: seconds.
        self.db_list = db_list  # type: str
        # The data verification task for a data migration or synchronization instance. The value is a JSON string that indicates parameter limits or alert configurations. For more information, see [DataCheckConfigure](~~459023~~).
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # Specifies whether to monitor the task status. Valid values:
        # 
        # *   **true**: monitors the task status.
        # *   **false**: does not monitor the task status.
        self.delay_notice = delay_notice  # type: bool
        # Specifies whether to monitor the task latency. Valid values:
        # 
        # *   **true**: monitors the task latency.
        # *   **false**: does not monitor the task latency.
        self.delay_phone = delay_phone  # type: str
        # The mobile numbers that receive status-related alerts. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile numbers in the Chinese mainland are supported. Up to 10 mobile numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.delay_rule_time = delay_rule_time  # type: long
        # The password of the destination database account.
        # 
        # >  If the destination database is a MaxCompute project, you must specify the AccessKey secret of your Alibaba Cloud account. For information about how to obtain your AccessKey pair, see [Create an AccessKey pair](~~116401~~).
        self.destination_endpoint_data_base_name = destination_endpoint_data_base_name  # type: str
        # The IP address of the destination instance.
        # 
        # >  If the **DestinationEndpointInstanceType** parameter is set to **OTHER**, **EXPRESS**, **DG**, or **CEN**, this parameter is available and required.
        self.destination_endpoint_engine_name = destination_endpoint_engine_name  # type: str
        # The name of the database to which the objects migrated to the destination instance belong.
        # 
        # > 
        # *   If the destination instance is a PolarDB for Oracle cluster, an AnalyticDB for PostgreSQL instance, a PostgreSQL database, a MaxCompute project, or a MongoDB database, this parameter is available and required.
        # *   If the destination instance is a MaxCompute project, you must specify the ID of the MaxCompute project.
        self.destination_endpoint_ip = destination_endpoint_ip  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the destination instance is an Alibaba Cloud database instance, this parameter is required.
        self.destination_endpoint_instance_id = destination_endpoint_instance_id  # type: str
        # The database engine of the destination instance. Valid values:
        # 
        # *   **MySQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **MARIADB**: ApsaraDB RDS for MariaDB instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **POLARDB_O**: PolarDB for Oracle cluster
        # *   **POLARDBX10**: PolarDB-X 1.0 instance
        # *   **POLARDBX20**: PolarDB-X 2.0 instance
        # *   **ORACLE**: self-managed Oracle database
        # *   **POSTGRESQL**: ApsaraDB RDS for PostgreSQL instance or self-managed PostgreSQL database
        # *   **MSSQL**: ApsaraDB RDS for SQL Server instance or self-managed SQL Server database
        # *   **ADS**: AnalyticDB for MySQL V2.0 cluster
        # *   **ADB30**: AnalyticDB for MySQL V3.0 cluster
        # *   **MONGODB**: ApsaraDB for MongoDB instance or self-managed MongoDB database
        # *   **GREENPLUM**: AnalyticDB for PostgreSQL instance
        # *   **KAFKA**: Message Queue for Apache Kafka instance or self-managed Kafka cluster
        # *   **DATAHUB**: DataHub project
        # *   **DB2**: self-managed Db2 for LUW database
        # *   **AS400**: self-managed Db2 for i database
        # *   **ODPS**: MaxCompute project
        # *   **Tablestore**: Tablestore instance
        # *   **ELK**: Elasticsearch cluster
        # *   **REDIS**: ApsaraDB for Redis instance or self-managed Redis database
        # 
        # > 
        # *   Default value: **MYSQL**.
        # *   If the DestinationEndpointEngineName parameter is set to **KAFKA**, **MONGODB**, or **PolarDB**, you must also specify the database information in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.destination_endpoint_instance_type = destination_endpoint_instance_type  # type: str
        # The ID of the data migration or synchronization task.
        # 
        # >  You must specify at least one of the DtsJobId and **DtsInstanceId** parameters. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.destination_endpoint_oracle_sid = destination_endpoint_oracle_sid  # type: str
        self.destination_endpoint_owner_id = destination_endpoint_owner_id  # type: str
        # Specifies whether to perform full data migration or synchronization. Default value: true. Valid values:
        # 
        # *   **true**: performs full data migration or synchronization.
        # *   **false**: does not perform full data migration or synchronization.
        self.destination_endpoint_password = destination_endpoint_password  # type: str
        # The database account of the destination database.
        # 
        # > 
        # *   In most cases, this parameter is required.
        # *   The permissions that are required for the database account vary with the migration or synchronization scenario. For more information, see [Prepare the database accounts for data migration](~~175878~~) or [Prepare the database accounts for data synchronization](~~213152~~).
        # *   If the destination database is a MaxCompute project, you must specify the AccessKey ID of your Alibaba Cloud account. For information about how to obtain your AccessKey pair, see [Create an AccessKey pair](~~116401~~).
        self.destination_endpoint_port = destination_endpoint_port  # type: str
        # The database service port of the destination instance.
        # 
        # >  If the destination instance is a self-managed database, this parameter is available and required.
        self.destination_endpoint_region = destination_endpoint_region  # type: str
        self.destination_endpoint_role = destination_endpoint_role  # type: str
        # Specifies whether to perform schema migration or synchronization. Default value: true. Valid values:
        # 
        # *   **true**: performs schema migration or synchronization.
        # *   **false**: does not perform schema migration or synchronization.
        self.destination_endpoint_user_name = destination_endpoint_user_name  # type: str
        # The ID of the request.
        self.disaster_recovery_job = disaster_recovery_job  # type: bool
        self.dts_bis_label = dts_bis_label  # type: str
        # The threshold for triggering latency-related alerts. Unit: seconds. The value must be an integer. You can set the threshold based on your business needs. To prevent jitters caused by network and database overloads, we recommend that you set the threshold to more than 10 seconds.
        # 
        # >  If the **DelayNotice** parameter is set to **true**, this parameter is required.
        self.dts_instance_id = dts_instance_id  # type: str
        # The mobile numbers that receive latency-related alerts. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile numbers in the Chinese mainland are supported. Up to 10 mobile numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the source instance.
        # 
        # If the source instance is an Alibaba Cloud database instance, you must specify the ID of the database instance. For example, if the source instance is an ApsaraDB RDS for MySQL instance, you must specify the ID of the ApsaraDB RDS for MySQL instance.
        # 
        # If the source instance is a self-managed database, the value of this parameter varies with the value of the **SourceEndpointInstanceType** parameter.****\
        # 
        # *   If the SourceEndpointInstanceType parameter is set to **ECS**, you must specify the ID of the ECS instance.
        # *   If the SourceEndpointInstanceType parameter is set to **DG**, you must specify the ID of the database gateway.
        # *   If the SourceEndpointInstanceType parameter is set to **EXPRESS** or **CEN**, you must specify the ID of the VPC that is connected to the source instance.
        # 
        # >  If the SourceEndpointInstanceType parameter is set to **CEN**, you must also specify the ID of the CEN instance in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.dts_job_name = dts_job_name  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.error_notice = error_notice  # type: bool
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   The value **Reverse** takes effect only if the topology of the data synchronization task is two-way synchronization.
        self.error_phone = error_phone  # type: str
        # Specifies whether the instance is a disaster recovery instance.
        # 
        # *   **true**: The instance is a disaster recovery instance.
        # *   **false**: The instance is not a disaster recovery instance.
        self.file_oss_url = file_oss_url  # type: str
        # The ID of the data migration or synchronization instance.
        # 
        # >  You must specify at least one of the **DtsJobId** and DtsInstanceId parameters. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.job_type = job_type  # type: str
        self.owner_id = owner_id  # type: str
        # The URL of the Object Storage Service (OSS) bucket that stores the files related to the DTS task.
        self.region_id = region_id  # type: str
        # The SID of the Oracle database.
        # 
        # >  If the **DestinationEndpointEngineName** parameter is set to **ORACLE** and the **Oracle** database is deployed in a non-RAC architecture, this parameter is available and required.
        self.reserve = reserve  # type: str
        # The password of the source database account.
        self.source_endpoint_database_name = source_endpoint_database_name  # type: str
        # The IP address of the source instance.
        # 
        # >  If the **SourceEndpointInstanceType** parameter is set to **OTHER**, **EXPRESS**, **DG**, or **CEN**, this parameter is available and required.
        self.source_endpoint_engine_name = source_endpoint_engine_name  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  If the **SourceEndpointEngineName** parameter is set to **ORACLE** and the **Oracle** database is deployed in an architecture that is not a Real Application Cluster (RAC), this parameter is available and required.
        self.source_endpoint_ip = source_endpoint_ip  # type: str
        # The ID of the region in which the source instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the source instance is an Alibaba Cloud database instance, this parameter is required.
        self.source_endpoint_instance_id = source_endpoint_instance_id  # type: str
        # The database engine of the source instance. Valid values:
        # 
        # *   **MYSQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **MARIADB**: ApsaraDB RDS for MariaDB instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **POLARDB_O**: PolarDB for Oracle cluster
        # *   **POLARDBX10**: PolarDB-X 1.0 instance
        # *   **POLARDBX20**: PolarDB-X 2.0 instance
        # *   **ORACLE**: self-managed Oracle database
        # *   **POSTGRESQL**: ApsaraDB RDS for PostgreSQL instance or self-managed PostgreSQL database
        # *   **MSSQL**: ApsaraDB RDS for SQL Server instance or self-managed SQL Server database
        # *   **MONGODB**: ApsaraDB for MongoDB instance or self-managed MongoDB database
        # *   **DB2**: self-managed Db2 for LUW database
        # *   **AS400**: self-managed Db2 for i database
        # *   **DMSPOLARDB**: DMS logical database
        # *   **HBASE**: self-managed HBase database
        # *   **TERADATA**: Teradata database
        # *   **TiDB**: TiDB database
        # *   **REDIS**: ApsaraDB for Redis instance or self-managed Redis database
        # 
        # > 
        # *   Default value: **MYSQL**.
        # *   If the SourceEndpointEngineName parameter is set to **MONGODB**, you must also specify the architecture type of the MongoDB database in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.source_endpoint_instance_type = source_endpoint_instance_type  # type: str
        # The database account of the source database.
        # 
        # > 
        # *   In most cases, this parameter is required.
        # *   The permissions that are required for the database account vary with the migration or synchronization scenario. For more information, see [Prepare the database accounts for data migration](~~175878~~) or [Prepare the database accounts for data synchronization](~~213152~~).
        self.source_endpoint_oracle_sid = source_endpoint_oracle_sid  # type: str
        # The type of the destination instance. Valid values:
        # 
        # **Alibaba Cloud database instances**\
        # 
        # *   **RDS**: ApsaraDB RDS for MySQL instance, ApsaraDB RDS for SQL Server instance, ApsaraDB RDS for PostgreSQL instance, or ApsaraDB RDS for MariaDB instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **POLARDBX10**: PolarDB-X 1.0 instance
        # *   **POLARDBX20**: PolarDB-X 2.0 instance
        # *   **REDIS**: ApsaraDB for Redis instance
        # *   **ADS**: AnalyticDB for MySQL V2.0 cluster or AnalyticDB for MySQL V3.0 cluster
        # *   **MONGODB**: ApsaraDB for MongoDB instance
        # *   **GREENPLUM**: AnalyticDB for PostgreSQL instance
        # *   **DATAHUB**: DataHub project
        # *   **ELK**: Elasticsearch cluster
        # *   **Tablestore**: Tablestore instance
        # *   **ODPS**: MaxCompute project
        # 
        # **Self-managed databases**\
        # 
        # *   **OTHER**: self-managed database with a public IP address
        # *   **ECS**: self-managed database hosted on an ECS instance
        # *   **EXPRESS**: self-managed database connected over Express Connect
        # *   **CEN**: self-managed database connected over CEN
        # *   **DG**: self-managed database connected over Database Gateway
        # 
        # > 
        # *   If the destination instance is a PolarDB for Oracle cluster, you must set this parameter to **OTHER** or **EXPRESS** because you can use a PolarDB for Oracle cluster only as a self-managed database connected over the Internet or Express Connect.
        # *   If the destination instance is a Message Queue for Apache Kafka instance, you must set this parameter to **ECS** or **EXPRESS** because you can use a Message Queue for Apache Kafka instance only as a self-managed database connected over ECS or Express Connect.
        # *   For more information, see [Supported databases](~~176064~~).
        # *   If the destination instance is a self-managed database, you must deploy the network environment for the database. For more information, see [Preparation overview](~~146958~~).
        self.source_endpoint_owner_id = source_endpoint_owner_id  # type: str
        # The name of the RAM role configured for the Alibaba Cloud account that owns the source instance.
        # 
        # >  This parameter is required when you migrate or synchronize data across different Alibaba Cloud accounts. For information about the permissions and authorization methods of the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.source_endpoint_password = source_endpoint_password  # type: str
        # The name of the database to which the objects to be migrated in the source instance belong.
        # 
        # >  If the source instance is a PolarDB for Oracle cluster, a PostgreSQL database, or a MongoDB database, this parameter is available and required.
        self.source_endpoint_port = source_endpoint_port  # type: str
        # The database service port of the source instance.
        # 
        # >  If the source instance is a self-managed database, this parameter is available and required.
        self.source_endpoint_region = source_endpoint_region  # type: str
        # The ID of the destination instance.
        # 
        # If the destination instance is an Alibaba Cloud database instance, you must specify the ID of the database instance. For example, if the destination instance is an ApsaraDB RDS for MySQL instance, you must specify the ID of the ApsaraDB RDS for MySQL instance.
        # 
        # If the destination instance is a self-managed database, the value of this parameter varies with the value of the **DestinationEndpointInstanceType** parameter.****\
        # 
        # *   If the DestinationEndpointInstanceType parameter is set to **ECS**, you must specify the ID of the ECS instance.
        # *   If the DestinationEndpointInstanceType parameter is set to **DG**, you must specify the ID of the database gateway.
        # *   If the DestinationEndpointInstanceType parameter is set to **EXPRESS** or **CEN**, you must specify the ID of the VPC that is connected to the source instance.
        # 
        # >  If the DestinationEndpointInstanceType parameter is set to **CEN**, you must also specify the ID of the CEN instance in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.source_endpoint_role = source_endpoint_role  # type: str
        # The ID of the Alibaba Cloud account to which the source instance belongs.
        # 
        # >  You can specify this parameter to migrate or synchronize data across different Alibaba Cloud accounts. In this case, you must specify the **SourceEndpointRole** parameter.
        self.source_endpoint_user_name = source_endpoint_user_name  # type: str
        # 数据投递链路交换机实例id
        self.source_endpoint_vswitch_id = source_endpoint_vswitch_id  # type: str
        # Specifies whether to perform incremental data migration or synchronization. Default value: false. Valid values:
        # 
        # *   **false**: does not perform incremental data migration or synchronization.
        # *   **true**: performs incremental data migration or synchronization.
        self.structure_initialization = structure_initialization  # type: bool
        # The ID of the DTS dedicated cluster on which the task runs.
        # 
        # >  If this parameter is specified, the task is scheduled to the specified DTS dedicated cluster.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.data_check_configure is not None:
            result['DataCheckConfigure'] = self.data_check_configure
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.db_list is not None:
            result['DbList'] = self.db_list
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.delay_notice is not None:
            result['DelayNotice'] = self.delay_notice
        if self.delay_phone is not None:
            result['DelayPhone'] = self.delay_phone
        if self.delay_rule_time is not None:
            result['DelayRuleTime'] = self.delay_rule_time
        if self.destination_endpoint_data_base_name is not None:
            result['DestinationEndpointDataBaseName'] = self.destination_endpoint_data_base_name
        if self.destination_endpoint_engine_name is not None:
            result['DestinationEndpointEngineName'] = self.destination_endpoint_engine_name
        if self.destination_endpoint_ip is not None:
            result['DestinationEndpointIP'] = self.destination_endpoint_ip
        if self.destination_endpoint_instance_id is not None:
            result['DestinationEndpointInstanceID'] = self.destination_endpoint_instance_id
        if self.destination_endpoint_instance_type is not None:
            result['DestinationEndpointInstanceType'] = self.destination_endpoint_instance_type
        if self.destination_endpoint_oracle_sid is not None:
            result['DestinationEndpointOracleSID'] = self.destination_endpoint_oracle_sid
        if self.destination_endpoint_owner_id is not None:
            result['DestinationEndpointOwnerID'] = self.destination_endpoint_owner_id
        if self.destination_endpoint_password is not None:
            result['DestinationEndpointPassword'] = self.destination_endpoint_password
        if self.destination_endpoint_port is not None:
            result['DestinationEndpointPort'] = self.destination_endpoint_port
        if self.destination_endpoint_region is not None:
            result['DestinationEndpointRegion'] = self.destination_endpoint_region
        if self.destination_endpoint_role is not None:
            result['DestinationEndpointRole'] = self.destination_endpoint_role
        if self.destination_endpoint_user_name is not None:
            result['DestinationEndpointUserName'] = self.destination_endpoint_user_name
        if self.disaster_recovery_job is not None:
            result['DisasterRecoveryJob'] = self.disaster_recovery_job
        if self.dts_bis_label is not None:
            result['DtsBisLabel'] = self.dts_bis_label
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.error_notice is not None:
            result['ErrorNotice'] = self.error_notice
        if self.error_phone is not None:
            result['ErrorPhone'] = self.error_phone
        if self.file_oss_url is not None:
            result['FileOssUrl'] = self.file_oss_url
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.reserve is not None:
            result['Reserve'] = self.reserve
        if self.source_endpoint_database_name is not None:
            result['SourceEndpointDatabaseName'] = self.source_endpoint_database_name
        if self.source_endpoint_engine_name is not None:
            result['SourceEndpointEngineName'] = self.source_endpoint_engine_name
        if self.source_endpoint_ip is not None:
            result['SourceEndpointIP'] = self.source_endpoint_ip
        if self.source_endpoint_instance_id is not None:
            result['SourceEndpointInstanceID'] = self.source_endpoint_instance_id
        if self.source_endpoint_instance_type is not None:
            result['SourceEndpointInstanceType'] = self.source_endpoint_instance_type
        if self.source_endpoint_oracle_sid is not None:
            result['SourceEndpointOracleSID'] = self.source_endpoint_oracle_sid
        if self.source_endpoint_owner_id is not None:
            result['SourceEndpointOwnerID'] = self.source_endpoint_owner_id
        if self.source_endpoint_password is not None:
            result['SourceEndpointPassword'] = self.source_endpoint_password
        if self.source_endpoint_port is not None:
            result['SourceEndpointPort'] = self.source_endpoint_port
        if self.source_endpoint_region is not None:
            result['SourceEndpointRegion'] = self.source_endpoint_region
        if self.source_endpoint_role is not None:
            result['SourceEndpointRole'] = self.source_endpoint_role
        if self.source_endpoint_user_name is not None:
            result['SourceEndpointUserName'] = self.source_endpoint_user_name
        if self.source_endpoint_vswitch_id is not None:
            result['SourceEndpointVSwitchID'] = self.source_endpoint_vswitch_id
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('DataCheckConfigure') is not None:
            self.data_check_configure = m.get('DataCheckConfigure')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('DbList') is not None:
            self.db_list = m.get('DbList')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DelayNotice') is not None:
            self.delay_notice = m.get('DelayNotice')
        if m.get('DelayPhone') is not None:
            self.delay_phone = m.get('DelayPhone')
        if m.get('DelayRuleTime') is not None:
            self.delay_rule_time = m.get('DelayRuleTime')
        if m.get('DestinationEndpointDataBaseName') is not None:
            self.destination_endpoint_data_base_name = m.get('DestinationEndpointDataBaseName')
        if m.get('DestinationEndpointEngineName') is not None:
            self.destination_endpoint_engine_name = m.get('DestinationEndpointEngineName')
        if m.get('DestinationEndpointIP') is not None:
            self.destination_endpoint_ip = m.get('DestinationEndpointIP')
        if m.get('DestinationEndpointInstanceID') is not None:
            self.destination_endpoint_instance_id = m.get('DestinationEndpointInstanceID')
        if m.get('DestinationEndpointInstanceType') is not None:
            self.destination_endpoint_instance_type = m.get('DestinationEndpointInstanceType')
        if m.get('DestinationEndpointOracleSID') is not None:
            self.destination_endpoint_oracle_sid = m.get('DestinationEndpointOracleSID')
        if m.get('DestinationEndpointOwnerID') is not None:
            self.destination_endpoint_owner_id = m.get('DestinationEndpointOwnerID')
        if m.get('DestinationEndpointPassword') is not None:
            self.destination_endpoint_password = m.get('DestinationEndpointPassword')
        if m.get('DestinationEndpointPort') is not None:
            self.destination_endpoint_port = m.get('DestinationEndpointPort')
        if m.get('DestinationEndpointRegion') is not None:
            self.destination_endpoint_region = m.get('DestinationEndpointRegion')
        if m.get('DestinationEndpointRole') is not None:
            self.destination_endpoint_role = m.get('DestinationEndpointRole')
        if m.get('DestinationEndpointUserName') is not None:
            self.destination_endpoint_user_name = m.get('DestinationEndpointUserName')
        if m.get('DisasterRecoveryJob') is not None:
            self.disaster_recovery_job = m.get('DisasterRecoveryJob')
        if m.get('DtsBisLabel') is not None:
            self.dts_bis_label = m.get('DtsBisLabel')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('ErrorNotice') is not None:
            self.error_notice = m.get('ErrorNotice')
        if m.get('ErrorPhone') is not None:
            self.error_phone = m.get('ErrorPhone')
        if m.get('FileOssUrl') is not None:
            self.file_oss_url = m.get('FileOssUrl')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Reserve') is not None:
            self.reserve = m.get('Reserve')
        if m.get('SourceEndpointDatabaseName') is not None:
            self.source_endpoint_database_name = m.get('SourceEndpointDatabaseName')
        if m.get('SourceEndpointEngineName') is not None:
            self.source_endpoint_engine_name = m.get('SourceEndpointEngineName')
        if m.get('SourceEndpointIP') is not None:
            self.source_endpoint_ip = m.get('SourceEndpointIP')
        if m.get('SourceEndpointInstanceID') is not None:
            self.source_endpoint_instance_id = m.get('SourceEndpointInstanceID')
        if m.get('SourceEndpointInstanceType') is not None:
            self.source_endpoint_instance_type = m.get('SourceEndpointInstanceType')
        if m.get('SourceEndpointOracleSID') is not None:
            self.source_endpoint_oracle_sid = m.get('SourceEndpointOracleSID')
        if m.get('SourceEndpointOwnerID') is not None:
            self.source_endpoint_owner_id = m.get('SourceEndpointOwnerID')
        if m.get('SourceEndpointPassword') is not None:
            self.source_endpoint_password = m.get('SourceEndpointPassword')
        if m.get('SourceEndpointPort') is not None:
            self.source_endpoint_port = m.get('SourceEndpointPort')
        if m.get('SourceEndpointRegion') is not None:
            self.source_endpoint_region = m.get('SourceEndpointRegion')
        if m.get('SourceEndpointRole') is not None:
            self.source_endpoint_role = m.get('SourceEndpointRole')
        if m.get('SourceEndpointUserName') is not None:
            self.source_endpoint_user_name = m.get('SourceEndpointUserName')
        if m.get('SourceEndpointVSwitchID') is not None:
            self.source_endpoint_vswitch_id = m.get('SourceEndpointVSwitchID')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class ConfigureDtsJobAdvanceRequest(TeaModel):
    def __init__(self, checkpoint=None, data_check_configure=None, data_initialization=None,
                 data_synchronization=None, db_list=None, dedicated_cluster_id=None, delay_notice=None, delay_phone=None,
                 delay_rule_time=None, destination_endpoint_data_base_name=None, destination_endpoint_engine_name=None,
                 destination_endpoint_ip=None, destination_endpoint_instance_id=None, destination_endpoint_instance_type=None,
                 destination_endpoint_oracle_sid=None, destination_endpoint_owner_id=None, destination_endpoint_password=None,
                 destination_endpoint_port=None, destination_endpoint_region=None, destination_endpoint_role=None,
                 destination_endpoint_user_name=None, disaster_recovery_job=None, dts_bis_label=None, dts_instance_id=None, dts_job_id=None,
                 dts_job_name=None, error_notice=None, error_phone=None, file_oss_url_object=None, job_type=None, owner_id=None,
                 region_id=None, reserve=None, source_endpoint_database_name=None, source_endpoint_engine_name=None,
                 source_endpoint_ip=None, source_endpoint_instance_id=None, source_endpoint_instance_type=None,
                 source_endpoint_oracle_sid=None, source_endpoint_owner_id=None, source_endpoint_password=None, source_endpoint_port=None,
                 source_endpoint_region=None, source_endpoint_role=None, source_endpoint_user_name=None, source_endpoint_vswitch_id=None,
                 structure_initialization=None, synchronization_direction=None):
        # The type of the task. Valid values:
        # 
        # *   **MIGRATION**: data migration task
        # *   **SYNC**: data synchronization task
        self.checkpoint = checkpoint  # type: str
        # The HTTP status code.
        self.data_check_configure = data_check_configure  # type: str
        # The objects that you want to migrate or synchronize. The value is a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        self.data_initialization = data_initialization  # type: bool
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to add more configurations of the source or destination instance to the DTS task. For example, you can specify the data storage format of the destination Kafka database and the ID of the CEN instance. For more information, see [Reserve](~~273111~~).
        self.data_synchronization = data_synchronization  # type: bool
        # The start offset of incremental data migration or synchronization. The value is a UNIX timestamp. Unit: seconds.
        self.db_list = db_list  # type: str
        # The data verification task for a data migration or synchronization instance. The value is a JSON string that indicates parameter limits or alert configurations. For more information, see [DataCheckConfigure](~~459023~~).
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # Specifies whether to monitor the task status. Valid values:
        # 
        # *   **true**: monitors the task status.
        # *   **false**: does not monitor the task status.
        self.delay_notice = delay_notice  # type: bool
        # Specifies whether to monitor the task latency. Valid values:
        # 
        # *   **true**: monitors the task latency.
        # *   **false**: does not monitor the task latency.
        self.delay_phone = delay_phone  # type: str
        # The mobile numbers that receive status-related alerts. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile numbers in the Chinese mainland are supported. Up to 10 mobile numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.delay_rule_time = delay_rule_time  # type: long
        # The password of the destination database account.
        # 
        # >  If the destination database is a MaxCompute project, you must specify the AccessKey secret of your Alibaba Cloud account. For information about how to obtain your AccessKey pair, see [Create an AccessKey pair](~~116401~~).
        self.destination_endpoint_data_base_name = destination_endpoint_data_base_name  # type: str
        # The IP address of the destination instance.
        # 
        # >  If the **DestinationEndpointInstanceType** parameter is set to **OTHER**, **EXPRESS**, **DG**, or **CEN**, this parameter is available and required.
        self.destination_endpoint_engine_name = destination_endpoint_engine_name  # type: str
        # The name of the database to which the objects migrated to the destination instance belong.
        # 
        # > 
        # *   If the destination instance is a PolarDB for Oracle cluster, an AnalyticDB for PostgreSQL instance, a PostgreSQL database, a MaxCompute project, or a MongoDB database, this parameter is available and required.
        # *   If the destination instance is a MaxCompute project, you must specify the ID of the MaxCompute project.
        self.destination_endpoint_ip = destination_endpoint_ip  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the destination instance is an Alibaba Cloud database instance, this parameter is required.
        self.destination_endpoint_instance_id = destination_endpoint_instance_id  # type: str
        # The database engine of the destination instance. Valid values:
        # 
        # *   **MySQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **MARIADB**: ApsaraDB RDS for MariaDB instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **POLARDB_O**: PolarDB for Oracle cluster
        # *   **POLARDBX10**: PolarDB-X 1.0 instance
        # *   **POLARDBX20**: PolarDB-X 2.0 instance
        # *   **ORACLE**: self-managed Oracle database
        # *   **POSTGRESQL**: ApsaraDB RDS for PostgreSQL instance or self-managed PostgreSQL database
        # *   **MSSQL**: ApsaraDB RDS for SQL Server instance or self-managed SQL Server database
        # *   **ADS**: AnalyticDB for MySQL V2.0 cluster
        # *   **ADB30**: AnalyticDB for MySQL V3.0 cluster
        # *   **MONGODB**: ApsaraDB for MongoDB instance or self-managed MongoDB database
        # *   **GREENPLUM**: AnalyticDB for PostgreSQL instance
        # *   **KAFKA**: Message Queue for Apache Kafka instance or self-managed Kafka cluster
        # *   **DATAHUB**: DataHub project
        # *   **DB2**: self-managed Db2 for LUW database
        # *   **AS400**: self-managed Db2 for i database
        # *   **ODPS**: MaxCompute project
        # *   **Tablestore**: Tablestore instance
        # *   **ELK**: Elasticsearch cluster
        # *   **REDIS**: ApsaraDB for Redis instance or self-managed Redis database
        # 
        # > 
        # *   Default value: **MYSQL**.
        # *   If the DestinationEndpointEngineName parameter is set to **KAFKA**, **MONGODB**, or **PolarDB**, you must also specify the database information in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.destination_endpoint_instance_type = destination_endpoint_instance_type  # type: str
        # The ID of the data migration or synchronization task.
        # 
        # >  You must specify at least one of the DtsJobId and **DtsInstanceId** parameters. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.destination_endpoint_oracle_sid = destination_endpoint_oracle_sid  # type: str
        self.destination_endpoint_owner_id = destination_endpoint_owner_id  # type: str
        # Specifies whether to perform full data migration or synchronization. Default value: true. Valid values:
        # 
        # *   **true**: performs full data migration or synchronization.
        # *   **false**: does not perform full data migration or synchronization.
        self.destination_endpoint_password = destination_endpoint_password  # type: str
        # The database account of the destination database.
        # 
        # > 
        # *   In most cases, this parameter is required.
        # *   The permissions that are required for the database account vary with the migration or synchronization scenario. For more information, see [Prepare the database accounts for data migration](~~175878~~) or [Prepare the database accounts for data synchronization](~~213152~~).
        # *   If the destination database is a MaxCompute project, you must specify the AccessKey ID of your Alibaba Cloud account. For information about how to obtain your AccessKey pair, see [Create an AccessKey pair](~~116401~~).
        self.destination_endpoint_port = destination_endpoint_port  # type: str
        # The database service port of the destination instance.
        # 
        # >  If the destination instance is a self-managed database, this parameter is available and required.
        self.destination_endpoint_region = destination_endpoint_region  # type: str
        self.destination_endpoint_role = destination_endpoint_role  # type: str
        # Specifies whether to perform schema migration or synchronization. Default value: true. Valid values:
        # 
        # *   **true**: performs schema migration or synchronization.
        # *   **false**: does not perform schema migration or synchronization.
        self.destination_endpoint_user_name = destination_endpoint_user_name  # type: str
        # The ID of the request.
        self.disaster_recovery_job = disaster_recovery_job  # type: bool
        self.dts_bis_label = dts_bis_label  # type: str
        # The threshold for triggering latency-related alerts. Unit: seconds. The value must be an integer. You can set the threshold based on your business needs. To prevent jitters caused by network and database overloads, we recommend that you set the threshold to more than 10 seconds.
        # 
        # >  If the **DelayNotice** parameter is set to **true**, this parameter is required.
        self.dts_instance_id = dts_instance_id  # type: str
        # The mobile numbers that receive latency-related alerts. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile numbers in the Chinese mainland are supported. Up to 10 mobile numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the source instance.
        # 
        # If the source instance is an Alibaba Cloud database instance, you must specify the ID of the database instance. For example, if the source instance is an ApsaraDB RDS for MySQL instance, you must specify the ID of the ApsaraDB RDS for MySQL instance.
        # 
        # If the source instance is a self-managed database, the value of this parameter varies with the value of the **SourceEndpointInstanceType** parameter.****\
        # 
        # *   If the SourceEndpointInstanceType parameter is set to **ECS**, you must specify the ID of the ECS instance.
        # *   If the SourceEndpointInstanceType parameter is set to **DG**, you must specify the ID of the database gateway.
        # *   If the SourceEndpointInstanceType parameter is set to **EXPRESS** or **CEN**, you must specify the ID of the VPC that is connected to the source instance.
        # 
        # >  If the SourceEndpointInstanceType parameter is set to **CEN**, you must also specify the ID of the CEN instance in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.dts_job_name = dts_job_name  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.error_notice = error_notice  # type: bool
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   The value **Reverse** takes effect only if the topology of the data synchronization task is two-way synchronization.
        self.error_phone = error_phone  # type: str
        # Specifies whether the instance is a disaster recovery instance.
        # 
        # *   **true**: The instance is a disaster recovery instance.
        # *   **false**: The instance is not a disaster recovery instance.
        self.file_oss_url_object = file_oss_url_object  # type: READABLE
        # The ID of the data migration or synchronization instance.
        # 
        # >  You must specify at least one of the **DtsJobId** and DtsInstanceId parameters. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.job_type = job_type  # type: str
        self.owner_id = owner_id  # type: str
        # The URL of the Object Storage Service (OSS) bucket that stores the files related to the DTS task.
        self.region_id = region_id  # type: str
        # The SID of the Oracle database.
        # 
        # >  If the **DestinationEndpointEngineName** parameter is set to **ORACLE** and the **Oracle** database is deployed in a non-RAC architecture, this parameter is available and required.
        self.reserve = reserve  # type: str
        # The password of the source database account.
        self.source_endpoint_database_name = source_endpoint_database_name  # type: str
        # The IP address of the source instance.
        # 
        # >  If the **SourceEndpointInstanceType** parameter is set to **OTHER**, **EXPRESS**, **DG**, or **CEN**, this parameter is available and required.
        self.source_endpoint_engine_name = source_endpoint_engine_name  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  If the **SourceEndpointEngineName** parameter is set to **ORACLE** and the **Oracle** database is deployed in an architecture that is not a Real Application Cluster (RAC), this parameter is available and required.
        self.source_endpoint_ip = source_endpoint_ip  # type: str
        # The ID of the region in which the source instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the source instance is an Alibaba Cloud database instance, this parameter is required.
        self.source_endpoint_instance_id = source_endpoint_instance_id  # type: str
        # The database engine of the source instance. Valid values:
        # 
        # *   **MYSQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **MARIADB**: ApsaraDB RDS for MariaDB instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **POLARDB_O**: PolarDB for Oracle cluster
        # *   **POLARDBX10**: PolarDB-X 1.0 instance
        # *   **POLARDBX20**: PolarDB-X 2.0 instance
        # *   **ORACLE**: self-managed Oracle database
        # *   **POSTGRESQL**: ApsaraDB RDS for PostgreSQL instance or self-managed PostgreSQL database
        # *   **MSSQL**: ApsaraDB RDS for SQL Server instance or self-managed SQL Server database
        # *   **MONGODB**: ApsaraDB for MongoDB instance or self-managed MongoDB database
        # *   **DB2**: self-managed Db2 for LUW database
        # *   **AS400**: self-managed Db2 for i database
        # *   **DMSPOLARDB**: DMS logical database
        # *   **HBASE**: self-managed HBase database
        # *   **TERADATA**: Teradata database
        # *   **TiDB**: TiDB database
        # *   **REDIS**: ApsaraDB for Redis instance or self-managed Redis database
        # 
        # > 
        # *   Default value: **MYSQL**.
        # *   If the SourceEndpointEngineName parameter is set to **MONGODB**, you must also specify the architecture type of the MongoDB database in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.source_endpoint_instance_type = source_endpoint_instance_type  # type: str
        # The database account of the source database.
        # 
        # > 
        # *   In most cases, this parameter is required.
        # *   The permissions that are required for the database account vary with the migration or synchronization scenario. For more information, see [Prepare the database accounts for data migration](~~175878~~) or [Prepare the database accounts for data synchronization](~~213152~~).
        self.source_endpoint_oracle_sid = source_endpoint_oracle_sid  # type: str
        # The type of the destination instance. Valid values:
        # 
        # **Alibaba Cloud database instances**\
        # 
        # *   **RDS**: ApsaraDB RDS for MySQL instance, ApsaraDB RDS for SQL Server instance, ApsaraDB RDS for PostgreSQL instance, or ApsaraDB RDS for MariaDB instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **POLARDBX10**: PolarDB-X 1.0 instance
        # *   **POLARDBX20**: PolarDB-X 2.0 instance
        # *   **REDIS**: ApsaraDB for Redis instance
        # *   **ADS**: AnalyticDB for MySQL V2.0 cluster or AnalyticDB for MySQL V3.0 cluster
        # *   **MONGODB**: ApsaraDB for MongoDB instance
        # *   **GREENPLUM**: AnalyticDB for PostgreSQL instance
        # *   **DATAHUB**: DataHub project
        # *   **ELK**: Elasticsearch cluster
        # *   **Tablestore**: Tablestore instance
        # *   **ODPS**: MaxCompute project
        # 
        # **Self-managed databases**\
        # 
        # *   **OTHER**: self-managed database with a public IP address
        # *   **ECS**: self-managed database hosted on an ECS instance
        # *   **EXPRESS**: self-managed database connected over Express Connect
        # *   **CEN**: self-managed database connected over CEN
        # *   **DG**: self-managed database connected over Database Gateway
        # 
        # > 
        # *   If the destination instance is a PolarDB for Oracle cluster, you must set this parameter to **OTHER** or **EXPRESS** because you can use a PolarDB for Oracle cluster only as a self-managed database connected over the Internet or Express Connect.
        # *   If the destination instance is a Message Queue for Apache Kafka instance, you must set this parameter to **ECS** or **EXPRESS** because you can use a Message Queue for Apache Kafka instance only as a self-managed database connected over ECS or Express Connect.
        # *   For more information, see [Supported databases](~~176064~~).
        # *   If the destination instance is a self-managed database, you must deploy the network environment for the database. For more information, see [Preparation overview](~~146958~~).
        self.source_endpoint_owner_id = source_endpoint_owner_id  # type: str
        # The name of the RAM role configured for the Alibaba Cloud account that owns the source instance.
        # 
        # >  This parameter is required when you migrate or synchronize data across different Alibaba Cloud accounts. For information about the permissions and authorization methods of the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.source_endpoint_password = source_endpoint_password  # type: str
        # The name of the database to which the objects to be migrated in the source instance belong.
        # 
        # >  If the source instance is a PolarDB for Oracle cluster, a PostgreSQL database, or a MongoDB database, this parameter is available and required.
        self.source_endpoint_port = source_endpoint_port  # type: str
        # The database service port of the source instance.
        # 
        # >  If the source instance is a self-managed database, this parameter is available and required.
        self.source_endpoint_region = source_endpoint_region  # type: str
        # The ID of the destination instance.
        # 
        # If the destination instance is an Alibaba Cloud database instance, you must specify the ID of the database instance. For example, if the destination instance is an ApsaraDB RDS for MySQL instance, you must specify the ID of the ApsaraDB RDS for MySQL instance.
        # 
        # If the destination instance is a self-managed database, the value of this parameter varies with the value of the **DestinationEndpointInstanceType** parameter.****\
        # 
        # *   If the DestinationEndpointInstanceType parameter is set to **ECS**, you must specify the ID of the ECS instance.
        # *   If the DestinationEndpointInstanceType parameter is set to **DG**, you must specify the ID of the database gateway.
        # *   If the DestinationEndpointInstanceType parameter is set to **EXPRESS** or **CEN**, you must specify the ID of the VPC that is connected to the source instance.
        # 
        # >  If the DestinationEndpointInstanceType parameter is set to **CEN**, you must also specify the ID of the CEN instance in the Reserve parameter. For more information, see [Reserve](~~273111~~).
        self.source_endpoint_role = source_endpoint_role  # type: str
        # The ID of the Alibaba Cloud account to which the source instance belongs.
        # 
        # >  You can specify this parameter to migrate or synchronize data across different Alibaba Cloud accounts. In this case, you must specify the **SourceEndpointRole** parameter.
        self.source_endpoint_user_name = source_endpoint_user_name  # type: str
        # 数据投递链路交换机实例id
        self.source_endpoint_vswitch_id = source_endpoint_vswitch_id  # type: str
        # Specifies whether to perform incremental data migration or synchronization. Default value: false. Valid values:
        # 
        # *   **false**: does not perform incremental data migration or synchronization.
        # *   **true**: performs incremental data migration or synchronization.
        self.structure_initialization = structure_initialization  # type: bool
        # The ID of the DTS dedicated cluster on which the task runs.
        # 
        # >  If this parameter is specified, the task is scheduled to the specified DTS dedicated cluster.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureDtsJobAdvanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.data_check_configure is not None:
            result['DataCheckConfigure'] = self.data_check_configure
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.db_list is not None:
            result['DbList'] = self.db_list
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.delay_notice is not None:
            result['DelayNotice'] = self.delay_notice
        if self.delay_phone is not None:
            result['DelayPhone'] = self.delay_phone
        if self.delay_rule_time is not None:
            result['DelayRuleTime'] = self.delay_rule_time
        if self.destination_endpoint_data_base_name is not None:
            result['DestinationEndpointDataBaseName'] = self.destination_endpoint_data_base_name
        if self.destination_endpoint_engine_name is not None:
            result['DestinationEndpointEngineName'] = self.destination_endpoint_engine_name
        if self.destination_endpoint_ip is not None:
            result['DestinationEndpointIP'] = self.destination_endpoint_ip
        if self.destination_endpoint_instance_id is not None:
            result['DestinationEndpointInstanceID'] = self.destination_endpoint_instance_id
        if self.destination_endpoint_instance_type is not None:
            result['DestinationEndpointInstanceType'] = self.destination_endpoint_instance_type
        if self.destination_endpoint_oracle_sid is not None:
            result['DestinationEndpointOracleSID'] = self.destination_endpoint_oracle_sid
        if self.destination_endpoint_owner_id is not None:
            result['DestinationEndpointOwnerID'] = self.destination_endpoint_owner_id
        if self.destination_endpoint_password is not None:
            result['DestinationEndpointPassword'] = self.destination_endpoint_password
        if self.destination_endpoint_port is not None:
            result['DestinationEndpointPort'] = self.destination_endpoint_port
        if self.destination_endpoint_region is not None:
            result['DestinationEndpointRegion'] = self.destination_endpoint_region
        if self.destination_endpoint_role is not None:
            result['DestinationEndpointRole'] = self.destination_endpoint_role
        if self.destination_endpoint_user_name is not None:
            result['DestinationEndpointUserName'] = self.destination_endpoint_user_name
        if self.disaster_recovery_job is not None:
            result['DisasterRecoveryJob'] = self.disaster_recovery_job
        if self.dts_bis_label is not None:
            result['DtsBisLabel'] = self.dts_bis_label
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.error_notice is not None:
            result['ErrorNotice'] = self.error_notice
        if self.error_phone is not None:
            result['ErrorPhone'] = self.error_phone
        if self.file_oss_url_object is not None:
            result['FileOssUrl'] = self.file_oss_url_object
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.reserve is not None:
            result['Reserve'] = self.reserve
        if self.source_endpoint_database_name is not None:
            result['SourceEndpointDatabaseName'] = self.source_endpoint_database_name
        if self.source_endpoint_engine_name is not None:
            result['SourceEndpointEngineName'] = self.source_endpoint_engine_name
        if self.source_endpoint_ip is not None:
            result['SourceEndpointIP'] = self.source_endpoint_ip
        if self.source_endpoint_instance_id is not None:
            result['SourceEndpointInstanceID'] = self.source_endpoint_instance_id
        if self.source_endpoint_instance_type is not None:
            result['SourceEndpointInstanceType'] = self.source_endpoint_instance_type
        if self.source_endpoint_oracle_sid is not None:
            result['SourceEndpointOracleSID'] = self.source_endpoint_oracle_sid
        if self.source_endpoint_owner_id is not None:
            result['SourceEndpointOwnerID'] = self.source_endpoint_owner_id
        if self.source_endpoint_password is not None:
            result['SourceEndpointPassword'] = self.source_endpoint_password
        if self.source_endpoint_port is not None:
            result['SourceEndpointPort'] = self.source_endpoint_port
        if self.source_endpoint_region is not None:
            result['SourceEndpointRegion'] = self.source_endpoint_region
        if self.source_endpoint_role is not None:
            result['SourceEndpointRole'] = self.source_endpoint_role
        if self.source_endpoint_user_name is not None:
            result['SourceEndpointUserName'] = self.source_endpoint_user_name
        if self.source_endpoint_vswitch_id is not None:
            result['SourceEndpointVSwitchID'] = self.source_endpoint_vswitch_id
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('DataCheckConfigure') is not None:
            self.data_check_configure = m.get('DataCheckConfigure')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('DbList') is not None:
            self.db_list = m.get('DbList')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DelayNotice') is not None:
            self.delay_notice = m.get('DelayNotice')
        if m.get('DelayPhone') is not None:
            self.delay_phone = m.get('DelayPhone')
        if m.get('DelayRuleTime') is not None:
            self.delay_rule_time = m.get('DelayRuleTime')
        if m.get('DestinationEndpointDataBaseName') is not None:
            self.destination_endpoint_data_base_name = m.get('DestinationEndpointDataBaseName')
        if m.get('DestinationEndpointEngineName') is not None:
            self.destination_endpoint_engine_name = m.get('DestinationEndpointEngineName')
        if m.get('DestinationEndpointIP') is not None:
            self.destination_endpoint_ip = m.get('DestinationEndpointIP')
        if m.get('DestinationEndpointInstanceID') is not None:
            self.destination_endpoint_instance_id = m.get('DestinationEndpointInstanceID')
        if m.get('DestinationEndpointInstanceType') is not None:
            self.destination_endpoint_instance_type = m.get('DestinationEndpointInstanceType')
        if m.get('DestinationEndpointOracleSID') is not None:
            self.destination_endpoint_oracle_sid = m.get('DestinationEndpointOracleSID')
        if m.get('DestinationEndpointOwnerID') is not None:
            self.destination_endpoint_owner_id = m.get('DestinationEndpointOwnerID')
        if m.get('DestinationEndpointPassword') is not None:
            self.destination_endpoint_password = m.get('DestinationEndpointPassword')
        if m.get('DestinationEndpointPort') is not None:
            self.destination_endpoint_port = m.get('DestinationEndpointPort')
        if m.get('DestinationEndpointRegion') is not None:
            self.destination_endpoint_region = m.get('DestinationEndpointRegion')
        if m.get('DestinationEndpointRole') is not None:
            self.destination_endpoint_role = m.get('DestinationEndpointRole')
        if m.get('DestinationEndpointUserName') is not None:
            self.destination_endpoint_user_name = m.get('DestinationEndpointUserName')
        if m.get('DisasterRecoveryJob') is not None:
            self.disaster_recovery_job = m.get('DisasterRecoveryJob')
        if m.get('DtsBisLabel') is not None:
            self.dts_bis_label = m.get('DtsBisLabel')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('ErrorNotice') is not None:
            self.error_notice = m.get('ErrorNotice')
        if m.get('ErrorPhone') is not None:
            self.error_phone = m.get('ErrorPhone')
        if m.get('FileOssUrl') is not None:
            self.file_oss_url_object = m.get('FileOssUrl')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Reserve') is not None:
            self.reserve = m.get('Reserve')
        if m.get('SourceEndpointDatabaseName') is not None:
            self.source_endpoint_database_name = m.get('SourceEndpointDatabaseName')
        if m.get('SourceEndpointEngineName') is not None:
            self.source_endpoint_engine_name = m.get('SourceEndpointEngineName')
        if m.get('SourceEndpointIP') is not None:
            self.source_endpoint_ip = m.get('SourceEndpointIP')
        if m.get('SourceEndpointInstanceID') is not None:
            self.source_endpoint_instance_id = m.get('SourceEndpointInstanceID')
        if m.get('SourceEndpointInstanceType') is not None:
            self.source_endpoint_instance_type = m.get('SourceEndpointInstanceType')
        if m.get('SourceEndpointOracleSID') is not None:
            self.source_endpoint_oracle_sid = m.get('SourceEndpointOracleSID')
        if m.get('SourceEndpointOwnerID') is not None:
            self.source_endpoint_owner_id = m.get('SourceEndpointOwnerID')
        if m.get('SourceEndpointPassword') is not None:
            self.source_endpoint_password = m.get('SourceEndpointPassword')
        if m.get('SourceEndpointPort') is not None:
            self.source_endpoint_port = m.get('SourceEndpointPort')
        if m.get('SourceEndpointRegion') is not None:
            self.source_endpoint_region = m.get('SourceEndpointRegion')
        if m.get('SourceEndpointRole') is not None:
            self.source_endpoint_role = m.get('SourceEndpointRole')
        if m.get('SourceEndpointUserName') is not None:
            self.source_endpoint_user_name = m.get('SourceEndpointUserName')
        if m.get('SourceEndpointVSwitchID') is not None:
            self.source_endpoint_vswitch_id = m.get('SourceEndpointVSwitchID')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class ConfigureDtsJobResponseBody(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The error message returned if the call failed.
        self.dts_instance_id = dts_instance_id  # type: str
        # Indicates whether the request was successful.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the data migration or synchronization instance.
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        # The error code returned if the call failed.
        self.http_status_code = http_status_code  # type: str
        # The ID of the data migration or synchronization task.
        self.request_id = request_id  # type: str
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureMigrationJobRequestDestinationEndpoint(TeaModel):
    def __init__(self, data_base_name=None, engine_name=None, ip=None, instance_id=None, instance_type=None,
                 oracle_sid=None, password=None, port=None, region=None, user_name=None):
        # The name of the destination database or the authentication database.
        # 
        # > 
        # *   You must specify the database name only if the **DestinationEndpoint.EngineName** parameter is set to **PostgreSQL**, **DRDS**, or **MongoDB**.
        # *   If the **DestinationEndpoint.EngineName** parameter is set to **PostgreSQL** or **DRDS**, specify the name of the destination database. If the DestinationEndpoint.EngineName parameter is set to **MongoDB**, specify the name of the authentication database.
        self.data_base_name = data_base_name  # type: str
        # The engine type of the destination database. Valid values: **MySQL**, **DRDS**, **SQLServer**, **PostgreSQL**, **PPAS**, **MongoDB**, **Redis**, **POLARDB**, and **polardb_pg**.
        # 
        # >  You must specify the engine type only if the **DestinationEndpoint.InstanceType** parameter is set to **RDS**, **POLARDB**, **ECS**, **LocalInstance**, or **Express**.
        self.engine_name = engine_name  # type: str
        # The endpoint of the destination database.
        # 
        # >  You must specify the endpoint only if the **DestinationEndpoint.InstanceType** parameter is set to **LocalInstance** or **Express**.
        self.ip = ip  # type: str
        # The ID of the instance that hosts the destination database.
        # 
        # >  You must specify the instance ID only if the **DestinationEndpoint.InstanceType** parameter is set to **RDS**, **ECS**, **MongoDB**, **Redis**, **DRDS**, **PetaData**, **OceanBase**, **POLARDB**, **PolarDB_o**, **AnalyticDB**, or **Greenplum**. For example, if the DestinationEndpoint.InstanceType parameter is set to **ECS**, you must specify the ID of the ECS instance.
        self.instance_id = instance_id  # type: str
        # The instance type of the destination database. Valid values:
        # 
        # *   **ECS**: self-managed database that is hosted on Elastic Compute Service (ECS)
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **RDS**: ApsaraDB RDS instance
        # *   **DRDS**: PolarDB-X instance
        # *   **MongoDB**: ApsaraDB for MongoDB instance
        # *   **Redis**: ApsaraDB for Redis instance
        # *   **PetaData**: HybridDB for MySQL instance
        # *   **POLARDB**: PolarDB for MySQL cluster or PolarDB for PostgreSQL cluster
        # *   **PolarDB_o**: PolarDB O Edition cluster
        # *   **AnalyticDB**: AnalyticDB for MySQL cluster V3.0 or V2.0
        # *   **Greenplum**: AnalyticDB for PostgreSQL instance
        self.instance_type = instance_type  # type: str
        # The SID of the Oracle database.
        # 
        # >  You must specify this parameter only if the **DestinationEndpoint.EngineName** parameter is set to **Oracle** and the **Oracle** database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The password of the destination database account.
        self.password = password  # type: str
        # The service port number of the destination database.
        # 
        # >  You must specify the service port number only if the **DestinationEndpoint.InstanceType** parameter is set to **ECS**, **LocalInstance**, or **Express**.
        self.port = port  # type: str
        # The region ID of the destination database.
        # 
        # >  If the **DestinationEndpoint.InstanceType** parameter is set to **LocalInstance**, you can enter **cn-hangzhou** or the ID of the region closest to the self-managed database. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        # The database account of the destination database.
        # 
        # >  The permissions that are required for database accounts vary with the migration scenario. For more information, see [Overview of data migration scenarios](~~26618~~).
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureMigrationJobRequestDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_base_name is not None:
            result['DataBaseName'] = self.data_base_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.password is not None:
            result['Password'] = self.password
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataBaseName') is not None:
            self.data_base_name = m.get('DataBaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class ConfigureMigrationJobRequestMigrationMode(TeaModel):
    def __init__(self, data_intialization=None, data_synchronization=None, structure_intialization=None):
        # Specifies whether to perform full data migration. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        # 
        # >  For more information about databases that support full data migration, see [Supported databases and migration types](~~26618~~).
        self.data_intialization = data_intialization  # type: bool
        # Specifies whether to perform incremental data migration. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        # 
        # >  For more information about databases that support incremental data migration, see [Supported databases and migration types](~~26618~~).
        self.data_synchronization = data_synchronization  # type: bool
        # Specifies whether to perform schema migration. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        # 
        # >  For more information about databases that support schema migration, see [Supported databases and migration types](~~26618~~).
        self.structure_intialization = structure_intialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureMigrationJobRequestMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_intialization is not None:
            result['DataIntialization'] = self.data_intialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_intialization is not None:
            result['StructureIntialization'] = self.structure_intialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataIntialization') is not None:
            self.data_intialization = m.get('DataIntialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureIntialization') is not None:
            self.structure_intialization = m.get('StructureIntialization')
        return self


class ConfigureMigrationJobRequestSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, ip=None, instance_id=None, instance_type=None,
                 oracle_sid=None, owner_id=None, password=None, port=None, region=None, role=None, user_name=None):
        # The name of the source database or the authentication database.
        # 
        # > 
        # *   You must specify the database name only if the **SourceEndpoint.EngineName** parameter is set to **PostgreSQL** or **MongoDB**.
        # *   If the **SourceEndpoint.EngineName** parameter is set to **PostgreSQL**, specify the name of the source database. If the SourceEndpoint.EngineName parameter is set to **MongoDB**, specify the name of the authentication database.
        self.database_name = database_name  # type: str
        # The engine type of the source database. Valid values: **MySQL**, **TiDB**, **SQLServer**, **PostgreSQL**, **Oracle**, **MongoDB**, **Redis**, **POLARDB**, and **polardb_pg**.
        # 
        # >  You must specify the engine type only if the **DestinationEndpoint.InstanceType** parameter is set to **RDS**, **POLARDB**, **ECS**, **LocalInstance**, or **Express**.
        self.engine_name = engine_name  # type: str
        # The endpoint of the source database.
        # 
        # >  You must specify the endpoint only if the **SourceEndpoint.InstanceType** parameter is set to **LocalInstance** or **Express**.
        self.ip = ip  # type: str
        # The ID of the instance that hosts the source database.
        # 
        # > 
        # *   You must specify the instance ID only if the **SourceEndpoint.InstanceType** parameter is set to **RDS**, **ECS**, **Express**, **MongoDB**, **POLARDB**, or **PolarDB_o**. For example, if the SourceEndpoint.InstanceType parameter is set to **ECS**, you must specify the ID of the ECS instance.
        # *   If the **SourceEndpoint.InstanceType** parameter is set to **Express**, you must specify the ID of the virtual private cloud (VPC).
        self.instance_id = instance_id  # type: str
        # The instance type of the source database. Valid values:
        # 
        # *   **RDS**: ApsaraDB RDS instance
        # *   **ECS**: self-managed database that is hosted on ECS
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **Express**: self-managed database that is connected over Express Connect, VPN Gateway, or Smart Access Gateway
        # *   **dg**: self-managed database that is connected over Database Gateway
        # *   **cen**: self-managed database that is connected over Cloud Enterprise Network (CEN)
        # *   **MongoDB**: ApsaraDB for MongoDB instance
        # *   **POLARDB**: PolarDB for MySQL cluster or PolarDB for PostgreSQL cluster
        # *   **PolarDB_o**: PolarDB O Edition cluster
        self.instance_type = instance_type  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  You must specify this parameter only if the **SourceEndpoint.EngineName** parameter is set to **Oracle** and the **Oracle** database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The ID of the Alibaba Cloud account to which the source instance belongs.
        # 
        # >  You must specify this parameter only when you configure data migration across different Alibaba Cloud accounts.
        self.owner_id = owner_id  # type: str
        # The password of the source database account.
        self.password = password  # type: str
        # The service port number of the source database.
        # 
        # >  You must specify the service port number only if the **SourceEndpoint.InstanceType** parameter is set to **ECS**, **LocalInstance**, or **Express**.
        self.port = port  # type: str
        # The region ID of the source database.
        # 
        # >  If the **SourceEndpoint.InstanceType** parameter is set to **LocalInstance**, you can enter **cn-hangzhou** or the ID of the region closest to the self-managed database. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        # The authorized RAM role of the source instance. You must specify the RAM role only if the source instance and the destination instance belong to different Alibaba Cloud accounts. You can use the RAM role to allow the Alibaba Cloud account that owns the destination instance to access the source instance.
        # 
        # >  For information about the permissions and authorization methods of the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.role = role  # type: str
        # The database account of the source database.
        # 
        # >  The permissions that are required for database accounts vary with the migration scenario. For more information, see [Overview of data migration scenarios](~~26618~~).
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureMigrationJobRequestSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.password is not None:
            result['Password'] = self.password
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role is not None:
            result['Role'] = self.role
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('Role') is not None:
            self.role = m.get('Role')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class ConfigureMigrationJobRequest(TeaModel):
    def __init__(self, destination_endpoint=None, migration_mode=None, source_endpoint=None, account_id=None,
                 checkpoint=None, migration_job_id=None, migration_job_name=None, migration_object=None,
                 migration_reserved=None, owner_id=None, region_id=None):
        self.destination_endpoint = destination_endpoint  # type: ConfigureMigrationJobRequestDestinationEndpoint
        self.migration_mode = migration_mode  # type: ConfigureMigrationJobRequestMigrationMode
        self.source_endpoint = source_endpoint  # type: ConfigureMigrationJobRequestSourceEndpoint
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The start offset of incremental data migration. The value is a UNIX timestamp. Unit: seconds.
        self.checkpoint = checkpoint  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query the instance ID.
        self.migration_job_id = migration_job_id  # type: str
        # The name of the data migration task. The name can be up to 32 characters in length. We recommend that you specify an informative name to identify the task. You do not need to use a unique task name.
        self.migration_job_name = migration_job_name  # type: str
        # The objects that you want to migrate. The value is a JSON string and can contain regular expressions.
        # 
        # For more information, see [MigrationObject](~~141227~~).
        self.migration_object = migration_object  # type: str
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet special requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        self.migration_reserved = migration_reserved  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region where the data migration instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  The region ID of the data migration instance is the same as that of the destination database.
        self.region_id = region_id  # type: str

    def validate(self):
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()

    def to_map(self):
        _map = super(ConfigureMigrationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.migration_job_name is not None:
            result['MigrationJobName'] = self.migration_job_name
        if self.migration_object is not None:
            result['MigrationObject'] = self.migration_object
        if self.migration_reserved is not None:
            result['MigrationReserved'] = self.migration_reserved
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationEndpoint') is not None:
            temp_model = ConfigureMigrationJobRequestDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('MigrationMode') is not None:
            temp_model = ConfigureMigrationJobRequestMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('SourceEndpoint') is not None:
            temp_model = ConfigureMigrationJobRequestSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('MigrationJobName') is not None:
            self.migration_job_name = m.get('MigrationJobName')
        if m.get('MigrationObject') is not None:
            self.migration_object = m.get('MigrationObject')
        if m.get('MigrationReserved') is not None:
            self.migration_reserved = m.get('MigrationReserved')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ConfigureMigrationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureMigrationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureMigrationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureMigrationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureMigrationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureMigrationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureMigrationJobAlertRequest(TeaModel):
    def __init__(self, account_id=None, delay_alert_phone=None, delay_alert_status=None, delay_over_seconds=None,
                 error_alert_phone=None, error_alert_status=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The mobile phone numbers that receive latency-related alerts. Separate mobile phone numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile phone numbers in the Chinese mainland are supported. Up to 10 mobile phone numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the Cloud Monitor console](~~175876~~).
        self.delay_alert_phone = delay_alert_phone  # type: str
        # Specifies whether to monitor task latency. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        # 
        # > 
        # *   The default value is **enable**.
        # *   You must specify at least one of the DelayAlertStatus and **ErrorAlertStatus** parameters.
        self.delay_alert_status = delay_alert_status  # type: str
        # The threshold for triggering latency alerts. The unit is seconds and the value must be an integer. You can set the threshold based on your business needs. To avoid delay fluctuations caused by network and database loads, we recommend that you set the threshold to more than 10 seconds.
        # 
        # >  If the **DelayAlertStatus** parameter is set to **enable**, this parameter must be specified.
        self.delay_over_seconds = delay_over_seconds  # type: str
        # The mobile phone numbers that receive status-related alerts. Separate mobile phone numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile phone numbers in the Chinese mainland are supported. Up to 10 mobile phone numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the Cloud Monitor console](~~175876~~).
        self.error_alert_phone = error_alert_phone  # type: str
        # Specifies whether to monitor task status. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        # 
        # > 
        # *   The default value is **enable**.
        # *   You must specify at least one of the **DelayAlertStatus** and ErrorAlertStatus parameters.
        # *   If the task that you monitor enters an abnormal state, an alert is triggered.
        self.error_alert_status = error_alert_status  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query the instance ID.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureMigrationJobAlertRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.delay_alert_phone is not None:
            result['DelayAlertPhone'] = self.delay_alert_phone
        if self.delay_alert_status is not None:
            result['DelayAlertStatus'] = self.delay_alert_status
        if self.delay_over_seconds is not None:
            result['DelayOverSeconds'] = self.delay_over_seconds
        if self.error_alert_phone is not None:
            result['ErrorAlertPhone'] = self.error_alert_phone
        if self.error_alert_status is not None:
            result['ErrorAlertStatus'] = self.error_alert_status
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('DelayAlertPhone') is not None:
            self.delay_alert_phone = m.get('DelayAlertPhone')
        if m.get('DelayAlertStatus') is not None:
            self.delay_alert_status = m.get('DelayAlertStatus')
        if m.get('DelayOverSeconds') is not None:
            self.delay_over_seconds = m.get('DelayOverSeconds')
        if m.get('ErrorAlertPhone') is not None:
            self.error_alert_phone = m.get('ErrorAlertPhone')
        if m.get('ErrorAlertStatus') is not None:
            self.error_alert_status = m.get('ErrorAlertStatus')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ConfigureMigrationJobAlertResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureMigrationJobAlertResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureMigrationJobAlertResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureMigrationJobAlertResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureMigrationJobAlertResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureMigrationJobAlertResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureSubscriptionRequest(TeaModel):
    def __init__(self, checkpoint=None, db_list=None, dedicated_cluster_id=None, delay_notice=None,
                 delay_phone=None, delay_rule_time=None, dts_bis_label=None, dts_instance_id=None, dts_job_id=None,
                 dts_job_name=None, error_notice=None, error_phone=None, region_id=None, reserve=None,
                 source_endpoint_database_name=None, source_endpoint_engine_name=None, source_endpoint_ip=None,
                 source_endpoint_instance_id=None, source_endpoint_instance_type=None, source_endpoint_oracle_sid=None,
                 source_endpoint_owner_id=None, source_endpoint_password=None, source_endpoint_port=None, source_endpoint_region=None,
                 source_endpoint_role=None, source_endpoint_user_name=None, subscription_data_type_ddl=None,
                 subscription_data_type_dml=None, subscription_instance_network_type=None, subscription_instance_vpcid=None,
                 subscription_instance_vswitch_id=None):
        # The UNIX timestamp that represents the start time of change tracking. Unit: seconds.
        # 
        # >  You can use a search engine to obtain a UNIX timestamp converter.
        self.checkpoint = checkpoint  # type: str
        # The objects for which you want to track data changes. The value must be a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        self.db_list = db_list  # type: str
        # The ID of the DTS dedicated cluster on which the change tracking task is scheduled to run.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # Specifies whether to monitor the task latency. Valid values:
        # 
        # *   **true**: monitors the task latency.
        # *   **false**: does not monitor the task latency.
        self.delay_notice = delay_notice  # type: bool
        # The mobile numbers to which latency-related alerts are sent. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for users of the China site (aliyun.com). Only mobile numbers in the Chinese mainland are supported. You can specify up to 10 mobile numbers.
        # *   Users of the international site (alibabacloud.com) cannot receive alerts by using mobile phones, but can [configure alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.delay_phone = delay_phone  # type: str
        # The threshold for triggering latency-related alerts. Unit: seconds. The value must be an integer. You can set the threshold based on your business needs. To prevent jitters caused by network and database overloads, we recommend that you set the threshold to more than 10 seconds.
        # 
        # >  If the **DelayNotice** parameter is set to **true**, this parameter is required.
        self.delay_rule_time = delay_rule_time  # type: long
        self.dts_bis_label = dts_bis_label  # type: str
        # The ID of the change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The name of the change tracking task.
        # 
        # >  We recommend that you specify a descriptive name for easy identification. You do not need to use a unique name.
        self.dts_job_name = dts_job_name  # type: str
        # Specifies whether to monitor the task status. Valid values:
        # 
        # *   **true**: monitors the task status.
        # *   **false**: does not monitor the task status.
        self.error_notice = error_notice  # type: bool
        # The mobile numbers to which status-related alerts are sent. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for users of the China site (aliyun.com). Only mobile numbers in the Chinese mainland are supported. You can specify up to 10 mobile numbers.
        # *   Users of the international site (alibabacloud.com) cannot receive alerts by using mobile phones, but can [configure alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.error_phone = error_phone  # type: str
        # The ID of the region in which the Data Transmission Service (DTS) instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The reserved parameter of DTS. The value must be a JSON string. You can specify this parameter to add more configurations of the source or destination database to the DTS task. For example, you can specify the data storage format of the destination Kafka database and the ID of the CEN instance. For more information, see [MigrationReserved](~~176470~~).
        self.reserve = reserve  # type: str
        # The name of the source database.
        self.source_endpoint_database_name = source_endpoint_database_name  # type: str
        # The engine of the source database. Valid values: **MySQL**, **PostgreSQL**, and **Oracle**.
        # 
        # >  If the source database is a self-managed database, you must specify this parameter.
        self.source_endpoint_engine_name = source_endpoint_engine_name  # type: str
        # The endpoint of the source database.
        # 
        # >  This parameter is required only when the source database is a self-managed database.
        self.source_endpoint_ip = source_endpoint_ip  # type: str
        # The ID of the source database.
        # 
        # >  This parameter is required only when the source database is an ApsaraDB RDS for MySQL instance, a PolarDB-X 1.0 instance, or a PolarDB for MySQL cluster.
        self.source_endpoint_instance_id = source_endpoint_instance_id  # type: str
        # The type of the source database. Valid values:
        # 
        # *   **RDS**: ApsaraDB RDS for MySQL instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **DRDS**: PolarDB-X 1.0 instance
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **ECS**: self-managed database hosted on an Elastic Compute Service (ECS) instance
        # *   **Express**: self-managed database connected over Express Connect
        # *   **CEN**: self-managed database connected over Cloud Enterprise Network (CEN)
        # *   **dg**: self-managed database connected over Database Gateway
        self.source_endpoint_instance_type = source_endpoint_instance_type  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  This parameter is required only when the source database is a self-managed Oracle database and is not deployed in the Real Application Clusters (RAC) architecture.
        self.source_endpoint_oracle_sid = source_endpoint_oracle_sid  # type: str
        # The ID of the Alibaba Cloud account to which the source database belongs.
        # 
        # >  This parameter is required only when you track data changes across different Alibaba Cloud accounts.
        self.source_endpoint_owner_id = source_endpoint_owner_id  # type: str
        # The password of the account that is used to connect to the source database.
        self.source_endpoint_password = source_endpoint_password  # type: str
        # The service port number of the source database.
        # 
        # >  This parameter is required only when the source database is a self-managed database.
        self.source_endpoint_port = source_endpoint_port  # type: str
        # The ID of the region in which the source database resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the source database is a self-managed database with a public IP address, you can set the value of this parameter to **cn-hangzhou** or the ID of the region that is closest to the region in which the self-managed database resides.
        self.source_endpoint_region = source_endpoint_region  # type: str
        # The RAM role that is authorized to access the source database. This parameter is required if the source database does not belong to the Alibaba Cloud account that you use to configure the change tracking task. In this case, you must authorize the Alibaba Cloud account to access the source database by using a RAM role.
        # 
        # >  For more information about the permissions that are required for the RAM role and how to grant the permissions to the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.source_endpoint_role = source_endpoint_role  # type: str
        # The username of the account that is used to connect to the source database.
        # 
        # >  The permissions that are required for the database account vary with the change tracking scenario. For more information, see [Prepare the source database account for change tracking](~~212653~~).
        self.source_endpoint_user_name = source_endpoint_user_name  # type: str
        # Specifies whether to track DDL statements. Default value: true. Valid values:
        # 
        # *   **true**: tracks DDL statements.
        # *   **false**: does not track DDL statements.
        self.subscription_data_type_ddl = subscription_data_type_ddl  # type: bool
        # Specifies whether to track DML statements. Default value: true. Valid values:
        # 
        # *   **true**: tracks DML statements.
        # *   **false**: does not track DML statements.
        self.subscription_data_type_dml = subscription_data_type_dml  # type: bool
        # The network type of the change tracking task. Set the value to **vpc**. A value of vpc indicates the Virtual Private Cloud (VPC) network type.
        # 
        # > 
        # *   To use the new version of the change tracking feature, you must specify the SubscriptionInstanceNetworkType parameter. You must also specify the **SubscriptionInstanceVPCId** and **SubscriptionInstanceVSwitchID** parameters. If you do not specify the SubscriptionInstanceNetworkType parameter, the previous version of the change tracking feature is used.
        # *   The previous version of the change tracking feature supports self-managed MySQL databases, ApsaraDB RDS for MySQL instances, and PolarDB-X 1.0 instances. The new version of the change tracking feature supports self-managed MySQL databases, ApsaraDB RDS for MySQL instances, PolarDB for MySQL clusters, and Oracle databases.
        self.subscription_instance_network_type = subscription_instance_network_type  # type: str
        # The ID of the VPC in which the change tracking instance is deployed.
        # 
        # >  This parameter is required only when the **SubscriptionInstanceNetworkType** parameter is set to **vpc**.
        self.subscription_instance_vpcid = subscription_instance_vpcid  # type: str
        # The ID of the vSwitch in the specified VPC.
        # 
        # >  This parameter is required only when the **SubscriptionInstanceNetworkType** parameter is set to **vpc**.
        self.subscription_instance_vswitch_id = subscription_instance_vswitch_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.db_list is not None:
            result['DbList'] = self.db_list
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.delay_notice is not None:
            result['DelayNotice'] = self.delay_notice
        if self.delay_phone is not None:
            result['DelayPhone'] = self.delay_phone
        if self.delay_rule_time is not None:
            result['DelayRuleTime'] = self.delay_rule_time
        if self.dts_bis_label is not None:
            result['DtsBisLabel'] = self.dts_bis_label
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.error_notice is not None:
            result['ErrorNotice'] = self.error_notice
        if self.error_phone is not None:
            result['ErrorPhone'] = self.error_phone
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.reserve is not None:
            result['Reserve'] = self.reserve
        if self.source_endpoint_database_name is not None:
            result['SourceEndpointDatabaseName'] = self.source_endpoint_database_name
        if self.source_endpoint_engine_name is not None:
            result['SourceEndpointEngineName'] = self.source_endpoint_engine_name
        if self.source_endpoint_ip is not None:
            result['SourceEndpointIP'] = self.source_endpoint_ip
        if self.source_endpoint_instance_id is not None:
            result['SourceEndpointInstanceID'] = self.source_endpoint_instance_id
        if self.source_endpoint_instance_type is not None:
            result['SourceEndpointInstanceType'] = self.source_endpoint_instance_type
        if self.source_endpoint_oracle_sid is not None:
            result['SourceEndpointOracleSID'] = self.source_endpoint_oracle_sid
        if self.source_endpoint_owner_id is not None:
            result['SourceEndpointOwnerID'] = self.source_endpoint_owner_id
        if self.source_endpoint_password is not None:
            result['SourceEndpointPassword'] = self.source_endpoint_password
        if self.source_endpoint_port is not None:
            result['SourceEndpointPort'] = self.source_endpoint_port
        if self.source_endpoint_region is not None:
            result['SourceEndpointRegion'] = self.source_endpoint_region
        if self.source_endpoint_role is not None:
            result['SourceEndpointRole'] = self.source_endpoint_role
        if self.source_endpoint_user_name is not None:
            result['SourceEndpointUserName'] = self.source_endpoint_user_name
        if self.subscription_data_type_ddl is not None:
            result['SubscriptionDataTypeDDL'] = self.subscription_data_type_ddl
        if self.subscription_data_type_dml is not None:
            result['SubscriptionDataTypeDML'] = self.subscription_data_type_dml
        if self.subscription_instance_network_type is not None:
            result['SubscriptionInstanceNetworkType'] = self.subscription_instance_network_type
        if self.subscription_instance_vpcid is not None:
            result['SubscriptionInstanceVPCId'] = self.subscription_instance_vpcid
        if self.subscription_instance_vswitch_id is not None:
            result['SubscriptionInstanceVSwitchId'] = self.subscription_instance_vswitch_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('DbList') is not None:
            self.db_list = m.get('DbList')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DelayNotice') is not None:
            self.delay_notice = m.get('DelayNotice')
        if m.get('DelayPhone') is not None:
            self.delay_phone = m.get('DelayPhone')
        if m.get('DelayRuleTime') is not None:
            self.delay_rule_time = m.get('DelayRuleTime')
        if m.get('DtsBisLabel') is not None:
            self.dts_bis_label = m.get('DtsBisLabel')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('ErrorNotice') is not None:
            self.error_notice = m.get('ErrorNotice')
        if m.get('ErrorPhone') is not None:
            self.error_phone = m.get('ErrorPhone')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Reserve') is not None:
            self.reserve = m.get('Reserve')
        if m.get('SourceEndpointDatabaseName') is not None:
            self.source_endpoint_database_name = m.get('SourceEndpointDatabaseName')
        if m.get('SourceEndpointEngineName') is not None:
            self.source_endpoint_engine_name = m.get('SourceEndpointEngineName')
        if m.get('SourceEndpointIP') is not None:
            self.source_endpoint_ip = m.get('SourceEndpointIP')
        if m.get('SourceEndpointInstanceID') is not None:
            self.source_endpoint_instance_id = m.get('SourceEndpointInstanceID')
        if m.get('SourceEndpointInstanceType') is not None:
            self.source_endpoint_instance_type = m.get('SourceEndpointInstanceType')
        if m.get('SourceEndpointOracleSID') is not None:
            self.source_endpoint_oracle_sid = m.get('SourceEndpointOracleSID')
        if m.get('SourceEndpointOwnerID') is not None:
            self.source_endpoint_owner_id = m.get('SourceEndpointOwnerID')
        if m.get('SourceEndpointPassword') is not None:
            self.source_endpoint_password = m.get('SourceEndpointPassword')
        if m.get('SourceEndpointPort') is not None:
            self.source_endpoint_port = m.get('SourceEndpointPort')
        if m.get('SourceEndpointRegion') is not None:
            self.source_endpoint_region = m.get('SourceEndpointRegion')
        if m.get('SourceEndpointRole') is not None:
            self.source_endpoint_role = m.get('SourceEndpointRole')
        if m.get('SourceEndpointUserName') is not None:
            self.source_endpoint_user_name = m.get('SourceEndpointUserName')
        if m.get('SubscriptionDataTypeDDL') is not None:
            self.subscription_data_type_ddl = m.get('SubscriptionDataTypeDDL')
        if m.get('SubscriptionDataTypeDML') is not None:
            self.subscription_data_type_dml = m.get('SubscriptionDataTypeDML')
        if m.get('SubscriptionInstanceNetworkType') is not None:
            self.subscription_instance_network_type = m.get('SubscriptionInstanceNetworkType')
        if m.get('SubscriptionInstanceVPCId') is not None:
            self.subscription_instance_vpcid = m.get('SubscriptionInstanceVPCId')
        if m.get('SubscriptionInstanceVSwitchId') is not None:
            self.subscription_instance_vswitch_id = m.get('SubscriptionInstanceVSwitchId')
        return self


class ConfigureSubscriptionResponseBody(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The ID of the change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureSubscriptionResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureSubscriptionResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureSubscriptionResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureSubscriptionResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureSubscriptionInstanceRequestSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, ip=None, instance_id=None, instance_type=None, oracle_sid=None,
                 owner_id=None, password=None, port=None, role=None, user_name=None):
        # The name of the source database.
        self.database_name = database_name  # type: str
        # The IP address of the source database.
        # 
        # >  This parameter is required only when the source database is a self-managed database.
        self.ip = ip  # type: str
        # The ID of the source database.
        # 
        # >  This parameter is required only when the source database is an ApsaraDB RDS for MySQL instance, a PolarDB-X 1.0 instance, or a PolarDB for MySQL cluster.
        self.instance_id = instance_id  # type: str
        # The type of the source database. Valid values:
        # 
        # *   **RDS**: ApsaraDB RDS for MySQL instance
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **ECS**: self-managed database hosted on an Elastic Compute Service (ECS) instance
        # *   **Express**: self-managed database connected over Express Connect
        # *   **CEN**: self-managed database connected over Cloud Enterprise Network (CEN)
        # *   **dg**: self-managed database connected over Database Gateway
        # 
        # >  The engine of a self-managed database can be MySQL or Oracle. You must specify the engine type when you call the [CreateSubscriptionInstance](~~49436~~) operation.
        self.instance_type = instance_type  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  This parameter is required only when the source database is a self-managed Oracle database and is not deployed in the Real Application Clusters (RAC) architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The ID of the Alibaba Cloud account to which the source database belongs.
        # 
        # >  This parameter is required only when you track data changes across different Alibaba Cloud accounts.
        self.owner_id = owner_id  # type: str
        # The password of the account that is used to connect to the source database.
        self.password = password  # type: str
        # The service port number of the source database.
        # 
        # >  This parameter is required only when the source database is a self-managed database.
        self.port = port  # type: str
        # The RAM role that is authorized to access the source database. This parameter is required if the source database does not belong to the Alibaba Cloud account that you use to configure the change tracking instance. In this case, you must authorize the Alibaba Cloud account to access the source database by using a RAM role.
        # 
        # >  For more information about the permissions that are required for the RAM role and how to grant permissions to the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.role = role  # type: str
        # The username of the account that is used to connect to the source database.
        # 
        # >  The permissions that are required for the database account vary with the change tracking scenario. For more information, see [Overview of change tracking scenarios](~~145715~~).
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceRequestSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.password is not None:
            result['Password'] = self.password
        if self.port is not None:
            result['Port'] = self.port
        if self.role is not None:
            result['Role'] = self.role
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Role') is not None:
            self.role = m.get('Role')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class ConfigureSubscriptionInstanceRequestSubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        # Specifies whether to track DDL statements. Default value: true. Valid values:
        # 
        # *   **true**: tracks DDL statements.
        # *   **false**: does not track DDL statements.
        self.ddl = ddl  # type: bool
        # Specifies whether to track DML statements. Default value: true. Valid values:
        # 
        # *   **true**: tracks DML statements.
        # *   **false**: does not tack DML statements.
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceRequestSubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['DDL'] = self.ddl
        if self.dml is not None:
            result['DML'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DDL') is not None:
            self.ddl = m.get('DDL')
        if m.get('DML') is not None:
            self.dml = m.get('DML')
        return self


class ConfigureSubscriptionInstanceRequestSubscriptionInstance(TeaModel):
    def __init__(self, vpcid=None, v_switch_id=None):
        # The ID of the VPC in which the change tracking instance is deployed.
        # 
        # >  This parameter is required only when the **SubscriptionInstanceNetworkType** parameter is set to **vpc**.
        self.vpcid = vpcid  # type: str
        # The ID of the vSwitch in the specified VPC.
        # 
        # >  This parameter is required only when the **SubscriptionInstanceNetworkType** parameter is set to **vpc**.
        self.v_switch_id = v_switch_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceRequestSubscriptionInstance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.vpcid is not None:
            result['VPCId'] = self.vpcid
        if self.v_switch_id is not None:
            result['VSwitchId'] = self.v_switch_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('VPCId') is not None:
            self.vpcid = m.get('VPCId')
        if m.get('VSwitchId') is not None:
            self.v_switch_id = m.get('VSwitchId')
        return self


class ConfigureSubscriptionInstanceRequest(TeaModel):
    def __init__(self, source_endpoint=None, subscription_data_type=None, subscription_instance=None,
                 account_id=None, owner_id=None, region_id=None, subscription_instance_id=None,
                 subscription_instance_name=None, subscription_instance_network_type=None, subscription_object=None):
        self.source_endpoint = source_endpoint  # type: ConfigureSubscriptionInstanceRequestSourceEndpoint
        self.subscription_data_type = subscription_data_type  # type: ConfigureSubscriptionInstanceRequestSubscriptionDataType
        self.subscription_instance = subscription_instance  # type: ConfigureSubscriptionInstanceRequestSubscriptionInstance
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter is discontinued.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the region in which the change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.subscription_instance_id = subscription_instance_id  # type: str
        # The ID of the change tracking instance. You can call the [DescribeSubscriptionInstances](~~49442~~) operation to query the instance ID.
        self.subscription_instance_name = subscription_instance_name  # type: str
        # The network type of the change tracking instance. Set the value to **vpc**. A value of vpc indicates the Virtual Private Cloud (VPC) network type.
        # 
        # > 
        # *   To use the new version of the change tracking feature, you must specify the SubscriptionInstanceNetworkType parameter. You must also specify the **SubscriptionInstance.VPCId** and **SubscriptionInstance.VSwitchID** parameters. If you do not specify the SubscriptionInstanceNetworkType parameter, the previous version of the change tracking feature is used.
        # *   The previous version of the change tracking feature supports self-managed MySQL databases, ApsaraDB RDS for MySQL instances, and PolarDB-X 1.0 instances. The new version of the change tracking feature supports self-managed MySQL databases, ApsaraDB RDS for MySQL instances, PolarDB for MySQL clusters, and Oracle databases.
        self.subscription_instance_network_type = subscription_instance_network_type  # type: str
        # The objects for which you want to track data changes. The value is a JSON string and can contain regular expressions. For more information, see [SubscriptionObjects](~~141902~~).
        self.subscription_object = subscription_object  # type: str

    def validate(self):
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_instance:
            self.subscription_instance.validate()

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_instance is not None:
            result['SubscriptionInstance'] = self.subscription_instance.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        if self.subscription_instance_name is not None:
            result['SubscriptionInstanceName'] = self.subscription_instance_name
        if self.subscription_instance_network_type is not None:
            result['SubscriptionInstanceNetworkType'] = self.subscription_instance_network_type
        if self.subscription_object is not None:
            result['SubscriptionObject'] = self.subscription_object
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('SourceEndpoint') is not None:
            temp_model = ConfigureSubscriptionInstanceRequestSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('SubscriptionDataType') is not None:
            temp_model = ConfigureSubscriptionInstanceRequestSubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionInstance') is not None:
            temp_model = ConfigureSubscriptionInstanceRequestSubscriptionInstance()
            self.subscription_instance = temp_model.from_map(m['SubscriptionInstance'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        if m.get('SubscriptionInstanceName') is not None:
            self.subscription_instance_name = m.get('SubscriptionInstanceName')
        if m.get('SubscriptionInstanceNetworkType') is not None:
            self.subscription_instance_network_type = m.get('SubscriptionInstanceNetworkType')
        if m.get('SubscriptionObject') is not None:
            self.subscription_object = m.get('SubscriptionObject')
        return self


class ConfigureSubscriptionInstanceResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureSubscriptionInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureSubscriptionInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureSubscriptionInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureSubscriptionInstanceAlertRequest(TeaModel):
    def __init__(self, account_id=None, delay_alert_phone=None, delay_alert_status=None, delay_over_seconds=None,
                 error_alert_phone=None, error_alert_status=None, owner_id=None, region_id=None, subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The mobile phone numbers that receive latency-related alerts. Separate mobile phone numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile phone numbers in the Chinese mainland are supported. Up to 10 mobile phone numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the Cloud Monitor console](~~175876~~).
        self.delay_alert_phone = delay_alert_phone  # type: str
        # Specifies whether to monitor task latency. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        # 
        # > 
        # *   The default value is **enable**.
        # *   You must specify at least one of the DelayAlertStatus and **ErrorAlertStatus** parameters.
        self.delay_alert_status = delay_alert_status  # type: str
        # The threshold for triggering latency alerts. The unit is seconds and the value must be an integer. You can set the threshold based on your business needs. To avoid delay fluctuations caused by network and database loads, we recommend that you set the threshold to more than 10 seconds.
        # 
        # >  If the **DelayAlertStatus** parameter is set to **enable**, this parameter must be specified.
        self.delay_over_seconds = delay_over_seconds  # type: str
        # The mobile phone numbers that receive status-related alerts. Separate mobile phone numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile phone numbers in the Chinese mainland are supported. Up to 10 mobile phone numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the Cloud Monitor console](~~175876~~).
        self.error_alert_phone = error_alert_phone  # type: str
        # Specifies whether to monitor task status. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        # 
        # > 
        # *   The default value is **enable**.
        # *   You must specify at least one of the **DelayAlertStatus** and ErrorAlertStatus parameters.
        # *   If the task that you monitor enters an abnormal state, an alert is triggered.
        self.error_alert_status = error_alert_status  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceAlertRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.delay_alert_phone is not None:
            result['DelayAlertPhone'] = self.delay_alert_phone
        if self.delay_alert_status is not None:
            result['DelayAlertStatus'] = self.delay_alert_status
        if self.delay_over_seconds is not None:
            result['DelayOverSeconds'] = self.delay_over_seconds
        if self.error_alert_phone is not None:
            result['ErrorAlertPhone'] = self.error_alert_phone
        if self.error_alert_status is not None:
            result['ErrorAlertStatus'] = self.error_alert_status
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('DelayAlertPhone') is not None:
            self.delay_alert_phone = m.get('DelayAlertPhone')
        if m.get('DelayAlertStatus') is not None:
            self.delay_alert_status = m.get('DelayAlertStatus')
        if m.get('DelayOverSeconds') is not None:
            self.delay_over_seconds = m.get('DelayOverSeconds')
        if m.get('ErrorAlertPhone') is not None:
            self.error_alert_phone = m.get('ErrorAlertPhone')
        if m.get('ErrorAlertStatus') is not None:
            self.error_alert_status = m.get('ErrorAlertStatus')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class ConfigureSubscriptionInstanceAlertResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceAlertResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureSubscriptionInstanceAlertResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureSubscriptionInstanceAlertResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureSubscriptionInstanceAlertResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureSubscriptionInstanceAlertResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureSynchronizationJobRequestDestinationEndpoint(TeaModel):
    def __init__(self, data_base_name=None, ip=None, instance_id=None, instance_type=None, password=None, port=None,
                 user_name=None):
        # The name of the database to which the synchronization object in the destination instance belongs.
        self.data_base_name = data_base_name  # type: str
        # The IP address of the destination database.
        # 
        # >  You must specify this parameter only if the **DestinationEndpoint.InstanceType** parameter is set to **Express**, **dg**, or **cen**.
        self.ip = ip  # type: str
        # The ID of the destination instance.
        # 
        # >  If the **DestinationEndpoint.InstanceType** parameter is set to **MaxCompute** or **DataHub**, you must specify the name of the MaxCompute project or the DataHub project.
        # 
        # If the destination instance is an AnalyticDB for MySQL cluster, specify the ID of the AnalyticDB for MySQL cluster.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance. Valid values:
        # 
        # *   **Redis**: ApsaraDB for Redis instance
        # *   **RDS**: ApsaraDB RDS instance
        # *   **PolarDB**: PolarDB for MySQL cluster or PolarDB O Edition cluster
        # *   **ECS**: self-managed database that is hosted on ECS
        # *   **Express**: self-managed database that is connected over Express Connect
        # *   **DataHub**: DataHub project
        # *   **MaxCompute**: MaxCompute project
        # *   **AnalyticDB**: AnalyticDB for MySQL cluster V3.0 or V2.0
        # *   **Greenplum**: AnalyticDB for PostgreSQL instance
        # 
        # >  The default value is **RDS**.
        self.instance_type = instance_type  # type: str
        # The password of the destination database account.
        # 
        # > 
        # *   If the **DestinationEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**, you must specify the DestinationEndpoint.Password parameter.
        self.password = password  # type: str
        # The service port number of the destination database.
        # 
        # >  You must specify this parameter only if the **DestinationEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**.
        self.port = port  # type: str
        # The database account of the destination database.
        # 
        # > 
        # *   The permissions that are required for database accounts vary with the synchronization scenario. For more information, see [Overview of data synchronization scenarios](~~140954~~).
        # *   If the **DestinationEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**, you must specify the DestinationEndpoint.UserName parameter.
        # *   If the **DestinationEndpoint.InstanceType** parameter is set to RDS and the database version is MySQL 5.5 or MySQL 5.6, you do not need to specify the DestinationEndpoint.UserName and **DestinationEndpoint.Password** parameters.
        # *   If the **DestinationEndpoint.InstanceType** parameter is set to **Redis**, you do not need to specify the DestinationEndpoint.UserName parameter.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobRequestDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_base_name is not None:
            result['DataBaseName'] = self.data_base_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.password is not None:
            result['Password'] = self.password
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataBaseName') is not None:
            self.data_base_name = m.get('DataBaseName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class ConfigureSynchronizationJobRequestPartitionKey(TeaModel):
    def __init__(self, modify_time_day=None, modify_time_hour=None, modify_time_minute=None,
                 modify_time_month=None, modify_time_year=None):
        # Specifies whether the incremental data table contains partitions defined by the modifytime_day field. Valid values: **true** and **false**.
        # 
        # >  This parameter is available only if the **DestinationEndpoint.InstanceType** parameter is set to **MaxCompute**.
        self.modify_time_day = modify_time_day  # type: bool
        # Specifies whether the incremental data table contains partitions defined by the modifytime_hour field. Valid values: **true** and **false**.
        # 
        # >  This parameter is available only if the **DestinationEndpoint.InstanceType** parameter is set to **MaxCompute**.
        self.modify_time_hour = modify_time_hour  # type: bool
        # Specifies whether the incremental data table contains partitions defined by the modifytime_minute field. Valid values: **true** and **false**.
        # 
        # >  This parameter is available only if the **DestinationEndpoint.InstanceType** parameter is set to **MaxCompute**.
        self.modify_time_minute = modify_time_minute  # type: bool
        # Specifies whether the incremental data table contains partitions defined by the modifytime_month field. Valid values: **true** and **false**.
        # 
        # >  This parameter is available only if the **DestinationEndpoint.InstanceType** parameter is set to **MaxCompute**.
        self.modify_time_month = modify_time_month  # type: bool
        # Specifies whether the incremental data table contains partitions defined by the modifytime_year field. Valid values: **true** and **false**.
        # 
        # >  This parameter is available only if the **DestinationEndpoint.InstanceType** parameter is set to **MaxCompute**.
        self.modify_time_year = modify_time_year  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobRequestPartitionKey, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.modify_time_day is not None:
            result['ModifyTime_Day'] = self.modify_time_day
        if self.modify_time_hour is not None:
            result['ModifyTime_Hour'] = self.modify_time_hour
        if self.modify_time_minute is not None:
            result['ModifyTime_Minute'] = self.modify_time_minute
        if self.modify_time_month is not None:
            result['ModifyTime_Month'] = self.modify_time_month
        if self.modify_time_year is not None:
            result['ModifyTime_Year'] = self.modify_time_year
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ModifyTime_Day') is not None:
            self.modify_time_day = m.get('ModifyTime_Day')
        if m.get('ModifyTime_Hour') is not None:
            self.modify_time_hour = m.get('ModifyTime_Hour')
        if m.get('ModifyTime_Minute') is not None:
            self.modify_time_minute = m.get('ModifyTime_Minute')
        if m.get('ModifyTime_Month') is not None:
            self.modify_time_month = m.get('ModifyTime_Month')
        if m.get('ModifyTime_Year') is not None:
            self.modify_time_year = m.get('ModifyTime_Year')
        return self


class ConfigureSynchronizationJobRequestSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, ip=None, instance_id=None, instance_type=None, owner_id=None,
                 password=None, port=None, role=None, user_name=None):
        # The name of the database to which the synchronization object in the source instance belongs.
        self.database_name = database_name  # type: str
        # The IP address of the source database.
        # 
        # >  You must specify this parameter only if the **SourceEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**.
        self.ip = ip  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance. Valid values:
        # 
        # *   **RDS**: ApsaraDB RDS instance
        # *   **Redis**: ApsaraDB for Redis instance
        # *   **PolarDB**: PolarDB for MySQL cluster or PolarDB O Edition cluster
        # *   **ECS**: self-managed database that is hosted on Elastic Compute Service (ECS)
        # *   **Express**: self-managed database that is connected over Express Connect
        # *   **dg**: self-managed database that is connected over Database Gateway
        # *   **cen**: self-managed database that is connected over Cloud Enterprise Network (CEN)
        # 
        # >  The default value is **RDS**.
        self.instance_type = instance_type  # type: str
        # The ID of the Alibaba Cloud account that owns the source RDS instance.
        # 
        # >  You can specify this parameter to synchronize data across different Alibaba Cloud accounts. In this case, you also need to specify the **SourceEndpoint.Role** parameter.
        self.owner_id = owner_id  # type: str
        # The password of the source database account.
        # 
        # >  You must specify this parameter only if the **SourceEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**.
        self.password = password  # type: str
        # The service port number of the source database.
        # 
        # >  You must specify this parameter only if the **SourceEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**.
        self.port = port  # type: str
        # The name of the RAM role configured for the Alibaba Cloud account that owns the source instance.
        # 
        # >  You must specify this parameter when you synchronize data across different Alibaba Cloud accounts. For information about the permissions and authorization methods of the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.role = role  # type: str
        # The database account of the source database.
        # 
        # > 
        # *   You must specify this parameter only if the **SourceEndpoint.InstanceType** parameter is set to **ECS**, **Express**, **dg**, or **cen**.
        # *   If the **SourceEndpoint.InstanceType** parameter is set to **Redis**, you do not need to specify the database account.
        # *   The permissions that are required for database accounts vary with the synchronization scenario. For more information, see [Overview of data synchronization scenarios](~~140954~~).
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobRequestSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.password is not None:
            result['Password'] = self.password
        if self.port is not None:
            result['Port'] = self.port
        if self.role is not None:
            result['Role'] = self.role
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Role') is not None:
            self.role = m.get('Role')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class ConfigureSynchronizationJobRequest(TeaModel):
    def __init__(self, destination_endpoint=None, partition_key=None, source_endpoint=None, account_id=None,
                 checkpoint=None, data_initialization=None, migration_reserved=None, owner_id=None, region_id=None,
                 structure_initialization=None, synchronization_direction=None, synchronization_job_id=None, synchronization_job_name=None,
                 synchronization_objects=None):
        self.destination_endpoint = destination_endpoint  # type: ConfigureSynchronizationJobRequestDestinationEndpoint
        self.partition_key = partition_key  # type: ConfigureSynchronizationJobRequestPartitionKey
        self.source_endpoint = source_endpoint  # type: ConfigureSynchronizationJobRequestSourceEndpoint
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The synchronization checkpoint.
        self.checkpoint = checkpoint  # type: str
        # Specifies whether to perform initial full data synchronization. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        # 
        # >  Default value: **true**.
        self.data_initialization = data_initialization  # type: bool
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet special requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        # 
        # >  This parameter can be used for data synchronization between ApsaraDB for Redis Enterprise Edition instances. For more information, see [Use OpenAPI Explorer to configure one-way or two-way data synchronization between ApsaraDB for Redis Enterprise Edition instances](~~155967~~).
        self.migration_reserved = migration_reserved  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # Specifies whether to perform initial schema synchronization. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        # 
        # >  Default value: **true**.
        self.structure_initialization = structure_initialization  # type: bool
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   The value **Reverse** takes effect only if the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the [DescribeSynchronizationJobs](~~49454~~) operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str
        # The name of the data synchronization task.
        # 
        # >  We recommend that you specify an informative name for easy identification. You do not need to use a unique task name.
        self.synchronization_job_name = synchronization_job_name  # type: str
        # The objects that you want to synchronize. The value is a JSON string and can contain regular expressions. For more information, see [SynchronizationObjects](~~141901~~).
        self.synchronization_objects = synchronization_objects  # type: str

    def validate(self):
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.partition_key:
            self.partition_key.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()

    def to_map(self):
        _map = super(ConfigureSynchronizationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.partition_key is not None:
            result['PartitionKey'] = self.partition_key.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.migration_reserved is not None:
            result['MigrationReserved'] = self.migration_reserved
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        if self.synchronization_job_name is not None:
            result['SynchronizationJobName'] = self.synchronization_job_name
        if self.synchronization_objects is not None:
            result['SynchronizationObjects'] = self.synchronization_objects
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationEndpoint') is not None:
            temp_model = ConfigureSynchronizationJobRequestDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('PartitionKey') is not None:
            temp_model = ConfigureSynchronizationJobRequestPartitionKey()
            self.partition_key = temp_model.from_map(m['PartitionKey'])
        if m.get('SourceEndpoint') is not None:
            temp_model = ConfigureSynchronizationJobRequestSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('MigrationReserved') is not None:
            self.migration_reserved = m.get('MigrationReserved')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        if m.get('SynchronizationJobName') is not None:
            self.synchronization_job_name = m.get('SynchronizationJobName')
        if m.get('SynchronizationObjects') is not None:
            self.synchronization_objects = m.get('SynchronizationObjects')
        return self


class ConfigureSynchronizationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureSynchronizationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureSynchronizationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureSynchronizationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureSynchronizationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureSynchronizationJobAlertRequest(TeaModel):
    def __init__(self, account_id=None, delay_alert_phone=None, delay_alert_status=None, delay_over_seconds=None,
                 error_alert_phone=None, error_alert_status=None, owner_id=None, region_id=None, synchronization_direction=None,
                 synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The mobile phone numbers that receive latency-related alerts. Separate mobile phone numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile phone numbers in the Chinese mainland are supported. Up to 10 mobile phone numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the Cloud Monitor console](~~175876~~).
        self.delay_alert_phone = delay_alert_phone  # type: str
        # Specifies whether to monitor task latency. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        # 
        # > 
        # *   The default value is **enable**.
        # *   You must specify at least one of the DelayAlertStatus and **ErrorAlertStatus** parameters.
        self.delay_alert_status = delay_alert_status  # type: str
        # The threshold for triggering latency alerts. The unit is seconds and the value must be an integer. You can set the threshold based on your business needs. To avoid delay fluctuations caused by network and database loads, we recommend that you set the threshold to more than 10 seconds.
        # 
        # >  If the **DelayAlertStatus** parameter is set to **enable**, this parameter must be specified.
        self.delay_over_seconds = delay_over_seconds  # type: str
        # The mobile phone numbers that receive status-related alerts. Separate mobile phone numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for China site (aliyun.com) users. Only mobile phone numbers in the Chinese mainland are supported. Up to 10 mobile phone numbers can be specified.
        # *   International site (alibabacloud.com) users cannot receive alerts by using mobile phones, but can [set alert rules for DTS tasks in the Cloud Monitor console](~~175876~~).
        self.error_alert_phone = error_alert_phone  # type: str
        # Specifies whether to monitor task status. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        # 
        # > 
        # *   The default value is **enable**.
        # *   You must specify at least one of the **DelayAlertStatus** and ErrorAlertStatus parameters.
        # *   If the task that you monitor enters an abnormal state, an alert is triggered.
        self.error_alert_status = error_alert_status  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # >  Default value: **Forward**.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the DescribeSynchronizationJobs operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobAlertRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.delay_alert_phone is not None:
            result['DelayAlertPhone'] = self.delay_alert_phone
        if self.delay_alert_status is not None:
            result['DelayAlertStatus'] = self.delay_alert_status
        if self.delay_over_seconds is not None:
            result['DelayOverSeconds'] = self.delay_over_seconds
        if self.error_alert_phone is not None:
            result['ErrorAlertPhone'] = self.error_alert_phone
        if self.error_alert_status is not None:
            result['ErrorAlertStatus'] = self.error_alert_status
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('DelayAlertPhone') is not None:
            self.delay_alert_phone = m.get('DelayAlertPhone')
        if m.get('DelayAlertStatus') is not None:
            self.delay_alert_status = m.get('DelayAlertStatus')
        if m.get('DelayOverSeconds') is not None:
            self.delay_over_seconds = m.get('DelayOverSeconds')
        if m.get('ErrorAlertPhone') is not None:
            self.error_alert_phone = m.get('ErrorAlertPhone')
        if m.get('ErrorAlertStatus') is not None:
            self.error_alert_status = m.get('ErrorAlertStatus')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class ConfigureSynchronizationJobAlertResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobAlertResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureSynchronizationJobAlertResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureSynchronizationJobAlertResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureSynchronizationJobAlertResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureSynchronizationJobAlertResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ConfigureSynchronizationJobReplicatorCompareRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None,
                 synchronization_direction=None, synchronization_job_id=None, synchronization_replicator_compare_enable=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   This parameter is required only when the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the [DescribeSynchronizationJobs](~~49454~~) operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str
        # Specifies whether to enable image matching. Valid values:
        # 
        # *   **true**: enables image matching
        # *   **false**: disables image matching
        self.synchronization_replicator_compare_enable = synchronization_replicator_compare_enable  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobReplicatorCompareRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        if self.synchronization_replicator_compare_enable is not None:
            result['SynchronizationReplicatorCompareEnable'] = self.synchronization_replicator_compare_enable
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        if m.get('SynchronizationReplicatorCompareEnable') is not None:
            self.synchronization_replicator_compare_enable = m.get('SynchronizationReplicatorCompareEnable')
        return self


class ConfigureSynchronizationJobReplicatorCompareResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ConfigureSynchronizationJobReplicatorCompareResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ConfigureSynchronizationJobReplicatorCompareResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ConfigureSynchronizationJobReplicatorCompareResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ConfigureSynchronizationJobReplicatorCompareResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ConfigureSynchronizationJobReplicatorCompareResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CountJobByConditionRequest(TeaModel):
    def __init__(self, dest_db_type=None, group_id=None, job_type=None, params=None, region=None, region_id=None,
                 src_db_type=None, status=None, type=None):
        # The type of the destination database.
        self.dest_db_type = dest_db_type  # type: str
        # The ID of the DTS task.
        self.group_id = group_id  # type: str
        # The type of the DTS task. Valid values:
        # 
        # *   **MIGRATION**: data migration task
        # *   **SYNC**: data synchronization task
        # *   **SUBSCRIBE**: change tracking task
        self.job_type = job_type  # type: str
        # The content of the query condition, which corresponds to the value of the JobType parameter.
        self.params = params  # type: str
        # One of the query conditions. The ID of the region. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [Supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The type of the source database.
        self.src_db_type = src_db_type  # type: str
        # The status of the DTS task.
        # 
        # Valid values for a data migration task:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is in precheck.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **PreCheckPass**: The task passed the precheck.
        # *   **NotConfigured**: The task is not configured.
        # *   **Migrating**: The task is in progress.
        # *   **Suspending**: The task is paused.
        # *   **MigrationFailed**: The task failed to migrate data.
        # *   **Finished**: The task is complete.
        # *   **Retrying**: The task is being retried.
        # *   **Upgrade**: The task is being upgraded.
        # *   **Locked**: The task is locked.
        # *   **Downgrade**: The task is being downgraded.
        # 
        # Valid values for a data synchronization task:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is in precheck.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **PreCheckPass**: The task passed the precheck.
        # *   **NotConfigured**: The task is not configured.
        # *   **Initializing**: The task is performing initial synchronization.
        # *   **InitializeFailed**: Initial synchronization failed.
        # *   **Synchronizing**: The task is in progress.
        # *   **Failed**: The task failed to synchronize data.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is complete.
        # *   **Retrying**: The task is being retried.
        # *   **Upgrade**: The task is being upgraded.
        # *   **Locked**: The task is locked.
        # *   **Downgrade**: The task is being downgraded.
        # 
        # Valid values for a change tracking task:
        # 
        # *   **NotConfigured**: The task is not configured.
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is in precheck.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **PreCheckPass**: The task passed the precheck.
        # *   **Starting**: The task is being started.
        # *   **Normal**: The task is running as expected.
        # *   **Retrying**: The task is being retried.
        # *   **Abnormal**: The task is not running as expected.
        # *   **Upgrade**: The task is being upgraded.
        # *   **Locked**: The task is locked.
        # *   **Downgrade**: The task is being downgraded.
        self.status = status  # type: str
        # The content of the query condition. Valid values:
        # 
        # *   **name**: the name of the task
        # *   **rds**: the ID of the destination instance
        # *   **instance**: the ID of the Data Transmission Service (DTS) instance
        # *   **srcRds**: the ID of the source instance
        # 
        # > The value of this parameter corresponds to the value of the **JobType** parameter.
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CountJobByConditionRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dest_db_type is not None:
            result['DestDbType'] = self.dest_db_type
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.params is not None:
            result['Params'] = self.params
        if self.region is not None:
            result['Region'] = self.region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.src_db_type is not None:
            result['SrcDbType'] = self.src_db_type
        if self.status is not None:
            result['Status'] = self.status
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestDbType') is not None:
            self.dest_db_type = m.get('DestDbType')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('Params') is not None:
            self.params = m.get('Params')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SrcDbType') is not None:
            self.src_db_type = m.get('SrcDbType')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class CountJobByConditionResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None, total_record_count=None):
        # The internal error code. This parameter will be removed soon.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the  **%s** variable in the **ErrMessage** parameter.
        # 
        # > If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool
        # The total number of data synchronization instances that meet the requirements and belong to your Alibaba Cloud account.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(CountJobByConditionResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class CountJobByConditionResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CountJobByConditionResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CountJobByConditionResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CountJobByConditionResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateConsumerChannelRequest(TeaModel):
    def __init__(self, consumer_group_name=None, consumer_group_password=None, consumer_group_user_name=None,
                 dts_instance_id=None, dts_job_id=None, region_id=None):
        # The name of the consumer group. The name can be up to 128 characters in length. We recommend that you use an informative name for easy identification.
        self.consumer_group_name = consumer_group_name  # type: str
        # The password of the consumer group.
        # 
        # *   A password must contain two or more of the following characters: uppercase letters, lowercase letters, digits, and special characters.
        # *   A password must be 8 to 32 characters in length.
        self.consumer_group_password = consumer_group_password  # type: str
        # The username of the consumer group.
        # 
        # *   A username must contain one or more of the following characters: uppercase letters, lowercase letters, digits, and underscores (\_).
        # *   A username cannot exceed 16 characters in length.
        self.consumer_group_user_name = consumer_group_user_name  # type: str
        # The ID of the change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId**. parameters.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId**. parameters.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the region where the change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateConsumerChannelRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_name is not None:
            result['ConsumerGroupName'] = self.consumer_group_name
        if self.consumer_group_password is not None:
            result['ConsumerGroupPassword'] = self.consumer_group_password
        if self.consumer_group_user_name is not None:
            result['ConsumerGroupUserName'] = self.consumer_group_user_name
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupName') is not None:
            self.consumer_group_name = m.get('ConsumerGroupName')
        if m.get('ConsumerGroupPassword') is not None:
            self.consumer_group_password = m.get('ConsumerGroupPassword')
        if m.get('ConsumerGroupUserName') is not None:
            self.consumer_group_user_name = m.get('ConsumerGroupUserName')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class CreateConsumerChannelResponseBody(TeaModel):
    def __init__(self, consumer_group_id=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        # The ID of the consumer group. You can specify this parameter on a downstream client when you consume tracked data.
        self.consumer_group_id = consumer_group_id  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateConsumerChannelResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_id is not None:
            result['ConsumerGroupID'] = self.consumer_group_id
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupID') is not None:
            self.consumer_group_id = m.get('ConsumerGroupID')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateConsumerChannelResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateConsumerChannelResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateConsumerChannelResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateConsumerChannelResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateConsumerGroupRequest(TeaModel):
    def __init__(self, account_id=None, consumer_group_name=None, consumer_group_password=None,
                 consumer_group_user_name=None, owner_id=None, region_id=None, subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The name of the consumer group. The name cannot exceed 128 characters in length. We recommend that you use an informative name for easy identification.
        self.consumer_group_name = consumer_group_name  # type: str
        # The password that corresponds to the username of the consumer group.
        # 
        # *   A password must contain two or more of the following characters: uppercase letters, lowercase letters, digits, and special characters.
        # *   A password must be 8 to 32 characters in length.
        self.consumer_group_password = consumer_group_password  # type: str
        # The username of the consumer group.
        # 
        # *   A username must contain one or more of the following characters: uppercase letters, lowercase letters, digits, and underscores (\_).
        # *   A username cannot exceed 16 characters in length.
        self.consumer_group_user_name = consumer_group_user_name  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateConsumerGroupRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.consumer_group_name is not None:
            result['ConsumerGroupName'] = self.consumer_group_name
        if self.consumer_group_password is not None:
            result['ConsumerGroupPassword'] = self.consumer_group_password
        if self.consumer_group_user_name is not None:
            result['ConsumerGroupUserName'] = self.consumer_group_user_name
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ConsumerGroupName') is not None:
            self.consumer_group_name = m.get('ConsumerGroupName')
        if m.get('ConsumerGroupPassword') is not None:
            self.consumer_group_password = m.get('ConsumerGroupPassword')
        if m.get('ConsumerGroupUserName') is not None:
            self.consumer_group_user_name = m.get('ConsumerGroupUserName')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class CreateConsumerGroupResponseBody(TeaModel):
    def __init__(self, consumer_group_id=None, err_code=None, err_message=None, request_id=None, success=None):
        # The ID of the consumer group.
        self.consumer_group_id = consumer_group_id  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateConsumerGroupResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_id is not None:
            result['ConsumerGroupID'] = self.consumer_group_id
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupID') is not None:
            self.consumer_group_id = m.get('ConsumerGroupID')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateConsumerGroupResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateConsumerGroupResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateConsumerGroupResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateConsumerGroupResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateDedicatedClusterMonitorRuleRequest(TeaModel):
    def __init__(self, cpu_alarm_threshold=None, dedicated_cluster_id=None, disk_alarm_threshold=None,
                 du_alarm_threshold=None, instance_id=None, mem_alarm_threshold=None, notice_switch=None, owner_id=None, phones=None,
                 region_id=None):
        # The alert threshold for CPU utilization. Unit: percentage.
        self.cpu_alarm_threshold = cpu_alarm_threshold  # type: long
        # The ID of the cluster.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The alert threshold for disk usage. Unit: percentage.
        self.disk_alarm_threshold = disk_alarm_threshold  # type: long
        # The alert threshold for DTS Unit (DU) usage. Unit: percentage.
        self.du_alarm_threshold = du_alarm_threshold  # type: long
        # The ID of the instance.
        self.instance_id = instance_id  # type: str
        # The alert threshold for memory usage. Unit: percentage.
        self.mem_alarm_threshold = mem_alarm_threshold  # type: long
        # Specifies whether to enable the alert feature. Valid values:
        # 
        # *   **1**: enables the alert feature.
        # *   **0**: disables the alert feature.
        self.notice_switch = notice_switch  # type: long
        self.owner_id = owner_id  # type: str
        # The mobile phone number to which alerts are sent. Separate multiple mobile phone numbers with commas (,).
        self.phones = phones  # type: str
        # The ID of the region in which the Data Transmission Service (DTS) instance resides.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateDedicatedClusterMonitorRuleRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.cpu_alarm_threshold is not None:
            result['CpuAlarmThreshold'] = self.cpu_alarm_threshold
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.disk_alarm_threshold is not None:
            result['DiskAlarmThreshold'] = self.disk_alarm_threshold
        if self.du_alarm_threshold is not None:
            result['DuAlarmThreshold'] = self.du_alarm_threshold
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.mem_alarm_threshold is not None:
            result['MemAlarmThreshold'] = self.mem_alarm_threshold
        if self.notice_switch is not None:
            result['NoticeSwitch'] = self.notice_switch
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.phones is not None:
            result['Phones'] = self.phones
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CpuAlarmThreshold') is not None:
            self.cpu_alarm_threshold = m.get('CpuAlarmThreshold')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DiskAlarmThreshold') is not None:
            self.disk_alarm_threshold = m.get('DiskAlarmThreshold')
        if m.get('DuAlarmThreshold') is not None:
            self.du_alarm_threshold = m.get('DuAlarmThreshold')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('MemAlarmThreshold') is not None:
            self.mem_alarm_threshold = m.get('MemAlarmThreshold')
        if m.get('NoticeSwitch') is not None:
            self.notice_switch = m.get('NoticeSwitch')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('Phones') is not None:
            self.phones = m.get('Phones')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class CreateDedicatedClusterMonitorRuleResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, http_status_code=None, request_id=None, success=None):
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateDedicatedClusterMonitorRuleResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateDedicatedClusterMonitorRuleResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateDedicatedClusterMonitorRuleResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateDedicatedClusterMonitorRuleResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateDedicatedClusterMonitorRuleResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateDtsInstanceRequest(TeaModel):
    def __init__(self, auto_pay=None, auto_start=None, compute_unit=None, database_count=None,
                 destination_endpoint_engine_name=None, destination_region=None, du=None, fee_type=None, instance_class=None, job_id=None,
                 pay_type=None, period=None, quantity=None, region_id=None, resource_group_id=None,
                 source_endpoint_engine_name=None, source_region=None, sync_architecture=None, type=None, used_time=None):
        # Specifies whether to automatically renew the DTS instance when it expires. Valid values:
        # 
        # *   **false**: does not automatically renew the DTS instance when it expires. This is the default value.
        # *   **true**: automatically renews the DTS instance when it expires.
        self.auto_pay = auto_pay  # type: bool
        # Specifies whether to automatically start the task after the DTS instance is purchased. Valid values:
        # 
        # *   **false**: does not automatically start the task after the DTS instance is purchased. This is the default value.
        # *   **true**: automatically starts the task after the DTS instance is purchased.
        self.auto_start = auto_start  # type: bool
        # The specifications of the extract, transform, and load (ETL) instance. The unit is compute unit (CU). One CU is equal to 1 vCPU and 4 GB of memory. The value of this parameter must be an integer greater than or equal to 2.
        self.compute_unit = compute_unit  # type: int
        # The number of private custom ApsaraDB RDS instances in a PolarDB-X instance. Default value: **1**.
        # 
        # >  You must specify this parameter only if the **SourceEndpointEngineName** parameter is set to **drds**.
        self.database_count = database_count  # type: int
        # The database engine of the destination instance.
        # 
        # *   **MySQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **polardb_o**: PolarDB for Oracle cluster
        # *   **polardb_pg**: PolarDB for PostgreSQL cluster
        # *   **Redis**: ApsaraDB for Redis instance or self-managed Redis database
        # *   **DRDS**: PolarDB-X 1.0 or PolarDB-X 2.0 instance
        # *   **PostgreSQL**: self-managed PostgreSQL database
        # *   **odps**: MaxCompute project
        # *   **oracle**: self-managed Oracle database
        # *   **mongodb**: ApsaraDB for MongoDB instance or self-managed MongoDB database
        # *   **tidb**: TiDB database
        # *   **ADS**: AnalyticDB for MySQL V2.0 cluster
        # *   **ADB30**: AnalyticDB for MySQL V3.0 cluster
        # *   **Greenplum**: AnalyticDB for PostgreSQL instance
        # *   **MSSQL**: ApsaraDB RDS for SQL Server instance or self-managed SQL Server database
        # *   **kafka**: Message Queue for Apache Kafka instance or self-managed Kafka cluster
        # *   **DataHub**: DataHub project
        # *   **DB2**: self-managed Db2 for LUW database
        # *   **as400**: AS/400
        # *   **Tablestore**: Tablestore instance
        # 
        # > 
        # *   The default value is **MySQL**.
        # *   For more information about the supported source and destination databases, see [Overview of data synchronization scenarios](~~130744~~) and [Overview of data migration scenarios](~~26618~~).
        # *   You must specify one of this parameter and the **JobId** parameter.
        self.destination_endpoint_engine_name = destination_endpoint_engine_name  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  You must specify one of this parameter and the **JobId** parameter.
        self.destination_region = destination_region  # type: str
        # The number of DTS units (DUs) that are assigned to a DTS task that is run on a DTS dedicated cluster. Valid values: **1** to **100**.
        # 
        # > 
        # *   The value of this parameter must be within the range of the number of DUs available for the DTS dedicated cluster.
        self.du = du  # type: int
        # The billing type for a change tracking instance. Valid values: ONLY_CONFIGURATION_FEE and CONFIGURATION_FEE_AND_DATA_FEE. ONLY_CONFIGURATION_FEE: charges only configuration fees. CONFIGURATION_FEE_AND_DATA_FEE: charges configuration fees and data traffic fees.
        self.fee_type = fee_type  # type: str
        # The instance class.
        # 
        # *   DTS supports the following instance classes for a data migration instance: **xxlarge**, **xlarge**, **large**, **medium**, and **small**.
        # *   DTS supports the following instance classes for a data synchronization instance: **large**, **medium**, **small**, and **micro**.
        # 
        # >  For more information about the test performance of each instance class, see [Specifications of data migration instances](~~26606~~) and [Specifications of data synchronization instances](~~26605~~).
        self.instance_class = instance_class  # type: str
        # The ID of the task. You can call the **ConfigureDtsJob** operation to obtain the task ID from the **DtsJobId** parameter.
        # 
        # >  If this parameter is specified, you do not need to specify the **SourceRegion**, **DestinationRegion**, **Type**, **SourceEndpointEngineName**, or **DestinationEndpointEngineName** parameter. Even if these parameters are specified, the value of the **JobId** parameter takes precedence.
        self.job_id = job_id  # type: str
        # The billing method. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        # 
        # >  This parameter must be specified.
        self.pay_type = pay_type  # type: str
        # The unit of the subscription duration. Valid values: **Year** and **Month**.
        # 
        # >  You must specify this parameter only if the **PayType** parameter is set to **PrePaid**.
        self.period = period  # type: str
        # The number of DTS instances that you want to purchase.
        # 
        # >  Only a single instance can be purchased each time.
        self.quantity = quantity  # type: int
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The ID of the resource group.
        self.resource_group_id = resource_group_id  # type: str
        # The database engine of the source instance.
        # 
        # *   **MySQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **PolarDB**: PolarDB for MySQL cluster
        # *   **polardb_o**: PolarDB for Oracle cluster
        # *   **polardb_pg**: PolarDB for PostgreSQL cluster
        # *   **Redis**: ApsaraDB for Redis instance or self-managed Redis database
        # *   **DRDS**: PolarDB-X 1.0 or PolarDB-X 2.0 instance
        # *   **PostgreSQL**: self-managed PostgreSQL database
        # *   **odps**: MaxCompute project
        # *   **oracle**: self-managed Oracle database
        # *   **mongodb**: ApsaraDB for MongoDB instance or self-managed MongoDB database
        # *   **tidb**: TiDB database
        # *   **ADS**: AnalyticDB for MySQL V2.0 cluster
        # *   **ADB30**: AnalyticDB for MySQL V3.0 cluster
        # *   **Greenplum**: AnalyticDB for PostgreSQL instance
        # *   **MSSQL**: ApsaraDB RDS for SQL Server instance or self-managed SQL Server database
        # *   **kafka**: Message Queue for Apache Kafka instance or self-managed Kafka cluster
        # *   **DataHub**: DataHub project
        # *   **DB2**: self-managed Db2 for LUW database
        # *   **as400**: AS/400
        # *   **Tablestore**: Tablestore instance
        # 
        # > 
        # *   The default value is **MySQL**.
        # *   For more information about the supported source and destination databases, see [Overview of data synchronization scenarios](~~130744~~) and [Overview of data migration scenarios](~~26618~~).
        # *   You must specify one of this parameter and the **JobId** parameter.
        self.source_endpoint_engine_name = source_endpoint_engine_name  # type: str
        # The ID of the region in which the source instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  You must specify one of this parameter and the **JobId** parameter.
        self.source_region = source_region  # type: str
        # The synchronization topology. Valid values:
        # 
        # *   **oneway**: one-way synchronization. This is the default value.
        # *   **bidirectional**: two-way synchronization.
        self.sync_architecture = sync_architecture  # type: str
        # The type of the DTS instance. Valid values:
        # 
        # *   **MIGRATION**: data migration instance
        # 
        # *   **SYNC**: data synchronization instance
        # 
        # *   **SUBSCRIBE**: change tracking instance
        # 
        # > You must specify one of this parameter and the **JobId** parameter.
        self.type = type  # type: str
        # The subscription duration.
        # 
        # *   Valid values if the **Period** parameter is set to **Month**: 1, 2, 3, 4, 5, 6, 7, 8, and 9.
        # 
        # *   Valid values if the **Period** parameter is set to **Year**: 1, 2, 3, and 5.
        # 
        # > *   You must specify this parameter only if the **PayType** parameter is set to **PrePaid**.
        #    *   You can set the **Period** parameter to specify the unit of the subscription duration.
        self.used_time = used_time  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateDtsInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.auto_pay is not None:
            result['AutoPay'] = self.auto_pay
        if self.auto_start is not None:
            result['AutoStart'] = self.auto_start
        if self.compute_unit is not None:
            result['ComputeUnit'] = self.compute_unit
        if self.database_count is not None:
            result['DatabaseCount'] = self.database_count
        if self.destination_endpoint_engine_name is not None:
            result['DestinationEndpointEngineName'] = self.destination_endpoint_engine_name
        if self.destination_region is not None:
            result['DestinationRegion'] = self.destination_region
        if self.du is not None:
            result['Du'] = self.du
        if self.fee_type is not None:
            result['FeeType'] = self.fee_type
        if self.instance_class is not None:
            result['InstanceClass'] = self.instance_class
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.period is not None:
            result['Period'] = self.period
        if self.quantity is not None:
            result['Quantity'] = self.quantity
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_group_id is not None:
            result['ResourceGroupId'] = self.resource_group_id
        if self.source_endpoint_engine_name is not None:
            result['SourceEndpointEngineName'] = self.source_endpoint_engine_name
        if self.source_region is not None:
            result['SourceRegion'] = self.source_region
        if self.sync_architecture is not None:
            result['SyncArchitecture'] = self.sync_architecture
        if self.type is not None:
            result['Type'] = self.type
        if self.used_time is not None:
            result['UsedTime'] = self.used_time
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AutoPay') is not None:
            self.auto_pay = m.get('AutoPay')
        if m.get('AutoStart') is not None:
            self.auto_start = m.get('AutoStart')
        if m.get('ComputeUnit') is not None:
            self.compute_unit = m.get('ComputeUnit')
        if m.get('DatabaseCount') is not None:
            self.database_count = m.get('DatabaseCount')
        if m.get('DestinationEndpointEngineName') is not None:
            self.destination_endpoint_engine_name = m.get('DestinationEndpointEngineName')
        if m.get('DestinationRegion') is not None:
            self.destination_region = m.get('DestinationRegion')
        if m.get('Du') is not None:
            self.du = m.get('Du')
        if m.get('FeeType') is not None:
            self.fee_type = m.get('FeeType')
        if m.get('InstanceClass') is not None:
            self.instance_class = m.get('InstanceClass')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('Quantity') is not None:
            self.quantity = m.get('Quantity')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceGroupId') is not None:
            self.resource_group_id = m.get('ResourceGroupId')
        if m.get('SourceEndpointEngineName') is not None:
            self.source_endpoint_engine_name = m.get('SourceEndpointEngineName')
        if m.get('SourceRegion') is not None:
            self.source_region = m.get('SourceRegion')
        if m.get('SyncArchitecture') is not None:
            self.sync_architecture = m.get('SyncArchitecture')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        if m.get('UsedTime') is not None:
            self.used_time = m.get('UsedTime')
        return self


class CreateDtsInstanceResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, instance_id=None, job_id=None, request_id=None, success=None):
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The ID of the DTS instance.
        self.instance_id = instance_id  # type: str
        # The ID of the task.
        self.job_id = job_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateDtsInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateDtsInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateDtsInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateDtsInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateDtsInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateJobMonitorRuleRequest(TeaModel):
    def __init__(self, delay_rule_time=None, dts_job_id=None, notice_value=None, period=None, phone=None,
                 region_id=None, state=None, times=None, type=None):
        # The threshold for triggering latency alerts.
        # 
        # *   If the **Type** parameter is set to **delay**, the threshold must be an integer. You can set the threshold based on your requirements. To prevent jitters caused by network and database overloads, we recommend that you set the threshold to more than 10 seconds. Unit: seconds.
        # *   If the **Type** parameter is set to **full_timeout**, the threshold must be an integer. Unit: hours.
        # 
        # >  This parameter is required if the **Type** parameter is set to **delay** or **full_timeout** and the **State** parameter is set to **Y**.
        self.delay_rule_time = delay_rule_time  # type: long
        # The ID of the data migration, data synchronization, or change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The alert threshold.
        self.notice_value = notice_value  # type: int
        # The statistical period of the incremental data verification task. Unit: minutes.
        # 
        # >  Valid values: 1, 3, 5, and 30.
        self.period = period  # type: int
        # The mobile numbers that receive alert notifications. Separate multiple mobile numbers with commas (,).
        # 
        # > 
        # *   This parameter is available only for users of the China site (aliyun.com). Only mobile numbers in the Chinese mainland are supported. You can specify up to 10 mobile numbers.
        # *   Users of the international site (alibabacloud.com) cannot receive alerts by using mobile phones, but can [configure alert rules for DTS tasks in the CloudMonitor console](~~175876~~).
        self.phone = phone  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # Specifies whether to enable the alert rule. Valid values:
        # 
        # *   **Y**: enables the alert rule.
        # *   **N**: disables the alert rule.
        # 
        # Default value: **Y**.
        self.state = state  # type: str
        # The number of statistical periods of the incremental data verification task.
        self.times = times  # type: int
        # The metric that is used to monitor the task. Valid values:
        # 
        # *   **delay**: the **Latency** metric.
        # *   **error**: the **Status** metric.
        # *   **full_timeout**: the **Full Timeout** metric.
        # 
        # Default value: **error**. You must manually set this value.
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateJobMonitorRuleRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay_rule_time is not None:
            result['DelayRuleTime'] = self.delay_rule_time
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.notice_value is not None:
            result['NoticeValue'] = self.notice_value
        if self.period is not None:
            result['Period'] = self.period
        if self.phone is not None:
            result['Phone'] = self.phone
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.state is not None:
            result['State'] = self.state
        if self.times is not None:
            result['Times'] = self.times
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DelayRuleTime') is not None:
            self.delay_rule_time = m.get('DelayRuleTime')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('NoticeValue') is not None:
            self.notice_value = m.get('NoticeValue')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('Phone') is not None:
            self.phone = m.get('Phone')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Times') is not None:
            self.times = m.get('Times')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class CreateJobMonitorRuleResponseBody(TeaModel):
    def __init__(self, code=None, dts_job_id=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The error code. This parameter will be removed in the future.
        self.code = code  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The dynamic part in the error message. The value of this parameter is used to replace the **%s** variable in the value of the **ErrMessage** parameter.
        # 
        # >  For example, if the specified **DtsJobId** parameter is invalid, **The Value of Input Parameter %s is not valid** is returned for **ErrMessage** and **DtsJobId** is returned for **DynamicMessage**.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful. Valid values:
        # 
        # *   **true**: The request was successful.
        # *   **false**: The request failed.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateJobMonitorRuleResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateJobMonitorRuleResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateJobMonitorRuleResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateJobMonitorRuleResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateJobMonitorRuleResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateMigrationJobRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, migration_job_class=None, owner_id=None, region=None,
                 region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that the value is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The specification of the data migration instance. Valid values: **small**, **medium**, **large**, **xlarge**, and **2xlarge**.
        # 
        # > 
        # *   For more information about the test performance of each specification, see [Specifications of data migration instances](~~26606~~).
        # *   For more information about the pricing of data migration instances, see [Pricing](~~117780~~).
        self.migration_job_class = migration_job_class  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region where the data migration instance resides. The region ID of the data migration instance is the same as that of the destination database. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        # The ID of the region where the data migration instance resides. You do not need to specify this parameter because this parameter will be removed in the future.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateMigrationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.migration_job_class is not None:
            result['MigrationJobClass'] = self.migration_job_class
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region is not None:
            result['Region'] = self.region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('MigrationJobClass') is not None:
            self.migration_job_class = m.get('MigrationJobClass')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class CreateMigrationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, migration_job_id=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the data migration instance.
        self.migration_job_id = migration_job_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateMigrationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateMigrationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateMigrationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateMigrationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateMigrationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateSubscriptionInstanceRequestSourceEndpoint(TeaModel):
    def __init__(self, instance_type=None):
        # The type of the source instance. Valid values: **MySQL**, **PolarDB**, **DRDS**, and **Oracle**.
        # 
        # >  Default value: **MySQL**.
        self.instance_type = instance_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateSubscriptionInstanceRequestSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        return self


class CreateSubscriptionInstanceRequest(TeaModel):
    def __init__(self, source_endpoint=None, account_id=None, client_token=None, owner_id=None, pay_type=None,
                 period=None, region=None, region_id=None, used_time=None):
        self.source_endpoint = source_endpoint  # type: CreateSubscriptionInstanceRequestSourceEndpoint
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        # The billing method of the change tracking instance.
        # 
        # *   **Postpaid**: pay-as-you-go
        # *   **Prepaid**: subscription
        self.pay_type = pay_type  # type: str
        # The billing cycle of the subscription instance. Valid values:
        # 
        # *   **Year**\
        # *   **Month**\
        # 
        # >  You must specify this parameter only if you set the PayType parameter to **Prepaid**.
        self.period = period  # type: str
        # The region ID of the change tracking instance. The region ID is the same as that of the source instance. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        self.region_id = region_id  # type: str
        # The subscription length.
        # 
        # *   If the billing cycle is **Year**, the value range is **1 to 5**.
        # *   If the billing cycle is **Month**, the value range is **1 to 60**.
        # 
        # >  You must specify this parameter only if you set the PayType parameter to **Prepaid**.
        self.used_time = used_time  # type: int

    def validate(self):
        if self.source_endpoint:
            self.source_endpoint.validate()

    def to_map(self):
        _map = super(CreateSubscriptionInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.period is not None:
            result['Period'] = self.period
        if self.region is not None:
            result['Region'] = self.region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.used_time is not None:
            result['UsedTime'] = self.used_time
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('SourceEndpoint') is not None:
            temp_model = CreateSubscriptionInstanceRequestSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('UsedTime') is not None:
            self.used_time = m.get('UsedTime')
        return self


class CreateSubscriptionInstanceResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, subscription_instance_id=None,
                 success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The ID of the change tracking instance.
        self.subscription_instance_id = subscription_instance_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateSubscriptionInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class CreateSubscriptionInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateSubscriptionInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateSubscriptionInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateSubscriptionInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class CreateSynchronizationJobRequestDestinationEndpoint(TeaModel):
    def __init__(self, instance_type=None):
        # The instance type of the destination database. Valid values:
        # 
        # *   **MySQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **PolarDB**: PolarDB for MySQL cluster or PolarDB O Edition cluster
        # *   **Redis**: Redis database
        # *   **MaxCompute**: MaxCompute project
        # 
        # > 
        # *   Default value: **MySQL**.
        # *   For more information about the supported source and destination databases, see [Database types, initial synchronization types, and synchronization topologies](~~130744~~).
        self.instance_type = instance_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateSynchronizationJobRequestDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        return self


class CreateSynchronizationJobRequestSourceEndpoint(TeaModel):
    def __init__(self, instance_type=None):
        # The instance type of the source database. Valid values:
        # 
        # *   **MySQL**: ApsaraDB RDS for MySQL instance or self-managed MySQL database
        # *   **PolarDB**: PolarDB for MySQL cluster or PolarDB O Edition cluster
        # *   **Redis**: Redis database
        # *   **DRDS**: PolarDB-X instance V1.0
        # 
        # > 
        # *   Default value: **MySQL**.
        # *   For more information about the supported source and destination databases, see [Database types, initial synchronization types, and synchronization topologies](~~130744~~).
        self.instance_type = instance_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateSynchronizationJobRequestSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        return self


class CreateSynchronizationJobRequest(TeaModel):
    def __init__(self, destination_endpoint=None, source_endpoint=None, account_id=None, client_token=None,
                 dbinstance_count=None, dest_region=None, owner_id=None, pay_type=None, period=None, region_id=None,
                 source_region=None, synchronization_job_class=None, topology=None, used_time=None, network_type=None):
        self.destination_endpoint = destination_endpoint  # type: CreateSynchronizationJobRequestDestinationEndpoint
        self.source_endpoint = source_endpoint  # type: CreateSynchronizationJobRequestSourceEndpoint
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # If you set the **SourceEndpoint.InstanceType** parameter to **DRDS**, you must specify the DBInstanceCount parameter. This parameter specifies the number of private RDS instances attached to the source PolarDB-X instance. Default value: **1**.
        self.dbinstance_count = dbinstance_count  # type: int
        # The ID of the region where the destination database resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the **SourceRegion** parameter is set to the China (Hong Kong) region or a region outside the Chinese mainland, you must set the DestRegion parameter to the same region ID.
        self.dest_region = dest_region  # type: str
        self.owner_id = owner_id  # type: str
        # The billing method of the data synchronization instance.
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid** (default value): pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The billing cycle of the subscription instance. Valid values:
        # 
        # *   **Year**\
        # *   **Month**\
        # 
        # >  You must specify this parameter only if you set the PayType parameter to **PrePaid**.
        self.period = period  # type: str
        self.region_id = region_id  # type: str
        # The ID of the region where the source database resides. For more information, see [List of supported regions](~~141033~~).
        self.source_region = source_region  # type: str
        # The specification of the data synchronization instance. Valid values: **micro**, **small**, **medium**, and **large**.
        # 
        # >  For more information about the test performance of each specification, see [Specifications of data synchronization instances](~~26605~~).
        self.synchronization_job_class = synchronization_job_class  # type: str
        # The synchronization topology. Valid values:
        # 
        # *   **oneway**: one-way synchronization
        # *   **bidirectional**: two-way synchronization
        # 
        # > 
        # *   The default value is **oneway**.
        # *   This parameter can be set to **bidirectional** only when the **SourceEndpoint.InstanceType** and **DestinationEndpoint.InstanceType** parameters are set to **MySQL**, **PolarDB**, or **Redis**.
        self.topology = topology  # type: str
        # The subscription length.
        # 
        # *   If the billing cycle is **Year**, the value range is **1 to 5**.
        # *   If the billing cycle is **Month**, the value range is **1 to 60**.
        # 
        # >  You must specify this parameter only if you set the PayType parameter to **PrePaid**.
        self.used_time = used_time  # type: int
        # The network type. Valid value: **Intranet**, which indicates virtual private cloud (VPC).
        self.network_type = network_type  # type: str

    def validate(self):
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()

    def to_map(self):
        _map = super(CreateSynchronizationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.dbinstance_count is not None:
            result['DBInstanceCount'] = self.dbinstance_count
        if self.dest_region is not None:
            result['DestRegion'] = self.dest_region
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.period is not None:
            result['Period'] = self.period
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.source_region is not None:
            result['SourceRegion'] = self.source_region
        if self.synchronization_job_class is not None:
            result['SynchronizationJobClass'] = self.synchronization_job_class
        if self.topology is not None:
            result['Topology'] = self.topology
        if self.used_time is not None:
            result['UsedTime'] = self.used_time
        if self.network_type is not None:
            result['networkType'] = self.network_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationEndpoint') is not None:
            temp_model = CreateSynchronizationJobRequestDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('SourceEndpoint') is not None:
            temp_model = CreateSynchronizationJobRequestSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DBInstanceCount') is not None:
            self.dbinstance_count = m.get('DBInstanceCount')
        if m.get('DestRegion') is not None:
            self.dest_region = m.get('DestRegion')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SourceRegion') is not None:
            self.source_region = m.get('SourceRegion')
        if m.get('SynchronizationJobClass') is not None:
            self.synchronization_job_class = m.get('SynchronizationJobClass')
        if m.get('Topology') is not None:
            self.topology = m.get('Topology')
        if m.get('UsedTime') is not None:
            self.used_time = m.get('UsedTime')
        if m.get('networkType') is not None:
            self.network_type = m.get('networkType')
        return self


class CreateSynchronizationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None, synchronization_job_id=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The ID of the data synchronization instance.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(CreateSynchronizationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class CreateSynchronizationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: CreateSynchronizationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(CreateSynchronizationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = CreateSynchronizationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteConsumerChannelRequest(TeaModel):
    def __init__(self, consumer_group_id=None, dts_instance_id=None, dts_job_id=None, region_id=None):
        # The ID of the consumer group. You can call the [DescribeConsumerChannel](~~264169~~) operation to query the consumer group ID.
        self.consumer_group_id = consumer_group_id  # type: str
        # The ID of the change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId** parameters.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId** parameters.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the region where the change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteConsumerChannelRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_id is not None:
            result['ConsumerGroupId'] = self.consumer_group_id
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupId') is not None:
            self.consumer_group_id = m.get('ConsumerGroupId')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DeleteConsumerChannelResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, http_status_code=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteConsumerChannelResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteConsumerChannelResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteConsumerChannelResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteConsumerChannelResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteConsumerChannelResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteConsumerGroupRequest(TeaModel):
    def __init__(self, account_id=None, consumer_group_id=None, owner_id=None, region_id=None,
                 subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The ID of the consumer group. You can call the [DescribeConsumerGroup](~~122886~~) operation to query the consumer group ID.
        self.consumer_group_id = consumer_group_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the **DescribeSubscriptionInstances** operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteConsumerGroupRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.consumer_group_id is not None:
            result['ConsumerGroupID'] = self.consumer_group_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ConsumerGroupID') is not None:
            self.consumer_group_id = m.get('ConsumerGroupID')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class DeleteConsumerGroupResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteConsumerGroupResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteConsumerGroupResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteConsumerGroupResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteConsumerGroupResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteConsumerGroupResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteDtsJobRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, job_type=None, region_id=None,
                 synchronization_direction=None):
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        self.job_type = job_type  # type: str
        # The error code returned if the call failed.
        self.region_id = region_id  # type: str
        # The dynamic error code. This parameter will be removed in the future.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class DeleteDtsJobResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The operation that you want to perform. Set the value to **DeleteDtsJob**.
        self.dynamic_code = dynamic_code  # type: str
        # The operation that you want to perform. Set the value to **DeleteDtsJob**.
        self.dynamic_message = dynamic_message  # type: str
        # The error message returned if the call failed.
        self.err_code = err_code  # type: str
        # The ID of the request.
        self.err_message = err_message  # type: str
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.http_status_code = http_status_code  # type: int
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to delete the reverse synchronization task only if the topology is two-way synchronization.
        self.request_id = request_id  # type: str
        # The ID of the region in which the data migration or synchronization task resides. For more information, see [List of supported regions](~~141033~~).
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteDtsJobsRequest(TeaModel):
    def __init__(self, dts_job_ids=None, region_id=None):
        # The ID of the data migration, data synchronization, or change tracking task.
        # 
        # > *   Separate multiple task IDs with commas (,).
        # > *   You can call the [DescribeDtsJobs](~~209702~~) operation to query task IDs.
        self.dts_job_ids = dts_job_ids  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteDtsJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_ids is not None:
            result['DtsJobIds'] = self.dts_job_ids
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobIds') is not None:
            self.dts_job_ids = m.get('DtsJobIds')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DeleteDtsJobsResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed soon.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the \*\*%s\*\* variable in the **ErrMessage** parameter.
        # 
        # > If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteDtsJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteDtsJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteDtsJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteDtsJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteDtsJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteMigrationJobRequest(TeaModel):
    def __init__(self, account_id=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query all data migration instances.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteMigrationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DeleteMigrationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteMigrationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteMigrationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteMigrationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteMigrationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteMigrationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteSubscriptionInstanceRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteSubscriptionInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class DeleteSubscriptionInstanceResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteSubscriptionInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteSubscriptionInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteSubscriptionInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteSubscriptionInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteSubscriptionInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DeleteSynchronizationJobRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the data synchronization instance. You can call the DescribeSynchronizationJobs operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteSynchronizationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class DeleteSynchronizationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DeleteSynchronizationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DeleteSynchronizationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DeleteSynchronizationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DeleteSynchronizationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DeleteSynchronizationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeChannelAccountRequest(TeaModel):
    def __init__(self, dts_job_id=None, owner_id=None, region=None, region_id=None, resource_group_id=None,
                 tags=None, type=None):
        self.dts_job_id = dts_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region = region  # type: str
        self.region_id = region_id  # type: str
        self.resource_group_id = resource_group_id  # type: str
        self.tags = tags  # type: str
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeChannelAccountRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region is not None:
            result['Region'] = self.region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_group_id is not None:
            result['ResourceGroupId'] = self.resource_group_id
        if self.tags is not None:
            result['Tags'] = self.tags
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceGroupId') is not None:
            self.resource_group_id = m.get('ResourceGroupId')
        if m.get('Tags') is not None:
            self.tags = m.get('Tags')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class DescribeChannelAccountResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, password=None, request_id=None, success=None, username=None):
        self.dynamic_code = dynamic_code  # type: str
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.password = password  # type: str
        self.request_id = request_id  # type: str
        self.success = success  # type: bool
        self.username = username  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeChannelAccountResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.password is not None:
            result['Password'] = self.password
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.username is not None:
            result['Username'] = self.username
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('Username') is not None:
            self.username = m.get('Username')
        return self


class DescribeChannelAccountResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeChannelAccountResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeChannelAccountResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeChannelAccountResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeCheckJobsRequest(TeaModel):
    def __init__(self, check_type=None, instance_id=None, job_name=None, page_number=None, page_size=None):
        self.check_type = check_type  # type: int
        self.instance_id = instance_id  # type: str
        self.job_name = job_name  # type: str
        self.page_number = page_number  # type: int
        self.page_size = page_size  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeCheckJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_type is not None:
            result['CheckType'] = self.check_type
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.job_name is not None:
            result['JobName'] = self.job_name
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckType') is not None:
            self.check_type = m.get('CheckType')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('JobName') is not None:
            self.job_name = m.get('JobName')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        return self


class DescribeCheckJobsResponseBodyCheckJobs(TeaModel):
    def __init__(self, charge_type=None, check_point=None, check_type=None, diff_count=None, diff_sum=None,
                 dts_instance_id=None, dts_job_id=None, finish_count=None, group_id=None, instance_class=None, job_name=None,
                 job_step_id=None, parent_job_type=None, region_id=None, status=None, total_count=None):
        self.charge_type = charge_type  # type: str
        self.check_point = check_point  # type: long
        self.check_type = check_type  # type: int
        self.diff_count = diff_count  # type: long
        self.diff_sum = diff_sum  # type: long
        self.dts_instance_id = dts_instance_id  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.finish_count = finish_count  # type: long
        self.group_id = group_id  # type: str
        self.instance_class = instance_class  # type: str
        self.job_name = job_name  # type: str
        self.job_step_id = job_step_id  # type: str
        self.parent_job_type = parent_job_type  # type: str
        self.region_id = region_id  # type: str
        self.status = status  # type: int
        self.total_count = total_count  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeCheckJobsResponseBodyCheckJobs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.charge_type is not None:
            result['ChargeType'] = self.charge_type
        if self.check_point is not None:
            result['CheckPoint'] = self.check_point
        if self.check_type is not None:
            result['CheckType'] = self.check_type
        if self.diff_count is not None:
            result['DiffCount'] = self.diff_count
        if self.diff_sum is not None:
            result['DiffSum'] = self.diff_sum
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.finish_count is not None:
            result['FinishCount'] = self.finish_count
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.instance_class is not None:
            result['InstanceClass'] = self.instance_class
        if self.job_name is not None:
            result['JobName'] = self.job_name
        if self.job_step_id is not None:
            result['JobStepId'] = self.job_step_id
        if self.parent_job_type is not None:
            result['ParentJobType'] = self.parent_job_type
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.status is not None:
            result['Status'] = self.status
        if self.total_count is not None:
            result['TotalCount'] = self.total_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ChargeType') is not None:
            self.charge_type = m.get('ChargeType')
        if m.get('CheckPoint') is not None:
            self.check_point = m.get('CheckPoint')
        if m.get('CheckType') is not None:
            self.check_type = m.get('CheckType')
        if m.get('DiffCount') is not None:
            self.diff_count = m.get('DiffCount')
        if m.get('DiffSum') is not None:
            self.diff_sum = m.get('DiffSum')
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('FinishCount') is not None:
            self.finish_count = m.get('FinishCount')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('InstanceClass') is not None:
            self.instance_class = m.get('InstanceClass')
        if m.get('JobName') is not None:
            self.job_name = m.get('JobName')
        if m.get('JobStepId') is not None:
            self.job_step_id = m.get('JobStepId')
        if m.get('ParentJobType') is not None:
            self.parent_job_type = m.get('ParentJobType')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TotalCount') is not None:
            self.total_count = m.get('TotalCount')
        return self


class DescribeCheckJobsResponseBody(TeaModel):
    def __init__(self, check_jobs=None, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, page_number=None, page_record_count=None, request_id=None, success=None,
                 total_record_count=None):
        self.check_jobs = check_jobs  # type: list[DescribeCheckJobsResponseBodyCheckJobs]
        self.dynamic_code = dynamic_code  # type: str
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.page_number = page_number  # type: int
        self.page_record_count = page_record_count  # type: long
        self.request_id = request_id  # type: str
        self.success = success  # type: bool
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.check_jobs:
            for k in self.check_jobs:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeCheckJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['CheckJobs'] = []
        if self.check_jobs is not None:
            for k in self.check_jobs:
                result['CheckJobs'].append(k.to_map() if k else None)
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.check_jobs = []
        if m.get('CheckJobs') is not None:
            for k in m.get('CheckJobs'):
                temp_model = DescribeCheckJobsResponseBodyCheckJobs()
                self.check_jobs.append(temp_model.from_map(k))
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeCheckJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeCheckJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeCheckJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeCheckJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeClusterOperateLogsRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, dedicated_cluster_id=None, dts_job_id=None,
                 end_time=None, owner_id=None, page_number=None, page_size=None, start_time=None):
        # The ID of the Alibaba Cloud account.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the token, but you must make sure that the token is unique among different requests. **The token can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the DTS dedicated cluster on which a DTS task runs.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The ID of the data migration or synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The end of the time range to query. The value must be in the UNIX timestamp format. Unit: milliseconds.
        self.end_time = end_time  # type: long
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than 0. Default value: **1**.
        self.page_number = page_number  # type: int
        # The number of entries to return on each page. Default value: **20**.
        self.page_size = page_size  # type: int
        # The beginning of the time range to query. The value must be in the UNIX timestamp format. Unit: milliseconds. If you do not specify this parameter, the data within the last seven days is returned by default.
        self.start_time = start_time  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeClusterOperateLogsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.end_time is not None:
            result['EndTime'] = self.end_time
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.start_time is not None:
            result['StartTime'] = self.start_time
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('EndTime') is not None:
            self.end_time = m.get('EndTime')
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('StartTime') is not None:
            self.start_time = m.get('StartTime')
        return self


class DescribeClusterOperateLogsResponseBodyDataPoints(TeaModel):
    def __init__(self, content=None, id=None, log_datetime=None, new_value=None, old_value=None, operation_name=None,
                 operation_user=None, success=None):
        # Other description of the operation.
        self.content = content  # type: str
        # The primary key of the log table.
        self.id = id  # type: str
        # The time when the operation is recorded. The value is in the UNIX timestamp format. Unit: milliseconds.
        self.log_datetime = log_datetime  # type: long
        # The value of the parameter after the operation if the operation is an UPDATE operation.
        self.new_value = new_value  # type: str
        # The value of the parameter before the operation if the operation is an UPDATE operation.
        self.old_value = old_value  # type: str
        # The type of the operation.
        self.operation_name = operation_name  # type: str
        # The user who performed the operation.
        self.operation_user = operation_user  # type: str
        # Indicates whether the request was successful. A value of **1** indicates that the request was successful.
        self.success = success  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeClusterOperateLogsResponseBodyDataPoints, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.content is not None:
            result['Content'] = self.content
        if self.id is not None:
            result['Id'] = self.id
        if self.log_datetime is not None:
            result['LogDatetime'] = self.log_datetime
        if self.new_value is not None:
            result['NewValue'] = self.new_value
        if self.old_value is not None:
            result['OldValue'] = self.old_value
        if self.operation_name is not None:
            result['OperationName'] = self.operation_name
        if self.operation_user is not None:
            result['OperationUser'] = self.operation_user
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Content') is not None:
            self.content = m.get('Content')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('LogDatetime') is not None:
            self.log_datetime = m.get('LogDatetime')
        if m.get('NewValue') is not None:
            self.new_value = m.get('NewValue')
        if m.get('OldValue') is not None:
            self.old_value = m.get('OldValue')
        if m.get('OperationName') is not None:
            self.operation_name = m.get('OperationName')
        if m.get('OperationUser') is not None:
            self.operation_user = m.get('OperationUser')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeClusterOperateLogsResponseBody(TeaModel):
    def __init__(self, code=None, data_points=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, page_number=None, page_record_count=None, request_id=None, success=None,
                 total_record_count=None):
        # The error code returned by the backend service. The number is incremented.
        self.code = code  # type: str
        # The information about the operation logs.
        self.data_points = data_points  # type: list[DescribeClusterOperateLogsResponseBodyDataPoints]
        # The dynamic part in the error message. This parameter is used to replace %s in the ErrMessage parameter.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned.
        self.err_message = err_message  # type: str
        # The HTTP status code returned for an exception.
        self.http_status_code = http_status_code  # type: int
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The number of entries returned per page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool
        # The total number of records.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.data_points:
            for k in self.data_points:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeClusterOperateLogsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        result['DataPoints'] = []
        if self.data_points is not None:
            for k in self.data_points:
                result['DataPoints'].append(k.to_map() if k else None)
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        self.data_points = []
        if m.get('DataPoints') is not None:
            for k in m.get('DataPoints'):
                temp_model = DescribeClusterOperateLogsResponseBodyDataPoints()
                self.data_points.append(temp_model.from_map(k))
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeClusterOperateLogsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeClusterOperateLogsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeClusterOperateLogsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeClusterOperateLogsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeClusterUsedUtilizationRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, dedicated_cluster_id=None, dts_job_id=None, env=None,
                 metric_type=None, owner_id=None, region_id=None, security_token=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter is discontinued.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the token, but you must make sure that the token is unique among different requests. **The token can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the cluster. If the **MetricType** parameter is set to **CLUSTER**, enter the ID of the exclusive cluster. Otherwise, set this parameter to a node ID.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The ID of the data migration or synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The cluster environment. Default value: **ALIYUN**.
        self.env = env  # type: str
        # Specifies whether to query the metrics of the cluster or a node. Default value: CLUSTER. Valid values:
        # 
        # *   **CLUSTER**: query the metrics of the cluster.
        # *   **NODE**: query the metrics of a node.
        self.metric_type = metric_type  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region in which the Data Transmission Service (DTS) instance resides.
        self.region_id = region_id  # type: str
        self.security_token = security_token  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeClusterUsedUtilizationRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.env is not None:
            result['Env'] = self.env
        if self.metric_type is not None:
            result['MetricType'] = self.metric_type
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.security_token is not None:
            result['SecurityToken'] = self.security_token
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('Env') is not None:
            self.env = m.get('Env')
        if m.get('MetricType') is not None:
            self.metric_type = m.get('MetricType')
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SecurityToken') is not None:
            self.security_token = m.get('SecurityToken')
        return self


class DescribeClusterUsedUtilizationResponseBody(TeaModel):
    def __init__(self, code=None, cpu_total=None, dedicated_cluster_id=None, disk_total=None, disk_used=None,
                 du_total=None, du_used=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 memory_total=None, memory_used=None, memory_used_percentage=None, request_id=None, success=None,
                 task_running=None):
        # The error code returned by the backend service. The number is incremented.
        self.code = code  # type: str
        # The CPU utilization of the cluster. Unit: percentage.
        self.cpu_total = cpu_total  # type: float
        # The ID of the cluster.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The total disk size of the cluster. Unit: GB.
        self.disk_total = disk_total  # type: float
        # The disk usage of the cluster. Unit: GB.
        self.disk_used = disk_used  # type: float
        # The total number of DTS units (DUs).
        self.du_total = du_total  # type: int
        # The usage of DUs.
        self.du_used = du_used  # type: int
        # The dynamic part in the error message. This parameter is used to replace %s in the ErrMessage parameter.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code returned.
        self.http_status_code = http_status_code  # type: int
        # The total amount of memory. A value of 0 is temporarily returned.
        self.memory_total = memory_total  # type: float
        # The memory usage. A value of 0 is temporarily returned.
        self.memory_used = memory_used  # type: float
        # The memory usage.
        self.memory_used_percentage = memory_used_percentage  # type: float
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool
        # The number of tasks that are in progress.
        self.task_running = task_running  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeClusterUsedUtilizationResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.cpu_total is not None:
            result['CpuTotal'] = self.cpu_total
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.disk_total is not None:
            result['DiskTotal'] = self.disk_total
        if self.disk_used is not None:
            result['DiskUsed'] = self.disk_used
        if self.du_total is not None:
            result['DuTotal'] = self.du_total
        if self.du_used is not None:
            result['DuUsed'] = self.du_used
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.memory_total is not None:
            result['MemoryTotal'] = self.memory_total
        if self.memory_used is not None:
            result['MemoryUsed'] = self.memory_used
        if self.memory_used_percentage is not None:
            result['MemoryUsedPercentage'] = self.memory_used_percentage
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.task_running is not None:
            result['TaskRunning'] = self.task_running
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('CpuTotal') is not None:
            self.cpu_total = m.get('CpuTotal')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DiskTotal') is not None:
            self.disk_total = m.get('DiskTotal')
        if m.get('DiskUsed') is not None:
            self.disk_used = m.get('DiskUsed')
        if m.get('DuTotal') is not None:
            self.du_total = m.get('DuTotal')
        if m.get('DuUsed') is not None:
            self.du_used = m.get('DuUsed')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('MemoryTotal') is not None:
            self.memory_total = m.get('MemoryTotal')
        if m.get('MemoryUsed') is not None:
            self.memory_used = m.get('MemoryUsed')
        if m.get('MemoryUsedPercentage') is not None:
            self.memory_used_percentage = m.get('MemoryUsedPercentage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TaskRunning') is not None:
            self.task_running = m.get('TaskRunning')
        return self


class DescribeClusterUsedUtilizationResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeClusterUsedUtilizationResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeClusterUsedUtilizationResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeClusterUsedUtilizationResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeConnectionStatusRequest(TeaModel):
    def __init__(self, destination_endpoint_architecture=None, destination_endpoint_database_name=None,
                 destination_endpoint_engine_name=None, destination_endpoint_ip=None, destination_endpoint_instance_id=None,
                 destination_endpoint_instance_type=None, destination_endpoint_oracle_sid=None, destination_endpoint_password=None,
                 destination_endpoint_port=None, destination_endpoint_region=None, destination_endpoint_user_name=None, region_id=None,
                 source_endpoint_architecture=None, source_endpoint_database_name=None, source_endpoint_engine_name=None,
                 source_endpoint_ip=None, source_endpoint_instance_id=None, source_endpoint_instance_type=None,
                 source_endpoint_oracle_sid=None, source_endpoint_password=None, source_endpoint_port=None, source_endpoint_region=None,
                 source_endpoint_user_name=None):
        # You must specify this parameter only if the **SourceEndpointEngineName** parameter is set to **Oracle**. Valid values:
        # 
        # *   **SID**: non-RAC architecture
        # *   **RAC**: Real Application Cluster (RAC) architecture
        # 
        # >  This parameter is optional. The data type of this parameter is String.
        self.destination_endpoint_architecture = destination_endpoint_architecture  # type: str
        # The name of the destination database or the authentication database.
        # 
        # > 
        # *   You must specify this parameter if the **DestinationEndpointEngineName** parameter is set to **PostgreSQL**, **DRDS**, or **MongoDB**. You must also specify this parameter if the **DestinationEndpointInstanceType** parameter is set to **PolarDB_o**.
        # *   If the **DestinationEndpointEngineName** parameter is set to **PostgreSQL** or **DRDS**, specify the name of the destination database. If the DestinationEndpointEngineName parameter is set to **MongoDB**, specify the name of the authentication database.
        # *   If the **DestinationEndpointInstanceType** parameter is set to **PolarDB_o**, specify the name of the destination database.
        self.destination_endpoint_database_name = destination_endpoint_database_name  # type: str
        # The engine type of the destination database. Valid values: **MySQL**, **DRDS**, **SQLServer**, **PostgreSQL**, **PPAS**, **MongoDB**, and **Redis**.
        # 
        # >  You must specify this parameter only if the **DestinationEndpointInstanceType** parameter is set to **RDS**, **DRDS**, **ECS**, **LocalInstance**, or **Express**.
        self.destination_endpoint_engine_name = destination_endpoint_engine_name  # type: str
        # The endpoint of the destination database.
        # 
        # >  You must specify this parameter only if the **DestinationEndpointInstanceType** parameter is set to **LocalInstance** or **Express**.
        self.destination_endpoint_ip = destination_endpoint_ip  # type: str
        # The ID of the destination instance.
        self.destination_endpoint_instance_id = destination_endpoint_instance_id  # type: str
        # The instance type of the destination database. Valid values:
        # 
        # > 
        # *   **ECS**: self-managed database that is hosted on Elastic Compute Service (ECS)
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **RDS**: ApsaraDB RDS instance
        # *   **DRDS**: PolarDB-X instance
        # *   **MongoDB**: ApsaraDB for MongoDB instance
        # *   **Redis**: ApsaraDB for Redis instance
        # *   **PetaData**: HybridDB for MySQL instance
        # *   **POLARDB**: PolarDB for MySQL cluster
        # *   **PolarDB_o**: PolarDB for Oracle cluster
        # *   **AnalyticDB**: AnalyticDB for MySQL cluster V3.0 or V2.0
        # *   **Greenplum**: AnalyticDB for PostgreSQL instance
        self.destination_endpoint_instance_type = destination_endpoint_instance_type  # type: str
        # You must specify this parameter only if the **DestinationEndpointEngineName** parameter is set to **Oracle**. Valid values:
        # 
        # *   **SID**: non-RAC architecture
        # *   **RAC**: RAC architecture
        # 
        # >  This parameter is optional. The data type of this parameter is String.
        self.destination_endpoint_oracle_sid = destination_endpoint_oracle_sid  # type: str
        # The password of the destination database account.
        self.destination_endpoint_password = destination_endpoint_password  # type: str
        # The service port number of the source database.
        # 
        # >  You must specify this parameter only if the **SourceEndpointInstanceType** parameter is set to **ECS**, **LocalInstance**, or **Express**.
        self.destination_endpoint_port = destination_endpoint_port  # type: str
        # The ID of the region where the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        self.destination_endpoint_region = destination_endpoint_region  # type: str
        # The database account of the destination database.
        # 
        # >  The permissions that are required for database accounts vary with the migration or synchronization scenario. For more information, see [Overview of data migration scenarios](~~26618~~) and [Overview of data synchronization scenarios](~~130744~~).
        self.destination_endpoint_user_name = destination_endpoint_user_name  # type: str
        # The ID of the region where the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # You must specify this parameter only if the **SourceEndpointEngineName** parameter is set to **Oracle**. Valid values:
        # 
        # *   **SID**: non-RAC architecture
        # *   **RAC**: RAC architecture
        # 
        # >  This parameter is optional.
        self.source_endpoint_architecture = source_endpoint_architecture  # type: str
        # The name of the source database or the authentication database.
        # 
        # > 
        # *   You must specify this parameter if the **SourceEndpointEngineName** parameter is set to **PostgreSQL** or **MongoDB**. You must also specify this parameter if the **SourceEndpointInstanceType** parameter is set to **PolarDB_o**.
        # *   If the **SourceEndpointEngineName** parameter is set to **PostgreSQL** or **DRDS**, specify the name of the source database. If the SourceEndpointEngineName parameter is set to **MongoDB**, specify the name of the authentication database.
        # *   If the **SourceEndpointInstanceType** parameter is set to **PolarDB_o**, specify the name of the source database.
        self.source_endpoint_database_name = source_endpoint_database_name  # type: str
        # The engine type of the source database. Valid values: **MySQL**, **TiDB**, **SQLServer**, **PostgreSQL**, **Oracle**, **MongoDB**, and **Redis**.
        # 
        # >  Default value: **MySQL**.
        self.source_endpoint_engine_name = source_endpoint_engine_name  # type: str
        # The endpoint of the source database.
        # 
        # >  You must specify this parameter only if the **SourceEndpointInstanceType** parameter is set to **LocalInstance** or **Express**.
        self.source_endpoint_ip = source_endpoint_ip  # type: str
        # The ID of the source instance.
        self.source_endpoint_instance_id = source_endpoint_instance_id  # type: str
        # The type of the source instance. Valid values:
        # 
        # *   **RDS**: ApsaraDB RDS instance
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **ECS**: self-managed database that is hosted on ECS
        # *   **Express**: self-managed database that is connected over Express Connect
        # *   **dg**: self-managed database that is connected over Database Gateway
        # *   **MongoDB**: ApsaraDB for MongoDB instance
        # *   **POLARDB**: PolarDB for MySQL cluster
        # *   **PolarDB_o**: PolarDB for Oracle cluster
        self.source_endpoint_instance_type = source_endpoint_instance_type  # type: str
        # The SID of the Oracle database.
        # 
        # >  You must specify this parameter only if the **SourceEndpointEngineName** parameter is set to **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.source_endpoint_oracle_sid = source_endpoint_oracle_sid  # type: str
        # The password of the source database account.
        self.source_endpoint_password = source_endpoint_password  # type: str
        # The service port number of the source database.
        # 
        # >  You must specify this parameter only if the **SourceEndpointInstanceType** parameter is set to **ECS**, **LocalInstance**, or **Express**.
        self.source_endpoint_port = source_endpoint_port  # type: str
        # The ID of the region where the source instance resides. For more information, see [List of supported regions](~~141033~~).
        self.source_endpoint_region = source_endpoint_region  # type: str
        # The database account of the source database.
        # 
        # >  The permissions that are required for database accounts vary with the migration or synchronization scenario. For more information, see [Overview of data migration scenarios](~~26618~~) and [Overview of data synchronization scenarios](~~130744~~).
        self.source_endpoint_user_name = source_endpoint_user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeConnectionStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_endpoint_architecture is not None:
            result['DestinationEndpointArchitecture'] = self.destination_endpoint_architecture
        if self.destination_endpoint_database_name is not None:
            result['DestinationEndpointDatabaseName'] = self.destination_endpoint_database_name
        if self.destination_endpoint_engine_name is not None:
            result['DestinationEndpointEngineName'] = self.destination_endpoint_engine_name
        if self.destination_endpoint_ip is not None:
            result['DestinationEndpointIP'] = self.destination_endpoint_ip
        if self.destination_endpoint_instance_id is not None:
            result['DestinationEndpointInstanceID'] = self.destination_endpoint_instance_id
        if self.destination_endpoint_instance_type is not None:
            result['DestinationEndpointInstanceType'] = self.destination_endpoint_instance_type
        if self.destination_endpoint_oracle_sid is not None:
            result['DestinationEndpointOracleSID'] = self.destination_endpoint_oracle_sid
        if self.destination_endpoint_password is not None:
            result['DestinationEndpointPassword'] = self.destination_endpoint_password
        if self.destination_endpoint_port is not None:
            result['DestinationEndpointPort'] = self.destination_endpoint_port
        if self.destination_endpoint_region is not None:
            result['DestinationEndpointRegion'] = self.destination_endpoint_region
        if self.destination_endpoint_user_name is not None:
            result['DestinationEndpointUserName'] = self.destination_endpoint_user_name
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.source_endpoint_architecture is not None:
            result['SourceEndpointArchitecture'] = self.source_endpoint_architecture
        if self.source_endpoint_database_name is not None:
            result['SourceEndpointDatabaseName'] = self.source_endpoint_database_name
        if self.source_endpoint_engine_name is not None:
            result['SourceEndpointEngineName'] = self.source_endpoint_engine_name
        if self.source_endpoint_ip is not None:
            result['SourceEndpointIP'] = self.source_endpoint_ip
        if self.source_endpoint_instance_id is not None:
            result['SourceEndpointInstanceID'] = self.source_endpoint_instance_id
        if self.source_endpoint_instance_type is not None:
            result['SourceEndpointInstanceType'] = self.source_endpoint_instance_type
        if self.source_endpoint_oracle_sid is not None:
            result['SourceEndpointOracleSID'] = self.source_endpoint_oracle_sid
        if self.source_endpoint_password is not None:
            result['SourceEndpointPassword'] = self.source_endpoint_password
        if self.source_endpoint_port is not None:
            result['SourceEndpointPort'] = self.source_endpoint_port
        if self.source_endpoint_region is not None:
            result['SourceEndpointRegion'] = self.source_endpoint_region
        if self.source_endpoint_user_name is not None:
            result['SourceEndpointUserName'] = self.source_endpoint_user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationEndpointArchitecture') is not None:
            self.destination_endpoint_architecture = m.get('DestinationEndpointArchitecture')
        if m.get('DestinationEndpointDatabaseName') is not None:
            self.destination_endpoint_database_name = m.get('DestinationEndpointDatabaseName')
        if m.get('DestinationEndpointEngineName') is not None:
            self.destination_endpoint_engine_name = m.get('DestinationEndpointEngineName')
        if m.get('DestinationEndpointIP') is not None:
            self.destination_endpoint_ip = m.get('DestinationEndpointIP')
        if m.get('DestinationEndpointInstanceID') is not None:
            self.destination_endpoint_instance_id = m.get('DestinationEndpointInstanceID')
        if m.get('DestinationEndpointInstanceType') is not None:
            self.destination_endpoint_instance_type = m.get('DestinationEndpointInstanceType')
        if m.get('DestinationEndpointOracleSID') is not None:
            self.destination_endpoint_oracle_sid = m.get('DestinationEndpointOracleSID')
        if m.get('DestinationEndpointPassword') is not None:
            self.destination_endpoint_password = m.get('DestinationEndpointPassword')
        if m.get('DestinationEndpointPort') is not None:
            self.destination_endpoint_port = m.get('DestinationEndpointPort')
        if m.get('DestinationEndpointRegion') is not None:
            self.destination_endpoint_region = m.get('DestinationEndpointRegion')
        if m.get('DestinationEndpointUserName') is not None:
            self.destination_endpoint_user_name = m.get('DestinationEndpointUserName')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SourceEndpointArchitecture') is not None:
            self.source_endpoint_architecture = m.get('SourceEndpointArchitecture')
        if m.get('SourceEndpointDatabaseName') is not None:
            self.source_endpoint_database_name = m.get('SourceEndpointDatabaseName')
        if m.get('SourceEndpointEngineName') is not None:
            self.source_endpoint_engine_name = m.get('SourceEndpointEngineName')
        if m.get('SourceEndpointIP') is not None:
            self.source_endpoint_ip = m.get('SourceEndpointIP')
        if m.get('SourceEndpointInstanceID') is not None:
            self.source_endpoint_instance_id = m.get('SourceEndpointInstanceID')
        if m.get('SourceEndpointInstanceType') is not None:
            self.source_endpoint_instance_type = m.get('SourceEndpointInstanceType')
        if m.get('SourceEndpointOracleSID') is not None:
            self.source_endpoint_oracle_sid = m.get('SourceEndpointOracleSID')
        if m.get('SourceEndpointPassword') is not None:
            self.source_endpoint_password = m.get('SourceEndpointPassword')
        if m.get('SourceEndpointPort') is not None:
            self.source_endpoint_port = m.get('SourceEndpointPort')
        if m.get('SourceEndpointRegion') is not None:
            self.source_endpoint_region = m.get('SourceEndpointRegion')
        if m.get('SourceEndpointUserName') is not None:
            self.source_endpoint_user_name = m.get('SourceEndpointUserName')
        return self


class DescribeConnectionStatusResponseBody(TeaModel):
    def __init__(self, destination_connection_status=None, err_code=None, err_message=None, request_id=None,
                 source_connection_status=None, success=None):
        # The connectivity of DTS servers to the destination database.
        self.destination_connection_status = destination_connection_status  # type: dict[str, any]
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The connectivity of DTS servers to the source database.
        self.source_connection_status = source_connection_status  # type: dict[str, any]
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeConnectionStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_connection_status is not None:
            result['DestinationConnectionStatus'] = self.destination_connection_status
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.source_connection_status is not None:
            result['SourceConnectionStatus'] = self.source_connection_status
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationConnectionStatus') is not None:
            self.destination_connection_status = m.get('DestinationConnectionStatus')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SourceConnectionStatus') is not None:
            self.source_connection_status = m.get('SourceConnectionStatus')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeConnectionStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeConnectionStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeConnectionStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeConnectionStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeConsumerChannelRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, page_number=None, page_size=None,
                 parent_channel_id=None, region_id=None):
        # The ID of the change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId** parameters.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId** parameters.
        self.dts_job_id = dts_job_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_number = page_number  # type: int
        # The number of entries to return on each page. Valid values: **1** to **100**. Default value: **20**.
        self.page_size = page_size  # type: int
        # The parent task ID of the distributed task.
        self.parent_channel_id = parent_channel_id  # type: str
        # The ID of the region in which the change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeConsumerChannelRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.parent_channel_id is not None:
            result['ParentChannelId'] = self.parent_channel_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('ParentChannelId') is not None:
            self.parent_channel_id = m.get('ParentChannelId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeConsumerChannelResponseBodyConsumerChannels(TeaModel):
    def __init__(self, consumer_group_id=None, consumer_group_name=None, consumer_group_user_name=None,
                 consumption_checkpoint=None, message_delay=None, unconsumed_data=None):
        # The ID of the consumer group.
        self.consumer_group_id = consumer_group_id  # type: str
        # The name of the consumer group.
        self.consumer_group_name = consumer_group_name  # type: str
        # The username of the consumer group.
        self.consumer_group_user_name = consumer_group_user_name  # type: str
        # The consumption checkpoint, which is the time when the latest data record was consumed by the change tracking client. The time is displayed in the yyyy-MM-ddTHH:mm:ssZ format in UTC.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The message latency, which is the timestamp of the latest data consumed by the downstream client minus the timestamp of the latest data tracked by the change tracking task. The value is a UNIX timestamp. Unit: seconds.
        # 
        # For example, the latest data in the source database is generated at 10:00. The change tracking task reads the data generated at 09:55, and the downstream client consumes the data generated at 09:30. In this case, the message latency is the UNIX timestamp difference between 09:55 and 09:30.
        # 
        # >  If the return value of this parameter is **-1**, no client is connected to the consumer group.
        self.message_delay = message_delay  # type: long
        # The total number of unconsumed messages, which is the number of unconsumed data records plus the number of heartbeat messages.
        # 
        # >  If the return value of this parameter is -1, no client is connected to the consumer group.
        self.unconsumed_data = unconsumed_data  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeConsumerChannelResponseBodyConsumerChannels, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_id is not None:
            result['ConsumerGroupId'] = self.consumer_group_id
        if self.consumer_group_name is not None:
            result['ConsumerGroupName'] = self.consumer_group_name
        if self.consumer_group_user_name is not None:
            result['ConsumerGroupUserName'] = self.consumer_group_user_name
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.message_delay is not None:
            result['MessageDelay'] = self.message_delay
        if self.unconsumed_data is not None:
            result['UnconsumedData'] = self.unconsumed_data
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupId') is not None:
            self.consumer_group_id = m.get('ConsumerGroupId')
        if m.get('ConsumerGroupName') is not None:
            self.consumer_group_name = m.get('ConsumerGroupName')
        if m.get('ConsumerGroupUserName') is not None:
            self.consumer_group_user_name = m.get('ConsumerGroupUserName')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('MessageDelay') is not None:
            self.message_delay = m.get('MessageDelay')
        if m.get('UnconsumedData') is not None:
            self.unconsumed_data = m.get('UnconsumedData')
        return self


class DescribeConsumerChannelResponseBody(TeaModel):
    def __init__(self, consumer_channels=None, err_code=None, err_message=None, http_status_code=None,
                 page_number=None, page_record_count=None, request_id=None, success=None, total_record_count=None):
        # The details of the consumer groups.
        self.consumer_channels = consumer_channels  # type: list[DescribeConsumerChannelResponseBodyConsumerChannels]
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The number of the returned page.
        self.page_number = page_number  # type: int
        # The maximum number of consumer groups that can be displayed on one page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str
        # The total number of consumer groups.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.consumer_channels:
            for k in self.consumer_channels:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeConsumerChannelResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['ConsumerChannels'] = []
        if self.consumer_channels is not None:
            for k in self.consumer_channels:
                result['ConsumerChannels'].append(k.to_map() if k else None)
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.consumer_channels = []
        if m.get('ConsumerChannels') is not None:
            for k in m.get('ConsumerChannels'):
                temp_model = DescribeConsumerChannelResponseBodyConsumerChannels()
                self.consumer_channels.append(temp_model.from_map(k))
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeConsumerChannelResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeConsumerChannelResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeConsumerChannelResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeConsumerChannelResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeConsumerGroupRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, page_num=None, page_size=None, region_id=None,
                 subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_num = page_num  # type: int
        # The number of entries to return on each page. Valid values: **30**, **50**, and **100**. Default value: **30**.
        self.page_size = page_size  # type: int
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeConsumerGroupRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_num is not None:
            result['PageNum'] = self.page_num
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNum') is not None:
            self.page_num = m.get('PageNum')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class DescribeConsumerGroupResponseBodyConsumerChannelsDescribeConsumerChannel(TeaModel):
    def __init__(self, consumer_group_id=None, consumer_group_name=None, consumer_group_user_name=None,
                 consumption_checkpoint=None, message_delay=None, unconsumed_data=None):
        # The ID of the consumer group.
        self.consumer_group_id = consumer_group_id  # type: str
        # The name of the consumer group.
        self.consumer_group_name = consumer_group_name  # type: str
        # The username of the consumer group.
        self.consumer_group_user_name = consumer_group_user_name  # type: str
        # The consumption checkpoint, which is the time when the latest data record was consumed by the change tracking client. The format is *yyyy-MM-dd*T*HH:mm:ss*Z. The time is displayed in UTC.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The message delay, which is the current time minus the timestamp of the earliest unconsumed message in the change tracking instance. Unit: seconds.
        # 
        # >  If the return value of this parameter is **-1**, no client is connected to the consumer group.
        self.message_delay = message_delay  # type: long
        # The total number of unconsumed messages, which is the number of unconsumed data records plus the number of heartbeat messages.
        # 
        # >  If the return value of this parameter is **-1**, no client is connected to the consumer group.
        self.unconsumed_data = unconsumed_data  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeConsumerGroupResponseBodyConsumerChannelsDescribeConsumerChannel, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_id is not None:
            result['ConsumerGroupID'] = self.consumer_group_id
        if self.consumer_group_name is not None:
            result['ConsumerGroupName'] = self.consumer_group_name
        if self.consumer_group_user_name is not None:
            result['ConsumerGroupUserName'] = self.consumer_group_user_name
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.message_delay is not None:
            result['MessageDelay'] = self.message_delay
        if self.unconsumed_data is not None:
            result['UnconsumedData'] = self.unconsumed_data
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupID') is not None:
            self.consumer_group_id = m.get('ConsumerGroupID')
        if m.get('ConsumerGroupName') is not None:
            self.consumer_group_name = m.get('ConsumerGroupName')
        if m.get('ConsumerGroupUserName') is not None:
            self.consumer_group_user_name = m.get('ConsumerGroupUserName')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('MessageDelay') is not None:
            self.message_delay = m.get('MessageDelay')
        if m.get('UnconsumedData') is not None:
            self.unconsumed_data = m.get('UnconsumedData')
        return self


class DescribeConsumerGroupResponseBodyConsumerChannels(TeaModel):
    def __init__(self, describe_consumer_channel=None):
        self.describe_consumer_channel = describe_consumer_channel  # type: list[DescribeConsumerGroupResponseBodyConsumerChannelsDescribeConsumerChannel]

    def validate(self):
        if self.describe_consumer_channel:
            for k in self.describe_consumer_channel:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeConsumerGroupResponseBodyConsumerChannels, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DescribeConsumerChannel'] = []
        if self.describe_consumer_channel is not None:
            for k in self.describe_consumer_channel:
                result['DescribeConsumerChannel'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.describe_consumer_channel = []
        if m.get('DescribeConsumerChannel') is not None:
            for k in m.get('DescribeConsumerChannel'):
                temp_model = DescribeConsumerGroupResponseBodyConsumerChannelsDescribeConsumerChannel()
                self.describe_consumer_channel.append(temp_model.from_map(k))
        return self


class DescribeConsumerGroupResponseBody(TeaModel):
    def __init__(self, consumer_channels=None, err_code=None, err_message=None, page_number=None,
                 page_record_count=None, request_id=None, success=None, total_record_count=None):
        # The list of consumer groups.
        self.consumer_channels = consumer_channels  # type: DescribeConsumerGroupResponseBodyConsumerChannels
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The maximum number of consumer groups that can be displayed on one page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The total number of consumer groups.
        self.total_record_count = total_record_count  # type: int

    def validate(self):
        if self.consumer_channels:
            self.consumer_channels.validate()

    def to_map(self):
        _map = super(DescribeConsumerGroupResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_channels is not None:
            result['ConsumerChannels'] = self.consumer_channels.to_map()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerChannels') is not None:
            temp_model = DescribeConsumerGroupResponseBodyConsumerChannels()
            self.consumer_channels = temp_model.from_map(m['ConsumerChannels'])
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeConsumerGroupResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeConsumerGroupResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeConsumerGroupResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeConsumerGroupResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDTSIPRequest(TeaModel):
    def __init__(self, destination_endpoint_region=None, region_id=None, source_endpoint_region=None):
        # The ID of the region where the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the destination instance is a self-managed database with a public IP address, you can set the parameter to **cn-hangzhou** or the ID of the closest region.
        self.destination_endpoint_region = destination_endpoint_region  # type: str
        self.region_id = region_id  # type: str
        # The ID of the region where the source instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the source instance is a self-managed database with a public IP address, you can set the parameter to **cn-hangzhou** or the ID of the closest region.
        self.source_endpoint_region = source_endpoint_region  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDTSIPRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_endpoint_region is not None:
            result['DestinationEndpointRegion'] = self.destination_endpoint_region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.source_endpoint_region is not None:
            result['SourceEndpointRegion'] = self.source_endpoint_region
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationEndpointRegion') is not None:
            self.destination_endpoint_region = m.get('DestinationEndpointRegion')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SourceEndpointRegion') is not None:
            self.source_endpoint_region = m.get('SourceEndpointRegion')
        return self


class DescribeDTSIPResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None, request_id=None,
                 success=None):
        # The internal error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The CIDR blocks of DTS servers.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDTSIPResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeDTSIPResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDTSIPResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDTSIPResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDTSIPResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDataCheckReportUrlRequest(TeaModel):
    def __init__(self, check_type=None, db_name=None, dts_job_id=None, tb_name=None):
        self.check_type = check_type  # type: int
        self.db_name = db_name  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.tb_name = tb_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDataCheckReportUrlRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_type is not None:
            result['CheckType'] = self.check_type
        if self.db_name is not None:
            result['DbName'] = self.db_name
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.tb_name is not None:
            result['TbName'] = self.tb_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckType') is not None:
            self.check_type = m.get('CheckType')
        if m.get('DbName') is not None:
            self.db_name = m.get('DbName')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('TbName') is not None:
            self.tb_name = m.get('TbName')
        return self


class DescribeDataCheckReportUrlResponseBody(TeaModel):
    def __init__(self, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.request_id = request_id  # type: str
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDataCheckReportUrlResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeDataCheckReportUrlResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDataCheckReportUrlResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDataCheckReportUrlResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDataCheckReportUrlResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDataCheckTableDetailsRequest(TeaModel):
    def __init__(self, check_type=None, dts_job_id=None, page_number=None, page_size=None, schema_name=None,
                 status=None, table_name=None):
        # The data verification method. Valid values:
        # 
        # *   **1**: full data verification.
        # *   **2**: incremental data verification.
        self.check_type = check_type  # type: int
        # The ID of the data migration or data synchronization task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0**. Default value: **1**.
        self.page_number = page_number  # type: int
        # The number of entries to return on each page.
        self.page_size = page_size  # type: int
        # The name of the schema whose data is verified in the source database.
        self.schema_name = schema_name  # type: str
        # The status of the data verification result. Valid values:
        # 
        # *   **-1** (default): All status.
        # *   **6**: Inconsistent data detected in the table.
        self.status = status  # type: str
        # The name of the table whose data is verified in the source database.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDataCheckTableDetailsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_type is not None:
            result['CheckType'] = self.check_type
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.schema_name is not None:
            result['SchemaName'] = self.schema_name
        if self.status is not None:
            result['Status'] = self.status
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckType') is not None:
            self.check_type = m.get('CheckType')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('SchemaName') is not None:
            self.schema_name = m.get('SchemaName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeDataCheckTableDetailsResponseBodyTableDetails(TeaModel):
    def __init__(self, boot_time=None, diff_count=None, error_code=None, finish_count=None, id=None,
                 source_db_name=None, source_tb_name=None, status=None, target_db_name=None, target_tb_name=None, total_count=None):
        # The time when data verification was performed.
        self.boot_time = boot_time  # type: str
        # The number of data rows that contain inconsistent data.
        self.diff_count = diff_count  # type: long
        # 任务运行出错时，返回报错信息的错误编码。
        # 
        # - **1**：无主键表数量超过限制。
        # - **2**：差异数据超过300行。
        # - **3**：待查询的表不存在。
        # - **4**：查询数据的SQL语法错误。
        self.error_code = error_code  # type: int
        # The number of data rows that were verified.
        self.finish_count = finish_count  # type: long
        # The auto-increment primary key that is used to identify a data record in a verification result.
        self.id = id  # type: long
        # The name of the source database.
        self.source_db_name = source_db_name  # type: str
        # The name of the source table.
        self.source_tb_name = source_tb_name  # type: str
        # The status of the data verification result. Valid values:
        # 
        # *   **0**: The data verification task was complete.
        # *   **2**: The data verification task was initialized.
        # *   **3**: The data verification task was running.
        # *   **5**: The data verification task failed.
        self.status = status  # type: str
        # The name of the destination database.
        self.target_db_name = target_db_name  # type: str
        # The name of the destination table.
        self.target_tb_name = target_tb_name  # type: str
        # The total number of data rows.
        self.total_count = total_count  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDataCheckTableDetailsResponseBodyTableDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.boot_time is not None:
            result['BootTime'] = self.boot_time
        if self.diff_count is not None:
            result['DiffCount'] = self.diff_count
        if self.error_code is not None:
            result['ErrorCode'] = self.error_code
        if self.finish_count is not None:
            result['FinishCount'] = self.finish_count
        if self.id is not None:
            result['Id'] = self.id
        if self.source_db_name is not None:
            result['SourceDbName'] = self.source_db_name
        if self.source_tb_name is not None:
            result['SourceTbName'] = self.source_tb_name
        if self.status is not None:
            result['Status'] = self.status
        if self.target_db_name is not None:
            result['TargetDbName'] = self.target_db_name
        if self.target_tb_name is not None:
            result['TargetTbName'] = self.target_tb_name
        if self.total_count is not None:
            result['TotalCount'] = self.total_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BootTime') is not None:
            self.boot_time = m.get('BootTime')
        if m.get('DiffCount') is not None:
            self.diff_count = m.get('DiffCount')
        if m.get('ErrorCode') is not None:
            self.error_code = m.get('ErrorCode')
        if m.get('FinishCount') is not None:
            self.finish_count = m.get('FinishCount')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('SourceDbName') is not None:
            self.source_db_name = m.get('SourceDbName')
        if m.get('SourceTbName') is not None:
            self.source_tb_name = m.get('SourceTbName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TargetDbName') is not None:
            self.target_db_name = m.get('TargetDbName')
        if m.get('TargetTbName') is not None:
            self.target_tb_name = m.get('TargetTbName')
        if m.get('TotalCount') is not None:
            self.total_count = m.get('TotalCount')
        return self


class DescribeDataCheckTableDetailsResponseBody(TeaModel):
    def __init__(self, diff_table_count=None, dynamic_code=None, dynamic_message=None, err_code=None,
                 err_message=None, finished_count=None, http_status_code=None, page_number=None, request_id=None, success=None,
                 table_details=None, total_count=None):
        # The number of tables that contain inconsistent data.
        self.diff_table_count = diff_table_count  # type: long
        # The dynamic error code. This parameter will be discontinued in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the \*\*%s\*\* variable in the **ErrMessage** parameter.
        # 
        # > For example, if the returned value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **Type**, the specified **Type** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The total number of data rows that were verified.
        self.finished_count = finished_count  # type: long
        # The HTTP status code returned.
        self.http_status_code = http_status_code  # type: int
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The request ID.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool
        # The details of the data verification result.
        self.table_details = table_details  # type: list[DescribeDataCheckTableDetailsResponseBodyTableDetails]
        # The total number of tables on which data verification was performed.
        self.total_count = total_count  # type: long

    def validate(self):
        if self.table_details:
            for k in self.table_details:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDataCheckTableDetailsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.diff_table_count is not None:
            result['DiffTableCount'] = self.diff_table_count
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.finished_count is not None:
            result['FinishedCount'] = self.finished_count
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        result['TableDetails'] = []
        if self.table_details is not None:
            for k in self.table_details:
                result['TableDetails'].append(k.to_map() if k else None)
        if self.total_count is not None:
            result['TotalCount'] = self.total_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DiffTableCount') is not None:
            self.diff_table_count = m.get('DiffTableCount')
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('FinishedCount') is not None:
            self.finished_count = m.get('FinishedCount')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        self.table_details = []
        if m.get('TableDetails') is not None:
            for k in m.get('TableDetails'):
                temp_model = DescribeDataCheckTableDetailsResponseBodyTableDetails()
                self.table_details.append(temp_model.from_map(k))
        if m.get('TotalCount') is not None:
            self.total_count = m.get('TotalCount')
        return self


class DescribeDataCheckTableDetailsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDataCheckTableDetailsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDataCheckTableDetailsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDataCheckTableDetailsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDataCheckTableDiffDetailsRequest(TeaModel):
    def __init__(self, check_type=None, db_name=None, dts_job_id=None, page_number=None, page_size=None,
                 tb_name=None):
        self.check_type = check_type  # type: int
        self.db_name = db_name  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.page_number = page_number  # type: long
        self.page_size = page_size  # type: long
        self.tb_name = tb_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDataCheckTableDiffDetailsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_type is not None:
            result['CheckType'] = self.check_type
        if self.db_name is not None:
            result['DbName'] = self.db_name
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.tb_name is not None:
            result['TbName'] = self.tb_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckType') is not None:
            self.check_type = m.get('CheckType')
        if m.get('DbName') is not None:
            self.db_name = m.get('DbName')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('TbName') is not None:
            self.tb_name = m.get('TbName')
        return self


class DescribeDataCheckTableDiffDetailsResponseBodyDiffDetails(TeaModel):
    def __init__(self, diff=None, gmt_created=None, id=None):
        self.diff = diff  # type: str
        self.gmt_created = gmt_created  # type: str
        self.id = id  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDataCheckTableDiffDetailsResponseBodyDiffDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.diff is not None:
            result['Diff'] = self.diff
        if self.gmt_created is not None:
            result['GmtCreated'] = self.gmt_created
        if self.id is not None:
            result['Id'] = self.id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Diff') is not None:
            self.diff = m.get('Diff')
        if m.get('GmtCreated') is not None:
            self.gmt_created = m.get('GmtCreated')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        return self


class DescribeDataCheckTableDiffDetailsResponseBody(TeaModel):
    def __init__(self, db_name=None, diff_count=None, diff_details=None, dynamic_message=None, err_code=None,
                 err_message=None, http_status_code=None, instance_id=None, request_id=None, success=None, tb_name=None):
        self.db_name = db_name  # type: str
        self.diff_count = diff_count  # type: long
        self.diff_details = diff_details  # type: list[DescribeDataCheckTableDiffDetailsResponseBodyDiffDetails]
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.instance_id = instance_id  # type: str
        self.request_id = request_id  # type: str
        self.success = success  # type: bool
        self.tb_name = tb_name  # type: str

    def validate(self):
        if self.diff_details:
            for k in self.diff_details:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDataCheckTableDiffDetailsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.db_name is not None:
            result['DbName'] = self.db_name
        if self.diff_count is not None:
            result['DiffCount'] = self.diff_count
        result['DiffDetails'] = []
        if self.diff_details is not None:
            for k in self.diff_details:
                result['DiffDetails'].append(k.to_map() if k else None)
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.tb_name is not None:
            result['TbName'] = self.tb_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DbName') is not None:
            self.db_name = m.get('DbName')
        if m.get('DiffCount') is not None:
            self.diff_count = m.get('DiffCount')
        self.diff_details = []
        if m.get('DiffDetails') is not None:
            for k in m.get('DiffDetails'):
                temp_model = DescribeDataCheckTableDiffDetailsResponseBodyDiffDetails()
                self.diff_details.append(temp_model.from_map(k))
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TbName') is not None:
            self.tb_name = m.get('TbName')
        return self


class DescribeDataCheckTableDiffDetailsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDataCheckTableDiffDetailsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDataCheckTableDiffDetailsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDataCheckTableDiffDetailsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDedicatedClusterRequest(TeaModel):
    def __init__(self, dedicated_cluster_id=None, owner_id=None, region_id=None):
        # The ID of the cluster.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region in which the instance resides.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDedicatedClusterRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeDedicatedClusterResponseBody(TeaModel):
    def __init__(self, cpu_utilization=None, dedicated_cluster_id=None, dedicated_cluster_name=None,
                 disk_utilization=None, dts_instance_id=None, du=None, du_utilization=None, err_code=None, err_message=None,
                 gmt_created=None, gmt_finished=None, http_status_code=None, mem_utilization=None, node_count=None,
                 oversold_du=None, region_id=None, request_id=None, state=None, success=None, total_cpu_core=None,
                 total_disk_gbsize=None, total_mem_gbsize=None, used_cpu_core=None, used_disk_gbsize=None, used_du=None,
                 used_mem_gbsize=None):
        # The CPU utilization. Unit: percentage.
        self.cpu_utilization = cpu_utilization  # type: long
        # The ID of the cluster.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The name of the cluster.
        self.dedicated_cluster_name = dedicated_cluster_name  # type: str
        # The disk usage.
        self.disk_utilization = disk_utilization  # type: long
        # The ID of the instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The number of DTS units (DUs).
        self.du = du  # type: long
        # The DU usage. Unit: percentage.
        self.du_utilization = du_utilization  # type: long
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The time when the cluster was created.
        self.gmt_created = gmt_created  # type: long
        # The time when the cluster stopped.
        self.gmt_finished = gmt_finished  # type: long
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The memory usage.
        self.mem_utilization = mem_utilization  # type: long
        # The number of nodes in the cluster.
        self.node_count = node_count  # type: long
        # The number of DUs that exceeds the upper limit.
        self.oversold_du = oversold_du  # type: long
        # The ID of the region in which the instance resides.
        self.region_id = region_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The status of the cluster. Valid values:
        # 
        # *   **init**: The cluster is being initialized.
        # *   **schedule**: The cluster is pending scheduling.
        # *   **running**: The cluster is running.
        # *   **upgrade**: The cluster is being upgraded.
        # *   **downgrade**: The cluster is being downgraded.
        # *   **locked**: The cluster is locked.
        # *   **releasing**: The cluster is being released.
        # *   **released**: The cluster is released.
        self.state = state  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str
        # The total number of CPU cores.
        self.total_cpu_core = total_cpu_core  # type: long
        # The total disk size. Unit: GB.
        self.total_disk_gbsize = total_disk_gbsize  # type: long
        # The total amount of memory. Unit: GB.
        self.total_mem_gbsize = total_mem_gbsize  # type: long
        # The number of used CPU cores.
        self.used_cpu_core = used_cpu_core  # type: long
        # The used disk size. Unit: GB.
        self.used_disk_gbsize = used_disk_gbsize  # type: long
        # The number of used DUs.
        self.used_du = used_du  # type: long
        # The amount of used memory. Unit: GB.
        self.used_mem_gbsize = used_mem_gbsize  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDedicatedClusterResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.cpu_utilization is not None:
            result['CpuUtilization'] = self.cpu_utilization
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dedicated_cluster_name is not None:
            result['DedicatedClusterName'] = self.dedicated_cluster_name
        if self.disk_utilization is not None:
            result['DiskUtilization'] = self.disk_utilization
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.du is not None:
            result['Du'] = self.du
        if self.du_utilization is not None:
            result['DuUtilization'] = self.du_utilization
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.gmt_created is not None:
            result['GmtCreated'] = self.gmt_created
        if self.gmt_finished is not None:
            result['GmtFinished'] = self.gmt_finished
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.mem_utilization is not None:
            result['MemUtilization'] = self.mem_utilization
        if self.node_count is not None:
            result['NodeCount'] = self.node_count
        if self.oversold_du is not None:
            result['OversoldDu'] = self.oversold_du
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.state is not None:
            result['State'] = self.state
        if self.success is not None:
            result['Success'] = self.success
        if self.total_cpu_core is not None:
            result['TotalCpuCore'] = self.total_cpu_core
        if self.total_disk_gbsize is not None:
            result['TotalDiskGBSize'] = self.total_disk_gbsize
        if self.total_mem_gbsize is not None:
            result['TotalMemGBSize'] = self.total_mem_gbsize
        if self.used_cpu_core is not None:
            result['UsedCpuCore'] = self.used_cpu_core
        if self.used_disk_gbsize is not None:
            result['UsedDiskGBSize'] = self.used_disk_gbsize
        if self.used_du is not None:
            result['UsedDu'] = self.used_du
        if self.used_mem_gbsize is not None:
            result['UsedMemGBSize'] = self.used_mem_gbsize
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CpuUtilization') is not None:
            self.cpu_utilization = m.get('CpuUtilization')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DedicatedClusterName') is not None:
            self.dedicated_cluster_name = m.get('DedicatedClusterName')
        if m.get('DiskUtilization') is not None:
            self.disk_utilization = m.get('DiskUtilization')
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('Du') is not None:
            self.du = m.get('Du')
        if m.get('DuUtilization') is not None:
            self.du_utilization = m.get('DuUtilization')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('GmtCreated') is not None:
            self.gmt_created = m.get('GmtCreated')
        if m.get('GmtFinished') is not None:
            self.gmt_finished = m.get('GmtFinished')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('MemUtilization') is not None:
            self.mem_utilization = m.get('MemUtilization')
        if m.get('NodeCount') is not None:
            self.node_count = m.get('NodeCount')
        if m.get('OversoldDu') is not None:
            self.oversold_du = m.get('OversoldDu')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalCpuCore') is not None:
            self.total_cpu_core = m.get('TotalCpuCore')
        if m.get('TotalDiskGBSize') is not None:
            self.total_disk_gbsize = m.get('TotalDiskGBSize')
        if m.get('TotalMemGBSize') is not None:
            self.total_mem_gbsize = m.get('TotalMemGBSize')
        if m.get('UsedCpuCore') is not None:
            self.used_cpu_core = m.get('UsedCpuCore')
        if m.get('UsedDiskGBSize') is not None:
            self.used_disk_gbsize = m.get('UsedDiskGBSize')
        if m.get('UsedDu') is not None:
            self.used_du = m.get('UsedDu')
        if m.get('UsedMemGBSize') is not None:
            self.used_mem_gbsize = m.get('UsedMemGBSize')
        return self


class DescribeDedicatedClusterResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDedicatedClusterResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDedicatedClusterResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDedicatedClusterResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDedicatedClusterMonitorRuleRequest(TeaModel):
    def __init__(self, dedicated_cluster_id=None, owner_id=None, region_id=None):
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDedicatedClusterMonitorRuleRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeDedicatedClusterMonitorRuleResponseBody(TeaModel):
    def __init__(self, cpu_alarm_threshold=None, dedicated_cluster_id=None, disk_alarm_threshold=None,
                 du_alarm_threshold=None, err_code=None, err_message=None, http_status_code=None, mem_alarm_threshold=None,
                 notice_switch=None, phones=None, request_id=None, success=None):
        self.cpu_alarm_threshold = cpu_alarm_threshold  # type: str
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        self.disk_alarm_threshold = disk_alarm_threshold  # type: str
        self.du_alarm_threshold = du_alarm_threshold  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: str
        self.mem_alarm_threshold = mem_alarm_threshold  # type: str
        self.notice_switch = notice_switch  # type: str
        self.phones = phones  # type: str
        self.request_id = request_id  # type: str
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDedicatedClusterMonitorRuleResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.cpu_alarm_threshold is not None:
            result['CpuAlarmThreshold'] = self.cpu_alarm_threshold
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.disk_alarm_threshold is not None:
            result['DiskAlarmThreshold'] = self.disk_alarm_threshold
        if self.du_alarm_threshold is not None:
            result['DuAlarmThreshold'] = self.du_alarm_threshold
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.mem_alarm_threshold is not None:
            result['MemAlarmThreshold'] = self.mem_alarm_threshold
        if self.notice_switch is not None:
            result['NoticeSwitch'] = self.notice_switch
        if self.phones is not None:
            result['Phones'] = self.phones
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CpuAlarmThreshold') is not None:
            self.cpu_alarm_threshold = m.get('CpuAlarmThreshold')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DiskAlarmThreshold') is not None:
            self.disk_alarm_threshold = m.get('DiskAlarmThreshold')
        if m.get('DuAlarmThreshold') is not None:
            self.du_alarm_threshold = m.get('DuAlarmThreshold')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('MemAlarmThreshold') is not None:
            self.mem_alarm_threshold = m.get('MemAlarmThreshold')
        if m.get('NoticeSwitch') is not None:
            self.notice_switch = m.get('NoticeSwitch')
        if m.get('Phones') is not None:
            self.phones = m.get('Phones')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeDedicatedClusterMonitorRuleResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDedicatedClusterMonitorRuleResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDedicatedClusterMonitorRuleResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDedicatedClusterMonitorRuleResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDtsEtlJobVersionInfoRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, page_number=None, page_size=None, region_id=None):
        # The ID of the Data Transmission Service (DTS) instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the ETL task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The number of the page to return. Default value: 1.
        self.page_number = page_number  # type: int
        # The number of entries to return on each page. Default value: 20.
        self.page_size = page_size  # type: int
        # The ID of the region in which the DTS instance resides. You can call the [DescribeRegions](~~25609~~) operation to query the available Alibaba Cloud regions.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsEtlJobVersionInfoRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeDtsEtlJobVersionInfoResponseBodyDtsEtlJobVersionInfos(TeaModel):
    def __init__(self, create_time=None, creator=None, creator_name=None, dts_instance_id=None, dts_job_id=None,
                 dts_job_name=None, modify_time=None, safe_checkpoint=None, status=None, version=None):
        # The time when the ETL task was created. This value is a UNIX timestamp representing the number of milliseconds that have elapsed since January 1, 1970, 00:00:00 UTC.
        self.create_time = create_time  # type: str
        # The ID of the creator.
        self.creator = creator  # type: str
        # The username of the creator.
        self.creator_name = creator_name  # type: str
        # The ID of the DTS instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the ETL task.
        self.dts_job_id = dts_job_id  # type: str
        # The name of the ETL task.
        self.dts_job_name = dts_job_name  # type: str
        # The time when the ETL task was last modified. This value is a UNIX timestamp representing the number of milliseconds that have elapsed since January 1, 1970, 00:00:00 UTC.
        self.modify_time = modify_time  # type: str
        # The safe checkpoint of the ETL task.
        self.safe_checkpoint = safe_checkpoint  # type: str
        # The log level. Valid values: ERROR, WARN, INFO, and DEBUG.
        self.status = status  # type: str
        # The version number of the ETL task.
        self.version = version  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsEtlJobVersionInfoResponseBodyDtsEtlJobVersionInfos, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.creator is not None:
            result['Creator'] = self.creator
        if self.creator_name is not None:
            result['CreatorName'] = self.creator_name
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.modify_time is not None:
            result['ModifyTime'] = self.modify_time
        if self.safe_checkpoint is not None:
            result['SafeCheckpoint'] = self.safe_checkpoint
        if self.status is not None:
            result['Status'] = self.status
        if self.version is not None:
            result['Version'] = self.version
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('Creator') is not None:
            self.creator = m.get('Creator')
        if m.get('CreatorName') is not None:
            self.creator_name = m.get('CreatorName')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('ModifyTime') is not None:
            self.modify_time = m.get('ModifyTime')
        if m.get('SafeCheckpoint') is not None:
            self.safe_checkpoint = m.get('SafeCheckpoint')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('Version') is not None:
            self.version = m.get('Version')
        return self


class DescribeDtsEtlJobVersionInfoResponseBody(TeaModel):
    def __init__(self, dts_etl_job_version_infos=None, dynamic_code=None, dynamic_message=None, err_code=None,
                 err_message=None, http_status_code=None, page_number=None, page_record_count=None, request_id=None,
                 success=None, total_record_count=None):
        # The details of ETL tasks.
        self.dts_etl_job_version_infos = dts_etl_job_version_infos  # type: list[DescribeDtsEtlJobVersionInfoResponseBodyDtsEtlJobVersionInfos]
        # The dynamic error code.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message.
        self.dynamic_message = dynamic_message  # type: str
        # The error code. This example indicates that the specified ETL task ID is invalid.
        self.err_code = err_code  # type: str
        # The error message. This example indicates that the specified ETL task ID does not exist. In this case, the ETL task may have been deleted.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The page number of the returned page. Default value: 1.
        self.page_number = page_number  # type: int
        # The number of records returned on the current page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful. If the call failed, false is returned.
        self.success = success  # type: bool
        # The total number of records.
        self.total_record_count = total_record_count  # type: int

    def validate(self):
        if self.dts_etl_job_version_infos:
            for k in self.dts_etl_job_version_infos:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsEtlJobVersionInfoResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DtsEtlJobVersionInfos'] = []
        if self.dts_etl_job_version_infos is not None:
            for k in self.dts_etl_job_version_infos:
                result['DtsEtlJobVersionInfos'].append(k.to_map() if k else None)
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.dts_etl_job_version_infos = []
        if m.get('DtsEtlJobVersionInfos') is not None:
            for k in m.get('DtsEtlJobVersionInfos'):
                temp_model = DescribeDtsEtlJobVersionInfoResponseBodyDtsEtlJobVersionInfos()
                self.dts_etl_job_version_infos.append(temp_model.from_map(k))
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeDtsEtlJobVersionInfoResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDtsEtlJobVersionInfoResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDtsEtlJobVersionInfoResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDtsEtlJobVersionInfoResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDtsJobDetailRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, region_id=None, sync_sub_job_history=None,
                 synchronization_direction=None):
        # DescribeDtsJobDetail
        self.dts_instance_id = dts_instance_id  # type: str
        # The state of the data migration or data synchronization task.
        # 
        # Valid values for a data migration task:
        # 
        # *   **NotStarted**: The migration is not started.
        # *   **Migrating**: The migration is in progress.
        # *   **Failed**: The migration failed.
        # *   **Finished**: The migration is complete.
        # 
        # Valid values for a data synchronization task:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is in precheck.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Initializing**: The task is performing initial synchronization.
        # *   **InitializeFailed**: Initial synchronization failed.
        # *   **Synchronizing**: The task is in progress.
        # *   **Failed**: The task failed to synchronize data.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is complete.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.region_id = region_id  # type: str
        self.sync_sub_job_history = sync_sub_job_history  # type: bool
        # Queries the details of a data migration, data synchronization, or change tracking task.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.sync_sub_job_history is not None:
            result['SyncSubJobHistory'] = self.sync_sub_job_history
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SyncSubJobHistory') is not None:
            self.sync_sub_job_history = m.get('SyncSubJobHistory')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class DescribeDtsJobDetailResponseBodyDataDeliveryChannelInfo(TeaModel):
    def __init__(self, partition_num=None, public_dproxy_url=None, region=None, topic=None, vpc_dproxy_url=None):
        self.partition_num = partition_num  # type: int
        self.public_dproxy_url = public_dproxy_url  # type: str
        self.region = region  # type: str
        self.topic = topic  # type: str
        self.vpc_dproxy_url = vpc_dproxy_url  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodyDataDeliveryChannelInfo, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.partition_num is not None:
            result['PartitionNum'] = self.partition_num
        if self.public_dproxy_url is not None:
            result['PublicDproxyUrl'] = self.public_dproxy_url
        if self.region is not None:
            result['Region'] = self.region
        if self.topic is not None:
            result['Topic'] = self.topic
        if self.vpc_dproxy_url is not None:
            result['VpcDproxyUrl'] = self.vpc_dproxy_url
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PartitionNum') is not None:
            self.partition_num = m.get('PartitionNum')
        if m.get('PublicDproxyUrl') is not None:
            self.public_dproxy_url = m.get('PublicDproxyUrl')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('Topic') is not None:
            self.topic = m.get('Topic')
        if m.get('VpcDproxyUrl') is not None:
            self.vpc_dproxy_url = m.get('VpcDproxyUrl')
        return self


class DescribeDtsJobDetailResponseBodyDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodyDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodyDestinationEndpoint(TeaModel):
    def __init__(self, can_modify_password=None, database_name=None, engine_name=None, instance_id=None,
                 instance_type=None, ip=None, oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        self.can_modify_password = can_modify_password  # type: bool
        # The connection settings of the destination instance.
        self.database_name = database_name  # type: str
        # The database service port of the destination instance.
        self.engine_name = engine_name  # type: str
        # The name of the database that contains the migrated objects in the destination instance.
        self.instance_id = instance_id  # type: str
        # The IP address of the destination instance.
        self.instance_type = instance_type  # type: str
        # The SID of the Oracle database.
        # 
        # >  This parameter is returned only if the **EngineName** parameter of the destination instance is set to **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.ip = ip  # type: str
        # The username of the account that is used to connect to the source database.
        self.oracle_sid = oracle_sid  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        self.port = port  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # *   **DISABLE**: SSL encryption is disabled.
        # *   **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled, and the CA certificate is uploaded.
        # *   **ENABLE_ONLY\_4\_MONGODB_ALTAS**: SSL encryption is enabled for the connection to an AWS MongoDB Altas database.
        # *   **ENABLE_ONLY\_4\_KAFKA_SCRAM_SHA\_256**: SCRAM-SHA-256 is used to encrypt the connection to a Kafka cluster.
        self.region = region  # type: str
        # The ID of the Alibaba Cloud account to which the source ApsaraDB RDS instance belongs.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The ID of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodyDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.can_modify_password is not None:
            result['CanModifyPassword'] = self.can_modify_password
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CanModifyPassword') is not None:
            self.can_modify_password = m.get('CanModifyPassword')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodyMigrationMode(TeaModel):
    def __init__(self, data_extract_transform_load=None, data_initialization=None, data_synchronization=None,
                 structure_initialization=None):
        # The database account of the destination instance.
        self.data_extract_transform_load = data_extract_transform_load  # type: bool
        # The database engine of the destination instance.
        self.data_initialization = data_initialization  # type: bool
        # The migration types or synchronization types.
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether data transformation is performed. Valid values:
        # 
        # *   **true**: Data transformation is performed.
        # *   **false**: Data transformation is not performed.
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodyMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_extract_transform_load is not None:
            result['DataExtractTransformLoad'] = self.data_extract_transform_load
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataExtractTransformLoad') is not None:
            self.data_extract_transform_load = m.get('DataExtractTransformLoad')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobDetailResponseBodyRetryState(TeaModel):
    def __init__(self, err_message=None, job_id=None, max_retry_time=None, module=None, retry_count=None,
                 retry_target=None, retry_time=None, retrying=None):
        self.err_message = err_message  # type: str
        self.job_id = job_id  # type: str
        self.max_retry_time = max_retry_time  # type: int
        self.module = module  # type: str
        self.retry_count = retry_count  # type: int
        self.retry_target = retry_target  # type: str
        self.retry_time = retry_time  # type: int
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodyRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobDetailResponseBodySourceEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, can_modify_password=None, database_name=None, engine_name=None,
                 instance_id=None, instance_type=None, ip=None, oracle_sid=None, port=None, region=None, role_name=None,
                 ssl_solution_enum=None, user_name=None):
        # The database engine of the source instance.
        self.aliyun_uid = aliyun_uid  # type: str
        self.can_modify_password = can_modify_password  # type: bool
        # The database service port of the source instance.
        self.database_name = database_name  # type: str
        # The name of the RAM role configured for the Alibaba Cloud account that owns the source instance.
        self.engine_name = engine_name  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  This parameter is returned only if the **EngineName** parameter of the source instance is set to **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.instance_id = instance_id  # type: str
        # The IP address of the source instance.
        self.instance_type = instance_type  # type: str
        # The connection settings of the source instance.
        self.ip = ip  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        self.oracle_sid = oracle_sid  # type: str
        # The ID of the source instance.
        self.port = port  # type: str
        # The type of the source instance.
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # *   **DISABLE**: SSL encryption is disabled.
        # *   **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled, and the CA certificate is uploaded.
        # *   **ENABLE_ONLY\_4\_MONGODB_ALTAS**: SSL encryption is enabled for the connection to an AWS MongoDB Altas database.
        # *   **ENABLE_ONLY\_4\_KAFKA_SCRAM_SHA\_256**: SCRAM-SHA-256 is used to encrypt the connection to a Kafka cluster.
        self.role_name = role_name  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # >  This parameter is returned only if the topology of the data synchronization instance is two-way synchronization.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The ID of the region in which the source instance resides. For more information, see [List of supported regions](~~141033~~).
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.can_modify_password is not None:
            result['CanModifyPassword'] = self.can_modify_password
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('CanModifyPassword') is not None:
            self.can_modify_password = m.get('CanModifyPassword')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobDataEtlStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobDataEtlStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobDestinationEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobMigrationMode(TeaModel):
    def __init__(self, data_extract_transform_load=None, data_initialization=None, data_synchronization=None,
                 structure_initialization=None):
        self.data_extract_transform_load = data_extract_transform_load  # type: bool
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_extract_transform_load is not None:
            result['DataExtractTransformLoad'] = self.data_extract_transform_load
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataExtractTransformLoad') is not None:
            self.data_extract_transform_load = m.get('DataExtractTransformLoad')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        self.flow = flow  # type: str
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        self.check_item = check_item  # type: str
        self.check_item_description = check_item_description  # type: str
        self.check_result = check_result  # type: str
        self.failed_reason = failed_reason  # type: str
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        self.detail = detail  # type: list[DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatusDetail]
        self.error_message = error_message  # type: str
        self.percent = percent  # type: str
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobRetryState(TeaModel):
    def __init__(self, err_msg=None, job_id=None, max_retry_time=None, module=None, retry_count=None,
                 retry_target=None, retry_time=None, retrying=None):
        self.err_msg = err_msg  # type: str
        self.job_id = job_id  # type: str
        self.max_retry_time = max_retry_time  # type: int
        self.module = module  # type: str
        self.retry_count = retry_count  # type: int
        # srcDB/destDB/metaDB/dstore
        self.retry_target = retry_target  # type: str
        self.retry_time = retry_time  # type: int
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataEtlStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataEtlStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDestinationEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobMigrationMode(TeaModel):
    def __init__(self, data_extract_transform_load=None, data_initialization=None, data_synchronization=None,
                 structure_initialization=None):
        self.data_extract_transform_load = data_extract_transform_load  # type: bool
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_extract_transform_load is not None:
            result['DataExtractTransformLoad'] = self.data_extract_transform_load
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataExtractTransformLoad') is not None:
            self.data_extract_transform_load = m.get('DataExtractTransformLoad')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        self.flow = flow  # type: str
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        self.check_item = check_item  # type: str
        self.check_item_description = check_item_description  # type: str
        self.check_result = check_result  # type: str
        self.failed_reason = failed_reason  # type: str
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        self.detail = detail  # type: list[DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatusDetail]
        self.error_message = error_message  # type: str
        self.percent = percent  # type: str
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobRetryState(TeaModel):
    def __init__(self, err_msg=None, job_id=None, max_retry_time=None, module=None, retry_count=None,
                 retry_target=None, retry_time=None, retrying=None):
        self.err_msg = err_msg  # type: str
        self.job_id = job_id  # type: str
        self.max_retry_time = max_retry_time  # type: int
        self.module = module  # type: str
        self.retry_count = retry_count  # type: int
        # srcDB/destDB/metaDB/dstore
        self.retry_target = retry_target  # type: str
        self.retry_time = retry_time  # type: int
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSourceEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        self.ddl = ddl  # type: bool
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['Ddl'] = self.ddl
        if self.dml is not None:
            result['Dml'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Ddl') is not None:
            self.ddl = m.get('Ddl')
        if m.get('Dml') is not None:
            self.dml = m.get('Dml')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpc_host=None):
        self.private_host = private_host  # type: str
        self.public_host = public_host  # type: str
        self.vpc_host = vpc_host  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpc_host is not None:
            result['VpcHost'] = self.vpc_host
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VpcHost') is not None:
            self.vpc_host = m.get('VpcHost')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobTagList(TeaModel):
    def __init__(self, ali_uid=None, creator=None, gmt_create=None, gmt_modified=None, id=None, region_id=None,
                 resource_id=None, resource_type=None, scope=None, src_region=None, tag_category=None, tag_key=None,
                 tag_value=None):
        self.ali_uid = ali_uid  # type: long
        self.creator = creator  # type: long
        self.gmt_create = gmt_create  # type: str
        self.gmt_modified = gmt_modified  # type: str
        self.id = id  # type: long
        # region_id
        self.region_id = region_id  # type: str
        # dts instance id
        self.resource_id = resource_id  # type: str
        self.resource_type = resource_type  # type: str
        self.scope = scope  # type: str
        self.src_region = src_region  # type: str
        self.tag_category = tag_category  # type: str
        self.tag_key = tag_key  # type: str
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobTagList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ali_uid is not None:
            result['AliUid'] = self.ali_uid
        if self.creator is not None:
            result['Creator'] = self.creator
        if self.gmt_create is not None:
            result['GmtCreate'] = self.gmt_create
        if self.gmt_modified is not None:
            result['GmtModified'] = self.gmt_modified
        if self.id is not None:
            result['Id'] = self.id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        if self.scope is not None:
            result['Scope'] = self.scope
        if self.src_region is not None:
            result['SrcRegion'] = self.src_region
        if self.tag_category is not None:
            result['TagCategory'] = self.tag_category
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliUid') is not None:
            self.ali_uid = m.get('AliUid')
        if m.get('Creator') is not None:
            self.creator = m.get('Creator')
        if m.get('GmtCreate') is not None:
            self.gmt_create = m.get('GmtCreate')
        if m.get('GmtModified') is not None:
            self.gmt_modified = m.get('GmtModified')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        if m.get('Scope') is not None:
            self.scope = m.get('Scope')
        if m.get('SrcRegion') is not None:
            self.src_region = m.get('SrcRegion')
        if m.get('TagCategory') is not None:
            self.tag_category = m.get('TagCategory')
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobReverseJob(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, checkpoint=None, consumption_checkpoint=None,
                 consumption_client=None, create_time=None, data_etl_status=None, data_initialization_status=None,
                 data_synchronization_status=None, database_count=None, db_object=None, delay=None, dest_net_type=None,
                 destination_endpoint=None, dts_instance_id=None, dts_job_class=None, dts_job_direction=None, dts_job_id=None,
                 dts_job_name=None, end_timestamp=None, error_message=None, etl_calculator=None, expire_time=None,
                 finish_time=None, group_id=None, is_demo_job=None, job_type=None, migration_mode=None, origin_type=None,
                 pay_type=None, performance=None, precheck_status=None, reserved=None, retry_state=None, reverse_job=None,
                 source_endpoint=None, status=None, structure_initialization_status=None, subscribe_topic=None,
                 subscription_data_type=None, subscription_host=None, synchronization_direction=None, tag_list=None, task_type=None):
        self.app_name = app_name  # type: str
        self.begin_timestamp = begin_timestamp  # type: str
        self.checkpoint = checkpoint  # type: str
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        self.consumption_client = consumption_client  # type: str
        self.create_time = create_time  # type: str
        self.data_etl_status = data_etl_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataEtlStatus
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataInitializationStatus
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataSynchronizationStatus
        self.database_count = database_count  # type: int
        self.db_object = db_object  # type: str
        self.delay = delay  # type: long
        self.dest_net_type = dest_net_type  # type: str
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDestinationEndpoint
        self.dts_instance_id = dts_instance_id  # type: str
        self.dts_job_class = dts_job_class  # type: str
        self.dts_job_direction = dts_job_direction  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.dts_job_name = dts_job_name  # type: str
        self.end_timestamp = end_timestamp  # type: str
        self.error_message = error_message  # type: str
        self.etl_calculator = etl_calculator  # type: str
        self.expire_time = expire_time  # type: str
        self.finish_time = finish_time  # type: str
        self.group_id = group_id  # type: str
        self.is_demo_job = is_demo_job  # type: bool
        self.job_type = job_type  # type: str
        self.migration_mode = migration_mode  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobMigrationMode
        self.origin_type = origin_type  # type: str
        self.pay_type = pay_type  # type: str
        self.performance = performance  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPerformance
        self.precheck_status = precheck_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatus
        self.reserved = reserved  # type: str
        self.retry_state = retry_state  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobRetryState
        self.reverse_job = reverse_job  # type: any
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSourceEndpoint
        self.status = status  # type: str
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobStructureInitializationStatus
        self.subscribe_topic = subscribe_topic  # type: str
        self.subscription_data_type = subscription_data_type  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionDataType
        self.subscription_host = subscription_host  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionHost
        self.synchronization_direction = synchronization_direction  # type: str
        self.tag_list = tag_list  # type: list[DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobTagList]
        self.task_type = task_type  # type: str

    def validate(self):
        if self.data_etl_status:
            self.data_etl_status.validate()
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()
        if self.tag_list:
            for k in self.tag_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobReverseJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_etl_status is not None:
            result['DataEtlStatus'] = self.data_etl_status.to_map()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.database_count is not None:
            result['DatabaseCount'] = self.database_count
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.dest_net_type is not None:
            result['DestNetType'] = self.dest_net_type
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_calculator is not None:
            result['EtlCalculator'] = self.etl_calculator
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.is_demo_job is not None:
            result['IsDemoJob'] = self.is_demo_job
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.origin_type is not None:
            result['OriginType'] = self.origin_type
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.reverse_job is not None:
            result['ReverseJob'] = self.reverse_job
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        result['TagList'] = []
        if self.tag_list is not None:
            for k in self.tag_list:
                result['TagList'].append(k.to_map() if k else None)
        if self.task_type is not None:
            result['TaskType'] = self.task_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataEtlStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataEtlStatus()
            self.data_etl_status = temp_model.from_map(m['DataEtlStatus'])
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DatabaseCount') is not None:
            self.database_count = m.get('DatabaseCount')
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestNetType') is not None:
            self.dest_net_type = m.get('DestNetType')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlCalculator') is not None:
            self.etl_calculator = m.get('EtlCalculator')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('IsDemoJob') is not None:
            self.is_demo_job = m.get('IsDemoJob')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('OriginType') is not None:
            self.origin_type = m.get('OriginType')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('ReverseJob') is not None:
            self.reverse_job = m.get('ReverseJob')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobSubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        self.tag_list = []
        if m.get('TagList') is not None:
            for k in m.get('TagList'):
                temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJobTagList()
                self.tag_list.append(temp_model.from_map(k))
        if m.get('TaskType') is not None:
            self.task_type = m.get('TaskType')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobSourceEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        self.ddl = ddl  # type: bool
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['Ddl'] = self.ddl
        if self.dml is not None:
            result['Dml'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Ddl') is not None:
            self.ddl = m.get('Ddl')
        if m.get('Dml') is not None:
            self.dml = m.get('Dml')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpc_host=None):
        self.private_host = private_host  # type: str
        self.public_host = public_host  # type: str
        self.vpc_host = vpc_host  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpc_host is not None:
            result['VpcHost'] = self.vpc_host
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VpcHost') is not None:
            self.vpc_host = m.get('VpcHost')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJobTagList(TeaModel):
    def __init__(self, ali_uid=None, creator=None, gmt_create=None, gmt_modified=None, id=None, region_id=None,
                 resource_id=None, resource_type=None, scope=None, src_region=None, tag_category=None, tag_key=None,
                 tag_value=None):
        self.ali_uid = ali_uid  # type: long
        self.creator = creator  # type: long
        self.gmt_create = gmt_create  # type: str
        self.gmt_modified = gmt_modified  # type: str
        self.id = id  # type: long
        # region_id
        self.region_id = region_id  # type: str
        # dts instance id
        self.resource_id = resource_id  # type: str
        self.resource_type = resource_type  # type: str
        self.scope = scope  # type: str
        self.src_region = src_region  # type: str
        self.tag_category = tag_category  # type: str
        self.tag_key = tag_key  # type: str
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJobTagList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ali_uid is not None:
            result['AliUid'] = self.ali_uid
        if self.creator is not None:
            result['Creator'] = self.creator
        if self.gmt_create is not None:
            result['GmtCreate'] = self.gmt_create
        if self.gmt_modified is not None:
            result['GmtModified'] = self.gmt_modified
        if self.id is not None:
            result['Id'] = self.id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        if self.scope is not None:
            result['Scope'] = self.scope
        if self.src_region is not None:
            result['SrcRegion'] = self.src_region
        if self.tag_category is not None:
            result['TagCategory'] = self.tag_category
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliUid') is not None:
            self.ali_uid = m.get('AliUid')
        if m.get('Creator') is not None:
            self.creator = m.get('Creator')
        if m.get('GmtCreate') is not None:
            self.gmt_create = m.get('GmtCreate')
        if m.get('GmtModified') is not None:
            self.gmt_modified = m.get('GmtModified')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        if m.get('Scope') is not None:
            self.scope = m.get('Scope')
        if m.get('SrcRegion') is not None:
            self.src_region = m.get('SrcRegion')
        if m.get('TagCategory') is not None:
            self.tag_category = m.get('TagCategory')
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class DescribeDtsJobDetailResponseBodySubDistributedJob(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, checkpoint=None, consumption_checkpoint=None,
                 consumption_client=None, create_time=None, data_etl_status=None, data_initialization_status=None,
                 data_synchronization_status=None, database_count=None, db_object=None, delay=None, dest_net_type=None,
                 destination_endpoint=None, dts_instance_id=None, dts_job_class=None, dts_job_direction=None, dts_job_id=None,
                 dts_job_name=None, end_timestamp=None, error_message=None, etl_calculator=None, expire_time=None,
                 finish_time=None, group_id=None, is_demo_job=None, job_type=None, migration_mode=None, origin_type=None,
                 pay_type=None, performance=None, precheck_status=None, reserved=None, retry_state=None, reverse_job=None,
                 source_endpoint=None, status=None, structure_initialization_status=None, sub_sync_job=None, subscribe_topic=None,
                 subscription_data_type=None, subscription_host=None, synchronization_direction=None, tag_list=None, task_type=None):
        self.app_name = app_name  # type: str
        self.begin_timestamp = begin_timestamp  # type: str
        self.checkpoint = checkpoint  # type: str
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        self.consumption_client = consumption_client  # type: str
        self.create_time = create_time  # type: str
        self.data_etl_status = data_etl_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobDataEtlStatus
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobDataInitializationStatus
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobDataSynchronizationStatus
        self.database_count = database_count  # type: int
        self.db_object = db_object  # type: str
        self.delay = delay  # type: long
        self.dest_net_type = dest_net_type  # type: str
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobDetailResponseBodySubDistributedJobDestinationEndpoint
        self.dts_instance_id = dts_instance_id  # type: str
        self.dts_job_class = dts_job_class  # type: str
        self.dts_job_direction = dts_job_direction  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.dts_job_name = dts_job_name  # type: str
        self.end_timestamp = end_timestamp  # type: str
        self.error_message = error_message  # type: str
        self.etl_calculator = etl_calculator  # type: str
        self.expire_time = expire_time  # type: str
        self.finish_time = finish_time  # type: str
        self.group_id = group_id  # type: str
        self.is_demo_job = is_demo_job  # type: bool
        self.job_type = job_type  # type: str
        self.migration_mode = migration_mode  # type: DescribeDtsJobDetailResponseBodySubDistributedJobMigrationMode
        self.origin_type = origin_type  # type: str
        self.pay_type = pay_type  # type: str
        self.performance = performance  # type: DescribeDtsJobDetailResponseBodySubDistributedJobPerformance
        self.precheck_status = precheck_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatus
        self.reserved = reserved  # type: str
        self.retry_state = retry_state  # type: DescribeDtsJobDetailResponseBodySubDistributedJobRetryState
        self.reverse_job = reverse_job  # type: DescribeDtsJobDetailResponseBodySubDistributedJobReverseJob
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobDetailResponseBodySubDistributedJobSourceEndpoint
        self.status = status  # type: str
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobDetailResponseBodySubDistributedJobStructureInitializationStatus
        self.sub_sync_job = sub_sync_job  # type: list[any]
        self.subscribe_topic = subscribe_topic  # type: str
        self.subscription_data_type = subscription_data_type  # type: DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionDataType
        self.subscription_host = subscription_host  # type: DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionHost
        self.synchronization_direction = synchronization_direction  # type: str
        self.tag_list = tag_list  # type: list[DescribeDtsJobDetailResponseBodySubDistributedJobTagList]
        self.task_type = task_type  # type: str

    def validate(self):
        if self.data_etl_status:
            self.data_etl_status.validate()
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.reverse_job:
            self.reverse_job.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()
        if self.tag_list:
            for k in self.tag_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubDistributedJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_etl_status is not None:
            result['DataEtlStatus'] = self.data_etl_status.to_map()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.database_count is not None:
            result['DatabaseCount'] = self.database_count
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.dest_net_type is not None:
            result['DestNetType'] = self.dest_net_type
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_calculator is not None:
            result['EtlCalculator'] = self.etl_calculator
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.is_demo_job is not None:
            result['IsDemoJob'] = self.is_demo_job
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.origin_type is not None:
            result['OriginType'] = self.origin_type
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.reverse_job is not None:
            result['ReverseJob'] = self.reverse_job.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.sub_sync_job is not None:
            result['SubSyncJob'] = self.sub_sync_job
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        result['TagList'] = []
        if self.tag_list is not None:
            for k in self.tag_list:
                result['TagList'].append(k.to_map() if k else None)
        if self.task_type is not None:
            result['TaskType'] = self.task_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataEtlStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobDataEtlStatus()
            self.data_etl_status = temp_model.from_map(m['DataEtlStatus'])
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DatabaseCount') is not None:
            self.database_count = m.get('DatabaseCount')
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestNetType') is not None:
            self.dest_net_type = m.get('DestNetType')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlCalculator') is not None:
            self.etl_calculator = m.get('EtlCalculator')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('IsDemoJob') is not None:
            self.is_demo_job = m.get('IsDemoJob')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('OriginType') is not None:
            self.origin_type = m.get('OriginType')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('ReverseJob') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobReverseJob()
            self.reverse_job = temp_model.from_map(m['ReverseJob'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('SubSyncJob') is not None:
            self.sub_sync_job = m.get('SubSyncJob')
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobSubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        self.tag_list = []
        if m.get('TagList') is not None:
            for k in m.get('TagList'):
                temp_model = DescribeDtsJobDetailResponseBodySubDistributedJobTagList()
                self.tag_list.append(temp_model.from_map(k))
        if m.get('TaskType') is not None:
            self.task_type = m.get('TaskType')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobDataEtlStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobDataEtlStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobDestinationEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobMigrationMode(TeaModel):
    def __init__(self, data_extract_transform_load=None, data_initialization=None, data_synchronization=None,
                 structure_initialization=None):
        self.data_extract_transform_load = data_extract_transform_load  # type: bool
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_extract_transform_load is not None:
            result['DataExtractTransformLoad'] = self.data_extract_transform_load
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataExtractTransformLoad') is not None:
            self.data_extract_transform_load = m.get('DataExtractTransformLoad')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        self.flow = flow  # type: str
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        self.check_item = check_item  # type: str
        self.check_item_description = check_item_description  # type: str
        self.check_result = check_result  # type: str
        self.failed_reason = failed_reason  # type: str
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        self.detail = detail  # type: list[DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatusDetail]
        self.error_message = error_message  # type: str
        self.percent = percent  # type: str
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobRetryState(TeaModel):
    def __init__(self, err_msg=None, job_id=None, max_retry_time=None, module=None, retry_count=None,
                 retry_target=None, retry_time=None, retrying=None):
        self.err_msg = err_msg  # type: str
        self.job_id = job_id  # type: str
        self.max_retry_time = max_retry_time  # type: int
        self.module = module  # type: str
        self.retry_count = retry_count  # type: int
        # srcDB/destDB/metaDB/dstore
        self.retry_target = retry_target  # type: str
        self.retry_time = retry_time  # type: int
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataEtlStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataEtlStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDestinationEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobMigrationMode(TeaModel):
    def __init__(self, data_extract_transform_load=None, data_initialization=None, data_synchronization=None,
                 structure_initialization=None):
        self.data_extract_transform_load = data_extract_transform_load  # type: bool
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_extract_transform_load is not None:
            result['DataExtractTransformLoad'] = self.data_extract_transform_load
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataExtractTransformLoad') is not None:
            self.data_extract_transform_load = m.get('DataExtractTransformLoad')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        self.flow = flow  # type: str
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        self.check_item = check_item  # type: str
        self.check_item_description = check_item_description  # type: str
        self.check_result = check_result  # type: str
        self.failed_reason = failed_reason  # type: str
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        self.detail = detail  # type: list[DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatusDetail]
        self.error_message = error_message  # type: str
        self.percent = percent  # type: str
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobRetryState(TeaModel):
    def __init__(self, err_msg=None, job_id=None, max_retry_time=None, module=None, retry_count=None,
                 retry_target=None, retry_time=None, retrying=None):
        self.err_msg = err_msg  # type: str
        self.job_id = job_id  # type: str
        self.max_retry_time = max_retry_time  # type: int
        self.module = module  # type: str
        self.retry_count = retry_count  # type: int
        # srcDB/destDB/metaDB/dstore
        self.retry_target = retry_target  # type: str
        self.retry_time = retry_time  # type: int
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSourceEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        self.ddl = ddl  # type: bool
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['Ddl'] = self.ddl
        if self.dml is not None:
            result['Dml'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Ddl') is not None:
            self.ddl = m.get('Ddl')
        if m.get('Dml') is not None:
            self.dml = m.get('Dml')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpc_host=None):
        self.private_host = private_host  # type: str
        self.public_host = public_host  # type: str
        self.vpc_host = vpc_host  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpc_host is not None:
            result['VpcHost'] = self.vpc_host
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VpcHost') is not None:
            self.vpc_host = m.get('VpcHost')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJobTagList(TeaModel):
    def __init__(self, ali_uid=None, creator=None, gmt_create=None, gmt_modified=None, id=None, region_id=None,
                 resource_id=None, resource_type=None, scope=None, src_region=None, tag_category=None, tag_key=None,
                 tag_value=None):
        self.ali_uid = ali_uid  # type: long
        self.creator = creator  # type: long
        self.gmt_create = gmt_create  # type: str
        self.gmt_modified = gmt_modified  # type: str
        self.id = id  # type: long
        # region_id
        self.region_id = region_id  # type: str
        # dts instance id
        self.resource_id = resource_id  # type: str
        self.resource_type = resource_type  # type: str
        self.scope = scope  # type: str
        self.src_region = src_region  # type: str
        self.tag_category = tag_category  # type: str
        self.tag_key = tag_key  # type: str
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJobTagList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ali_uid is not None:
            result['AliUid'] = self.ali_uid
        if self.creator is not None:
            result['Creator'] = self.creator
        if self.gmt_create is not None:
            result['GmtCreate'] = self.gmt_create
        if self.gmt_modified is not None:
            result['GmtModified'] = self.gmt_modified
        if self.id is not None:
            result['Id'] = self.id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        if self.scope is not None:
            result['Scope'] = self.scope
        if self.src_region is not None:
            result['SrcRegion'] = self.src_region
        if self.tag_category is not None:
            result['TagCategory'] = self.tag_category
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliUid') is not None:
            self.ali_uid = m.get('AliUid')
        if m.get('Creator') is not None:
            self.creator = m.get('Creator')
        if m.get('GmtCreate') is not None:
            self.gmt_create = m.get('GmtCreate')
        if m.get('GmtModified') is not None:
            self.gmt_modified = m.get('GmtModified')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        if m.get('Scope') is not None:
            self.scope = m.get('Scope')
        if m.get('SrcRegion') is not None:
            self.src_region = m.get('SrcRegion')
        if m.get('TagCategory') is not None:
            self.tag_category = m.get('TagCategory')
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobReverseJob(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, checkpoint=None, consumption_checkpoint=None,
                 consumption_client=None, create_time=None, data_etl_status=None, data_initialization_status=None,
                 data_synchronization_status=None, database_count=None, db_object=None, delay=None, dest_net_type=None,
                 destination_endpoint=None, dts_instance_id=None, dts_job_class=None, dts_job_direction=None, dts_job_id=None,
                 dts_job_name=None, end_timestamp=None, error_message=None, etl_calculator=None, expire_time=None,
                 finish_time=None, group_id=None, is_demo_job=None, job_type=None, migration_mode=None, origin_type=None,
                 pay_type=None, performance=None, precheck_status=None, reserved=None, retry_state=None, reverse_job=None,
                 source_endpoint=None, status=None, structure_initialization_status=None, subscribe_topic=None,
                 subscription_data_type=None, subscription_host=None, synchronization_direction=None, tag_list=None, task_type=None):
        self.app_name = app_name  # type: str
        self.begin_timestamp = begin_timestamp  # type: str
        self.checkpoint = checkpoint  # type: str
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        self.consumption_client = consumption_client  # type: str
        self.create_time = create_time  # type: str
        self.data_etl_status = data_etl_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataEtlStatus
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataInitializationStatus
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataSynchronizationStatus
        self.database_count = database_count  # type: int
        self.db_object = db_object  # type: str
        self.delay = delay  # type: long
        self.dest_net_type = dest_net_type  # type: str
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDestinationEndpoint
        self.dts_instance_id = dts_instance_id  # type: str
        self.dts_job_class = dts_job_class  # type: str
        self.dts_job_direction = dts_job_direction  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.dts_job_name = dts_job_name  # type: str
        self.end_timestamp = end_timestamp  # type: str
        self.error_message = error_message  # type: str
        self.etl_calculator = etl_calculator  # type: str
        self.expire_time = expire_time  # type: str
        self.finish_time = finish_time  # type: str
        self.group_id = group_id  # type: str
        self.is_demo_job = is_demo_job  # type: bool
        self.job_type = job_type  # type: str
        self.migration_mode = migration_mode  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobMigrationMode
        self.origin_type = origin_type  # type: str
        self.pay_type = pay_type  # type: str
        self.performance = performance  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPerformance
        self.precheck_status = precheck_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatus
        self.reserved = reserved  # type: str
        self.retry_state = retry_state  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobRetryState
        self.reverse_job = reverse_job  # type: any
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSourceEndpoint
        self.status = status  # type: str
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobStructureInitializationStatus
        self.subscribe_topic = subscribe_topic  # type: str
        self.subscription_data_type = subscription_data_type  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionDataType
        self.subscription_host = subscription_host  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionHost
        self.synchronization_direction = synchronization_direction  # type: str
        self.tag_list = tag_list  # type: list[DescribeDtsJobDetailResponseBodySubSyncJobReverseJobTagList]
        self.task_type = task_type  # type: str

    def validate(self):
        if self.data_etl_status:
            self.data_etl_status.validate()
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()
        if self.tag_list:
            for k in self.tag_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobReverseJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_etl_status is not None:
            result['DataEtlStatus'] = self.data_etl_status.to_map()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.database_count is not None:
            result['DatabaseCount'] = self.database_count
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.dest_net_type is not None:
            result['DestNetType'] = self.dest_net_type
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_calculator is not None:
            result['EtlCalculator'] = self.etl_calculator
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.is_demo_job is not None:
            result['IsDemoJob'] = self.is_demo_job
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.origin_type is not None:
            result['OriginType'] = self.origin_type
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.reverse_job is not None:
            result['ReverseJob'] = self.reverse_job
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        result['TagList'] = []
        if self.tag_list is not None:
            for k in self.tag_list:
                result['TagList'].append(k.to_map() if k else None)
        if self.task_type is not None:
            result['TaskType'] = self.task_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataEtlStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataEtlStatus()
            self.data_etl_status = temp_model.from_map(m['DataEtlStatus'])
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DatabaseCount') is not None:
            self.database_count = m.get('DatabaseCount')
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestNetType') is not None:
            self.dest_net_type = m.get('DestNetType')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlCalculator') is not None:
            self.etl_calculator = m.get('EtlCalculator')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('IsDemoJob') is not None:
            self.is_demo_job = m.get('IsDemoJob')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('OriginType') is not None:
            self.origin_type = m.get('OriginType')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('ReverseJob') is not None:
            self.reverse_job = m.get('ReverseJob')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobSubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        self.tag_list = []
        if m.get('TagList') is not None:
            for k in m.get('TagList'):
                temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJobTagList()
                self.tag_list.append(temp_model.from_map(k))
        if m.get('TaskType') is not None:
            self.task_type = m.get('TaskType')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobSourceEndpoint(TeaModel):
    def __init__(self, aliyun_uid=None, database_name=None, engine_name=None, instance_id=None, instance_type=None,
                 ip=None, oracle_sid=None, port=None, region=None, role_name=None, ssl_solution_enum=None,
                 user_name=None):
        self.aliyun_uid = aliyun_uid  # type: str
        self.database_name = database_name  # type: str
        self.engine_name = engine_name  # type: str
        self.instance_id = instance_id  # type: str
        self.instance_type = instance_type  # type: str
        self.ip = ip  # type: str
        self.oracle_sid = oracle_sid  # type: str
        self.port = port  # type: str
        self.region = region  # type: str
        self.role_name = role_name  # type: str
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.aliyun_uid is not None:
            result['AliyunUid'] = self.aliyun_uid
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.role_name is not None:
            result['RoleName'] = self.role_name
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliyunUid') is not None:
            self.aliyun_uid = m.get('AliyunUid')
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RoleName') is not None:
            self.role_name = m.get('RoleName')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.need_upgrade = need_upgrade  # type: bool
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        self.ddl = ddl  # type: bool
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['Ddl'] = self.ddl
        if self.dml is not None:
            result['Dml'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Ddl') is not None:
            self.ddl = m.get('Ddl')
        if m.get('Dml') is not None:
            self.dml = m.get('Dml')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpc_host=None):
        self.private_host = private_host  # type: str
        self.public_host = public_host  # type: str
        self.vpc_host = vpc_host  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpc_host is not None:
            result['VpcHost'] = self.vpc_host
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VpcHost') is not None:
            self.vpc_host = m.get('VpcHost')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJobTagList(TeaModel):
    def __init__(self, ali_uid=None, creator=None, gmt_create=None, gmt_modified=None, id=None, region_id=None,
                 resource_id=None, resource_type=None, scope=None, src_region=None, tag_category=None, tag_key=None,
                 tag_value=None):
        self.ali_uid = ali_uid  # type: long
        self.creator = creator  # type: long
        self.gmt_create = gmt_create  # type: str
        self.gmt_modified = gmt_modified  # type: str
        self.id = id  # type: long
        # region_id
        self.region_id = region_id  # type: str
        # dts instance id
        self.resource_id = resource_id  # type: str
        self.resource_type = resource_type  # type: str
        self.scope = scope  # type: str
        self.src_region = src_region  # type: str
        self.tag_category = tag_category  # type: str
        self.tag_key = tag_key  # type: str
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJobTagList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ali_uid is not None:
            result['AliUid'] = self.ali_uid
        if self.creator is not None:
            result['Creator'] = self.creator
        if self.gmt_create is not None:
            result['GmtCreate'] = self.gmt_create
        if self.gmt_modified is not None:
            result['GmtModified'] = self.gmt_modified
        if self.id is not None:
            result['Id'] = self.id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        if self.scope is not None:
            result['Scope'] = self.scope
        if self.src_region is not None:
            result['SrcRegion'] = self.src_region
        if self.tag_category is not None:
            result['TagCategory'] = self.tag_category
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AliUid') is not None:
            self.ali_uid = m.get('AliUid')
        if m.get('Creator') is not None:
            self.creator = m.get('Creator')
        if m.get('GmtCreate') is not None:
            self.gmt_create = m.get('GmtCreate')
        if m.get('GmtModified') is not None:
            self.gmt_modified = m.get('GmtModified')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        if m.get('Scope') is not None:
            self.scope = m.get('Scope')
        if m.get('SrcRegion') is not None:
            self.src_region = m.get('SrcRegion')
        if m.get('TagCategory') is not None:
            self.tag_category = m.get('TagCategory')
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class DescribeDtsJobDetailResponseBodySubSyncJob(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, checkpoint=None, consumption_checkpoint=None,
                 consumption_client=None, create_time=None, data_etl_status=None, data_initialization_status=None,
                 data_synchronization_status=None, database_count=None, db_object=None, delay=None, dest_net_type=None,
                 destination_endpoint=None, dts_instance_id=None, dts_job_class=None, dts_job_direction=None, dts_job_id=None,
                 dts_job_name=None, end_timestamp=None, error_message=None, etl_calculator=None, expire_time=None,
                 finish_time=None, group_id=None, is_demo_job=None, job_type=None, migration_mode=None, origin_type=None,
                 pay_type=None, performance=None, precheck_status=None, reserved=None, retry_state=None, reverse_job=None,
                 source_endpoint=None, status=None, structure_initialization_status=None, sub_sync_job=None, subscribe_topic=None,
                 subscription_data_type=None, subscription_host=None, synchronization_direction=None, tag_list=None, task_type=None):
        self.app_name = app_name  # type: str
        self.begin_timestamp = begin_timestamp  # type: str
        self.checkpoint = checkpoint  # type: str
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        self.consumption_client = consumption_client  # type: str
        self.create_time = create_time  # type: str
        self.data_etl_status = data_etl_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobDataEtlStatus
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobDataInitializationStatus
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobDataSynchronizationStatus
        self.database_count = database_count  # type: int
        self.db_object = db_object  # type: str
        self.delay = delay  # type: long
        self.dest_net_type = dest_net_type  # type: str
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobDetailResponseBodySubSyncJobDestinationEndpoint
        self.dts_instance_id = dts_instance_id  # type: str
        self.dts_job_class = dts_job_class  # type: str
        self.dts_job_direction = dts_job_direction  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.dts_job_name = dts_job_name  # type: str
        self.end_timestamp = end_timestamp  # type: str
        self.error_message = error_message  # type: str
        self.etl_calculator = etl_calculator  # type: str
        self.expire_time = expire_time  # type: str
        self.finish_time = finish_time  # type: str
        self.group_id = group_id  # type: str
        self.is_demo_job = is_demo_job  # type: bool
        self.job_type = job_type  # type: str
        self.migration_mode = migration_mode  # type: DescribeDtsJobDetailResponseBodySubSyncJobMigrationMode
        self.origin_type = origin_type  # type: str
        self.pay_type = pay_type  # type: str
        self.performance = performance  # type: DescribeDtsJobDetailResponseBodySubSyncJobPerformance
        self.precheck_status = precheck_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatus
        self.reserved = reserved  # type: str
        self.retry_state = retry_state  # type: DescribeDtsJobDetailResponseBodySubSyncJobRetryState
        self.reverse_job = reverse_job  # type: DescribeDtsJobDetailResponseBodySubSyncJobReverseJob
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobDetailResponseBodySubSyncJobSourceEndpoint
        self.status = status  # type: str
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobDetailResponseBodySubSyncJobStructureInitializationStatus
        self.sub_sync_job = sub_sync_job  # type: list[any]
        self.subscribe_topic = subscribe_topic  # type: str
        self.subscription_data_type = subscription_data_type  # type: DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionDataType
        self.subscription_host = subscription_host  # type: DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionHost
        self.synchronization_direction = synchronization_direction  # type: str
        self.tag_list = tag_list  # type: list[DescribeDtsJobDetailResponseBodySubSyncJobTagList]
        self.task_type = task_type  # type: str

    def validate(self):
        if self.data_etl_status:
            self.data_etl_status.validate()
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.reverse_job:
            self.reverse_job.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()
        if self.tag_list:
            for k in self.tag_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubSyncJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_etl_status is not None:
            result['DataEtlStatus'] = self.data_etl_status.to_map()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.database_count is not None:
            result['DatabaseCount'] = self.database_count
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.dest_net_type is not None:
            result['DestNetType'] = self.dest_net_type
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_calculator is not None:
            result['EtlCalculator'] = self.etl_calculator
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.is_demo_job is not None:
            result['IsDemoJob'] = self.is_demo_job
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.origin_type is not None:
            result['OriginType'] = self.origin_type
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.reverse_job is not None:
            result['ReverseJob'] = self.reverse_job.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.sub_sync_job is not None:
            result['SubSyncJob'] = self.sub_sync_job
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        result['TagList'] = []
        if self.tag_list is not None:
            for k in self.tag_list:
                result['TagList'].append(k.to_map() if k else None)
        if self.task_type is not None:
            result['TaskType'] = self.task_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataEtlStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobDataEtlStatus()
            self.data_etl_status = temp_model.from_map(m['DataEtlStatus'])
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DatabaseCount') is not None:
            self.database_count = m.get('DatabaseCount')
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestNetType') is not None:
            self.dest_net_type = m.get('DestNetType')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlCalculator') is not None:
            self.etl_calculator = m.get('EtlCalculator')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('IsDemoJob') is not None:
            self.is_demo_job = m.get('IsDemoJob')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('OriginType') is not None:
            self.origin_type = m.get('OriginType')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('ReverseJob') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobReverseJob()
            self.reverse_job = temp_model.from_map(m['ReverseJob'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('SubSyncJob') is not None:
            self.sub_sync_job = m.get('SubSyncJob')
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubSyncJobSubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        self.tag_list = []
        if m.get('TagList') is not None:
            for k in m.get('TagList'):
                temp_model = DescribeDtsJobDetailResponseBodySubSyncJobTagList()
                self.tag_list.append(temp_model.from_map(k))
        if m.get('TaskType') is not None:
            self.task_type = m.get('TaskType')
        return self


class DescribeDtsJobDetailResponseBodySubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        # The private endpoint of the change tracking instance in the `<Address>:<Port number>` format.
        self.ddl = ddl  # type: bool
        # The public endpoint of the change tracking instance in the `<Address>:<Port number>` format.
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['Ddl'] = self.ddl
        if self.dml is not None:
            result['Dml'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Ddl') is not None:
            self.ddl = m.get('Ddl')
        if m.get('Dml') is not None:
            self.dml = m.get('Dml')
        return self


class DescribeDtsJobDetailResponseBodySubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpc_host=None):
        # The endpoint of the change tracking instance.
        self.private_host = private_host  # type: str
        # Indicates whether schema migration or schema synchronization is performed. Valid values:
        # 
        # *   **true**: Schema migration or schema synchronization is performed.
        # *   **false**: Schema migration or schema synchronization is not performed.
        self.public_host = public_host  # type: str
        # Indicates whether incremental data migration or synchronization is performed. Valid values:
        # 
        # *   **true**: Incremental data migration or synchronization is performed.
        # *   **false**: Incremental data migration or synchronization is not performed.
        self.vpc_host = vpc_host  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBodySubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpc_host is not None:
            result['VpcHost'] = self.vpc_host
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VpcHost') is not None:
            self.vpc_host = m.get('VpcHost')
        return self


class DescribeDtsJobDetailResponseBody(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, binlog=None, binlog_site=None, binlog_time=None,
                 boot_time=None, checkpoint=None, code=None, consumption_checkpoint=None, consumption_client=None,
                 create_time=None, data_delivery_channel_info=None, data_synchronization_status=None, database_count=None,
                 db_object=None, dedicated_cluster_id=None, delay=None, demo_job=None, dest_net_type=None,
                 destination_endpoint=None, dts_bis_label=None, dts_instance_id=None, dts_job_class=None, dts_job_direction=None,
                 dts_job_id=None, dts_job_name=None, dynamic_message=None, end_timestamp=None, err_code=None, err_message=None,
                 error_message=None, etl_calculator=None, expire_time=None, finish_time=None, group_id=None,
                 http_status_code=None, job_type=None, last_update_time=None, migration_mode=None, pay_type=None, request_id=None,
                 reserved=None, resource_group_display_name=None, resource_group_id=None, retry_state=None,
                 source_endpoint=None, status=None, sub_distributed_job=None, sub_sync_job=None, subscribe_topic=None,
                 subscription_data_type=None, subscription_host=None, success=None, synchronization_direction=None, task_type=None):
        # The number of ApsaraDB RDS for MySQL instances that are attached to the source PolarDB-X 1.0 instance.
        self.app_name = app_name  # type: str
        # The consumption checkpoint of the change tracking instance. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.begin_timestamp = begin_timestamp  # type: str
        self.binlog = binlog  # type: str
        self.binlog_site = binlog_site  # type: str
        self.binlog_time = binlog_time  # type: str
        self.boot_time = boot_time  # type: str
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.checkpoint = checkpoint  # type: long
        # The topic of the change tracking instance.
        # 
        # >  This parameter is returned only if your change tracking instances are of the new version and you have called the [CreateConsumerGroup](~~122863~~) operation to create a consumer group.
        self.code = code  # type: int
        # The downstream client information in the following format: \<IP address of the downstream client>:\<Random ID generated by DTS>.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The error code returned if the request failed.
        self.consumption_client = consumption_client  # type: str
        # The end time of the task. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.create_time = create_time  # type: str
        self.data_delivery_channel_info = data_delivery_channel_info  # type: DescribeDtsJobDetailResponseBodyDataDeliveryChannelInfo
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobDetailResponseBodyDataSynchronizationStatus
        # The point in time when the task was created. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.database_count = database_count  # type: int
        # Indicates whether the request was successful.
        self.db_object = db_object  # type: str
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The ID of the request.
        self.delay = delay  # type: long
        self.demo_job = demo_job  # type: bool
        # The instance class.
        # 
        # >  For more information about the test performance of each instance class, see [Specifications of data migration instances](~~26606~~) and [Specifications of data synchronization instances](~~26605~~).
        self.dest_net_type = dest_net_type  # type: str
        # The name of the database that contains the objects to be migrated from the source instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobDetailResponseBodyDestinationEndpoint
        self.dts_bis_label = dts_bis_label  # type: str
        # Indicates whether the new change tracking feature is used.
        # 
        # >  This parameter is returned only for change tracking instances of the new version.
        self.dts_instance_id = dts_instance_id  # type: str
        # The billing method of the instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.dts_job_class = dts_job_class  # type: str
        # The beginning of the time range for change tracking. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.dts_job_direction = dts_job_direction  # type: str
        # API test
        self.dts_job_id = dts_job_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   The value **Reverse** takes effect only if the topology of the data synchronization instance is two-way synchronization.
        self.dts_job_name = dts_job_name  # type: str
        # The error message returned if the request failed.
        self.dynamic_message = dynamic_message  # type: str
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet specific requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        self.end_timestamp = end_timestamp  # type: str
        # The start offset of incremental data migration or synchronization. The value is a UNIX timestamp. Unit: seconds.
        self.err_code = err_code  # type: str
        # The point in time when the instance expires. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        # 
        # >  This parameter is returned only if the return value of the **PayType** parameter is **PrePaid**.
        self.err_message = err_message  # type: str
        # The name of the data migration, data synchronization, or change tracking task.
        self.error_message = error_message  # type: str
        # The objects of the data migration, data synchronization, or change tracking task. For more information, see [Objects of DTS tasks](~~209545~~).
        self.etl_calculator = etl_calculator  # type: str
        # The error code. This parameter will be removed in the future.
        self.expire_time = expire_time  # type: str
        # The state of the data migration or data synchronization task.
        # 
        # Valid values for a data migration task:
        # 
        # *   **NotStarted**: The migration is not started.
        # *   **Migrating**: The migration is in progress.
        # *   **Failed**: The migration failed.
        # *   **Finished**: The migration is complete.
        # 
        # Valid values for a data synchronization task:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is in precheck.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Initializing**: The task is performing initial synchronization.
        # *   **InitializeFailed**: Initial synchronization failed.
        # *   **Synchronizing**: The task is in progress.
        # *   **Failed**: The task failed to synchronize data.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is complete.
        self.finish_time = finish_time  # type: str
        # The operator information of the extract, transform, and load (ETL) task.
        # 
        # >  This parameter is returned only if you query the details of an ETL task.
        self.group_id = group_id  # type: str
        # The dynamic part in the error message. This parameter is used to replace the \*\*%s\*\* variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.http_status_code = http_status_code  # type: int
        self.job_type = job_type  # type: str
        self.last_update_time = last_update_time  # type: str
        # The type of the destination instance.
        self.migration_mode = migration_mode  # type: DescribeDtsJobDetailResponseBodyMigrationMode
        # The error message returned if the task failed.
        self.pay_type = pay_type  # type: str
        # The network type of the consumer client. Valid values:
        # 
        # *   **CLASSIC**: classic network
        # *   **VPC**: Virtual Private Cloud (VPC)
        self.request_id = request_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.reserved = reserved  # type: str
        self.resource_group_display_name = resource_group_display_name  # type: str
        self.resource_group_id = resource_group_id  # type: str
        self.retry_state = retry_state  # type: DescribeDtsJobDetailResponseBodyRetryState
        # The ID of the DTS task.
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobDetailResponseBodySourceEndpoint
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.status = status  # type: str
        self.sub_distributed_job = sub_distributed_job  # type: list[DescribeDtsJobDetailResponseBodySubDistributedJob]
        self.sub_sync_job = sub_sync_job  # type: list[DescribeDtsJobDetailResponseBodySubSyncJob]
        # The end of the time range for change tracking. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.subscribe_topic = subscribe_topic  # type: str
        # The VPC endpoint of the change tracking instance in the `<Address>:<Port number>` format.
        self.subscription_data_type = subscription_data_type  # type: DescribeDtsJobDetailResponseBodySubscriptionDataType
        # Indicates whether full data migration or synchronization is performed. Valid values:
        # 
        # *   **true**: Full data migration or synchronization is performed.
        # *   **false**: Full data migration or synchronization is not performed.
        self.subscription_host = subscription_host  # type: DescribeDtsJobDetailResponseBodySubscriptionHost
        # The latency of incremental data migration or synchronization.
        # 
        # >  If you query data migration tasks, the unit of this parameter is milliseconds. If you query data synchronization tasks, the unit of this parameter is seconds.
        self.success = success  # type: bool
        # The status code returned.
        self.synchronization_direction = synchronization_direction  # type: str
        self.task_type = task_type  # type: str

    def validate(self):
        if self.data_delivery_channel_info:
            self.data_delivery_channel_info.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.sub_distributed_job:
            for k in self.sub_distributed_job:
                if k:
                    k.validate()
        if self.sub_sync_job:
            for k in self.sub_sync_job:
                if k:
                    k.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.binlog is not None:
            result['Binlog'] = self.binlog
        if self.binlog_site is not None:
            result['BinlogSite'] = self.binlog_site
        if self.binlog_time is not None:
            result['BinlogTime'] = self.binlog_time
        if self.boot_time is not None:
            result['BootTime'] = self.boot_time
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.code is not None:
            result['Code'] = self.code
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_delivery_channel_info is not None:
            result['DataDeliveryChannelInfo'] = self.data_delivery_channel_info.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.database_count is not None:
            result['DatabaseCount'] = self.database_count
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.demo_job is not None:
            result['DemoJob'] = self.demo_job
        if self.dest_net_type is not None:
            result['DestNetType'] = self.dest_net_type
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_bis_label is not None:
            result['DtsBisLabel'] = self.dts_bis_label
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_calculator is not None:
            result['EtlCalculator'] = self.etl_calculator
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.last_update_time is not None:
            result['LastUpdateTime'] = self.last_update_time
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.resource_group_display_name is not None:
            result['ResourceGroupDisplayName'] = self.resource_group_display_name
        if self.resource_group_id is not None:
            result['ResourceGroupId'] = self.resource_group_id
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        result['SubDistributedJob'] = []
        if self.sub_distributed_job is not None:
            for k in self.sub_distributed_job:
                result['SubDistributedJob'].append(k.to_map() if k else None)
        result['SubSyncJob'] = []
        if self.sub_sync_job is not None:
            for k in self.sub_sync_job:
                result['SubSyncJob'].append(k.to_map() if k else None)
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.success is not None:
            result['Success'] = self.success
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.task_type is not None:
            result['TaskType'] = self.task_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Binlog') is not None:
            self.binlog = m.get('Binlog')
        if m.get('BinlogSite') is not None:
            self.binlog_site = m.get('BinlogSite')
        if m.get('BinlogTime') is not None:
            self.binlog_time = m.get('BinlogTime')
        if m.get('BootTime') is not None:
            self.boot_time = m.get('BootTime')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataDeliveryChannelInfo') is not None:
            temp_model = DescribeDtsJobDetailResponseBodyDataDeliveryChannelInfo()
            self.data_delivery_channel_info = temp_model.from_map(m['DataDeliveryChannelInfo'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobDetailResponseBodyDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DatabaseCount') is not None:
            self.database_count = m.get('DatabaseCount')
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DemoJob') is not None:
            self.demo_job = m.get('DemoJob')
        if m.get('DestNetType') is not None:
            self.dest_net_type = m.get('DestNetType')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodyDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsBisLabel') is not None:
            self.dts_bis_label = m.get('DtsBisLabel')
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlCalculator') is not None:
            self.etl_calculator = m.get('EtlCalculator')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('LastUpdateTime') is not None:
            self.last_update_time = m.get('LastUpdateTime')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobDetailResponseBodyMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('ResourceGroupDisplayName') is not None:
            self.resource_group_display_name = m.get('ResourceGroupDisplayName')
        if m.get('ResourceGroupId') is not None:
            self.resource_group_id = m.get('ResourceGroupId')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobDetailResponseBodyRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        self.sub_distributed_job = []
        if m.get('SubDistributedJob') is not None:
            for k in m.get('SubDistributedJob'):
                temp_model = DescribeDtsJobDetailResponseBodySubDistributedJob()
                self.sub_distributed_job.append(temp_model.from_map(k))
        self.sub_sync_job = []
        if m.get('SubSyncJob') is not None:
            for k in m.get('SubSyncJob'):
                temp_model = DescribeDtsJobDetailResponseBodySubSyncJob()
                self.sub_sync_job.append(temp_model.from_map(k))
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeDtsJobDetailResponseBodySubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('TaskType') is not None:
            self.task_type = m.get('TaskType')
        return self


class DescribeDtsJobDetailResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDtsJobDetailResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDtsJobDetailResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDtsJobDetailResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDtsJobsRequest(TeaModel):
    def __init__(self, dedicated_cluster_id=None, dts_bis_label=None, dts_instance_id=None, dts_job_id=None,
                 group_id=None, job_type=None, order_column=None, order_direction=None, owner_id=None, page_number=None,
                 page_size=None, params=None, region=None, region_id=None, resource_group_id=None, status=None, tags=None,
                 type=None, without_db_list=None):
        # The ID of the DTS dedicated cluster on which the task runs.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        self.dts_bis_label = dts_bis_label  # type: str
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the parent task.
        # 
        # >  In most cases, you do not need to specify this parameter.
        self.group_id = group_id  # type: str
        # The type of the DTS task. Valid values:
        # 
        # *   **MIGRATION**: data migration. This is the default value.
        # *   **SYNC**: data synchronization.
        # *   **SUBSCRIBE**: change tracking.
        self.job_type = job_type  # type: str
        # The basis on which the returned DTS tasks are sorted. Valid values:
        # 
        # *   **CreateTime**: sorts the DTS tasks based on the points in time when the DTS tasks are created.
        # *   **FinishTime**: sorts the DTS tasks based on the points in time when the DTS tasks are complete.
        # *   **duLimit** sorts the DTS tasks based on the upper limits on DTS Units (DUs) that the DTS tasks can use. This option applies only to the DTS tasks that are run on a DTS dedicated cluster.
        # 
        # >  You can also set the **OrderDirection** parameter to specify whether to sort the DTS tasks in ascending or descending order.
        self.order_column = order_column  # type: str
        # The order in which the returned DTS tasks are sorted. Valid values:
        # 
        # *   **ASC**: sorts the DTS tasks in ascending order. This is the default value.
        # *   **DESC**: sorts the DTS tasks in descending order.
        self.order_direction = order_direction  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_number = page_number  # type: int
        # The number of entries to return on each page. Valid values: **30**, **50**, and **100**. Default value: **30**.
        self.page_size = page_size  # type: int
        # The content of the query condition.
        # 
        # >  You must set the **Type** parameter to specify the type of the query condition.
        self.params = params  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        # This parameter is discontinued.
        self.region_id = region_id  # type: str
        # The resource group ID.
        self.resource_group_id = resource_group_id  # type: str
        # The state of the DTS task.
        # 
        # Valid values for a data migration task:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **PreCheckPass**: The task passed the precheck.
        # *   **NotConfigured**: The task is not configured.
        # *   **Migrating**: The task is in progress.
        # *   **Suspending**: The task is paused.
        # *   **MigrationFailed**: The task failed.
        # *   **Finished**: The task is complete.
        # *   **Retrying**: The task is being retried.
        # *   **Upgrade**: The task is being upgraded.
        # *   **Locked**: The task is locked.
        # *   **Downgrade**: The task is being downgraded.
        # 
        # Valid values for a data synchronization task:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **PreCheckPass**: The task passed the precheck.
        # *   **NotConfigured**: The task is not configured.
        # *   **Initializing**: The task is being initialized.
        # *   **InitializeFailed**: Initialization failed.
        # *   **Synchronizing**: The task is in progress.
        # *   **Failed**: The task failed.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is complete.
        # *   **Retrying**: The task is being retried.
        # *   **Upgrade**: The task is being upgraded.
        # *   **Locked**: The task is locked.
        # *   **Downgrade**: The task is being downgraded.
        # 
        # Valid values for a change tracking task:
        # 
        # *   **NotConfigured**: The task is not configured.
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **PreCheckPass**: The task passed the precheck.
        # *   **Starting**: The task is being started.
        # *   **Normal**: The task is running as expected.
        # *   **Retrying**: The task is being retried.
        # *   **Abnormal**: The task is not running as expected.
        # *   **Upgrade**: The task is being upgraded.
        # *   **Locked**: The task is locked.
        # *   **Downgrade**: The task is being downgraded.
        self.status = status  # type: str
        # The tags of the DTS task to be queried. Specify tags in the JSON format.
        # 
        # >  You can call the **ListTagResources** operation to query the tag key and tag value.
        self.tags = tags  # type: str
        # The type of the query condition. Valid values:
        # 
        # *   **instance**: queries DTS tasks based on the ID of a DTS instance.
        # *   **name**: queries DTS tasks based on the name of a DTS instance. Fuzzy match is supported.
        # *   **srcRds**: queries DTS tasks based on the ID of an ApsaraDB RDS instance. The ApsaraDB RDS instance is the source instance of a DTS task.
        # *   **rds**: queries DTS tasks based on the ID of an ApsaraDB RDS instance. The ApsaraDB RDS instance is the destination instance of a DTS task.
        # 
        # >  You must set the **Params** parameter to specify the content of the query condition.
        self.type = type  # type: str
        # Specifies whether to skip the **DbObject** parameter in the response. The DbObject parameter specifies the objects of the data migration, data synchronization, or change tracking task. Valid values:
        # 
        # - **true**: does not return **DbObject**.
        # - **false**: returns **DbObject**. If you set this parameter to false, the response time is shortened.
        self.without_db_list = without_db_list  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dts_bis_label is not None:
            result['DtsBisLabel'] = self.dts_bis_label
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.group_id is not None:
            result['GroupId'] = self.group_id
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.order_column is not None:
            result['OrderColumn'] = self.order_column
        if self.order_direction is not None:
            result['OrderDirection'] = self.order_direction
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.params is not None:
            result['Params'] = self.params
        if self.region is not None:
            result['Region'] = self.region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_group_id is not None:
            result['ResourceGroupId'] = self.resource_group_id
        if self.status is not None:
            result['Status'] = self.status
        if self.tags is not None:
            result['Tags'] = self.tags
        if self.type is not None:
            result['Type'] = self.type
        if self.without_db_list is not None:
            result['WithoutDbList'] = self.without_db_list
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DtsBisLabel') is not None:
            self.dts_bis_label = m.get('DtsBisLabel')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('GroupId') is not None:
            self.group_id = m.get('GroupId')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('OrderColumn') is not None:
            self.order_column = m.get('OrderColumn')
        if m.get('OrderDirection') is not None:
            self.order_direction = m.get('OrderDirection')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('Params') is not None:
            self.params = m.get('Params')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceGroupId') is not None:
            self.resource_group_id = m.get('ResourceGroupId')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('Tags') is not None:
            self.tags = m.get('Tags')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        if m.get('WithoutDbList') is not None:
            self.without_db_list = m.get('WithoutDbList')
        return self


class DescribeDtsJobsResponseBodyDtsJobListDataCloudStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # Indicates whether the instance needs to be upgraded. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.need_upgrade = need_upgrade  # type: bool
        # The progress of the task. Unit: percentage.
        self.percent = percent  # type: str
        # The number of tables that have been migrated.
        self.progress = progress  # type: str
        # The state of the task. For more information about the valid values, see the description of the request parameter **Status**.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListDataCloudStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListDataEtlStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The progress of the ETL task.
        self.percent = percent  # type: str
        # The number of records that have been processed by the ETL task.
        self.progress = progress  # type: str
        # The state of the ETL task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Migrating**: The task is in progress.
        # *   **Failed**: The task failed.
        # *   **Finished**: The task is complete.
        # *   **Catched**: The task is not delayed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListDataEtlStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if full data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of full data synchronization. This is expressed as a percentage.
        self.percent = percent  # type: str
        # The number of records that have been synchronized during full data synchronization.
        self.progress = progress  # type: str
        # The state of full data synchronization. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Migrating**: The task is in progress.
        # *   **Failed**: The task failed.
        # *   **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        # The error message returned if incremental data migration or synchronization failed.
        self.error_message = error_message  # type: str
        # Indicates whether the instance needs to be upgraded. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        # 
        # >  To upgrade a DTS instance, call the [TransferInstanceClass](~~281093~~) operation.
        self.need_upgrade = need_upgrade  # type: bool
        # The progress of incremental data migration or synchronization.
        self.percent = percent  # type: str
        # The number of records that have been migrated or synchronized during incremental data migration or synchronization.
        self.progress = progress  # type: str
        # The state of incremental data migration or synchronization. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Migrating**: The task is in progress.
        # *   **Failed**: The task failed.
        # *   **Finished**: The task is complete.
        # *   **Catched**: The task is not delayed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListDestinationEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database to which the migration object in the destination instance belongs.
        self.database_name = database_name  # type: str
        # The database type of the destination instance.
        self.engine_name = engine_name  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database.
        # 
        # >  This parameter is returned only if the **EngineName** parameter of the destination instance is set to **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The database service port of the destination instance.
        self.port = port  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # *   **DISABLE**: SSL encryption is disabled.
        # *   **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled, and the CA certificate is uploaded.
        # *   **ENABLE_ONLY\_4\_MONGODB_ALTAS**: SSL encryption is enabled for the connection to an AWS MongoDB Altas database.
        # *   **ENABLE_ONLY\_4\_KAFKA_SCRAM_SHA\_256**: SCRAM-SHA-256 is used to encrypt the connection to a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyDtsJobListErrorDetails(TeaModel):
    def __init__(self, error_code=None, help_url=None):
        # The error code returned.
        self.error_code = error_code  # type: str
        # The URL of the documentation.
        self.help_url = help_url  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListErrorDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_code is not None:
            result['ErrorCode'] = self.error_code
        if self.help_url is not None:
            result['HelpUrl'] = self.help_url
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorCode') is not None:
            self.error_code = m.get('ErrorCode')
        if m.get('HelpUrl') is not None:
            self.help_url = m.get('HelpUrl')
        return self


class DescribeDtsJobsResponseBodyDtsJobListFullDataCheckStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The progress of the full data verification task. Unit: percentage.
        self.percent = percent  # type: str
        # The progress of the full data verification task.
        self.progress = progress  # type: str
        # The state of the full data verification task. Valid values:
        # 
        # - **NotStarted**: The verification is not started. 
        # - **Checking**: The verification is in progress. 
        # - **Failed**: The verification failed. 
        # - **Finished**: The verification is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListFullDataCheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListIncDataCheckStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The progress of the incremental data verification task. Unit: percentage.
        self.percent = percent  # type: str
        # The progress of the incremental data verification task.
        self.progress = progress  # type: str
        # The state of the incremental data verification task. Valid values:
        # 
        # - **Catched**: The verification is delayed. 
        # - **NotStarted**: The verification is not started. 
        # - **Checking**: The verification is in progress. 
        # - **Failed**: The verification failed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListIncDataCheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, full_data_check=None,
                 inc_data_check=None, structure_initialization=None):
        # Indicates whether full data migration or synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_initialization = data_initialization  # type: bool
        # Indicates whether incremental data migration or synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether full data verification is performed. Valid values:
        # -  **true**: yes
        # -   **false**: no
        self.full_data_check = full_data_check  # type: bool
        # Indicates whether incremental data verification is performed. Valid values:
        # -  **true**: yes
        # -   **false**: no
        self.inc_data_check = inc_data_check  # type: bool
        # Indicates whether schema migration or schema synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.full_data_check is not None:
            result['FullDataCheck'] = self.full_data_check
        if self.inc_data_check is not None:
            result['IncDataCheck'] = self.inc_data_check
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('FullDataCheck') is not None:
            self.full_data_check = m.get('FullDataCheck')
        if m.get('IncDataCheck') is not None:
            self.inc_data_check = m.get('IncDataCheck')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobsResponseBodyDtsJobListPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        # The size of data that is migrated or synchronized per second. Unit: MB/s.
        self.flow = flow  # type: str
        # The number of times that SQL statements are migrated or synchronized per second, including BEGIN, COMMIT, DML, and DDL statements. DML statements include INSERT, DELETE, and UPDATE.
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobsResponseBodyDtsJobListPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        # The name of the precheck item.
        self.check_item = check_item  # type: str
        # The description of the precheck item.
        self.check_item_description = check_item_description  # type: str
        # The precheck result. Valid values:
        # 
        # *   **Success**\
        # *   **Failed**\
        self.check_result = check_result  # type: str
        # The error message returned if the task failed to pass the precheck.
        # 
        # >  This parameter is returned only if the value of the **CheckResult** parameter is **Failed**.
        self.failed_reason = failed_reason  # type: str
        # The method to fix the precheck failure.
        # 
        # >  This parameter is returned only if the value of the **CheckResult** parameter is **Failed**.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobsResponseBodyDtsJobListPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: list[DescribeDtsJobsResponseBodyDtsJobListPrecheckStatusDetail]
        # The cause of the precheck failure.
        self.error_message = error_message  # type: str
        # The precheck progress. This is expressed as a percentage.
        self.percent = percent  # type: str
        # The precheck status. Valid values:
        # 
        # *   **NotStarted**\
        # *   **Suspending**:
        # *   **Checking**\
        # *   **Failed**\
        # *   **Finished**\
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobsResponseBodyDtsJobListPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListRetryState(TeaModel):
    def __init__(self, err_message=None, job_id=None, max_retry_time=None, migration_err_code=None,
                 migration_err_help_doc_id=None, migration_err_help_doc_key=None, migration_err_msg=None, migration_err_type=None,
                 migration_err_workaround=None, module=None, retry_count=None, retry_target=None, retry_time=None, retrying=None):
        # The error message returned if these retries failed.
        self.err_message = err_message  # type: str
        # The task ID.
        self.job_id = job_id  # type: str
        # The maximum duration of a retry. Unit: seconds.
        self.max_retry_time = max_retry_time  # type: int
        # The error code.
        self.migration_err_code = migration_err_code  # type: str
        # The ID of the error code-related documentation.
        self.migration_err_help_doc_id = migration_err_help_doc_id  # type: str
        # The key of the error code-related documentation.
        self.migration_err_help_doc_key = migration_err_help_doc_key  # type: str
        # The error message.
        self.migration_err_msg = migration_err_msg  # type: str
        # The type of the error code.
        self.migration_err_type = migration_err_type  # type: str
        # The solution to the error.
        self.migration_err_workaround = migration_err_workaround  # type: str
        # The progress of the instance when DTS retries.
        self.module = module  # type: str
        # The number of retries that have been performed.
        self.retry_count = retry_count  # type: int
        # The object on which these retries are performed. Valid values:
        # 
        # - **srcDB**: the source database 
        # - **destDB**: the destination database 
        # - **inner_module**: an internal module of DTS
        self.retry_target = retry_target  # type: str
        # The time that has elapsed from the time when the first retry starts. Unit: seconds.
        self.retry_time = retry_time  # type: int
        # Indicates whether the task is being retried. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.migration_err_code is not None:
            result['MigrationErrCode'] = self.migration_err_code
        if self.migration_err_help_doc_id is not None:
            result['MigrationErrHelpDocId'] = self.migration_err_help_doc_id
        if self.migration_err_help_doc_key is not None:
            result['MigrationErrHelpDocKey'] = self.migration_err_help_doc_key
        if self.migration_err_msg is not None:
            result['MigrationErrMsg'] = self.migration_err_msg
        if self.migration_err_type is not None:
            result['MigrationErrType'] = self.migration_err_type
        if self.migration_err_workaround is not None:
            result['MigrationErrWorkaround'] = self.migration_err_workaround
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('MigrationErrCode') is not None:
            self.migration_err_code = m.get('MigrationErrCode')
        if m.get('MigrationErrHelpDocId') is not None:
            self.migration_err_help_doc_id = m.get('MigrationErrHelpDocId')
        if m.get('MigrationErrHelpDocKey') is not None:
            self.migration_err_help_doc_key = m.get('MigrationErrHelpDocKey')
        if m.get('MigrationErrMsg') is not None:
            self.migration_err_msg = m.get('MigrationErrMsg')
        if m.get('MigrationErrType') is not None:
            self.migration_err_type = m.get('MigrationErrType')
        if m.get('MigrationErrWorkaround') is not None:
            self.migration_err_workaround = m.get('MigrationErrWorkaround')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if initial full data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of initial full data synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been synchronized during initial full data synchronization.
        self.progress = progress  # type: str
        # The state of initial full data synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        # The error message returned if incremental data synchronization failed.
        self.error_message = error_message  # type: str
        # Indicates whether the instance needs to be upgraded. Valid values:
        # 
        # - **true**\
        # - **false**\
        # 
        # > To upgrade a DTS instance, call the [TransferInstanceClass](~~281093~~) operation.
        self.need_upgrade = need_upgrade  # type: bool
        # The progress of incremental data synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been migrated or synchronized during incremental data migration or synchronization.
        self.progress = progress  # type: str
        # The state of incremental data synchronization.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobDestinationEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the synchronized objects in the destination instance.
        self.database_name = database_name  # type: str
        # The database engine of the destination instance.
        self.engine_name = engine_name  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the destination instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the destination instance.
        self.port = port  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobErrorDetails(TeaModel):
    def __init__(self, error_code=None, help_url=None):
        # The error code returned.
        self.error_code = error_code  # type: str
        # The URL of the documentation.
        self.help_url = help_url  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobErrorDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_code is not None:
            result['ErrorCode'] = self.error_code
        if self.help_url is not None:
            result['HelpUrl'] = self.help_url
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorCode') is not None:
            self.error_code = m.get('ErrorCode')
        if m.get('HelpUrl') is not None:
            self.help_url = m.get('HelpUrl')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, structure_initialization=None):
        # Indicates whether initial full data synchronization is performed. Valid values:
        # 
        # -  **true**\
        # -  **false**\
        self.data_initialization = data_initialization  # type: bool
        # Indicates whether incremental data synchronization is performed. Valid values:
        # -  **true**\
        # -  **false**\
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether initial schema synchronization is performed. Valid values:
        # -  **true**\
        # -  **false**\
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        # The size of data that is synchronized per second. Unit: MB/s.
        self.flow = flow  # type: str
        # The number of times that SQL statements are synchronized per second, including BEGIN, COMMIT, DML, and DDL statements. DML statements include INSERT, DELETE, and UPDATE.
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        # The name of the precheck item.
        self.check_item = check_item  # type: str
        # The description of the precheck item.
        self.check_item_description = check_item_description  # type: str
        # The precheck result. Valid values:
        # 
        # - **Success**\
        # - **Failed**\
        self.check_result = check_result  # type: str
        # The error message returned if the task failed to pass the precheck.
        self.failed_reason = failed_reason  # type: str
        # The method to fix a precheck failure.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: list[DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatusDetail]
        # The error message returned if the precheck failed.
        self.error_message = error_message  # type: str
        # The precheck progress. Unit: percentage.
        self.percent = percent  # type: str
        # The precheck state. Valid values:
        # 
        # - **NotStarted**: The precheck is not started. 
        # - **Suspending**: The precheck is paused. 
        # - **Checking**: The precheck is in progress. 
        # - **Failed**: The precheck failed. 
        # - **Finished**: The precheck is complete.
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the objects to be migrated from the source instance.
        self.database_name = database_name  # type: str
        # The database engine of the source instance.
        self.engine_name = engine_name  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the source instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the source instance.
        self.port = port  # type: str
        # The ID of the region in which the source instance resides. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJobStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if initial schema synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of initial schema synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of tables that have been synchronized during initial schema synchronization.
        self.progress = progress  # type: str
        # The state of initial schema synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJobStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListReverseJob(TeaModel):
    def __init__(self, checkpoint=None, cpu_usage=None, create_time=None, data_initialization_status=None,
                 data_synchronization_status=None, db_object=None, dedicated_cluster_id=None, delay=None, destination_endpoint=None,
                 dts_instance_id=None, dts_job_class=None, dts_job_direction=None, dts_job_id=None, dts_job_name=None,
                 du_usage=None, error_details=None, error_message=None, etl_safe_checkpoint=None, expire_time=None,
                 mem_usage=None, migration_mode=None, pay_type=None, performance=None, precheck_status=None, reserved=None,
                 source_endpoint=None, status=None, structure_initialization_status=None):
        # The start offset of incremental data synchronization. This value is a UNIX timestamp representing the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC.
        self.checkpoint = checkpoint  # type: str
        # The CPU utilization of the instance. Unit: percentage.
        self.cpu_usage = cpu_usage  # type: str
        # The time when the task was created. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.create_time = create_time  # type: str
        # The state of initial full data synchronization.
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobDataInitializationStatus
        # The state of incremental data synchronization.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobDataSynchronizationStatus
        # The schema of the objects that you want to synchronize. The value is a JSON string and can contain regular expressions. For more information, see Objects of DTS tasks.
        self.db_object = db_object  # type: str
        # The ID of the DTS dedicated cluster on which a DTS task runs.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The latency of incremental data synchronization. Unit: seconds.
        self.delay = delay  # type: long
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobDestinationEndpoint
        # The ID of the data synchronization instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The instance class. 
        # 
        # > For more information about the test performance of each instance class, see [Specifications of data synchronization instances](~~26605~~).
        self.dts_job_class = dts_job_class  # type: str
        # The synchronization direction. **Reverse** is returned.
        self.dts_job_direction = dts_job_direction  # type: str
        # The ID of the synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The name of the data synchronization task.
        self.dts_job_name = dts_job_name  # type: str
        # The number of DUs that have been used.
        self.du_usage = du_usage  # type: long
        # The error message returned.
        self.error_details = error_details  # type: list[DescribeDtsJobsResponseBodyDtsJobListReverseJobErrorDetails]
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The checkpoint of the ETL task.
        self.etl_safe_checkpoint = etl_safe_checkpoint  # type: str
        # The time when the instance expires. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC. 
        # 
        # > This parameter is returned only if the returned value of **PayType** is **PrePaid**.
        self.expire_time = expire_time  # type: str
        # The memory that has been used. Unit: MB.
        self.mem_usage = mem_usage  # type: str
        # The initial synchronization types.
        self.migration_mode = migration_mode  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobMigrationMode
        # The billing method of the DTS instance. Valid values:
        # 
        # - **PrePaid**: subscription
        # - **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The performance of the data synchronization instance.
        self.performance = performance  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobPerformance
        # The precheck state.
        self.precheck_status = precheck_status  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatus
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet specific requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobSourceEndpoint
        # The state of the DTS instance. For more information about the valid values, see the description of the request parameter **Status**.
        self.status = status  # type: str
        # The state of initial schema synchronization.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJobStructureInitializationStatus

    def validate(self):
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.error_details:
            for k in self.error_details:
                if k:
                    k.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListReverseJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.cpu_usage is not None:
            result['CpuUsage'] = self.cpu_usage
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.du_usage is not None:
            result['DuUsage'] = self.du_usage
        result['ErrorDetails'] = []
        if self.error_details is not None:
            for k in self.error_details:
                result['ErrorDetails'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_safe_checkpoint is not None:
            result['EtlSafeCheckpoint'] = self.etl_safe_checkpoint
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.mem_usage is not None:
            result['MemUsage'] = self.mem_usage
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('CpuUsage') is not None:
            self.cpu_usage = m.get('CpuUsage')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('DuUsage') is not None:
            self.du_usage = m.get('DuUsage')
        self.error_details = []
        if m.get('ErrorDetails') is not None:
            for k in m.get('ErrorDetails'):
                temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobErrorDetails()
                self.error_details.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlSafeCheckpoint') is not None:
            self.etl_safe_checkpoint = m.get('EtlSafeCheckpoint')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('MemUsage') is not None:
            self.mem_usage = m.get('MemUsage')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJobStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        return self


class DescribeDtsJobsResponseBodyDtsJobListSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the objects to be migrated from the source instance.
        self.database_name = database_name  # type: str
        # The database engine of the source instance.
        self.engine_name = engine_name  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the source instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the source instance.
        self.port = port  # type: str
        # The ID of the region in which the source instance resides. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICAT**E: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyDtsJobListStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if schema migration or initial schema synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of schema migration or initial schema synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of tables that have been migrated or synchronized during schema migration or initial schema synchronization.
        self.progress = progress  # type: str
        # The state of schema migration or initial schema synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyDtsJobListTagList(TeaModel):
    def __init__(self, tag_key=None, tag_value=None):
        # The key of the tag.
        self.tag_key = tag_key  # type: str
        # The value of the tag.
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobListTagList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class DescribeDtsJobsResponseBodyDtsJobList(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, checkpoint=None, consumption_checkpoint=None,
                 consumption_client=None, cpu_usage=None, create_time=None, data_cloud_status=None, data_etl_status=None,
                 data_initialization_status=None, data_synchronization_status=None, db_object=None, dedicated_cluster_id=None, delay=None,
                 destination_endpoint=None, dts_bis_label=None, dts_instance_id=None, dts_job_class=None, dts_job_direction=None,
                 dts_job_id=None, dts_job_name=None, du_usage=None, end_timestamp=None, error_details=None, error_message=None,
                 etl_safe_checkpoint=None, expire_time=None, full_data_check_status=None, inc_data_check_status=None, job_type=None,
                 mem_usage=None, migration_err_code=None, migration_err_help_doc_id=None, migration_err_help_doc_key=None,
                 migration_err_msg=None, migration_err_type=None, migration_err_workaround=None, migration_mode=None,
                 origin_type=None, pay_type=None, performance=None, precheck_status=None, reserved=None,
                 resource_group_display_name=None, resource_group_id=None, retry_state=None, reverse_job=None, source_endpoint=None,
                 status=None, structure_initialization_status=None, tag_list=None):
        # Indicates whether the **new** change tracking feature is used.
        # 
        # >  This parameter is returned only for change tracking instances of the new version.
        self.app_name = app_name  # type: str
        # The start of the time range for change tracking. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.begin_timestamp = begin_timestamp  # type: str
        # The start offset of incremental data synchronization. The value is a UNIX timestamp representing the number of seconds that have elapsed since the epoch time January 1, 1970, 00:00:00 UTC.
        self.checkpoint = checkpoint  # type: str
        # The consumption checkpoint of the change tracking instance. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The downstream client information, in the following format: \<IP address of the downstream client>:\<Random ID generated by DTS>.
        self.consumption_client = consumption_client  # type: str
        # The CPU utilization of the instance. Unit: percentage.
        self.cpu_usage = cpu_usage  # type: str
        # The point in time when the task was created. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.create_time = create_time  # type: str
        # The state of the physical gateway-based migration task.
        self.data_cloud_status = data_cloud_status  # type: DescribeDtsJobsResponseBodyDtsJobListDataCloudStatus
        # The state of the extract, transform, and load (ETL) task. Valid values:
        # 
        # >  This parameter collection is returned only if an ETL task is configured.
        self.data_etl_status = data_etl_status  # type: DescribeDtsJobsResponseBodyDtsJobListDataEtlStatus
        # The state of full data synchronization.
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobsResponseBodyDtsJobListDataInitializationStatus
        # The state of incremental data migration or synchronization.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobsResponseBodyDtsJobListDataSynchronizationStatus
        # The objects that you want to synchronize. The value is a JSON string and can contain regular expressions. For more information, see "Objects of DTS tasks".
        self.db_object = db_object  # type: str
        # The ID of the DTS dedicated cluster on which a DTS task runs.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The latency of incremental data synchronization. Unit: seconds.
        self.delay = delay  # type: long
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobsResponseBodyDtsJobListDestinationEndpoint
        self.dts_bis_label = dts_bis_label  # type: str
        # The ID of the data synchronization instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The instance class.
        # 
        # >  For more information about the test performance of each instance class, see [Specifications of data synchronization instances](~~26605~~).
        self.dts_job_class = dts_job_class  # type: str
        # The synchronization direction. The value is **Reverse**.
        self.dts_job_direction = dts_job_direction  # type: str
        # The ID of the data synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The name of the data synchronization task.
        self.dts_job_name = dts_job_name  # type: str
        # The number of DUs that have been used.
        self.du_usage = du_usage  # type: long
        # The end of the time range for change tracking. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.end_timestamp = end_timestamp  # type: str
        # The error message returned.
        self.error_details = error_details  # type: list[DescribeDtsJobsResponseBodyDtsJobListErrorDetails]
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The checkpoint of the ETL task.
        self.etl_safe_checkpoint = etl_safe_checkpoint  # type: str
        # The point in time when the instance expires. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        # 
        # >  This parameter is returned only if the value of the **PayType** parameter is **PrePaid**.
        self.expire_time = expire_time  # type: str
        # The state information about the full data verification task.
        self.full_data_check_status = full_data_check_status  # type: DescribeDtsJobsResponseBodyDtsJobListFullDataCheckStatus
        # The state information about the incremental data verification task.
        self.inc_data_check_status = inc_data_check_status  # type: DescribeDtsJobsResponseBodyDtsJobListIncDataCheckStatus
        # The type of the DTS task. Valid values:
        # 
        # - **MIGRATION**: data migration task 
        # - **SYNC**: data synchronization task 
        # - **SUBSCRIBE**: change tracking task
        self.job_type = job_type  # type: str
        # The memory that has been used. Unit: MB.
        self.mem_usage = mem_usage  # type: str
        # The error code.
        self.migration_err_code = migration_err_code  # type: str
        # The ID of the error code-related documentation.
        self.migration_err_help_doc_id = migration_err_help_doc_id  # type: str
        # The key of the error code-related documentation.
        self.migration_err_help_doc_key = migration_err_help_doc_key  # type: str
        # The error message.
        self.migration_err_msg = migration_err_msg  # type: str
        # The type of the error code.
        self.migration_err_type = migration_err_type  # type: str
        # The solution to the error.
        self.migration_err_workaround = migration_err_workaround  # type: str
        # The migration or synchronization modes.
        self.migration_mode = migration_mode  # type: DescribeDtsJobsResponseBodyDtsJobListMigrationMode
        # The source of the task. Valid values:
        # 
        # *   **PTS**\
        # *   **DMS**\
        # *   **DTS**\
        self.origin_type = origin_type  # type: str
        # The billing method of the DTS instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The performance of the data migration or synchronization instance.
        self.performance = performance  # type: DescribeDtsJobsResponseBodyDtsJobListPerformance
        # The precheck state.
        self.precheck_status = precheck_status  # type: DescribeDtsJobsResponseBodyDtsJobListPrecheckStatus
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet specific requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        # The name of the resource group.
        self.resource_group_display_name = resource_group_display_name  # type: str
        # The resource group ID.
        self.resource_group_id = resource_group_id  # type: str
        # The information about the retries performed by DTS due to an exception.
        self.retry_state = retry_state  # type: DescribeDtsJobsResponseBodyDtsJobListRetryState
        # The details of the data synchronization task in the reverse direction. 
        # 
        # > This parameter is returned only for two-way data synchronization tasks.
        self.reverse_job = reverse_job  # type: DescribeDtsJobsResponseBodyDtsJobListReverseJob
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobsResponseBodyDtsJobListSourceEndpoint
        # The state of the DTS instance. For more information about the valid values, see the description of the request parameter **Status**.
        self.status = status  # type: str
        # The state of schema migration or initial schema synchronization.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobsResponseBodyDtsJobListStructureInitializationStatus
        # The tags of the task.
        self.tag_list = tag_list  # type: list[DescribeDtsJobsResponseBodyDtsJobListTagList]

    def validate(self):
        if self.data_cloud_status:
            self.data_cloud_status.validate()
        if self.data_etl_status:
            self.data_etl_status.validate()
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.error_details:
            for k in self.error_details:
                if k:
                    k.validate()
        if self.full_data_check_status:
            self.full_data_check_status.validate()
        if self.inc_data_check_status:
            self.inc_data_check_status.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.reverse_job:
            self.reverse_job.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.tag_list:
            for k in self.tag_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyDtsJobList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.cpu_usage is not None:
            result['CpuUsage'] = self.cpu_usage
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_cloud_status is not None:
            result['DataCloudStatus'] = self.data_cloud_status.to_map()
        if self.data_etl_status is not None:
            result['DataEtlStatus'] = self.data_etl_status.to_map()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_bis_label is not None:
            result['DtsBisLabel'] = self.dts_bis_label
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.du_usage is not None:
            result['DuUsage'] = self.du_usage
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        result['ErrorDetails'] = []
        if self.error_details is not None:
            for k in self.error_details:
                result['ErrorDetails'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_safe_checkpoint is not None:
            result['EtlSafeCheckpoint'] = self.etl_safe_checkpoint
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.full_data_check_status is not None:
            result['FullDataCheckStatus'] = self.full_data_check_status.to_map()
        if self.inc_data_check_status is not None:
            result['IncDataCheckStatus'] = self.inc_data_check_status.to_map()
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.mem_usage is not None:
            result['MemUsage'] = self.mem_usage
        if self.migration_err_code is not None:
            result['MigrationErrCode'] = self.migration_err_code
        if self.migration_err_help_doc_id is not None:
            result['MigrationErrHelpDocId'] = self.migration_err_help_doc_id
        if self.migration_err_help_doc_key is not None:
            result['MigrationErrHelpDocKey'] = self.migration_err_help_doc_key
        if self.migration_err_msg is not None:
            result['MigrationErrMsg'] = self.migration_err_msg
        if self.migration_err_type is not None:
            result['MigrationErrType'] = self.migration_err_type
        if self.migration_err_workaround is not None:
            result['MigrationErrWorkaround'] = self.migration_err_workaround
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.origin_type is not None:
            result['OriginType'] = self.origin_type
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.resource_group_display_name is not None:
            result['ResourceGroupDisplayName'] = self.resource_group_display_name
        if self.resource_group_id is not None:
            result['ResourceGroupId'] = self.resource_group_id
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.reverse_job is not None:
            result['ReverseJob'] = self.reverse_job.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        result['TagList'] = []
        if self.tag_list is not None:
            for k in self.tag_list:
                result['TagList'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CpuUsage') is not None:
            self.cpu_usage = m.get('CpuUsage')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataCloudStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListDataCloudStatus()
            self.data_cloud_status = temp_model.from_map(m['DataCloudStatus'])
        if m.get('DataEtlStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListDataEtlStatus()
            self.data_etl_status = temp_model.from_map(m['DataEtlStatus'])
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsBisLabel') is not None:
            self.dts_bis_label = m.get('DtsBisLabel')
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('DuUsage') is not None:
            self.du_usage = m.get('DuUsage')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        self.error_details = []
        if m.get('ErrorDetails') is not None:
            for k in m.get('ErrorDetails'):
                temp_model = DescribeDtsJobsResponseBodyDtsJobListErrorDetails()
                self.error_details.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlSafeCheckpoint') is not None:
            self.etl_safe_checkpoint = m.get('EtlSafeCheckpoint')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('FullDataCheckStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListFullDataCheckStatus()
            self.full_data_check_status = temp_model.from_map(m['FullDataCheckStatus'])
        if m.get('IncDataCheckStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListIncDataCheckStatus()
            self.inc_data_check_status = temp_model.from_map(m['IncDataCheckStatus'])
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('MemUsage') is not None:
            self.mem_usage = m.get('MemUsage')
        if m.get('MigrationErrCode') is not None:
            self.migration_err_code = m.get('MigrationErrCode')
        if m.get('MigrationErrHelpDocId') is not None:
            self.migration_err_help_doc_id = m.get('MigrationErrHelpDocId')
        if m.get('MigrationErrHelpDocKey') is not None:
            self.migration_err_help_doc_key = m.get('MigrationErrHelpDocKey')
        if m.get('MigrationErrMsg') is not None:
            self.migration_err_msg = m.get('MigrationErrMsg')
        if m.get('MigrationErrType') is not None:
            self.migration_err_type = m.get('MigrationErrType')
        if m.get('MigrationErrWorkaround') is not None:
            self.migration_err_workaround = m.get('MigrationErrWorkaround')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('OriginType') is not None:
            self.origin_type = m.get('OriginType')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('ResourceGroupDisplayName') is not None:
            self.resource_group_display_name = m.get('ResourceGroupDisplayName')
        if m.get('ResourceGroupId') is not None:
            self.resource_group_id = m.get('ResourceGroupId')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('ReverseJob') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListReverseJob()
            self.reverse_job = temp_model.from_map(m['ReverseJob'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyDtsJobListStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        self.tag_list = []
        if m.get('TagList') is not None:
            for k in m.get('TagList'):
                temp_model = DescribeDtsJobsResponseBodyDtsJobListTagList()
                self.tag_list.append(temp_model.from_map(k))
        return self


class DescribeDtsJobsResponseBodyEtlDemoListDataEtlStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if the ETL task failed.
        self.error_message = error_message  # type: str
        # The progress of the ETL task. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been processed by the ETL task.
        self.progress = progress  # type: str
        # The state of the ETL task. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete. 
        # - **Catched**: The task is not delayed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListDataEtlStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if full data migration or initial full data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of full data migration or initial full data synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been migrated or synchronized during full data migration or initial full data synchronization.
        self.progress = progress  # type: str
        # The state of full data migration or initial full data synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        # The error message returned if incremental data migration or synchronization failed.
        self.error_message = error_message  # type: str
        # Indicates whether the instance needs to be upgraded. Valid values:
        # 
        # - **true**\
        # - **false**\
        # 
        # > To upgrade a DTS instance, call the [TransferInstanceClass](~~281093~~) operation.
        self.need_upgrade = need_upgrade  # type: bool
        # The progress of incremental data migration or synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been migrated or synchronized during incremental data migration or synchronization.
        self.progress = progress  # type: str
        # The state of incremental data migration or synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete. 
        # - **Catched**: The task is not delayed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListDestinationEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the migrated objects in the destination instance.
        self.database_name = database_name  # type: str
        # The database engine of the destination instance.
        self.engine_name = engine_name  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the destination instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the destination instance.
        self.port = port  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, structure_initialization=None):
        # Indicates whether full data migration or initial full data synchronization is performed. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.data_initialization = data_initialization  # type: bool
        # Indicates whether incremental data migration or synchronization is performed. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether schema migration or initial schema synchronization is performed. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        # The size of data that is migrated or synchronized per second. Unit: MB/s.
        self.flow = flow  # type: str
        # The number of times that SQL statements are migrated or synchronized per second, including BEGIN, COMMIT, DML, and DDL statements. DML statements include INSERT, DELETE, and UPDATE.
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        # The name of the precheck item.
        self.check_item = check_item  # type: str
        # The description of the precheck item.
        self.check_item_description = check_item_description  # type: str
        # The precheck result. Valid values:
        # 
        # - **Success**\
        # - **Failed**\
        self.check_result = check_result  # type: str
        # The error message returned if the task failed to pass the precheck. 
        # 
        # > This parameter is returned only if the returned value of **CheckResult** is **Failed**.
        self.failed_reason = failed_reason  # type: str
        # The method to fix a precheck failure. 
        # 
        # > This parameter is returned only if the returned value of **CheckResult** is **Failed**.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: list[DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatusDetail]
        # The error message returned if the precheck failed.
        self.error_message = error_message  # type: str
        # The precheck progress. Unit: percentage.
        self.percent = percent  # type: str
        # The precheck state. Valid values:
        # 
        # - **NotStarted**: The precheck is not started. 
        # - **Suspending**: The precheck is paused. 
        # - **Checking**: The precheck is in progress. 
        # - **Failed**: The precheck failed. 
        # - **Finished**: The precheck is complete.
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListRetryState(TeaModel):
    def __init__(self, err_message=None, job_id=None, max_retry_time=None, module=None, retry_count=None,
                 retry_target=None, retry_time=None, retrying=None):
        # The error message returned if these retries failed.
        self.err_message = err_message  # type: str
        # The task ID.
        self.job_id = job_id  # type: str
        # The maximum duration of a retry. Unit: seconds.
        self.max_retry_time = max_retry_time  # type: int
        # The progress of the instance when DTS retries.
        self.module = module  # type: str
        # The number of retries that have been performed.
        self.retry_count = retry_count  # type: int
        # The object on which these retries are performed. Valid values:
        # 
        # - **srcDB**: the source database 
        # - **destDB**: the destination database 
        # - **inner_module**: an internal module of DTS
        self.retry_target = retry_target  # type: str
        # The time that has elapsed from the time when the first retry starts. Unit: seconds.
        self.retry_time = retry_time  # type: int
        # Indicates whether the task is being retried. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.retrying = retrying  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListRetryState, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.max_retry_time is not None:
            result['MaxRetryTime'] = self.max_retry_time
        if self.module is not None:
            result['Module'] = self.module
        if self.retry_count is not None:
            result['RetryCount'] = self.retry_count
        if self.retry_target is not None:
            result['RetryTarget'] = self.retry_target
        if self.retry_time is not None:
            result['RetryTime'] = self.retry_time
        if self.retrying is not None:
            result['Retrying'] = self.retrying
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('MaxRetryTime') is not None:
            self.max_retry_time = m.get('MaxRetryTime')
        if m.get('Module') is not None:
            self.module = m.get('Module')
        if m.get('RetryCount') is not None:
            self.retry_count = m.get('RetryCount')
        if m.get('RetryTarget') is not None:
            self.retry_target = m.get('RetryTarget')
        if m.get('RetryTime') is not None:
            self.retry_time = m.get('RetryTime')
        if m.get('Retrying') is not None:
            self.retrying = m.get('Retrying')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if initial full data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of initial full data synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been synchronized during initial full data synchronization.
        self.progress = progress  # type: str
        # The state of initial full data synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataSynchronizationStatus(TeaModel):
    def __init__(self, error_message=None, need_upgrade=None, percent=None, progress=None, status=None):
        # The error message returned if incremental data synchronization failed.
        self.error_message = error_message  # type: str
        # Indicates whether the instance needs to be upgraded. Valid values:
        # 
        # - **true**\
        # - **false**\
        # 
        # > To upgrade a DTS instance, call the [TransferInstanceClass](~~281093~~) operation.
        self.need_upgrade = need_upgrade  # type: bool
        # The progress of incremental data synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of entries that have been migrated or synchronized during incremental data migration or synchronization.
        self.progress = progress  # type: str
        # The state of incremental data synchronization.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.need_upgrade is not None:
            result['NeedUpgrade'] = self.need_upgrade
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('NeedUpgrade') is not None:
            self.need_upgrade = m.get('NeedUpgrade')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobDestinationEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the synchronized objects in the destination instance.
        self.database_name = database_name  # type: str
        # The database engine of the destination instance.
        self.engine_name = engine_name  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the destination instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the destination instance.
        self.port = port  # type: str
        # The ID of the region in which the destination instance resides. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, structure_initialization=None):
        # Indicates whether full data migration or initial full data synchronization is performed. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.data_initialization = data_initialization  # type: bool
        # Indicates whether incremental data migration or synchronization is performed. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether schema migration or initial schema synchronization is performed. Valid values:
        # 
        # - **true**\
        # - **false**\
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        # The size of data that is migrated or synchronized per second. Unit: MB/s.
        self.flow = flow  # type: str
        # The number of times that SQL statements are migrated or synchronized per second, including BEGIN, COMMIT, DML, and DDL statements. DML statements include INSERT, DELETE, and UPDATE.
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['Flow'] = self.flow
        if self.rps is not None:
            result['Rps'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Flow') is not None:
            self.flow = m.get('Flow')
        if m.get('Rps') is not None:
            self.rps = m.get('Rps')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None, check_item_description=None, check_result=None, failed_reason=None,
                 repair_method=None):
        # The name of the precheck item.
        self.check_item = check_item  # type: str
        # The description of the precheck item.
        self.check_item_description = check_item_description  # type: str
        # The precheck result. Valid values:
        # 
        # - **Success**\
        # - **Failed**\
        self.check_result = check_result  # type: str
        # The error message returned if the task failed to pass the precheck. 
        # 
        # > This parameter is returned only if the returned value of **CheckResult** is **Failed**.
        self.failed_reason = failed_reason  # type: str
        # The method to fix a precheck failure. 
        # 
        # > This parameter is returned only if the returned value of **CheckResult** is **Failed**.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_item is not None:
            result['CheckItem'] = self.check_item
        if self.check_item_description is not None:
            result['CheckItemDescription'] = self.check_item_description
        if self.check_result is not None:
            result['CheckResult'] = self.check_result
        if self.failed_reason is not None:
            result['FailedReason'] = self.failed_reason
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckItem') is not None:
            self.check_item = m.get('CheckItem')
        if m.get('CheckItemDescription') is not None:
            self.check_item_description = m.get('CheckItemDescription')
        if m.get('CheckResult') is not None:
            self.check_result = m.get('CheckResult')
        if m.get('FailedReason') is not None:
            self.failed_reason = m.get('FailedReason')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatus(TeaModel):
    def __init__(self, detail=None, error_message=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: list[DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatusDetail]
        # The error message returned if the precheck failed.
        self.error_message = error_message  # type: str
        # The precheck progress. Unit: percentage.
        self.percent = percent  # type: str
        # The precheck state. Valid values:
        # 
        # - **NotStarted**: The precheck is not started. 
        # - **Suspending**: The precheck is paused. 
        # - **Checking**: The precheck is in progress. 
        # - **Failed**: The precheck failed. 
        # - **Finished**: The precheck is complete.
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the objects to be migrated from the source instance.
        self.database_name = database_name  # type: str
        # The database engine of the source instance.
        self.engine_name = engine_name  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the source instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the source instance.
        self.port = port  # type: str
        # The ID of the region in which the source instance resides. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJobStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if initial schema synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of initial schema synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of tables that have been synchronized during initial schema synchronization.
        self.progress = progress  # type: str
        # The state of initial schema synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJobStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListReverseJob(TeaModel):
    def __init__(self, checkpoint=None, create_time=None, data_initialization_status=None,
                 data_synchronization_status=None, db_object=None, delay=None, destination_endpoint=None, dts_instance_id=None,
                 dts_job_class=None, dts_job_direction=None, dts_job_id=None, dts_job_name=None, error_message=None,
                 etl_safe_checkpoint=None, expire_time=None, migration_mode=None, pay_type=None, performance=None, precheck_status=None,
                 reserved=None, source_endpoint=None, status=None, structure_initialization_status=None):
        # The start offset of incremental data synchronization. This value is a UNIX timestamp representing the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC.
        self.checkpoint = checkpoint  # type: str
        # The time when the task was created. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.create_time = create_time  # type: str
        # The state of initial full data synchronization.
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataInitializationStatus
        # The state of incremental data synchronization.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataSynchronizationStatus
        # The schema of the objects that you want to synchronize. The value is a JSON string and can contain regular expressions. For more information, see Objects of DTS tasks.
        self.db_object = db_object  # type: str
        # The latency of incremental data synchronization. Unit: seconds.
        self.delay = delay  # type: long
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobDestinationEndpoint
        # The ID of the data synchronization instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The instance class. 
        # 
        # > For more information about the test performance of each instance class, see [Specifications of data synchronization instances](~~26605~~).
        self.dts_job_class = dts_job_class  # type: str
        # The synchronization direction. **Reverse** is returned.
        self.dts_job_direction = dts_job_direction  # type: str
        # The ID of the synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The name of the data synchronization task.
        self.dts_job_name = dts_job_name  # type: str
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The checkpoint of the ETL task.
        self.etl_safe_checkpoint = etl_safe_checkpoint  # type: str
        # The time when the instance expires. The time follows the ISO 8601 standard in the* yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC. 
        # 
        # > This parameter is returned only if the returned value of **PayType** is **PrePaid**.
        self.expire_time = expire_time  # type: str
        # The migration types or initial synchronization types.
        self.migration_mode = migration_mode  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobMigrationMode
        # The billing method of the DTS instance. Valid values:
        # 
        # - **PrePaid**: subscription
        # - **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The performance of the data migration or synchronization instance.
        self.performance = performance  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobPerformance
        # The precheck state.
        self.precheck_status = precheck_status  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatus
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet specific requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobSourceEndpoint
        # The state of the DTS instance. For more information about the valid values, see the description of the request parameter **Status**.
        self.status = status  # type: str
        # The state of initial schema synchronization.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJobStructureInitializationStatus

    def validate(self):
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListReverseJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_safe_checkpoint is not None:
            result['EtlSafeCheckpoint'] = self.etl_safe_checkpoint
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlSafeCheckpoint') is not None:
            self.etl_safe_checkpoint = m.get('EtlSafeCheckpoint')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJobStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        return self


class DescribeDtsJobsResponseBodyEtlDemoListSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, instance_id=None, instance_type=None, ip=None,
                 oracle_sid=None, port=None, region=None, ssl_solution_enum=None, user_name=None):
        # The name of the database that contains the objects to be migrated from the source instance.
        self.database_name = database_name  # type: str
        # The database engine of the source instance.
        self.engine_name = engine_name  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        self.instance_type = instance_type  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The SID of the Oracle database. 
        # 
        # > This parameter is returned only if the returned value of **EngineName** of the source instance is **Oracle** and the Oracle database is deployed in a non-RAC architecture.
        self.oracle_sid = oracle_sid  # type: str
        # The port number of the source instance.
        self.port = port  # type: str
        # The ID of the region in which the source instance resides. For more information, see [Supported regions](~~141033~~).
        self.region = region  # type: str
        # Indicates whether SSL encryption is enabled. Valid values:
        # 
        # - **DISABLE**: SSL encryption is disabled. 
        # - **ENABLE_WITH_CERTIFICATE**: SSL encryption is enabled and the CA certificate is uploaded. 
        # - **ENABLE_ONLY_4_MONGODB_ALTAS**: SSL encryption is enabled for the connection with an AWS MongoDB Altas database. 
        # - **ENABLE_ONLY_4_KAFKA_SCRAM_SHA_256**: SCRAM-SHA-256 is used to encrypt the connection with a Kafka cluster.
        self.ssl_solution_enum = ssl_solution_enum  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.ip is not None:
            result['Ip'] = self.ip
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.region is not None:
            result['Region'] = self.region
        if self.ssl_solution_enum is not None:
            result['SslSolutionEnum'] = self.ssl_solution_enum
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Ip') is not None:
            self.ip = m.get('Ip')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('SslSolutionEnum') is not None:
            self.ssl_solution_enum = m.get('SslSolutionEnum')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if schema migration or initial schema synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of schema migration or initial schema synchronization. Unit: percentage.
        self.percent = percent  # type: str
        # The number of tables that have been migrated or synchronized during schema migration or initial schema synchronization.
        self.progress = progress  # type: str
        # The state of schema migration or initial schema synchronization. Valid values:
        # 
        # - **NotStarted**: The task is not started. 
        # - **Migrating**: The task is in progress. 
        # - **Failed**: The task failed. 
        # - **Finished**: The task is complete.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeDtsJobsResponseBodyEtlDemoListTagList(TeaModel):
    def __init__(self, tag_key=None, tag_value=None):
        # The tag key.
        self.tag_key = tag_key  # type: str
        # The tag value.
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoListTagList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class DescribeDtsJobsResponseBodyEtlDemoList(TeaModel):
    def __init__(self, app_name=None, begin_timestamp=None, checkpoint=None, consumption_checkpoint=None,
                 consumption_client=None, create_time=None, data_etl_status=None, data_initialization_status=None,
                 data_synchronization_status=None, db_object=None, delay=None, destination_endpoint=None, dts_instance_id=None,
                 dts_job_class=None, dts_job_direction=None, dts_job_id=None, dts_job_name=None, end_timestamp=None,
                 error_message=None, etl_safe_checkpoint=None, expire_time=None, job_type=None, migration_mode=None,
                 origin_type=None, pay_type=None, performance=None, precheck_status=None, reserved=None,
                 resource_group_display_name=None, resource_group_id=None, retry_state=None, reverse_job=None, source_endpoint=None,
                 status=None, structure_initialization_status=None, tag_list=None):
        # Indicates whether the **new** change tracking feature is used. 
        # 
        # > This parameter is returned only for change tracking instances of the new version.
        self.app_name = app_name  # type: str
        # The start of the time range for change tracking. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.begin_timestamp = begin_timestamp  # type: str
        # The start offset of incremental data migration or data synchronization. This value is a UNIX timestamp representing the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC.
        self.checkpoint = checkpoint  # type: str
        # The consumption checkpoint of the change tracking instance. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The downstream client information in the following format: <IP address of the downstream client>:<Random ID generated by DTS>.
        self.consumption_client = consumption_client  # type: str
        # The time when the task was created. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:s*sZ format. The time is displayed in UTC.
        self.create_time = create_time  # type: str
        # The state of the ETL task. 
        # 
        # > This parameter collection is returned only if an ETL task is configured.
        self.data_etl_status = data_etl_status  # type: DescribeDtsJobsResponseBodyEtlDemoListDataEtlStatus
        # The state of full data migration or initial full data synchronization.
        self.data_initialization_status = data_initialization_status  # type: DescribeDtsJobsResponseBodyEtlDemoListDataInitializationStatus
        # The state of incremental data migration or synchronization.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeDtsJobsResponseBodyEtlDemoListDataSynchronizationStatus
        # The objects of the data migration, data synchronization, or change tracking task. For more information, see [Objects of DTS tasks](~~209545~~).
        self.db_object = db_object  # type: str
        # The latency of incremental data migration or synchronization. 
        # 
        # > If you query data migration tasks, the unit of this parameter is milliseconds. If you query data synchronization tasks, the unit of this parameter is seconds.
        self.delay = delay  # type: long
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeDtsJobsResponseBodyEtlDemoListDestinationEndpoint
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The instance class. 
        # 
        # > For more information about the test performance of each instance class, see [Specifications of data migration instances](~~26606~~) and [Specifications of data synchronization instances](~~26605~~).
        self.dts_job_class = dts_job_class  # type: str
        # The synchronization direction. Valid values:
        # 
        # - **Forward**\
        # - **Reverse**\
        # 
        # > This parameter is returned only if the topology of the data synchronization instance is two-way synchronization.
        self.dts_job_direction = dts_job_direction  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The name of the data migration, data synchronization, or change tracking task.
        self.dts_job_name = dts_job_name  # type: str
        # The end of the time range for change tracking. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        self.end_timestamp = end_timestamp  # type: str
        # The error message returned if the task failed.
        self.error_message = error_message  # type: str
        # The checkpoint of the ETL task.
        self.etl_safe_checkpoint = etl_safe_checkpoint  # type: str
        # The time when the instance expires. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time is displayed in UTC.
        # 
        # > This parameter is returned only if the returned value of **PayType** is **PrePaid**.
        self.expire_time = expire_time  # type: str
        # The type of the DTS task. Valid values:
        # 
        # - **MIGRATION**: data migration task 
        # - **SYNC**: data synchronization task 
        # - **SUBSCRIBE**: change tracking task
        self.job_type = job_type  # type: str
        # The migration types or initial synchronization types.
        self.migration_mode = migration_mode  # type: DescribeDtsJobsResponseBodyEtlDemoListMigrationMode
        # The source of the task.
        # - **PTS**\
        # - **DMS**\
        # - **DTS**\
        self.origin_type = origin_type  # type: str
        # The billing method of the DTS instance. Valid values:
        # 
        # - **PrePaid**: subscription 
        # - **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The performance of the data migration or synchronization instance.
        self.performance = performance  # type: DescribeDtsJobsResponseBodyEtlDemoListPerformance
        # The precheck state.
        self.precheck_status = precheck_status  # type: DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatus
        # The reserved parameter of DTS. The value is a JSON string. You can specify this parameter to meet specific requirements, for example, whether to automatically start a precheck. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        # The name of the resource group.
        self.resource_group_display_name = resource_group_display_name  # type: str
        # The resource group ID.
        self.resource_group_id = resource_group_id  # type: str
        # The information about the retries performed by DTS due to an exception.
        self.retry_state = retry_state  # type: DescribeDtsJobsResponseBodyEtlDemoListRetryState
        # The details of the data synchronization task in the reverse direction. 
        # 
        # > This parameter is returned only for two-way data synchronization tasks.
        self.reverse_job = reverse_job  # type: DescribeDtsJobsResponseBodyEtlDemoListReverseJob
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeDtsJobsResponseBodyEtlDemoListSourceEndpoint
        # The state of the DTS instance. For more information about the valid values, see the description of the request parameter **Status**.
        self.status = status  # type: str
        # The state of schema migration or initial schema synchronization.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeDtsJobsResponseBodyEtlDemoListStructureInitializationStatus
        # The tags of the task.
        self.tag_list = tag_list  # type: list[DescribeDtsJobsResponseBodyEtlDemoListTagList]

    def validate(self):
        if self.data_etl_status:
            self.data_etl_status.validate()
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.retry_state:
            self.retry_state.validate()
        if self.reverse_job:
            self.reverse_job.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.tag_list:
            for k in self.tag_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBodyEtlDemoList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.app_name is not None:
            result['AppName'] = self.app_name
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_etl_status is not None:
            result['DataEtlStatus'] = self.data_etl_status.to_map()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.db_object is not None:
            result['DbObject'] = self.db_object
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.dts_job_class is not None:
            result['DtsJobClass'] = self.dts_job_class
        if self.dts_job_direction is not None:
            result['DtsJobDirection'] = self.dts_job_direction
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.etl_safe_checkpoint is not None:
            result['EtlSafeCheckpoint'] = self.etl_safe_checkpoint
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.origin_type is not None:
            result['OriginType'] = self.origin_type
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.resource_group_display_name is not None:
            result['ResourceGroupDisplayName'] = self.resource_group_display_name
        if self.resource_group_id is not None:
            result['ResourceGroupId'] = self.resource_group_id
        if self.retry_state is not None:
            result['RetryState'] = self.retry_state.to_map()
        if self.reverse_job is not None:
            result['ReverseJob'] = self.reverse_job.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        result['TagList'] = []
        if self.tag_list is not None:
            for k in self.tag_list:
                result['TagList'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AppName') is not None:
            self.app_name = m.get('AppName')
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataEtlStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListDataEtlStatus()
            self.data_etl_status = temp_model.from_map(m['DataEtlStatus'])
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DbObject') is not None:
            self.db_object = m.get('DbObject')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('DtsJobClass') is not None:
            self.dts_job_class = m.get('DtsJobClass')
        if m.get('DtsJobDirection') is not None:
            self.dts_job_direction = m.get('DtsJobDirection')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('EtlSafeCheckpoint') is not None:
            self.etl_safe_checkpoint = m.get('EtlSafeCheckpoint')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('OriginType') is not None:
            self.origin_type = m.get('OriginType')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('ResourceGroupDisplayName') is not None:
            self.resource_group_display_name = m.get('ResourceGroupDisplayName')
        if m.get('ResourceGroupId') is not None:
            self.resource_group_id = m.get('ResourceGroupId')
        if m.get('RetryState') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListRetryState()
            self.retry_state = temp_model.from_map(m['RetryState'])
        if m.get('ReverseJob') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListReverseJob()
            self.reverse_job = temp_model.from_map(m['ReverseJob'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeDtsJobsResponseBodyEtlDemoListStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        self.tag_list = []
        if m.get('TagList') is not None:
            for k in m.get('TagList'):
                temp_model = DescribeDtsJobsResponseBodyEtlDemoListTagList()
                self.tag_list.append(temp_model.from_map(k))
        return self


class DescribeDtsJobsResponseBody(TeaModel):
    def __init__(self, dts_job_list=None, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 etl_demo_list=None, http_status_code=None, page_number=None, page_record_count=None, request_id=None,
                 success=None, total_record_count=None):
        # The list of DTS tasks and the details of each task.
        self.dts_job_list = dts_job_list  # type: list[DescribeDtsJobsResponseBodyDtsJobList]
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. The value of this parameter is used to replace the **%s** variable in the value of the **ErrMessage** parameter.
        # 
        # >  For example, if the value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the value of the **DynamicMessage** parameter is **Type**, the specified **Type** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The DTS tasks and the details of each task.
        self.etl_demo_list = etl_demo_list  # type: list[DescribeDtsJobsResponseBodyEtlDemoList]
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The number of entries returned per page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool
        # The total number of DTS tasks that meet the query condition.
        self.total_record_count = total_record_count  # type: int

    def validate(self):
        if self.dts_job_list:
            for k in self.dts_job_list:
                if k:
                    k.validate()
        if self.etl_demo_list:
            for k in self.etl_demo_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DtsJobList'] = []
        if self.dts_job_list is not None:
            for k in self.dts_job_list:
                result['DtsJobList'].append(k.to_map() if k else None)
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        result['EtlDemoList'] = []
        if self.etl_demo_list is not None:
            for k in self.etl_demo_list:
                result['EtlDemoList'].append(k.to_map() if k else None)
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.dts_job_list = []
        if m.get('DtsJobList') is not None:
            for k in m.get('DtsJobList'):
                temp_model = DescribeDtsJobsResponseBodyDtsJobList()
                self.dts_job_list.append(temp_model.from_map(k))
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        self.etl_demo_list = []
        if m.get('EtlDemoList') is not None:
            for k in m.get('EtlDemoList'):
                temp_model = DescribeDtsJobsResponseBodyEtlDemoList()
                self.etl_demo_list.append(temp_model.from_map(k))
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeDtsJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDtsJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDtsJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDtsJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeDtsServiceLogRequest(TeaModel):
    def __init__(self, dts_job_id=None, end_time=None, keyword=None, page_number=None, page_size=None,
                 region_id=None, start_time=None, status=None, sub_job_type=None):
        # The ID of the data migration or synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The end of the time range to query. You can call the [DescribePreCheckStatus](~~209718~~) operation to query the execution time of the subtasks.
        # 
        # > *   To obtain the logs that are generated for DTS subtasks within a specific period of time, you can call the [DescribePreCheckStatus](~~209718~~) operation to query the execution time of the subtasks.
        # >*   Specify the time in the 13-digit UNIX timestamp format. Unit: milliseconds. You can use a search engine to obtain a UNIX timestamp converter.
        self.end_time = end_time  # type: long
        # The keyword that is passed to specify the query content.
        # 
        # >  Fuzzy match is used and the keyword is case-sensitive.
        self.keyword = keyword  # type: str
        # The number of the page to return. The value must be an integer that is greater than 0 and less than or equal to the maximum value supported by the integer data type. Default value: **1**.
        self.page_number = page_number  # type: int
        # The number of log entries to return on each page. Valid values: **20**, **50**, **100**, **500**, and **1000**. Default value: **20**.
        self.page_size = page_size  # type: int
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The beginning of the time range to query.
        # 
        # > *   To obtain the logs that are generated for Data Transmission Service (DTS) subtasks within a specific period of time, you can call the [DescribePreCheckStatus](~~209718~~) operation to query the execution time of the subtasks.
        # >*   Specify the time in the 13-digit UNIX timestamp format. Unit: milliseconds. You can use a search engine to obtain a UNIX timestamp converter.
        self.start_time = start_time  # type: long
        # The log level. Separate multiple log levels with commas (,). Valid values:
        # 
        # *   **NORMAL**: displays the logs that are generated when the DTS task runs as expected.
        # *   **WARN**: displays the logs about severe issues that stop the DTS task from running.
        # *   **ERROR**: displays the logs about unexpected issues that stop specific processes form running.
        self.status = status  # type: str
        # The type of a DTS subtask. Valid values:
        # 
        # *   **DATA_LOAD**: full migration or full synchronization
        # *   **ONLINE_WRITER**: incremental migration
        # *   **SYNC_WRITER**: incremental synchronization
        self.sub_job_type = sub_job_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsServiceLogRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.end_time is not None:
            result['EndTime'] = self.end_time
        if self.keyword is not None:
            result['Keyword'] = self.keyword
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.start_time is not None:
            result['StartTime'] = self.start_time
        if self.status is not None:
            result['Status'] = self.status
        if self.sub_job_type is not None:
            result['SubJobType'] = self.sub_job_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('EndTime') is not None:
            self.end_time = m.get('EndTime')
        if m.get('Keyword') is not None:
            self.keyword = m.get('Keyword')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('StartTime') is not None:
            self.start_time = m.get('StartTime')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('SubJobType') is not None:
            self.sub_job_type = m.get('SubJobType')
        return self


class DescribeDtsServiceLogResponseBodyServiceLogContexts(TeaModel):
    def __init__(self, context=None, state=None, time=None):
        # The log content.
        self.context = context  # type: str
        # The log level.
        self.state = state  # type: str
        # The time when the logs were collected. The time follows the ISO 8601 standard in the yyyy-MM-ddThh:mm:ssZ format. The time is displayed in UTC.
        self.time = time  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeDtsServiceLogResponseBodyServiceLogContexts, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.context is not None:
            result['Context'] = self.context
        if self.state is not None:
            result['State'] = self.state
        if self.time is not None:
            result['Time'] = self.time
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Context') is not None:
            self.context = m.get('Context')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Time') is not None:
            self.time = m.get('Time')
        return self


class DescribeDtsServiceLogResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, page_number=None, page_record_count=None, request_id=None, service_log_contexts=None,
                 success=None, total_record_count=None):
        # The dynamic error code. This parameter will be removed soon.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the \*\*%s\*\* variable in the **ErrMessage** parameter.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request fails.
        self.err_code = err_code  # type: str
        # The error message returned if the request fails.
        self.err_message = err_message  # type: str
        # The HTTP status code that is returned.
        self.http_status_code = http_status_code  # type: int
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The number of log entries returned per page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The details of the logs.
        self.service_log_contexts = service_log_contexts  # type: list[DescribeDtsServiceLogResponseBodyServiceLogContexts]
        # Indicates whether the request is successful.
        self.success = success  # type: bool
        # The total number of logs that meet the query conditions.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.service_log_contexts:
            for k in self.service_log_contexts:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeDtsServiceLogResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        result['ServiceLogContexts'] = []
        if self.service_log_contexts is not None:
            for k in self.service_log_contexts:
                result['ServiceLogContexts'].append(k.to_map() if k else None)
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        self.service_log_contexts = []
        if m.get('ServiceLogContexts') is not None:
            for k in m.get('ServiceLogContexts'):
                temp_model = DescribeDtsServiceLogResponseBodyServiceLogContexts()
                self.service_log_contexts.append(temp_model.from_map(k))
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeDtsServiceLogResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeDtsServiceLogResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeDtsServiceLogResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeDtsServiceLogResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeEndpointSwitchStatusRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None, task_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The task ID, which is returned after you call the [SwitchSynchronizationEndpoint](~~201858~~) operation.
        self.task_id = task_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeEndpointSwitchStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class DescribeEndpointSwitchStatusResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, error_message=None, request_id=None, status=None,
                 success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # This parameter is no longer available.
        self.error_message = error_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The status of the task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Initializing**: The task is being initialized.
        # *   **Switching**: The task is running.
        # *   **Failed**: The task failed.
        # *   **Finished**: The task is completed.
        self.status = status  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeEndpointSwitchStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.status is not None:
            result['Status'] = self.status
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeEndpointSwitchStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeEndpointSwitchStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeEndpointSwitchStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeEndpointSwitchStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeEtlJobLogsRequest(TeaModel):
    def __init__(self, dts_job_id=None, region_id=None):
        # The ID of the ETL task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the region in which the Data Transmission Service (DTS) instance resides. You can call the [DescribeRegions](~~25609~~) operation to query the available Alibaba Cloud regions.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeEtlJobLogsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeEtlJobLogsResponseBodyEtlRunningLogs(TeaModel):
    def __init__(self, content=None, content_key=None, etl_id=None, log_datetime=None, status=None, user_id=None):
        # The state of the ETL task.
        self.content = content  # type: str
        # The module for which the logs are generated, such as the conversion module of ETL tasks.
        self.content_key = content_key  # type: str
        # The ID of the ETL task.
        self.etl_id = etl_id  # type: str
        # The time when the log was generated. This value is a UNIX timestamp representing the number of milliseconds that have elapsed since January 1, 1970, 00:00:00 UTC.
        self.log_datetime = log_datetime  # type: str
        # The log level. Valid values: ERROR, WARN, INFO, and DEBUG.
        self.status = status  # type: str
        # The ID of the user.
        self.user_id = user_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeEtlJobLogsResponseBodyEtlRunningLogs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.content is not None:
            result['Content'] = self.content
        if self.content_key is not None:
            result['ContentKey'] = self.content_key
        if self.etl_id is not None:
            result['EtlId'] = self.etl_id
        if self.log_datetime is not None:
            result['LogDatetime'] = self.log_datetime
        if self.status is not None:
            result['Status'] = self.status
        if self.user_id is not None:
            result['UserId'] = self.user_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Content') is not None:
            self.content = m.get('Content')
        if m.get('ContentKey') is not None:
            self.content_key = m.get('ContentKey')
        if m.get('EtlId') is not None:
            self.etl_id = m.get('EtlId')
        if m.get('LogDatetime') is not None:
            self.log_datetime = m.get('LogDatetime')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('UserId') is not None:
            self.user_id = m.get('UserId')
        return self


class DescribeEtlJobLogsResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 etl_running_logs=None, http_status_code=None, request_id=None, success=None):
        # The dynamic error code.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message.
        self.dynamic_message = dynamic_message  # type: str
        # The error code. This example indicates that the specified ETL task ID is invalid.
        self.err_code = err_code  # type: str
        # The error message. This example indicates that the specified ETL task ID does not exist. In this case, the ETL task may be deleted.
        self.err_message = err_message  # type: str
        # The logs of ETL tasks.
        self.etl_running_logs = etl_running_logs  # type: list[DescribeEtlJobLogsResponseBodyEtlRunningLogs]
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful. If the call failed, false is returned.
        self.success = success  # type: bool

    def validate(self):
        if self.etl_running_logs:
            for k in self.etl_running_logs:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeEtlJobLogsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        result['EtlRunningLogs'] = []
        if self.etl_running_logs is not None:
            for k in self.etl_running_logs:
                result['EtlRunningLogs'].append(k.to_map() if k else None)
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        self.etl_running_logs = []
        if m.get('EtlRunningLogs') is not None:
            for k in m.get('EtlRunningLogs'):
                temp_model = DescribeEtlJobLogsResponseBodyEtlRunningLogs()
                self.etl_running_logs.append(temp_model.from_map(k))
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeEtlJobLogsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeEtlJobLogsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeEtlJobLogsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeEtlJobLogsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeInitializationStatusRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, page_num=None, page_size=None, region_id=None,
                 synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_num = page_num  # type: int
        # The number of entries to return on each page. Valid values: **1** to **100**. Default value: **30**.
        self.page_size = page_size  # type: int
        self.region_id = region_id  # type: str
        # The ID of the data synchronization instance. You can call the [DescribeSynchronizationJobs](~~49454~~) operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeInitializationStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_num is not None:
            result['PageNum'] = self.page_num
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNum') is not None:
            self.page_num = m.get('PageNum')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class DescribeInitializationStatusResponseBodyDataInitializationDetails(TeaModel):
    def __init__(self, destination_owner_dbname=None, error_message=None, finish_row_num=None,
                 source_owner_dbname=None, status=None, table_name=None, total_row_num=None, used_time=None):
        # The name of the database to which the object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if initial full data synchronization failed.
        self.error_message = error_message  # type: str
        # The total number of rows that are actually synchronized.
        # 
        # >  This parameter indicates the total number of actually synchronized rows. In contrast, the value of the **TotalRowNum** parameter is calculated based on the system tables in the source database. The values of the two parameters may be different due to time difference.
        self.finish_row_num = finish_row_num  # type: str
        # The name of the database to which the object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of initial full data synchronization. Valid values:
        # 
        # *   **NotStarted**\
        # *   **Migrating**\
        # *   **Failed**\
        # *   **Finished**\
        self.status = status  # type: str
        # The table name.
        self.table_name = table_name  # type: str
        # The total number of rows that are supposed to be synchronized.
        # 
        # >  The value of this parameter is calculated based on the system tables in the source database. In contrast, the **FinishRowNum** parameter indicates the total number of actually synchronized rows. The values of the two parameters may be different due to time difference.
        self.total_row_num = total_row_num  # type: str
        # The time spent on full data synchronization.
        self.used_time = used_time  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeInitializationStatusResponseBodyDataInitializationDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.finish_row_num is not None:
            result['FinishRowNum'] = self.finish_row_num
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        if self.table_name is not None:
            result['TableName'] = self.table_name
        if self.total_row_num is not None:
            result['TotalRowNum'] = self.total_row_num
        if self.used_time is not None:
            result['UsedTime'] = self.used_time
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('FinishRowNum') is not None:
            self.finish_row_num = m.get('FinishRowNum')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        if m.get('TotalRowNum') is not None:
            self.total_row_num = m.get('TotalRowNum')
        if m.get('UsedTime') is not None:
            self.used_time = m.get('UsedTime')
        return self


class DescribeInitializationStatusResponseBodyDataSynchronizationDetails(TeaModel):
    def __init__(self, destination_owner_dbname=None, error_message=None, source_owner_dbname=None, status=None,
                 table_name=None):
        # The name of the database to which the object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if incremental data synchronization failed.
        self.error_message = error_message  # type: str
        # The name of the database to which the object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of incremental data synchronization. Valid values:
        # 
        # *   **NotStarted**\
        # *   **Migrating**\
        # *   **Failed**\
        # *   **Finished**\
        self.status = status  # type: str
        # The table name.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeInitializationStatusResponseBodyDataSynchronizationDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeInitializationStatusResponseBodyStructureInitializationDetailsConstraints(TeaModel):
    def __init__(self, destination_owner_dbname=None, error_message=None, object_definition=None, object_name=None,
                 object_type=None, source_owner_dbname=None, status=None):
        # The name of the database to which the object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if constraints failed to be created.
        self.error_message = error_message  # type: str
        # The syntax to create constraints.
        self.object_definition = object_definition  # type: str
        # The name of the object.
        self.object_name = object_name  # type: str
        # The type of the object. Valid value: **Table**.
        self.object_type = object_type  # type: str
        # The name of the database to which the object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of constraint creation. Valid values:
        # 
        # *   **NotStarted**\
        # *   **Migrating**\
        # *   **Failed**\
        # *   **Finished**\
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeInitializationStatusResponseBodyStructureInitializationDetailsConstraints, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.object_definition is not None:
            result['ObjectDefinition'] = self.object_definition
        if self.object_name is not None:
            result['ObjectName'] = self.object_name
        if self.object_type is not None:
            result['ObjectType'] = self.object_type
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ObjectDefinition') is not None:
            self.object_definition = m.get('ObjectDefinition')
        if m.get('ObjectName') is not None:
            self.object_name = m.get('ObjectName')
        if m.get('ObjectType') is not None:
            self.object_type = m.get('ObjectType')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeInitializationStatusResponseBodyStructureInitializationDetails(TeaModel):
    def __init__(self, constraints=None, destination_owner_dbname=None, error_message=None, object_definition=None,
                 object_name=None, object_type=None, source_owner_dbname=None, status=None):
        # The constraints of the synchronization object, such as indexes and foreign keys.
        # 
        # >  This parameter is returned only if the **ObjectType** parameter is set to **Table** and the synchronization object has constraints.
        self.constraints = constraints  # type: list[DescribeInitializationStatusResponseBodyStructureInitializationDetailsConstraints]
        # The name of the database to which the object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if initial schema synchronization failed.
        self.error_message = error_message  # type: str
        # The schema of the object.
        self.object_definition = object_definition  # type: str
        # The name of the object.
        self.object_name = object_name  # type: str
        # The type of the object. Valid values:
        # 
        # **Table**, **Constraint**, **Index**, **View**, **Materialize View**, **Type**, **Synonym**, **Trigger**, **Function**, **Procedure**, **Package**, **Default**, **Rule**, **PlanGuide**, and **Sequence**.
        self.object_type = object_type  # type: str
        # The name of the database to which the object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of initial schema synchronization. Valid values:
        # 
        # *   **NotStarted**\
        # *   **Migrating**\
        # *   **Failed**\
        # *   **Finished**\
        self.status = status  # type: str

    def validate(self):
        if self.constraints:
            for k in self.constraints:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeInitializationStatusResponseBodyStructureInitializationDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Constraints'] = []
        if self.constraints is not None:
            for k in self.constraints:
                result['Constraints'].append(k.to_map() if k else None)
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.object_definition is not None:
            result['ObjectDefinition'] = self.object_definition
        if self.object_name is not None:
            result['ObjectName'] = self.object_name
        if self.object_type is not None:
            result['ObjectType'] = self.object_type
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.constraints = []
        if m.get('Constraints') is not None:
            for k in m.get('Constraints'):
                temp_model = DescribeInitializationStatusResponseBodyStructureInitializationDetailsConstraints()
                self.constraints.append(temp_model.from_map(k))
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ObjectDefinition') is not None:
            self.object_definition = m.get('ObjectDefinition')
        if m.get('ObjectName') is not None:
            self.object_name = m.get('ObjectName')
        if m.get('ObjectType') is not None:
            self.object_type = m.get('ObjectType')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeInitializationStatusResponseBody(TeaModel):
    def __init__(self, data_initialization_details=None, data_synchronization_details=None, err_code=None,
                 err_message=None, request_id=None, structure_initialization_details=None, success=None):
        # The details of initial full data synchronization.
        self.data_initialization_details = data_initialization_details  # type: list[DescribeInitializationStatusResponseBodyDataInitializationDetails]
        # The details of incremental data synchronization.
        # 
        # >  This parameter and the parameters it contains will be removed in the future.
        self.data_synchronization_details = data_synchronization_details  # type: list[DescribeInitializationStatusResponseBodyDataSynchronizationDetails]
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The details of initial schema synchronization.
        self.structure_initialization_details = structure_initialization_details  # type: list[DescribeInitializationStatusResponseBodyStructureInitializationDetails]
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        if self.data_initialization_details:
            for k in self.data_initialization_details:
                if k:
                    k.validate()
        if self.data_synchronization_details:
            for k in self.data_synchronization_details:
                if k:
                    k.validate()
        if self.structure_initialization_details:
            for k in self.structure_initialization_details:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeInitializationStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DataInitializationDetails'] = []
        if self.data_initialization_details is not None:
            for k in self.data_initialization_details:
                result['DataInitializationDetails'].append(k.to_map() if k else None)
        result['DataSynchronizationDetails'] = []
        if self.data_synchronization_details is not None:
            for k in self.data_synchronization_details:
                result['DataSynchronizationDetails'].append(k.to_map() if k else None)
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        result['StructureInitializationDetails'] = []
        if self.structure_initialization_details is not None:
            for k in self.structure_initialization_details:
                result['StructureInitializationDetails'].append(k.to_map() if k else None)
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.data_initialization_details = []
        if m.get('DataInitializationDetails') is not None:
            for k in m.get('DataInitializationDetails'):
                temp_model = DescribeInitializationStatusResponseBodyDataInitializationDetails()
                self.data_initialization_details.append(temp_model.from_map(k))
        self.data_synchronization_details = []
        if m.get('DataSynchronizationDetails') is not None:
            for k in m.get('DataSynchronizationDetails'):
                temp_model = DescribeInitializationStatusResponseBodyDataSynchronizationDetails()
                self.data_synchronization_details.append(temp_model.from_map(k))
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        self.structure_initialization_details = []
        if m.get('StructureInitializationDetails') is not None:
            for k in m.get('StructureInitializationDetails'):
                temp_model = DescribeInitializationStatusResponseBodyStructureInitializationDetails()
                self.structure_initialization_details.append(temp_model.from_map(k))
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeInitializationStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeInitializationStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeInitializationStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeInitializationStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeJobMonitorRuleRequest(TeaModel):
    def __init__(self, dts_job_id=None, region_id=None):
        # The ID of the data migration, data synchronization, or change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeJobMonitorRuleRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeJobMonitorRuleResponseBodyMonitorRules(TeaModel):
    def __init__(self, delay_rule_time=None, job_id=None, job_type=None, notice_value=None, period=None, phone=None,
                 state=None, times=None, type=None):
        # The threshold that triggers the alert.
        # 
        # *   If the request parameter **Type** of the [CreateJobMonitorRule](~~212332~~) operation is set to **delay**, the unit of DelayRuleTime is seconds.
        # *   If the request parameter **Type** of the [CreateJobMonitorRule](~~212332~~) operation is set to **full_timeout**, the unit of DelayRuleTime is hours.
        self.delay_rule_time = delay_rule_time  # type: long
        self.job_id = job_id  # type: str
        self.job_type = job_type  # type: str
        self.notice_value = notice_value  # type: int
        self.period = period  # type: int
        # The mobile phone numbers that receive alert notifications. Multiple mobile numbers are separated by commas (,).
        self.phone = phone  # type: str
        # Indicates whether the monitoring rule is enabled. Valid values:
        # 
        # *   **Y**: The monitoring rule is enabled.
        # *   **N**: The monitoring rule is disabled.
        self.state = state  # type: str
        self.times = times  # type: int
        # The type of the monitoring rule. Valid values:
        # 
        # *   **delay**: If the task latency reaches the threshold, an alert is triggered.
        # *   **error**: If an exception occurs, an alert is triggered.
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeJobMonitorRuleResponseBodyMonitorRules, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay_rule_time is not None:
            result['DelayRuleTime'] = self.delay_rule_time
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.job_type is not None:
            result['JobType'] = self.job_type
        if self.notice_value is not None:
            result['NoticeValue'] = self.notice_value
        if self.period is not None:
            result['Period'] = self.period
        if self.phone is not None:
            result['Phone'] = self.phone
        if self.state is not None:
            result['State'] = self.state
        if self.times is not None:
            result['Times'] = self.times
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DelayRuleTime') is not None:
            self.delay_rule_time = m.get('DelayRuleTime')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('JobType') is not None:
            self.job_type = m.get('JobType')
        if m.get('NoticeValue') is not None:
            self.notice_value = m.get('NoticeValue')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('Phone') is not None:
            self.phone = m.get('Phone')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Times') is not None:
            self.times = m.get('Times')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class DescribeJobMonitorRuleResponseBody(TeaModel):
    def __init__(self, code=None, dts_job_id=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, monitor_rules=None, request_id=None, success=None, topics=None):
        # The error code. This parameter will be removed in the future.
        self.code = code  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the specified **DtsJobId** parameter is invalid, **The Value of Input Parameter %s is not valid** is returned for **ErrMessage** and **DtsJobId** is returned for **DynamicMessage**.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The monitoring rules of the DTS task.
        self.monitor_rules = monitor_rules  # type: list[DescribeJobMonitorRuleResponseBodyMonitorRules]
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful. Valid values:
        # 
        # *   **true**: The call was successful.
        # *   **false**:The call failed.
        self.success = success  # type: bool
        # The topics of all subtasks in the distributed change tracking task.
        self.topics = topics  # type: list[str]

    def validate(self):
        if self.monitor_rules:
            for k in self.monitor_rules:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeJobMonitorRuleResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        result['MonitorRules'] = []
        if self.monitor_rules is not None:
            for k in self.monitor_rules:
                result['MonitorRules'].append(k.to_map() if k else None)
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.topics is not None:
            result['Topics'] = self.topics
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        self.monitor_rules = []
        if m.get('MonitorRules') is not None:
            for k in m.get('MonitorRules'):
                temp_model = DescribeJobMonitorRuleResponseBodyMonitorRules()
                self.monitor_rules.append(temp_model.from_map(k))
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('Topics') is not None:
            self.topics = m.get('Topics')
        return self


class DescribeJobMonitorRuleResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeJobMonitorRuleResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeJobMonitorRuleResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeJobMonitorRuleResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeMetricListRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, dts_job_id=None, end_time=None, env=None,
                 metric_name=None, metric_type=None, owner_id=None, param=None, period=None, start_time=None):
        # The ID of the Alibaba Cloud account.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the token, but you must make sure that the token is unique among different requests. **The token can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the data migration or synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The timestamp that indicates the end of the time range to query. Unit: milliseconds.
        self.end_time = end_time  # type: long
        # Default value: **ALIYUN**.
        self.env = env  # type: str
        # *   **InternetOut**: the outbound traffic over the Internet. Unit: byte.
        # *   **diskusage_utilization**: the disk usage.
        # *   **IntranetInRate**: the inbound traffic over the internal network. Unit: byte.
        # *   **InternetIn**: the inbound traffic from the Internet. Unit: byte.
        # *   **cpu_total**: the CPU utilization.
        # *   **memory_usedutilization**: the memory usage.
        # *   **IntranetOutRate**: the outbound traffic over the internal network. Unit: byte.
        self.metric_name = metric_name  # type: str
        # Specifies whether to query the metrics of the cluster or a node. Valid values:
        # 
        # *   **CLUSTER**: query the metrics of the cluster.
        # *   **NODE**: query the metrics of a node.
        self.metric_type = metric_type  # type: str
        self.owner_id = owner_id  # type: str
        # The monitored object. If the **MetricType** parameter is set to **NODE**, set this parameter to the ID of the node that is monitored.
        self.param = param  # type: str
        # The monitoring interval. Unit: seconds. Minimum value: 15.
        self.period = period  # type: long
        # The timestamp that indicates the beginning of the time range to query. Unit: milliseconds.
        self.start_time = start_time  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMetricListRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.end_time is not None:
            result['EndTime'] = self.end_time
        if self.env is not None:
            result['Env'] = self.env
        if self.metric_name is not None:
            result['MetricName'] = self.metric_name
        if self.metric_type is not None:
            result['MetricType'] = self.metric_type
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.param is not None:
            result['Param'] = self.param
        if self.period is not None:
            result['Period'] = self.period
        if self.start_time is not None:
            result['StartTime'] = self.start_time
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('EndTime') is not None:
            self.end_time = m.get('EndTime')
        if m.get('Env') is not None:
            self.env = m.get('Env')
        if m.get('MetricName') is not None:
            self.metric_name = m.get('MetricName')
        if m.get('MetricType') is not None:
            self.metric_type = m.get('MetricType')
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('Param') is not None:
            self.param = m.get('Param')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('StartTime') is not None:
            self.start_time = m.get('StartTime')
        return self


class DescribeMetricListResponseBodyDataPoints(TeaModel):
    def __init__(self, statistics=None, timestamp=None):
        # The statistical value.
        self.statistics = statistics  # type: float
        # The timestamp of the record. Unit: milliseconds.
        self.timestamp = timestamp  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMetricListResponseBodyDataPoints, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.statistics is not None:
            result['Statistics'] = self.statistics
        if self.timestamp is not None:
            result['Timestamp'] = self.timestamp
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Statistics') is not None:
            self.statistics = m.get('Statistics')
        if m.get('Timestamp') is not None:
            self.timestamp = m.get('Timestamp')
        return self


class DescribeMetricListResponseBody(TeaModel):
    def __init__(self, code=None, data_points=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, metric_name=None, metric_type=None, param=None, period=None, request_id=None, success=None):
        # The error code returned by the backend service. The number is incremented.
        self.code = code  # type: str
        # The monitoring statistics.
        self.data_points = data_points  # type: list[DescribeMetricListResponseBodyDataPoints]
        # The dynamic part in the error message. This parameter is used to replace the %s variable in the **ErrMessage** parameter.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code returned for an exception.
        self.http_status_code = http_status_code  # type: int
        # *   **InternetOut**: the outbound traffic over the Internet. Unit: byte.
        # *   **diskusage_utilization**: the disk usage.
        # *   **IntranetInRate**: the inbound traffic over the internal network. Unit: byte.
        # *   **InternetIn**: the inbound traffic from the Internet. Unit: byte.
        # *   **cpu_total**: the CPU utilization.
        # *   **memory_usedutilization**: the memory usage.
        # *   **IntranetOutRate**: the outbound traffic over the internal network. Unit: byte.
        self.metric_name = metric_name  # type: str
        # Indicates whether the metrics of the cluster or a node are queried. Valid values:
        # 
        # *   **CLUSTER**: The metrics of the cluster are queried.
        # *   **NODE**: The metrics of a node are queried.
        self.metric_type = metric_type  # type: str
        # The monitored object.
        # 
        # *   If the **MetricType** parameter is set to **NODE**, the value of this parameter is the ID of the node that is monitored.****\
        # *   If the **MetricType** parameter is set to **CLUSTER**, the value of this parameter is the ID of the dedicated cluster. You can obtain the ID by calling the ListDedicatedCluster operation.
        self.param = param  # type: str
        # The monitoring interval. Unit: seconds. Minimum value: 15.
        self.period = period  # type: long
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool

    def validate(self):
        if self.data_points:
            for k in self.data_points:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMetricListResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        result['DataPoints'] = []
        if self.data_points is not None:
            for k in self.data_points:
                result['DataPoints'].append(k.to_map() if k else None)
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.metric_name is not None:
            result['MetricName'] = self.metric_name
        if self.metric_type is not None:
            result['MetricType'] = self.metric_type
        if self.param is not None:
            result['Param'] = self.param
        if self.period is not None:
            result['Period'] = self.period
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        self.data_points = []
        if m.get('DataPoints') is not None:
            for k in m.get('DataPoints'):
                temp_model = DescribeMetricListResponseBodyDataPoints()
                self.data_points.append(temp_model.from_map(k))
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('MetricName') is not None:
            self.metric_name = m.get('MetricName')
        if m.get('MetricType') is not None:
            self.metric_type = m.get('MetricType')
        if m.get('Param') is not None:
            self.param = m.get('Param')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeMetricListResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeMetricListResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeMetricListResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeMetricListResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeMigrationJobAlertRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that it is unique among different requests. The token can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query the instance ID.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobAlertRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeMigrationJobAlertResponseBody(TeaModel):
    def __init__(self, delay_alert_phone=None, delay_alert_status=None, delay_over_seconds=None, err_code=None,
                 err_message=None, error_alert_phone=None, error_alert_status=None, migration_job_id=None,
                 migration_job_name=None, request_id=None, success=None):
        # The mobile phone numbers that receive latency-related alerts.
        self.delay_alert_phone = delay_alert_phone  # type: str
        # Indicates whether task latency is monitored. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        self.delay_alert_status = delay_alert_status  # type: str
        # The threshold for triggering latency alerts. Unit: seconds.
        self.delay_over_seconds = delay_over_seconds  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The mobile phone numbers that receive status-related alerts.
        self.error_alert_phone = error_alert_phone  # type: str
        # Indicates whether task status is monitored. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        self.error_alert_status = error_alert_status  # type: str
        # The ID of the data migration instance.
        self.migration_job_id = migration_job_id  # type: str
        # The name of the data migration task.
        self.migration_job_name = migration_job_name  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobAlertResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay_alert_phone is not None:
            result['DelayAlertPhone'] = self.delay_alert_phone
        if self.delay_alert_status is not None:
            result['DelayAlertStatus'] = self.delay_alert_status
        if self.delay_over_seconds is not None:
            result['DelayOverSeconds'] = self.delay_over_seconds
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_alert_phone is not None:
            result['ErrorAlertPhone'] = self.error_alert_phone
        if self.error_alert_status is not None:
            result['ErrorAlertStatus'] = self.error_alert_status
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.migration_job_name is not None:
            result['MigrationJobName'] = self.migration_job_name
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DelayAlertPhone') is not None:
            self.delay_alert_phone = m.get('DelayAlertPhone')
        if m.get('DelayAlertStatus') is not None:
            self.delay_alert_status = m.get('DelayAlertStatus')
        if m.get('DelayOverSeconds') is not None:
            self.delay_over_seconds = m.get('DelayOverSeconds')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorAlertPhone') is not None:
            self.error_alert_phone = m.get('ErrorAlertPhone')
        if m.get('ErrorAlertStatus') is not None:
            self.error_alert_status = m.get('ErrorAlertStatus')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('MigrationJobName') is not None:
            self.migration_job_name = m.get('MigrationJobName')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeMigrationJobAlertResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeMigrationJobAlertResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobAlertResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeMigrationJobAlertResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeMigrationJobDetailRequestMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, structure_initialization=None):
        # Specifies whether to query the details of full data migration. Valid values:
        # 
        # *   **true**: yes
        # 
        # *   **false**: no
        # 
        # > Default value: **false**\
        self.data_initialization = data_initialization  # type: bool
        # Specifies whether to query the details of incremental data migration. Valid values:
        # 
        # *   **true**: yes
        # 
        # *   **false**: no
        # 
        # > Default value: **false**\
        self.data_synchronization = data_synchronization  # type: bool
        # Specifies whether to query the details of schema migration. Valid values:
        # 
        # *   **true**: yes
        # 
        # *   **false**: no
        # 
        # > Default value: **false**\
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobDetailRequestMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeMigrationJobDetailRequest(TeaModel):
    def __init__(self, migration_mode=None, account_id=None, client_token=None, migration_job_id=None,
                 owner_id=None, page_num=None, page_size=None, region_id=None):
        self.migration_mode = migration_mode  # type: DescribeMigrationJobDetailRequestMigrationMode
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that the value is unique among different requests. The **ClientToken** value can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query the instance ID.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_num = page_num  # type: int
        # The number of entries to return on each page. Valid values: **30**, **50**, and **100**. Default value: **30**.
        self.page_size = page_size  # type: int
        # The ID of the region where the data migration instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        if self.migration_mode:
            self.migration_mode.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_num is not None:
            result['PageNum'] = self.page_num
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('MigrationMode') is not None:
            temp_model = DescribeMigrationJobDetailRequestMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNum') is not None:
            self.page_num = m.get('PageNum')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeMigrationJobDetailResponseBodyDataInitializationDetailListDataInitializationDetail(TeaModel):
    def __init__(self, destination_owner_dbname=None, error_message=None, finish_row_num=None, migration_time=None,
                 source_owner_dbname=None, status=None, table_name=None, total_row_num=None):
        # The name of the database to which the migration object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if full data migration failed.
        self.error_message = error_message  # type: str
        # The number of records that have been migrated.
        self.finish_row_num = finish_row_num  # type: str
        # The time taken by full data migration.
        self.migration_time = migration_time  # type: str
        # The name of the database to which the migration object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of full data migration. Valid values:
        # 
        # - **NotStarted**: Full data migration is not started.
        # - **Migrating**: Full data migration is in progress.
        # - **Failed**: Full data migration failed.
        # - **Finished**: Full data migration is completed.
        self.status = status  # type: str
        # The table name.
        self.table_name = table_name  # type: str
        # The total number of records that are supposed to be migrated by the task.
        self.total_row_num = total_row_num  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyDataInitializationDetailListDataInitializationDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.finish_row_num is not None:
            result['FinishRowNum'] = self.finish_row_num
        if self.migration_time is not None:
            result['MigrationTime'] = self.migration_time
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        if self.table_name is not None:
            result['TableName'] = self.table_name
        if self.total_row_num is not None:
            result['TotalRowNum'] = self.total_row_num
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('FinishRowNum') is not None:
            self.finish_row_num = m.get('FinishRowNum')
        if m.get('MigrationTime') is not None:
            self.migration_time = m.get('MigrationTime')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        if m.get('TotalRowNum') is not None:
            self.total_row_num = m.get('TotalRowNum')
        return self


class DescribeMigrationJobDetailResponseBodyDataInitializationDetailList(TeaModel):
    def __init__(self, data_initialization_detail=None):
        self.data_initialization_detail = data_initialization_detail  # type: list[DescribeMigrationJobDetailResponseBodyDataInitializationDetailListDataInitializationDetail]

    def validate(self):
        if self.data_initialization_detail:
            for k in self.data_initialization_detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyDataInitializationDetailList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DataInitializationDetail'] = []
        if self.data_initialization_detail is not None:
            for k in self.data_initialization_detail:
                result['DataInitializationDetail'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.data_initialization_detail = []
        if m.get('DataInitializationDetail') is not None:
            for k in m.get('DataInitializationDetail'):
                temp_model = DescribeMigrationJobDetailResponseBodyDataInitializationDetailListDataInitializationDetail()
                self.data_initialization_detail.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailListDataSynchronizationDetail(TeaModel):
    def __init__(self, destination_owner_dbname=None, error_message=None, source_owner_dbname=None, status=None,
                 table_name=None):
        # The name of the database to which the migration object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if incremental data migration failed.
        self.error_message = error_message  # type: str
        # The name of the database to which the migration object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of incremental data migration. Valid values:
        # 
        # *   **NotStarted**: Incremental data migration is not started.
        # *   **Migrating**: Incremental data migration is in progress.
        # *   **Failed**: Incremental data migration failed.
        # *   **Finished**: Incremental data migration is completed.
        self.status = status  # type: str
        # The table name.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailListDataSynchronizationDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailList(TeaModel):
    def __init__(self, data_synchronization_detail=None):
        self.data_synchronization_detail = data_synchronization_detail  # type: list[DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailListDataSynchronizationDetail]

    def validate(self):
        if self.data_synchronization_detail:
            for k in self.data_synchronization_detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DataSynchronizationDetail'] = []
        if self.data_synchronization_detail is not None:
            for k in self.data_synchronization_detail:
                result['DataSynchronizationDetail'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.data_synchronization_detail = []
        if m.get('DataSynchronizationDetail') is not None:
            for k in m.get('DataSynchronizationDetail'):
                temp_model = DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailListDataSynchronizationDetail()
                self.data_synchronization_detail.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintListStructureInitializationDetail(TeaModel):
    def __init__(self, destination_owner_dbname=None, error_message=None, object_definition=None, object_name=None,
                 object_type=None, source_owner_dbname=None, status=None):
        # The name of the database to which the migration object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if constraints failed to be created.
        self.error_message = error_message  # type: str
        # The syntax to create constraints.
        self.object_definition = object_definition  # type: str
        # The name of migration object.
        self.object_name = object_name  # type: str
        # The type of the migration object. The value is **Table**.
        self.object_type = object_type  # type: str
        # The name of the database to which the migration object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of constraint creation. Valid values:
        # 
        # - **NotStarted**\
        # - **Migrating**\
        # - **Failed**\
        # - **Finished**\
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintListStructureInitializationDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.object_definition is not None:
            result['ObjectDefinition'] = self.object_definition
        if self.object_name is not None:
            result['ObjectName'] = self.object_name
        if self.object_type is not None:
            result['ObjectType'] = self.object_type
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ObjectDefinition') is not None:
            self.object_definition = m.get('ObjectDefinition')
        if m.get('ObjectName') is not None:
            self.object_name = m.get('ObjectName')
        if m.get('ObjectType') is not None:
            self.object_type = m.get('ObjectType')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintList(TeaModel):
    def __init__(self, structure_initialization_detail=None):
        self.structure_initialization_detail = structure_initialization_detail  # type: list[DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintListStructureInitializationDetail]

    def validate(self):
        if self.structure_initialization_detail:
            for k in self.structure_initialization_detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['StructureInitializationDetail'] = []
        if self.structure_initialization_detail is not None:
            for k in self.structure_initialization_detail:
                result['StructureInitializationDetail'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.structure_initialization_detail = []
        if m.get('StructureInitializationDetail') is not None:
            for k in m.get('StructureInitializationDetail'):
                temp_model = DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintListStructureInitializationDetail()
                self.structure_initialization_detail.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetail(TeaModel):
    def __init__(self, constraint_list=None, destination_owner_dbname=None, error_message=None,
                 object_definition=None, object_name=None, object_type=None, source_owner_dbname=None, status=None):
        # The constraints of the migration object, such as indexes and foreign keys. 
        # 
        # >  This parameter is returned only if the **ObjectType** parameter is set to **Table** and the migration object has constraints.
        self.constraint_list = constraint_list  # type: DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintList
        # The name of the database to which the migration object in the destination instance belongs.
        self.destination_owner_dbname = destination_owner_dbname  # type: str
        # The error message returned if schema migration failed.
        self.error_message = error_message  # type: str
        # The schema of the migration object.
        self.object_definition = object_definition  # type: str
        # The name of migration object.
        self.object_name = object_name  # type: str
        # The type of the migration object. Valid values: **Table**, **Constraint**, **Index**, **View**, **Materialize View**, **Type**, **Synonym**, **Trigger**, **Function**, **Procedure**, **Package**, **Default**, **Rule**, **PlanGuide**, and **Sequence**.
        self.object_type = object_type  # type: str
        # The name of the database to which the migration object in the source instance belongs.
        self.source_owner_dbname = source_owner_dbname  # type: str
        # The status of schema migration. Valid values:
        # 
        # - **NotStarted**: Schema migration is not started.
        # - **Migrating**: Schema migration is in progress.
        # - **Failed**: Schema migration failed.
        # - **Finished**: Schema migration is completed.
        self.status = status  # type: str

    def validate(self):
        if self.constraint_list:
            self.constraint_list.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.constraint_list is not None:
            result['ConstraintList'] = self.constraint_list.to_map()
        if self.destination_owner_dbname is not None:
            result['DestinationOwnerDBName'] = self.destination_owner_dbname
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.object_definition is not None:
            result['ObjectDefinition'] = self.object_definition
        if self.object_name is not None:
            result['ObjectName'] = self.object_name
        if self.object_type is not None:
            result['ObjectType'] = self.object_type
        if self.source_owner_dbname is not None:
            result['SourceOwnerDBName'] = self.source_owner_dbname
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConstraintList') is not None:
            temp_model = DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetailConstraintList()
            self.constraint_list = temp_model.from_map(m['ConstraintList'])
        if m.get('DestinationOwnerDBName') is not None:
            self.destination_owner_dbname = m.get('DestinationOwnerDBName')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ObjectDefinition') is not None:
            self.object_definition = m.get('ObjectDefinition')
        if m.get('ObjectName') is not None:
            self.object_name = m.get('ObjectName')
        if m.get('ObjectType') is not None:
            self.object_type = m.get('ObjectType')
        if m.get('SourceOwnerDBName') is not None:
            self.source_owner_dbname = m.get('SourceOwnerDBName')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobDetailResponseBodyStructureInitializationDetailList(TeaModel):
    def __init__(self, structure_initialization_detail=None):
        self.structure_initialization_detail = structure_initialization_detail  # type: list[DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetail]

    def validate(self):
        if self.structure_initialization_detail:
            for k in self.structure_initialization_detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBodyStructureInitializationDetailList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['StructureInitializationDetail'] = []
        if self.structure_initialization_detail is not None:
            for k in self.structure_initialization_detail:
                result['StructureInitializationDetail'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.structure_initialization_detail = []
        if m.get('StructureInitializationDetail') is not None:
            for k in m.get('StructureInitializationDetail'):
                temp_model = DescribeMigrationJobDetailResponseBodyStructureInitializationDetailListStructureInitializationDetail()
                self.structure_initialization_detail.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobDetailResponseBody(TeaModel):
    def __init__(self, data_initialization_detail_list=None, data_synchronization_detail_list=None, err_code=None,
                 err_message=None, page_number=None, page_record_count=None, request_id=None,
                 structure_initialization_detail_list=None, success=None, total_record_count=None):
        # The details of full data migration.
        self.data_initialization_detail_list = data_initialization_detail_list  # type: DescribeMigrationJobDetailResponseBodyDataInitializationDetailList
        # The details of incremental data migration.
        self.data_synchronization_detail_list = data_synchronization_detail_list  # type: DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailList
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The maximum number of data migration instances that can be displayed on one page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The details of schema migration.
        self.structure_initialization_detail_list = structure_initialization_detail_list  # type: DescribeMigrationJobDetailResponseBodyStructureInitializationDetailList
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The total number of entries that are returned.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.data_initialization_detail_list:
            self.data_initialization_detail_list.validate()
        if self.data_synchronization_detail_list:
            self.data_synchronization_detail_list.validate()
        if self.structure_initialization_detail_list:
            self.structure_initialization_detail_list.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization_detail_list is not None:
            result['DataInitializationDetailList'] = self.data_initialization_detail_list.to_map()
        if self.data_synchronization_detail_list is not None:
            result['DataSynchronizationDetailList'] = self.data_synchronization_detail_list.to_map()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.structure_initialization_detail_list is not None:
            result['StructureInitializationDetailList'] = self.structure_initialization_detail_list.to_map()
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitializationDetailList') is not None:
            temp_model = DescribeMigrationJobDetailResponseBodyDataInitializationDetailList()
            self.data_initialization_detail_list = temp_model.from_map(m['DataInitializationDetailList'])
        if m.get('DataSynchronizationDetailList') is not None:
            temp_model = DescribeMigrationJobDetailResponseBodyDataSynchronizationDetailList()
            self.data_synchronization_detail_list = temp_model.from_map(m['DataSynchronizationDetailList'])
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('StructureInitializationDetailList') is not None:
            temp_model = DescribeMigrationJobDetailResponseBodyStructureInitializationDetailList()
            self.structure_initialization_detail_list = temp_model.from_map(m['StructureInitializationDetailList'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeMigrationJobDetailResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeMigrationJobDetailResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobDetailResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeMigrationJobDetailResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeMigrationJobStatusRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that the value is unique among different requests. The **ClientToken** value can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query the instance ID.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class DescribeMigrationJobStatusResponseBodyDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if full data migration failed.
        self.error_message = error_message  # type: str
        # The migration progress. Unit: %.
        self.percent = percent  # type: str
        # The number of records that have been migrated during full data migration.
        self.progress = progress  # type: str
        # The status of full data migration. Valid values:
        # 
        # *   **NotStarted**: Full data migration is not started.
        # *   **Migrating**: Full data migration is in progress.
        # *   **Failed**: Full data migration failed.
        # *   **Finished**: Full data migration is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobStatusResponseBodyDataSynchronizationStatus(TeaModel):
    def __init__(self, checkpoint=None, delay=None, error_message=None, percent=None, status=None):
        # The UNIX timestamp generated when the latest incremental data is migrated. Unit: seconds.
        self.checkpoint = checkpoint  # type: str
        # The latency of incremental data migration. Unit: seconds.
        self.delay = delay  # type: str
        # The error message returned if incremental data migration failed.
        self.error_message = error_message  # type: str
        # The progress of incremental data migration. Unit: %.
        self.percent = percent  # type: str
        # The status of incremental data migration. Valid values:
        # 
        # *   **NotStarted**: Incremental data migration is not started.
        # *   **Migrating**: Incremental data migration is in progress.
        # *   **Failed**: Incremental data migration failed.
        # *   **Finished**: Incremental data migration is completed.
        # *   **Catched**: Incremental data migration is not delayed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobStatusResponseBodyDestinationEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, ip=None, instance_id=None, instance_type=None,
                 port=None, user_name=None, oracle_sid=None):
        # The name of the database to which the migration object in the destination instance belongs.
        self.database_name = database_name  # type: str
        # The database type of the destination instance.
        self.engine_name = engine_name  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The database service port of the destination instance.
        self.port = port  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str
        # The system ID (SID) of the Oracle database.
        # 
        # >  This parameter is returned only if the database type of the destination instance is **Oracle**.
        self.oracle_sid = oracle_sid  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        if self.oracle_sid is not None:
            result['oracleSID'] = self.oracle_sid
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        if m.get('oracleSID') is not None:
            self.oracle_sid = m.get('oracleSID')
        return self


class DescribeMigrationJobStatusResponseBodyMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, structure_initialization=None):
        # Indicates whether full data migration is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_initialization = data_initialization  # type: bool
        # Indicates whether incremental data migration is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether schema migration is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['dataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['dataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['structureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('dataInitialization') is not None:
            self.data_initialization = m.get('dataInitialization')
        if m.get('dataSynchronization') is not None:
            self.data_synchronization = m.get('dataSynchronization')
        if m.get('structureInitialization') is not None:
            self.structure_initialization = m.get('structureInitialization')
        return self


class DescribeMigrationJobStatusResponseBodyPrecheckStatusDetailCheckItem(TeaModel):
    def __init__(self, check_status=None, error_message=None, item_name=None, repair_method=None):
        # The precheck result. Valid values:
        # 
        # *   **Success**: The task passed the precheck.
        # *   **Failed**: The task failed to pass the precheck.
        self.check_status = check_status  # type: str
        # The error message returned if the task failed to pass the precheck.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.error_message = error_message  # type: str
        # The name of the precheck item.
        self.item_name = item_name  # type: str
        # The method to fix the precheck failure.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyPrecheckStatusDetailCheckItem, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_status is not None:
            result['CheckStatus'] = self.check_status
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.item_name is not None:
            result['ItemName'] = self.item_name
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckStatus') is not None:
            self.check_status = m.get('CheckStatus')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ItemName') is not None:
            self.item_name = m.get('ItemName')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeMigrationJobStatusResponseBodyPrecheckStatusDetail(TeaModel):
    def __init__(self, check_item=None):
        self.check_item = check_item  # type: list[DescribeMigrationJobStatusResponseBodyPrecheckStatusDetailCheckItem]

    def validate(self):
        if self.check_item:
            for k in self.check_item:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['CheckItem'] = []
        if self.check_item is not None:
            for k in self.check_item:
                result['CheckItem'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.check_item = []
        if m.get('CheckItem') is not None:
            for k in m.get('CheckItem'):
                temp_model = DescribeMigrationJobStatusResponseBodyPrecheckStatusDetailCheckItem()
                self.check_item.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobStatusResponseBodyPrecheckStatus(TeaModel):
    def __init__(self, detail=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: DescribeMigrationJobStatusResponseBodyPrecheckStatusDetail
        # The precheck progress. Unit: %.
        self.percent = percent  # type: str
        # The precheck status. Valid values:
        # 
        # *   **NotStarted**\
        # *   **Suspending**:
        # *   **Checking**\
        # *   **Failed**\
        # *   **Finished**\
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            self.detail.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.detail is not None:
            result['Detail'] = self.detail.to_map()
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Detail') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyPrecheckStatusDetail()
            self.detail = temp_model.from_map(m['Detail'])
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobStatusResponseBodySourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, ip=None, instance_id=None, instance_type=None,
                 port=None, user_name=None, oracle_sid=None):
        # The name of the database to which the migration object in the source instance belongs.
        self.database_name = database_name  # type: str
        # The database type of the source instance.
        self.engine_name = engine_name  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        # 
        # *   **RDS**: ApsaraDB RDS instance
        # *   **ECS**: self-managed database that is hosted on Elastic Compute Service (ECS)
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **Express**: self-managed database that is connected over Express Connect, VPN Gateway, or Smart Access Gateway
        # *   **MongoDB**: ApsaraDB for MongoDB instance
        # *   **POLARDB**: PolarDB for MySQL cluster (available only for the China site)
        self.instance_type = instance_type  # type: str
        # The database service port of the source instance.
        self.port = port  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str
        # The SID of the Oracle database.
        # 
        # >  This parameter is returned only if the database type of the source instance is **Oracle**.
        self.oracle_sid = oracle_sid  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodySourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        if self.oracle_sid is not None:
            result['oracleSID'] = self.oracle_sid
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        if m.get('oracleSID') is not None:
            self.oracle_sid = m.get('oracleSID')
        return self


class DescribeMigrationJobStatusResponseBodyStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if schema migration failed.
        self.error_message = error_message  # type: str
        # The progress of schema migration. Unit: %.
        self.percent = percent  # type: str
        # The number of tables whose schemas have been migrated.
        self.progress = progress  # type: str
        # The status of schema migration. Valid values:
        # 
        # *   **NotStarted**: Schema migration is not started.
        # *   **Migrating**: Schema migration is in progress.
        # *   **Failed**: Schema migration failed.
        # *   **Finished**: Schema migration is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBodyStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobStatusResponseBody(TeaModel):
    def __init__(self, data_initialization_status=None, data_synchronization_status=None,
                 destination_endpoint=None, err_code=None, err_message=None, migration_job_class=None, migration_job_id=None,
                 migration_job_name=None, migration_job_status=None, migration_mode=None, migration_object=None, pay_type=None,
                 precheck_status=None, request_id=None, source_endpoint=None, structure_initialization_status=None, success=None,
                 task_id=None):
        # The status of full data migration.
        self.data_initialization_status = data_initialization_status  # type: DescribeMigrationJobStatusResponseBodyDataInitializationStatus
        # The status of incremental data migration.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeMigrationJobStatusResponseBodyDataSynchronizationStatus
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeMigrationJobStatusResponseBodyDestinationEndpoint
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The specification of the data migration instance. Valid values: **small**, **medium**, **large**, **xlarge**, and **2xlarge**. For more information, see [Specifications of data migration instances](~~26606~~).
        self.migration_job_class = migration_job_class  # type: str
        # The ID of the data migration instance.
        self.migration_job_id = migration_job_id  # type: str
        # The name of the data migration task.
        self.migration_job_name = migration_job_name  # type: str
        # The status of the data migration task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Migrating**: The task is migrating data.
        # *   **Suspending**: The task is paused.
        # *   **MigrationFailed**: The task failed to migrate data.
        # *   **Finished**: The task is completed.
        self.migration_job_status = migration_job_status  # type: str
        # The migration types.
        self.migration_mode = migration_mode  # type: DescribeMigrationJobStatusResponseBodyMigrationMode
        # The objects that are migrated by the task.
        self.migration_object = migration_object  # type: str
        # The billing method of the data migration instance. The value is **PostPaid** (pay-as-you-go).
        self.pay_type = pay_type  # type: str
        # The precheck details.
        self.precheck_status = precheck_status  # type: DescribeMigrationJobStatusResponseBodyPrecheckStatus
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeMigrationJobStatusResponseBodySourceEndpoint
        # The status of schema migration.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeMigrationJobStatusResponseBodyStructureInitializationStatus
        # Indicates whether the call was successful.
        self.success = success  # type: str
        self.task_id = task_id  # type: str

    def validate(self):
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.migration_job_class is not None:
            result['MigrationJobClass'] = self.migration_job_class
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.migration_job_name is not None:
            result['MigrationJobName'] = self.migration_job_name
        if self.migration_job_status is not None:
            result['MigrationJobStatus'] = self.migration_job_status
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.migration_object is not None:
            result['MigrationObject'] = self.migration_object
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.success is not None:
            result['Success'] = self.success
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('MigrationJobClass') is not None:
            self.migration_job_class = m.get('MigrationJobClass')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('MigrationJobName') is not None:
            self.migration_job_name = m.get('MigrationJobName')
        if m.get('MigrationJobStatus') is not None:
            self.migration_job_status = m.get('MigrationJobStatus')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('MigrationObject') is not None:
            self.migration_object = m.get('MigrationObject')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodySourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeMigrationJobStatusResponseBodyStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class DescribeMigrationJobStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeMigrationJobStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeMigrationJobStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeMigrationJobsRequestTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The tag key. You can call the [ListTagResources](~~191187~~) operation to query the tag key.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Key specifies the key of the first tag and Tag.2.Key specifies the key of the second tag. You can specify 1 to 20 tag keys at a time.
        # *   This parameter cannot be an empty string.
        self.key = key  # type: str
        # The tag value. You can call the [ListTagResources](~~191187~~) operation to query the tag value.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Value specifies the value of the first tag and Tag.2.Value specifies the value of the second tag. You can specify 1 to 20 tag values at a time.
        # *   This parameter can be an empty string.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsRequestTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class DescribeMigrationJobsRequest(TeaModel):
    def __init__(self, account_id=None, migration_job_name=None, owner_id=None, page_num=None, page_size=None,
                 region_id=None, tag=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The name of the data migration task.
        # 
        # >  Fuzzy match is supported.
        self.migration_job_name = migration_job_name  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_num = page_num  # type: int
        # The number of entries to return on each page. Valid values: **30**, **50**, and **100**. Default value: **30**.
        self.page_size = page_size  # type: int
        # The ID of the region where the data migration instances reside. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        self.tag = tag  # type: list[DescribeMigrationJobsRequestTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.migration_job_name is not None:
            result['MigrationJobName'] = self.migration_job_name
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_num is not None:
            result['PageNum'] = self.page_num
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('MigrationJobName') is not None:
            self.migration_job_name = m.get('MigrationJobName')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNum') is not None:
            self.page_num = m.get('PageNum')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = DescribeMigrationJobsRequestTag()
                self.tag.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataInitialization(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if full data migration failed.
        self.error_message = error_message  # type: str
        # The migration progress. Unit: %.
        self.percent = percent  # type: str
        # The number of records that have been migrated during full data migration.
        self.progress = progress  # type: str
        # The status of full data migration. Valid values:
        # 
        # *   **NotStarted**: Full data migration is not started.
        # *   **Migrating**: Full data migration is in progress.
        # *   **Failed**: Full data migration failed.
        # *   **Finished**: Full data migration is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataInitialization, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('status') is not None:
            self.status = m.get('status')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataSynchronization(TeaModel):
    def __init__(self, delay=None, error_message=None, percent=None, status=None):
        # The latency of incremental data migration. Unit: seconds.
        self.delay = delay  # type: str
        # The error message returned if incremental data migration failed.
        self.error_message = error_message  # type: str
        # The progress of incremental data migration. Unit: %.
        self.percent = percent  # type: str
        # The status of incremental data migration. Valid values:
        # 
        # *   **NotStarted**: Incremental data migration is not started.
        # *   **Migrating**: Incremental data migration is in progress.
        # *   **Failed**: Incremental data migration failed.
        # *   **Finished**: Incremental data migration is completed.
        # *   **Catched**: Incremental data migration is not delayed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataSynchronization, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('status') is not None:
            self.status = m.get('status')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDestinationEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, ip=None, instance_id=None, instance_type=None,
                 oracle_sid=None, port=None, user_name=None):
        # The name of the database to which the migration object in the destination instance belongs.
        self.database_name = database_name  # type: str
        # The database type of the destination instance.
        self.engine_name = engine_name  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # This parameter is returned only if the database type of the destination instance is **Oracle**.
        self.oracle_sid = oracle_sid  # type: str
        # The database service port of the destination instance.
        self.port = port  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationMode(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, structure_initialization=None):
        # Indicates whether full data migration is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_initialization = data_initialization  # type: bool
        # Indicates whether incremental data migration is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_synchronization = data_synchronization  # type: bool
        # Indicates whether schema migration is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.structure_initialization = structure_initialization  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationMode, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObjectTableList(TeaModel):
    def __init__(self, table=None):
        self.table = table  # type: list[str]

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObjectTableList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table is not None:
            result['Table'] = self.table
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Table') is not None:
            self.table = m.get('Table')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObject(TeaModel):
    def __init__(self, database_name=None, table_list=None, whole_database=None):
        # The name of the database to which the migration object in the source instance belongs.
        self.database_name = database_name  # type: str
        # The names of the migrated tables.
        self.table_list = table_list  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObjectTableList
        # Indicates whether an entire database is migrated. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.whole_database = whole_database  # type: str

    def validate(self):
        if self.table_list:
            self.table_list.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObject, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.table_list is not None:
            result['TableList'] = self.table_list.to_map()
        if self.whole_database is not None:
            result['WholeDatabase'] = self.whole_database
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('TableList') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObjectTableList()
            self.table_list = temp_model.from_map(m['TableList'])
        if m.get('WholeDatabase') is not None:
            self.whole_database = m.get('WholeDatabase')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObject(TeaModel):
    def __init__(self, synchronous_object=None):
        self.synchronous_object = synchronous_object  # type: list[DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObject]

    def validate(self):
        if self.synchronous_object:
            for k in self.synchronous_object:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObject, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['SynchronousObject'] = []
        if self.synchronous_object is not None:
            for k in self.synchronous_object:
                result['SynchronousObject'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.synchronous_object = []
        if m.get('SynchronousObject') is not None:
            for k in m.get('SynchronousObject'):
                temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObjectSynchronousObject()
                self.synchronous_object.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobPrecheck(TeaModel):
    def __init__(self, percent=None, status=None):
        # The precheck progress. Unit: %.
        self.percent = percent  # type: str
        # The precheck result. Valid values:
        # 
        # *   **Success**: The task passed the precheck.
        # *   **Failed**: The task failed to pass the precheck.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobPrecheck, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobSourceEndpoint(TeaModel):
    def __init__(self, database_name=None, engine_name=None, ip=None, instance_id=None, instance_type=None,
                 oracle_sid=None, port=None, user_name=None):
        # The name of the database to which the migration object in the source instance belongs.
        self.database_name = database_name  # type: str
        # The database type of the source instance.
        self.engine_name = engine_name  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        self.instance_type = instance_type  # type: str
        # This parameter is returned only if the database type of the source instance is **Oracle**.
        self.oracle_sid = oracle_sid  # type: str
        # The database service port of the source instance.
        self.port = port  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.oracle_sid is not None:
            result['OracleSID'] = self.oracle_sid
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('OracleSID') is not None:
            self.oracle_sid = m.get('OracleSID')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobStructureInitialization(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if schema migration failed.
        self.error_message = error_message  # type: str
        # The progress of schema migration. Unit: %.
        self.percent = percent  # type: str
        # The number of tables whose schemas have been migrated.
        self.progress = progress  # type: str
        # The status of schema migration. Valid values:
        # 
        # *   **NotStarted**: Schema migration is not started.
        # *   **Migrating**: Schema migration is in progress.
        # *   **Failed**: Schema migration failed.
        # *   **Finished**: Schema migration is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobStructureInitialization, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('status') is not None:
            self.status = m.get('status')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTagsTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The tag key.
        self.key = key  # type: str
        # The tag value that corresponds to the tag key.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTagsTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTags(TeaModel):
    def __init__(self, tag=None):
        self.tag = tag  # type: list[DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTagsTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTags, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTagsTag()
                self.tag.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobsResponseBodyMigrationJobsMigrationJob(TeaModel):
    def __init__(self, data_initialization=None, data_synchronization=None, destination_endpoint=None,
                 instance_create_time=None, job_create_time=None, migration_job_class=None, migration_job_id=None,
                 migration_job_name=None, migration_job_status=None, migration_mode=None, migration_object=None, pay_type=None,
                 precheck=None, source_endpoint=None, structure_initialization=None, tags=None):
        # The details of full data migration.
        self.data_initialization = data_initialization  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataInitialization
        # The details of incremental data migration.
        self.data_synchronization = data_synchronization  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataSynchronization
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDestinationEndpoint
        # The time when the data migration instance was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.instance_create_time = instance_create_time  # type: str
        # The time when the data migration task was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.job_create_time = job_create_time  # type: str
        # The specification of the data migration instance. Valid values: **small**, **medium**, **large**, **xlarge**, and **2xlarge**. For more information, see [Specifications of data migration instances](~~26606~~).
        self.migration_job_class = migration_job_class  # type: str
        # The ID of the data migration instance.
        self.migration_job_id = migration_job_id  # type: str
        # The name of the data migration task.
        self.migration_job_name = migration_job_name  # type: str
        # The status of the data migration task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Migrating**: The task is migrating data.
        # *   **Suspending**: The task is paused.
        # *   **MigrationFailed**: The task failed to migrate data.
        # *   **Finished**: The task is completed.
        self.migration_job_status = migration_job_status  # type: str
        # The migration types.
        self.migration_mode = migration_mode  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationMode
        # The objects that are migrated by the task.
        self.migration_object = migration_object  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObject
        # The billing method of the data migration instance. The value is **PostPaid** (pay-as-you-go).
        self.pay_type = pay_type  # type: str
        # The precheck details.
        self.precheck = precheck  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobPrecheck
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobSourceEndpoint
        # The details of schema migration.
        self.structure_initialization = structure_initialization  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobStructureInitialization
        # The collection of tags.
        self.tags = tags  # type: DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTags

    def validate(self):
        if self.data_initialization:
            self.data_initialization.validate()
        if self.data_synchronization:
            self.data_synchronization.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.migration_mode:
            self.migration_mode.validate()
        if self.migration_object:
            self.migration_object.validate()
        if self.precheck:
            self.precheck.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization:
            self.structure_initialization.validate()
        if self.tags:
            self.tags.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobsMigrationJob, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization.to_map()
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization.to_map()
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.instance_create_time is not None:
            result['InstanceCreateTime'] = self.instance_create_time
        if self.job_create_time is not None:
            result['JobCreateTime'] = self.job_create_time
        if self.migration_job_class is not None:
            result['MigrationJobClass'] = self.migration_job_class
        if self.migration_job_id is not None:
            result['MigrationJobID'] = self.migration_job_id
        if self.migration_job_name is not None:
            result['MigrationJobName'] = self.migration_job_name
        if self.migration_job_status is not None:
            result['MigrationJobStatus'] = self.migration_job_status
        if self.migration_mode is not None:
            result['MigrationMode'] = self.migration_mode.to_map()
        if self.migration_object is not None:
            result['MigrationObject'] = self.migration_object.to_map()
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.precheck is not None:
            result['Precheck'] = self.precheck.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization.to_map()
        if self.tags is not None:
            result['Tags'] = self.tags.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitialization') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataInitialization()
            self.data_initialization = temp_model.from_map(m['DataInitialization'])
        if m.get('DataSynchronization') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDataSynchronization()
            self.data_synchronization = temp_model.from_map(m['DataSynchronization'])
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('InstanceCreateTime') is not None:
            self.instance_create_time = m.get('InstanceCreateTime')
        if m.get('JobCreateTime') is not None:
            self.job_create_time = m.get('JobCreateTime')
        if m.get('MigrationJobClass') is not None:
            self.migration_job_class = m.get('MigrationJobClass')
        if m.get('MigrationJobID') is not None:
            self.migration_job_id = m.get('MigrationJobID')
        if m.get('MigrationJobName') is not None:
            self.migration_job_name = m.get('MigrationJobName')
        if m.get('MigrationJobStatus') is not None:
            self.migration_job_status = m.get('MigrationJobStatus')
        if m.get('MigrationMode') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationMode()
            self.migration_mode = temp_model.from_map(m['MigrationMode'])
        if m.get('MigrationObject') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobMigrationObject()
            self.migration_object = temp_model.from_map(m['MigrationObject'])
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Precheck') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobPrecheck()
            self.precheck = temp_model.from_map(m['Precheck'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('StructureInitialization') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobStructureInitialization()
            self.structure_initialization = temp_model.from_map(m['StructureInitialization'])
        if m.get('Tags') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJobTags()
            self.tags = temp_model.from_map(m['Tags'])
        return self


class DescribeMigrationJobsResponseBodyMigrationJobs(TeaModel):
    def __init__(self, migration_job=None):
        self.migration_job = migration_job  # type: list[DescribeMigrationJobsResponseBodyMigrationJobsMigrationJob]

    def validate(self):
        if self.migration_job:
            for k in self.migration_job:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBodyMigrationJobs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['MigrationJob'] = []
        if self.migration_job is not None:
            for k in self.migration_job:
                result['MigrationJob'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.migration_job = []
        if m.get('MigrationJob') is not None:
            for k in m.get('MigrationJob'):
                temp_model = DescribeMigrationJobsResponseBodyMigrationJobsMigrationJob()
                self.migration_job.append(temp_model.from_map(k))
        return self


class DescribeMigrationJobsResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, migration_jobs=None, page_number=None,
                 page_record_count=None, request_id=None, success=None, total_record_count=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The list of data migration instances and the details of each instance.
        self.migration_jobs = migration_jobs  # type: DescribeMigrationJobsResponseBodyMigrationJobs
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The maximum number of entries that can be displayed on the current page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The total number of data migration instances that belong to your Alibaba Cloud account.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.migration_jobs:
            self.migration_jobs.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.migration_jobs is not None:
            result['MigrationJobs'] = self.migration_jobs.to_map()
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('MigrationJobs') is not None:
            temp_model = DescribeMigrationJobsResponseBodyMigrationJobs()
            self.migration_jobs = temp_model.from_map(m['MigrationJobs'])
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeMigrationJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeMigrationJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeMigrationJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeMigrationJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribePreCheckStatusRequest(TeaModel):
    def __init__(self, dts_job_id=None, job_code=None, name=None, page_no=None, page_size=None, region_id=None,
                 struct_phase=None, struct_type=None):
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The task code that specifies the type of the DTS subtask. Valid values:
        # 
        # *   **01**: precheck
        # *   **02**: schema migration or initial schema synchronization
        # *   **03**: full data migration or initial full data synchronization
        # *   **04**: incremental data migration or synchronization
        self.job_code = job_code  # type: str
        # The filter item used to filter tables in fuzzy match.
        self.name = name  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_no = page_no  # type: str
        # The number of entries to return on each page. Default value: **20**.
        self.page_size = page_size  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The filter item used to filter tables, views, and functions during schema migration.
        self.struct_phase = struct_phase  # type: str
        # The type of schema definition. Valid values:
        # 
        # *   **before**: schema migration or initial schema synchronization
        # *   **after**: DDL operations performed during incremental data migration or synchronization
        self.struct_type = struct_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribePreCheckStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.job_code is not None:
            result['JobCode'] = self.job_code
        if self.name is not None:
            result['Name'] = self.name
        if self.page_no is not None:
            result['PageNo'] = self.page_no
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.struct_phase is not None:
            result['StructPhase'] = self.struct_phase
        if self.struct_type is not None:
            result['StructType'] = self.struct_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('JobCode') is not None:
            self.job_code = m.get('JobCode')
        if m.get('Name') is not None:
            self.name = m.get('Name')
        if m.get('PageNo') is not None:
            self.page_no = m.get('PageNo')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('StructPhase') is not None:
            self.struct_phase = m.get('StructPhase')
        if m.get('StructType') is not None:
            self.struct_type = m.get('StructType')
        return self


class DescribePreCheckStatusResponseBodyAnalysisJobProgressLogs(TeaModel):
    def __init__(self, err_data=None, err_msg=None, err_type=None, log_level=None):
        self.err_data = err_data  # type: str
        self.err_msg = err_msg  # type: str
        self.err_type = err_type  # type: str
        self.log_level = log_level  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyAnalysisJobProgressLogs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_data is not None:
            result['ErrData'] = self.err_data
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.err_type is not None:
            result['ErrType'] = self.err_type
        if self.log_level is not None:
            result['LogLevel'] = self.log_level
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrData') is not None:
            self.err_data = m.get('ErrData')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('ErrType') is not None:
            self.err_type = m.get('ErrType')
        if m.get('LogLevel') is not None:
            self.log_level = m.get('LogLevel')
        return self


class DescribePreCheckStatusResponseBodyAnalysisJobProgress(TeaModel):
    def __init__(self, boot_time=None, can_skip=None, current=None, ddl_sql=None, delay_seconds=None,
                 dest_schema=None, diff_row=None, err_detail=None, err_msg=None, finish_time=None, id=None, ignore_flag=None,
                 item=None, job_id=None, logs=None, names=None, order_num=None, parent_obj=None, repair_method=None,
                 skip=None, source_schema=None, state=None, sub=None, target_names=None, total=None):
        self.boot_time = boot_time  # type: str
        self.can_skip = can_skip  # type: bool
        self.current = current  # type: str
        self.ddl_sql = ddl_sql  # type: str
        self.delay_seconds = delay_seconds  # type: int
        self.dest_schema = dest_schema  # type: str
        self.diff_row = diff_row  # type: long
        self.err_detail = err_detail  # type: str
        self.err_msg = err_msg  # type: str
        self.finish_time = finish_time  # type: str
        self.id = id  # type: str
        self.ignore_flag = ignore_flag  # type: str
        self.item = item  # type: str
        self.job_id = job_id  # type: str
        self.logs = logs  # type: list[DescribePreCheckStatusResponseBodyAnalysisJobProgressLogs]
        self.names = names  # type: str
        self.order_num = order_num  # type: int
        self.parent_obj = parent_obj  # type: str
        self.repair_method = repair_method  # type: str
        self.skip = skip  # type: bool
        self.source_schema = source_schema  # type: str
        self.state = state  # type: str
        self.sub = sub  # type: str
        self.target_names = target_names  # type: str
        self.total = total  # type: int

    def validate(self):
        if self.logs:
            for k in self.logs:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyAnalysisJobProgress, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.boot_time is not None:
            result['BootTime'] = self.boot_time
        if self.can_skip is not None:
            result['CanSkip'] = self.can_skip
        if self.current is not None:
            result['Current'] = self.current
        if self.ddl_sql is not None:
            result['DdlSql'] = self.ddl_sql
        if self.delay_seconds is not None:
            result['DelaySeconds'] = self.delay_seconds
        if self.dest_schema is not None:
            result['DestSchema'] = self.dest_schema
        if self.diff_row is not None:
            result['DiffRow'] = self.diff_row
        if self.err_detail is not None:
            result['ErrDetail'] = self.err_detail
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.id is not None:
            result['Id'] = self.id
        if self.ignore_flag is not None:
            result['IgnoreFlag'] = self.ignore_flag
        if self.item is not None:
            result['Item'] = self.item
        if self.job_id is not None:
            result['JobId'] = self.job_id
        result['Logs'] = []
        if self.logs is not None:
            for k in self.logs:
                result['Logs'].append(k.to_map() if k else None)
        if self.names is not None:
            result['Names'] = self.names
        if self.order_num is not None:
            result['OrderNum'] = self.order_num
        if self.parent_obj is not None:
            result['ParentObj'] = self.parent_obj
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        if self.skip is not None:
            result['Skip'] = self.skip
        if self.source_schema is not None:
            result['SourceSchema'] = self.source_schema
        if self.state is not None:
            result['State'] = self.state
        if self.sub is not None:
            result['Sub'] = self.sub
        if self.target_names is not None:
            result['TargetNames'] = self.target_names
        if self.total is not None:
            result['Total'] = self.total
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BootTime') is not None:
            self.boot_time = m.get('BootTime')
        if m.get('CanSkip') is not None:
            self.can_skip = m.get('CanSkip')
        if m.get('Current') is not None:
            self.current = m.get('Current')
        if m.get('DdlSql') is not None:
            self.ddl_sql = m.get('DdlSql')
        if m.get('DelaySeconds') is not None:
            self.delay_seconds = m.get('DelaySeconds')
        if m.get('DestSchema') is not None:
            self.dest_schema = m.get('DestSchema')
        if m.get('DiffRow') is not None:
            self.diff_row = m.get('DiffRow')
        if m.get('ErrDetail') is not None:
            self.err_detail = m.get('ErrDetail')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('IgnoreFlag') is not None:
            self.ignore_flag = m.get('IgnoreFlag')
        if m.get('Item') is not None:
            self.item = m.get('Item')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        self.logs = []
        if m.get('Logs') is not None:
            for k in m.get('Logs'):
                temp_model = DescribePreCheckStatusResponseBodyAnalysisJobProgressLogs()
                self.logs.append(temp_model.from_map(k))
        if m.get('Names') is not None:
            self.names = m.get('Names')
        if m.get('OrderNum') is not None:
            self.order_num = m.get('OrderNum')
        if m.get('ParentObj') is not None:
            self.parent_obj = m.get('ParentObj')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        if m.get('Skip') is not None:
            self.skip = m.get('Skip')
        if m.get('SourceSchema') is not None:
            self.source_schema = m.get('SourceSchema')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Sub') is not None:
            self.sub = m.get('Sub')
        if m.get('TargetNames') is not None:
            self.target_names = m.get('TargetNames')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        return self


class DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgressLogs(TeaModel):
    def __init__(self, err_data=None, err_msg=None, err_type=None, log_level=None):
        self.err_data = err_data  # type: str
        self.err_msg = err_msg  # type: str
        self.err_type = err_type  # type: str
        self.log_level = log_level  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgressLogs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_data is not None:
            result['ErrData'] = self.err_data
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.err_type is not None:
            result['ErrType'] = self.err_type
        if self.log_level is not None:
            result['LogLevel'] = self.log_level
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrData') is not None:
            self.err_data = m.get('ErrData')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('ErrType') is not None:
            self.err_type = m.get('ErrType')
        if m.get('LogLevel') is not None:
            self.log_level = m.get('LogLevel')
        return self


class DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgress(TeaModel):
    def __init__(self, boot_time=None, can_skip=None, current=None, ddl_sql=None, delay_seconds=None,
                 dest_schema=None, diff_row=None, err_detail=None, err_msg=None, finish_time=None, id=None, ignore_flag=None,
                 item=None, job_id=None, logs=None, names=None, order_num=None, parent_obj=None, repair_method=None,
                 skip=None, source_schema=None, state=None, sub=None, target_names=None, total=None):
        self.boot_time = boot_time  # type: str
        self.can_skip = can_skip  # type: bool
        self.current = current  # type: str
        self.ddl_sql = ddl_sql  # type: str
        self.delay_seconds = delay_seconds  # type: int
        self.dest_schema = dest_schema  # type: str
        self.diff_row = diff_row  # type: long
        self.err_detail = err_detail  # type: str
        self.err_msg = err_msg  # type: str
        self.finish_time = finish_time  # type: str
        self.id = id  # type: str
        self.ignore_flag = ignore_flag  # type: str
        self.item = item  # type: str
        self.job_id = job_id  # type: str
        self.logs = logs  # type: list[DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgressLogs]
        self.names = names  # type: str
        self.order_num = order_num  # type: int
        self.parent_obj = parent_obj  # type: str
        self.repair_method = repair_method  # type: str
        self.skip = skip  # type: bool
        self.source_schema = source_schema  # type: str
        self.state = state  # type: str
        self.sub = sub  # type: str
        self.target_names = target_names  # type: str
        self.total = total  # type: int

    def validate(self):
        if self.logs:
            for k in self.logs:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgress, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.boot_time is not None:
            result['BootTime'] = self.boot_time
        if self.can_skip is not None:
            result['CanSkip'] = self.can_skip
        if self.current is not None:
            result['Current'] = self.current
        if self.ddl_sql is not None:
            result['DdlSql'] = self.ddl_sql
        if self.delay_seconds is not None:
            result['DelaySeconds'] = self.delay_seconds
        if self.dest_schema is not None:
            result['DestSchema'] = self.dest_schema
        if self.diff_row is not None:
            result['DiffRow'] = self.diff_row
        if self.err_detail is not None:
            result['ErrDetail'] = self.err_detail
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.id is not None:
            result['Id'] = self.id
        if self.ignore_flag is not None:
            result['IgnoreFlag'] = self.ignore_flag
        if self.item is not None:
            result['Item'] = self.item
        if self.job_id is not None:
            result['JobId'] = self.job_id
        result['Logs'] = []
        if self.logs is not None:
            for k in self.logs:
                result['Logs'].append(k.to_map() if k else None)
        if self.names is not None:
            result['Names'] = self.names
        if self.order_num is not None:
            result['OrderNum'] = self.order_num
        if self.parent_obj is not None:
            result['ParentObj'] = self.parent_obj
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        if self.skip is not None:
            result['Skip'] = self.skip
        if self.source_schema is not None:
            result['SourceSchema'] = self.source_schema
        if self.state is not None:
            result['State'] = self.state
        if self.sub is not None:
            result['Sub'] = self.sub
        if self.target_names is not None:
            result['TargetNames'] = self.target_names
        if self.total is not None:
            result['Total'] = self.total
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BootTime') is not None:
            self.boot_time = m.get('BootTime')
        if m.get('CanSkip') is not None:
            self.can_skip = m.get('CanSkip')
        if m.get('Current') is not None:
            self.current = m.get('Current')
        if m.get('DdlSql') is not None:
            self.ddl_sql = m.get('DdlSql')
        if m.get('DelaySeconds') is not None:
            self.delay_seconds = m.get('DelaySeconds')
        if m.get('DestSchema') is not None:
            self.dest_schema = m.get('DestSchema')
        if m.get('DiffRow') is not None:
            self.diff_row = m.get('DiffRow')
        if m.get('ErrDetail') is not None:
            self.err_detail = m.get('ErrDetail')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('IgnoreFlag') is not None:
            self.ignore_flag = m.get('IgnoreFlag')
        if m.get('Item') is not None:
            self.item = m.get('Item')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        self.logs = []
        if m.get('Logs') is not None:
            for k in m.get('Logs'):
                temp_model = DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgressLogs()
                self.logs.append(temp_model.from_map(k))
        if m.get('Names') is not None:
            self.names = m.get('Names')
        if m.get('OrderNum') is not None:
            self.order_num = m.get('OrderNum')
        if m.get('ParentObj') is not None:
            self.parent_obj = m.get('ParentObj')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        if m.get('Skip') is not None:
            self.skip = m.get('Skip')
        if m.get('SourceSchema') is not None:
            self.source_schema = m.get('SourceSchema')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Sub') is not None:
            self.sub = m.get('Sub')
        if m.get('TargetNames') is not None:
            self.target_names = m.get('TargetNames')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        return self


class DescribePreCheckStatusResponseBodyFullNetCheckJobStatus(TeaModel):
    def __init__(self, code=None, dest_region=None, dest_region_cidr=None, destination_endpoint_type=None,
                 error_item=None, host_region=None, job_id=None, job_name=None, job_progress=None, source_endpoint_type=None,
                 src_region=None, src_region_cidr=None, state=None, total=None):
        self.code = code  # type: str
        self.dest_region = dest_region  # type: str
        self.dest_region_cidr = dest_region_cidr  # type: str
        self.destination_endpoint_type = destination_endpoint_type  # type: str
        self.error_item = error_item  # type: int
        self.host_region = host_region  # type: str
        self.job_id = job_id  # type: str
        self.job_name = job_name  # type: str
        self.job_progress = job_progress  # type: list[DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgress]
        self.source_endpoint_type = source_endpoint_type  # type: str
        self.src_region = src_region  # type: str
        self.src_region_cidr = src_region_cidr  # type: str
        self.state = state  # type: str
        self.total = total  # type: int

    def validate(self):
        if self.job_progress:
            for k in self.job_progress:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyFullNetCheckJobStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dest_region is not None:
            result['DestRegion'] = self.dest_region
        if self.dest_region_cidr is not None:
            result['DestRegionCidr'] = self.dest_region_cidr
        if self.destination_endpoint_type is not None:
            result['DestinationEndpointType'] = self.destination_endpoint_type
        if self.error_item is not None:
            result['ErrorItem'] = self.error_item
        if self.host_region is not None:
            result['HostRegion'] = self.host_region
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.job_name is not None:
            result['JobName'] = self.job_name
        result['JobProgress'] = []
        if self.job_progress is not None:
            for k in self.job_progress:
                result['JobProgress'].append(k.to_map() if k else None)
        if self.source_endpoint_type is not None:
            result['SourceEndpointType'] = self.source_endpoint_type
        if self.src_region is not None:
            result['SrcRegion'] = self.src_region
        if self.src_region_cidr is not None:
            result['SrcRegionCidr'] = self.src_region_cidr
        if self.state is not None:
            result['State'] = self.state
        if self.total is not None:
            result['Total'] = self.total
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DestRegion') is not None:
            self.dest_region = m.get('DestRegion')
        if m.get('DestRegionCidr') is not None:
            self.dest_region_cidr = m.get('DestRegionCidr')
        if m.get('DestinationEndpointType') is not None:
            self.destination_endpoint_type = m.get('DestinationEndpointType')
        if m.get('ErrorItem') is not None:
            self.error_item = m.get('ErrorItem')
        if m.get('HostRegion') is not None:
            self.host_region = m.get('HostRegion')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('JobName') is not None:
            self.job_name = m.get('JobName')
        self.job_progress = []
        if m.get('JobProgress') is not None:
            for k in m.get('JobProgress'):
                temp_model = DescribePreCheckStatusResponseBodyFullNetCheckJobStatusJobProgress()
                self.job_progress.append(temp_model.from_map(k))
        if m.get('SourceEndpointType') is not None:
            self.source_endpoint_type = m.get('SourceEndpointType')
        if m.get('SrcRegion') is not None:
            self.src_region = m.get('SrcRegion')
        if m.get('SrcRegionCidr') is not None:
            self.src_region_cidr = m.get('SrcRegionCidr')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        return self


class DescribePreCheckStatusResponseBodyJobProgressLogs(TeaModel):
    def __init__(self, err_data=None, err_msg=None, err_type=None, log_level=None):
        # The error message.
        self.err_data = err_data  # type: str
        # The error message returned when an error occurs on the subtask.
        self.err_msg = err_msg  # type: str
        # The error type.
        self.err_type = err_type  # type: str
        # The level of logs.
        self.log_level = log_level  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyJobProgressLogs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_data is not None:
            result['ErrData'] = self.err_data
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.err_type is not None:
            result['ErrType'] = self.err_type
        if self.log_level is not None:
            result['LogLevel'] = self.log_level
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrData') is not None:
            self.err_data = m.get('ErrData')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('ErrType') is not None:
            self.err_type = m.get('ErrType')
        if m.get('LogLevel') is not None:
            self.log_level = m.get('LogLevel')
        return self


class DescribePreCheckStatusResponseBodyJobProgress(TeaModel):
    def __init__(self, boot_time=None, can_skip=None, current=None, ddl_sql=None, delay_seconds=None,
                 dest_schema=None, diff_row=None, err_detail=None, err_msg=None, finish_time=None, id=None, ignore_flag=None,
                 item=None, job_id=None, logs=None, names=None, order_num=None, parent_obj=None, repair_method=None,
                 skip=None, source_schema=None, state=None, sub=None, target_names=None, total=None):
        # The time when the subtask was started. The time is displayed in the yyyy-MM-ddTHH:mm:ssZ format in UTC.
        self.boot_time = boot_time  # type: str
        # Indicates whether the subtask can be ignored if it fails.
        self.can_skip = can_skip  # type: bool
        # The number of the subtasks that are running.
        self.current = current  # type: str
        # The DDL statements.
        self.ddl_sql = ddl_sql  # type: str
        # The latency of incremental data migration or synchronization.
        # 
        # >  For data migration tasks, the unit of this parameter is milliseconds. For data synchronization tasks, the unit of this parameter is seconds.
        self.delay_seconds = delay_seconds  # type: int
        # The name of the database to which the object in the destination instance belongs.
        self.dest_schema = dest_schema  # type: str
        # This parameter will be removed in the future.
        self.diff_row = diff_row  # type: long
        # The error details of the subtask failure.
        self.err_detail = err_detail  # type: str
        # The error message of the subtask failure.
        self.err_msg = err_msg  # type: str
        # The time when the subtask was complete. The time is displayed in the yyyy-MM-ddTHH:mm:ssZ format in UTC.
        self.finish_time = finish_time  # type: str
        # The ID recorded in the metadatabase.
        self.id = id  # type: str
        # Indicates whether DTS ignores the subtask and proceeds with the next subtask. Valid values:
        # 
        # *   **N**: no
        # *   **Y**: yes
        self.ignore_flag = ignore_flag  # type: str
        # The shortened name of the subtask.
        self.item = item  # type: str
        # The ID of the subtask.
        self.job_id = job_id  # type: str
        # The logs of subtask failures.
        self.logs = logs  # type: list[DescribePreCheckStatusResponseBodyJobProgressLogs]
        # The name of the subtask.
        self.names = names  # type: str
        # The serial number of the subtask.
        self.order_num = order_num  # type: int
        # This parameter will be removed in the future.
        self.parent_obj = parent_obj  # type: str
        # The method to fix the subtask failure.
        self.repair_method = repair_method  # type: str
        # Indicates whether the subtask is ignored if it fails. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.skip = skip  # type: bool
        # The name of the database to which the object in the source instance belongs.
        self.source_schema = source_schema  # type: str
        # The status of the subtask. Valid values:
        # 
        # *   **NotStarted**: The subtask is not started.
        # *   **Checking**: The subtask is being checked.
        # *   **Migrating**: The subtask is in progress. Data is being migrated.
        # *   **Failed**: The subtask failed.
        # *   **Warning**: The subtask encounters an exception.
        # *   **Success**: The subtask is complete.
        self.state = state  # type: str
        # The sub-item progress of the subtask.
        # 
        # >  If **\[]** is returned, the subtask has no sub-items.
        self.sub = sub  # type: str
        # The names of the objects that are migrated or synchronized.
        self.target_names = target_names  # type: str
        # The total number of subtasks.
        self.total = total  # type: int

    def validate(self):
        if self.logs:
            for k in self.logs:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyJobProgress, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.boot_time is not None:
            result['BootTime'] = self.boot_time
        if self.can_skip is not None:
            result['CanSkip'] = self.can_skip
        if self.current is not None:
            result['Current'] = self.current
        if self.ddl_sql is not None:
            result['DdlSql'] = self.ddl_sql
        if self.delay_seconds is not None:
            result['DelaySeconds'] = self.delay_seconds
        if self.dest_schema is not None:
            result['DestSchema'] = self.dest_schema
        if self.diff_row is not None:
            result['DiffRow'] = self.diff_row
        if self.err_detail is not None:
            result['ErrDetail'] = self.err_detail
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.id is not None:
            result['Id'] = self.id
        if self.ignore_flag is not None:
            result['IgnoreFlag'] = self.ignore_flag
        if self.item is not None:
            result['Item'] = self.item
        if self.job_id is not None:
            result['JobId'] = self.job_id
        result['Logs'] = []
        if self.logs is not None:
            for k in self.logs:
                result['Logs'].append(k.to_map() if k else None)
        if self.names is not None:
            result['Names'] = self.names
        if self.order_num is not None:
            result['OrderNum'] = self.order_num
        if self.parent_obj is not None:
            result['ParentObj'] = self.parent_obj
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        if self.skip is not None:
            result['Skip'] = self.skip
        if self.source_schema is not None:
            result['SourceSchema'] = self.source_schema
        if self.state is not None:
            result['State'] = self.state
        if self.sub is not None:
            result['Sub'] = self.sub
        if self.target_names is not None:
            result['TargetNames'] = self.target_names
        if self.total is not None:
            result['Total'] = self.total
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BootTime') is not None:
            self.boot_time = m.get('BootTime')
        if m.get('CanSkip') is not None:
            self.can_skip = m.get('CanSkip')
        if m.get('Current') is not None:
            self.current = m.get('Current')
        if m.get('DdlSql') is not None:
            self.ddl_sql = m.get('DdlSql')
        if m.get('DelaySeconds') is not None:
            self.delay_seconds = m.get('DelaySeconds')
        if m.get('DestSchema') is not None:
            self.dest_schema = m.get('DestSchema')
        if m.get('DiffRow') is not None:
            self.diff_row = m.get('DiffRow')
        if m.get('ErrDetail') is not None:
            self.err_detail = m.get('ErrDetail')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('IgnoreFlag') is not None:
            self.ignore_flag = m.get('IgnoreFlag')
        if m.get('Item') is not None:
            self.item = m.get('Item')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        self.logs = []
        if m.get('Logs') is not None:
            for k in m.get('Logs'):
                temp_model = DescribePreCheckStatusResponseBodyJobProgressLogs()
                self.logs.append(temp_model.from_map(k))
        if m.get('Names') is not None:
            self.names = m.get('Names')
        if m.get('OrderNum') is not None:
            self.order_num = m.get('OrderNum')
        if m.get('ParentObj') is not None:
            self.parent_obj = m.get('ParentObj')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        if m.get('Skip') is not None:
            self.skip = m.get('Skip')
        if m.get('SourceSchema') is not None:
            self.source_schema = m.get('SourceSchema')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Sub') is not None:
            self.sub = m.get('Sub')
        if m.get('TargetNames') is not None:
            self.target_names = m.get('TargetNames')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        return self


class DescribePreCheckStatusResponseBodyNetworkDiagnosisResultDiagnosis(TeaModel):
    def __init__(self, cn_doc_url=None, code=None, endpoint_type=None, international_doc_url=None, result=None):
        self.cn_doc_url = cn_doc_url  # type: str
        self.code = code  # type: str
        self.endpoint_type = endpoint_type  # type: str
        self.international_doc_url = international_doc_url  # type: str
        self.result = result  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyNetworkDiagnosisResultDiagnosis, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.cn_doc_url is not None:
            result['CnDocUrl'] = self.cn_doc_url
        if self.code is not None:
            result['Code'] = self.code
        if self.endpoint_type is not None:
            result['EndpointType'] = self.endpoint_type
        if self.international_doc_url is not None:
            result['InternationalDocUrl'] = self.international_doc_url
        if self.result is not None:
            result['Result'] = self.result
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CnDocUrl') is not None:
            self.cn_doc_url = m.get('CnDocUrl')
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('EndpointType') is not None:
            self.endpoint_type = m.get('EndpointType')
        if m.get('InternationalDocUrl') is not None:
            self.international_doc_url = m.get('InternationalDocUrl')
        if m.get('Result') is not None:
            self.result = m.get('Result')
        return self


class DescribePreCheckStatusResponseBodyNetworkDiagnosisResult(TeaModel):
    def __init__(self, diagnosis=None, model_version=None):
        self.diagnosis = diagnosis  # type: list[DescribePreCheckStatusResponseBodyNetworkDiagnosisResultDiagnosis]
        self.model_version = model_version  # type: str

    def validate(self):
        if self.diagnosis:
            for k in self.diagnosis:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodyNetworkDiagnosisResult, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Diagnosis'] = []
        if self.diagnosis is not None:
            for k in self.diagnosis:
                result['Diagnosis'].append(k.to_map() if k else None)
        if self.model_version is not None:
            result['ModelVersion'] = self.model_version
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.diagnosis = []
        if m.get('Diagnosis') is not None:
            for k in m.get('Diagnosis'):
                temp_model = DescribePreCheckStatusResponseBodyNetworkDiagnosisResultDiagnosis()
                self.diagnosis.append(temp_model.from_map(k))
        if m.get('ModelVersion') is not None:
            self.model_version = m.get('ModelVersion')
        return self


class DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgressLogs(TeaModel):
    def __init__(self, err_data=None, err_msg=None, err_type=None, log_level=None):
        # The record of errors.
        self.err_data = err_data  # type: str
        # The error message.
        self.err_msg = err_msg  # type: str
        # The error type.
        self.err_type = err_type  # type: str
        # The level of logs.
        self.log_level = log_level  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgressLogs, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_data is not None:
            result['ErrData'] = self.err_data
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.err_type is not None:
            result['ErrType'] = self.err_type
        if self.log_level is not None:
            result['LogLevel'] = self.log_level
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrData') is not None:
            self.err_data = m.get('ErrData')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('ErrType') is not None:
            self.err_type = m.get('ErrType')
        if m.get('LogLevel') is not None:
            self.log_level = m.get('LogLevel')
        return self


class DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgress(TeaModel):
    def __init__(self, boot_time=None, can_skip=None, current=None, ddl_sql=None, delay_seconds=None,
                 dest_schema=None, diff_row=None, err_detail=None, err_msg=None, finish_time=None, id=None, ignore_flag=None,
                 item=None, job_id=None, logs=None, names=None, order_num=None, parent_obj=None, repair_method=None,
                 skip=None, source_schema=None, state=None, sub=None, target_names=None, total=None):
        # The time when the subtask was started. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.boot_time = boot_time  # type: str
        # Indicates whether the subtask can be ignored if it fails. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.can_skip = can_skip  # type: bool
        # The number of the subtasks that are running.
        self.current = current  # type: str
        # The DDL statements.
        self.ddl_sql = ddl_sql  # type: str
        # The latency of incremental data migration or synchronization.
        self.delay_seconds = delay_seconds  # type: int
        # The name of the database to which the object in the destination instance belongs.
        self.dest_schema = dest_schema  # type: str
        # This parameter will be removed in the future.
        self.diff_row = diff_row  # type: long
        # The error details of the subtask failure.
        self.err_detail = err_detail  # type: str
        # The error message of the subtask failure.
        self.err_msg = err_msg  # type: str
        # The time when the instance was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.finish_time = finish_time  # type: str
        # The ID of the entry in the metadatabase.
        self.id = id  # type: str
        # Indicates whether DTS ignores the subtask and proceeds with the next subtask. Valid values:
        # 
        # *   **N**: no
        # *   **Y**: yes
        self.ignore_flag = ignore_flag  # type: str
        # The name of the subtask.
        self.item = item  # type: str
        # The ID of the subtask.
        self.job_id = job_id  # type: str
        # The operations logs of errors.
        self.logs = logs  # type: list[DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgressLogs]
        # The name of the subtask.
        self.names = names  # type: str
        # The serial number of the subtask.
        self.order_num = order_num  # type: int
        # This parameter will be removed in the future.
        self.parent_obj = parent_obj  # type: str
        # The method used to fix a precheck failure.
        self.repair_method = repair_method  # type: str
        # Indicates whether the subtask was skipped. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.skip = skip  # type: bool
        # The name of the database to which the object in the source instance belongs.
        self.source_schema = source_schema  # type: str
        # The status of the subtask. Valid values:
        # 
        # *   **NotStarted**: The subtask is not started.
        # *   **Suspending**: The subtask is paused.
        # *   **Checking**: The subtask is being checked.
        # *   **Migrating**: The subtask is in progress. Data is being migrated.
        # *   **Failed**: The subtask failed.
        # *   **Catched**: The subtask is in progress. Incremental data is being migrated or synchronized.
        # *   **Finished**: The subtask is complete.
        self.state = state  # type: str
        # The sub-item progress of the subtask.
        # 
        # >  If **\[]** is returned, the subtask has no sub-items.
        self.sub = sub  # type: str
        # The names of the objects that are migrated or synchronized.
        self.target_names = target_names  # type: str
        # The total number of subtasks.
        self.total = total  # type: int

    def validate(self):
        if self.logs:
            for k in self.logs:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgress, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.boot_time is not None:
            result['BootTime'] = self.boot_time
        if self.can_skip is not None:
            result['CanSkip'] = self.can_skip
        if self.current is not None:
            result['Current'] = self.current
        if self.ddl_sql is not None:
            result['DdlSql'] = self.ddl_sql
        if self.delay_seconds is not None:
            result['DelaySeconds'] = self.delay_seconds
        if self.dest_schema is not None:
            result['DestSchema'] = self.dest_schema
        if self.diff_row is not None:
            result['DiffRow'] = self.diff_row
        if self.err_detail is not None:
            result['ErrDetail'] = self.err_detail
        if self.err_msg is not None:
            result['ErrMsg'] = self.err_msg
        if self.finish_time is not None:
            result['FinishTime'] = self.finish_time
        if self.id is not None:
            result['Id'] = self.id
        if self.ignore_flag is not None:
            result['IgnoreFlag'] = self.ignore_flag
        if self.item is not None:
            result['Item'] = self.item
        if self.job_id is not None:
            result['JobId'] = self.job_id
        result['Logs'] = []
        if self.logs is not None:
            for k in self.logs:
                result['Logs'].append(k.to_map() if k else None)
        if self.names is not None:
            result['Names'] = self.names
        if self.order_num is not None:
            result['OrderNum'] = self.order_num
        if self.parent_obj is not None:
            result['ParentObj'] = self.parent_obj
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        if self.skip is not None:
            result['Skip'] = self.skip
        if self.source_schema is not None:
            result['SourceSchema'] = self.source_schema
        if self.state is not None:
            result['State'] = self.state
        if self.sub is not None:
            result['Sub'] = self.sub
        if self.target_names is not None:
            result['TargetNames'] = self.target_names
        if self.total is not None:
            result['Total'] = self.total
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BootTime') is not None:
            self.boot_time = m.get('BootTime')
        if m.get('CanSkip') is not None:
            self.can_skip = m.get('CanSkip')
        if m.get('Current') is not None:
            self.current = m.get('Current')
        if m.get('DdlSql') is not None:
            self.ddl_sql = m.get('DdlSql')
        if m.get('DelaySeconds') is not None:
            self.delay_seconds = m.get('DelaySeconds')
        if m.get('DestSchema') is not None:
            self.dest_schema = m.get('DestSchema')
        if m.get('DiffRow') is not None:
            self.diff_row = m.get('DiffRow')
        if m.get('ErrDetail') is not None:
            self.err_detail = m.get('ErrDetail')
        if m.get('ErrMsg') is not None:
            self.err_msg = m.get('ErrMsg')
        if m.get('FinishTime') is not None:
            self.finish_time = m.get('FinishTime')
        if m.get('Id') is not None:
            self.id = m.get('Id')
        if m.get('IgnoreFlag') is not None:
            self.ignore_flag = m.get('IgnoreFlag')
        if m.get('Item') is not None:
            self.item = m.get('Item')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        self.logs = []
        if m.get('Logs') is not None:
            for k in m.get('Logs'):
                temp_model = DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgressLogs()
                self.logs.append(temp_model.from_map(k))
        if m.get('Names') is not None:
            self.names = m.get('Names')
        if m.get('OrderNum') is not None:
            self.order_num = m.get('OrderNum')
        if m.get('ParentObj') is not None:
            self.parent_obj = m.get('ParentObj')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        if m.get('Skip') is not None:
            self.skip = m.get('Skip')
        if m.get('SourceSchema') is not None:
            self.source_schema = m.get('SourceSchema')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Sub') is not None:
            self.sub = m.get('Sub')
        if m.get('TargetNames') is not None:
            self.target_names = m.get('TargetNames')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        return self


class DescribePreCheckStatusResponseBodySubDistributedJobStatus(TeaModel):
    def __init__(self, code=None, error_item=None, job_id=None, job_name=None, job_progress=None, state=None,
                 total=None):
        # The task code that indicates the subtask type. Valid values:
        # 
        # *   **01**: precheck
        # *   **02**: schema migration or initial schema synchronization
        # *   **03**: full data migration or initial full data synchronization
        # *   **04**: incremental data migration or synchronization
        self.code = code  # type: str
        # The number of subtasks that failed.
        self.error_item = error_item  # type: int
        # The ID of the subtask.
        self.job_id = job_id  # type: str
        # The name of distributed subtasks associated with the subtask.
        self.job_name = job_name  # type: str
        # The list of subtasks and the progress of each subtask.
        self.job_progress = job_progress  # type: list[DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgress]
        # The status of the subtask. Valid values:
        # 
        # *   **NotStarted**: The subtask is not started.
        # *   **Suspending**: The subtask is paused.
        # *   **Checking**: The subtask is being checked.
        # *   **Migrating**: The subtask is in progress. Data is being migrated.
        # *   **Failed**: The subtask failed.
        # *   **Catched**: The subtask is in progress. Incremental data is being migrated or synchronized.
        # *   **Finished**: The subtask is complete.
        self.state = state  # type: str
        # The total number of returned entries.
        self.total = total  # type: int

    def validate(self):
        if self.job_progress:
            for k in self.job_progress:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBodySubDistributedJobStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.error_item is not None:
            result['ErrorItem'] = self.error_item
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.job_name is not None:
            result['JobName'] = self.job_name
        result['JobProgress'] = []
        if self.job_progress is not None:
            for k in self.job_progress:
                result['JobProgress'].append(k.to_map() if k else None)
        if self.state is not None:
            result['State'] = self.state
        if self.total is not None:
            result['Total'] = self.total
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('ErrorItem') is not None:
            self.error_item = m.get('ErrorItem')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('JobName') is not None:
            self.job_name = m.get('JobName')
        self.job_progress = []
        if m.get('JobProgress') is not None:
            for k in m.get('JobProgress'):
                temp_model = DescribePreCheckStatusResponseBodySubDistributedJobStatusJobProgress()
                self.job_progress.append(temp_model.from_map(k))
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        return self


class DescribePreCheckStatusResponseBody(TeaModel):
    def __init__(self, analysis_job_progress=None, code=None, error_analysis_item=None, error_item=None,
                 full_net_check_job_status=None, http_status_code=None, job_id=None, job_name=None, job_progress=None,
                 network_diagnosis_result=None, page_number=None, page_record_count=None, request_id=None, state=None,
                 sub_distributed_job_status=None, success=None, total=None, total_record_count=None):
        self.analysis_job_progress = analysis_job_progress  # type: list[DescribePreCheckStatusResponseBodyAnalysisJobProgress]
        # The task code that indicates the subtask type. Valid values:
        # 
        # *   **01**: precheck
        # *   **02**: schema migration or initial schema synchronization
        # *   **03**: full data migration or initial full data synchronization
        # *   **04**: incremental data migration or synchronization
        self.code = code  # type: str
        self.error_analysis_item = error_analysis_item  # type: int
        # The total number of subtask failures.
        self.error_item = error_item  # type: int
        self.full_net_check_job_status = full_net_check_job_status  # type: list[DescribePreCheckStatusResponseBodyFullNetCheckJobStatus]
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the data migration or synchronization task.
        self.job_id = job_id  # type: str
        # The name of the subtask.
        self.job_name = job_name  # type: str
        # The list of subtasks and the progress of each subtask.
        self.job_progress = job_progress  # type: list[DescribePreCheckStatusResponseBodyJobProgress]
        self.network_diagnosis_result = network_diagnosis_result  # type: DescribePreCheckStatusResponseBodyNetworkDiagnosisResult
        # The number of the page returned. The value is an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_number = page_number  # type: long
        # The number of entries returned per page.
        self.page_record_count = page_record_count  # type: long
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The status of the subtask. Valid values:
        # 
        # *   **NotStarted**: The subtask is not started.
        # *   **Suspending**: The subtask is paused.
        # *   **Checking**: The subtask is being checked.
        # *   **Migrating**: The subtask is in progress. Data is being migrated.
        # *   **Failed**: The subtask failed.
        # *   **Catched**: The subtask is in progress. Incremental data is being migrated or synchronized.
        # *   **Finished**: The subtask is complete.
        self.state = state  # type: str
        # The state of the distributed subtask.
        self.sub_distributed_job_status = sub_distributed_job_status  # type: list[DescribePreCheckStatusResponseBodySubDistributedJobStatus]
        # Indicates whether the request was successful.
        self.success = success  # type: bool
        # The total number of subtasks.
        self.total = total  # type: int
        # The total number of returned records.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.analysis_job_progress:
            for k in self.analysis_job_progress:
                if k:
                    k.validate()
        if self.full_net_check_job_status:
            for k in self.full_net_check_job_status:
                if k:
                    k.validate()
        if self.job_progress:
            for k in self.job_progress:
                if k:
                    k.validate()
        if self.network_diagnosis_result:
            self.network_diagnosis_result.validate()
        if self.sub_distributed_job_status:
            for k in self.sub_distributed_job_status:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['AnalysisJobProgress'] = []
        if self.analysis_job_progress is not None:
            for k in self.analysis_job_progress:
                result['AnalysisJobProgress'].append(k.to_map() if k else None)
        if self.code is not None:
            result['Code'] = self.code
        if self.error_analysis_item is not None:
            result['ErrorAnalysisItem'] = self.error_analysis_item
        if self.error_item is not None:
            result['ErrorItem'] = self.error_item
        result['FullNetCheckJobStatus'] = []
        if self.full_net_check_job_status is not None:
            for k in self.full_net_check_job_status:
                result['FullNetCheckJobStatus'].append(k.to_map() if k else None)
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.job_name is not None:
            result['JobName'] = self.job_name
        result['JobProgress'] = []
        if self.job_progress is not None:
            for k in self.job_progress:
                result['JobProgress'].append(k.to_map() if k else None)
        if self.network_diagnosis_result is not None:
            result['NetworkDiagnosisResult'] = self.network_diagnosis_result.to_map()
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.state is not None:
            result['State'] = self.state
        result['SubDistributedJobStatus'] = []
        if self.sub_distributed_job_status is not None:
            for k in self.sub_distributed_job_status:
                result['SubDistributedJobStatus'].append(k.to_map() if k else None)
        if self.success is not None:
            result['Success'] = self.success
        if self.total is not None:
            result['Total'] = self.total
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.analysis_job_progress = []
        if m.get('AnalysisJobProgress') is not None:
            for k in m.get('AnalysisJobProgress'):
                temp_model = DescribePreCheckStatusResponseBodyAnalysisJobProgress()
                self.analysis_job_progress.append(temp_model.from_map(k))
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('ErrorAnalysisItem') is not None:
            self.error_analysis_item = m.get('ErrorAnalysisItem')
        if m.get('ErrorItem') is not None:
            self.error_item = m.get('ErrorItem')
        self.full_net_check_job_status = []
        if m.get('FullNetCheckJobStatus') is not None:
            for k in m.get('FullNetCheckJobStatus'):
                temp_model = DescribePreCheckStatusResponseBodyFullNetCheckJobStatus()
                self.full_net_check_job_status.append(temp_model.from_map(k))
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('JobName') is not None:
            self.job_name = m.get('JobName')
        self.job_progress = []
        if m.get('JobProgress') is not None:
            for k in m.get('JobProgress'):
                temp_model = DescribePreCheckStatusResponseBodyJobProgress()
                self.job_progress.append(temp_model.from_map(k))
        if m.get('NetworkDiagnosisResult') is not None:
            temp_model = DescribePreCheckStatusResponseBodyNetworkDiagnosisResult()
            self.network_diagnosis_result = temp_model.from_map(m['NetworkDiagnosisResult'])
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('State') is not None:
            self.state = m.get('State')
        self.sub_distributed_job_status = []
        if m.get('SubDistributedJobStatus') is not None:
            for k in m.get('SubDistributedJobStatus'):
                temp_model = DescribePreCheckStatusResponseBodySubDistributedJobStatus()
                self.sub_distributed_job_status.append(temp_model.from_map(k))
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('Total') is not None:
            self.total = m.get('Total')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribePreCheckStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribePreCheckStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribePreCheckStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribePreCheckStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSubscriptionInstanceAlertRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None,
                 subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The token can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceAlertRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class DescribeSubscriptionInstanceAlertResponseBody(TeaModel):
    def __init__(self, delay_alert_phone=None, delay_alert_status=None, delay_over_seconds=None, err_code=None,
                 err_message=None, error_alert_phone=None, error_alert_status=None, request_id=None,
                 subscription_instance_id=None, subscription_instance_name=None, success=None):
        # The mobile phone numbers that receive latency-related alerts.
        self.delay_alert_phone = delay_alert_phone  # type: str
        # Indicates whether task latency is monitored. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        self.delay_alert_status = delay_alert_status  # type: str
        # The threshold for triggering latency alerts. The unit is seconds and the value is an integer. The recommended value is 10 seconds.
        self.delay_over_seconds = delay_over_seconds  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The mobile phone numbers that receive status-related alerts.
        self.error_alert_phone = error_alert_phone  # type: str
        # Indicates whether task status is monitored. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        self.error_alert_status = error_alert_status  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The ID of the change tracking instance.
        self.subscription_instance_id = subscription_instance_id  # type: str
        # The name of the change tracking instance.
        self.subscription_instance_name = subscription_instance_name  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceAlertResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay_alert_phone is not None:
            result['DelayAlertPhone'] = self.delay_alert_phone
        if self.delay_alert_status is not None:
            result['DelayAlertStatus'] = self.delay_alert_status
        if self.delay_over_seconds is not None:
            result['DelayOverSeconds'] = self.delay_over_seconds
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_alert_phone is not None:
            result['ErrorAlertPhone'] = self.error_alert_phone
        if self.error_alert_status is not None:
            result['ErrorAlertStatus'] = self.error_alert_status
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceID'] = self.subscription_instance_id
        if self.subscription_instance_name is not None:
            result['SubscriptionInstanceName'] = self.subscription_instance_name
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DelayAlertPhone') is not None:
            self.delay_alert_phone = m.get('DelayAlertPhone')
        if m.get('DelayAlertStatus') is not None:
            self.delay_alert_status = m.get('DelayAlertStatus')
        if m.get('DelayOverSeconds') is not None:
            self.delay_over_seconds = m.get('DelayOverSeconds')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorAlertPhone') is not None:
            self.error_alert_phone = m.get('ErrorAlertPhone')
        if m.get('ErrorAlertStatus') is not None:
            self.error_alert_status = m.get('ErrorAlertStatus')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SubscriptionInstanceID') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceID')
        if m.get('SubscriptionInstanceName') is not None:
            self.subscription_instance_name = m.get('SubscriptionInstanceName')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeSubscriptionInstanceAlertResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSubscriptionInstanceAlertResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceAlertResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSubscriptionInstanceAlertResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSubscriptionInstanceStatusRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the [DescribeSubscriptionInstances](~~49442~~) operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class DescribeSubscriptionInstanceStatusResponseBodySourceEndpoint(TeaModel):
    def __init__(self, instance_id=None, instance_type=None):
        # The ID of the instance that hosts the source database.
        self.instance_id = instance_id  # type: str
        # The instance type of the source database.
        # 
        # >  This parameter is returned only for change tracking instances of the new version.
        self.instance_type = instance_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBodySourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        return self


class DescribeSubscriptionInstanceStatusResponseBodySubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        # Indicates whether data definition language (DDL) operations are tracked. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.ddl = ddl  # type: bool
        # Indicates whether data manipulation language (DML) operations are tracked. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBodySubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['DDL'] = self.ddl
        if self.dml is not None:
            result['DML'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DDL') is not None:
            self.ddl = m.get('DDL')
        if m.get('DML') is not None:
            self.dml = m.get('DML')
        return self


class DescribeSubscriptionInstanceStatusResponseBodySubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpchost=None):
        # The private endpoint of the change tracking instance. The format is `<Address>:<Port number>`.
        self.private_host = private_host  # type: str
        # The public endpoint of the change tracking instance. The format is `<Address>:<Port number>`.
        self.public_host = public_host  # type: str
        # The virtual private cloud (VPC) endpoint of the change tracking instance. The format is `<Address>:<Port number>`.
        self.vpchost = vpchost  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBodySubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpchost is not None:
            result['VPCHost'] = self.vpchost
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VPCHost') is not None:
            self.vpchost = m.get('VPCHost')
        return self


class DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObjectTableList(TeaModel):
    def __init__(self, table=None):
        self.table = table  # type: list[str]

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObjectTableList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table is not None:
            result['Table'] = self.table
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Table') is not None:
            self.table = m.get('Table')
        return self


class DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObject(TeaModel):
    def __init__(self, database_name=None, table_list=None, whole_database=None):
        # The name of the database to which the object belongs.
        self.database_name = database_name  # type: str
        # The table name.
        self.table_list = table_list  # type: DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObjectTableList
        # Indicates whether the data of an entire database is tracked. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.whole_database = whole_database  # type: str

    def validate(self):
        if self.table_list:
            self.table_list.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObject, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.table_list is not None:
            result['TableList'] = self.table_list.to_map()
        if self.whole_database is not None:
            result['WholeDatabase'] = self.whole_database
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('TableList') is not None:
            temp_model = DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObjectTableList()
            self.table_list = temp_model.from_map(m['TableList'])
        if m.get('WholeDatabase') is not None:
            self.whole_database = m.get('WholeDatabase')
        return self


class DescribeSubscriptionInstanceStatusResponseBodySubscriptionObject(TeaModel):
    def __init__(self, synchronous_object=None):
        self.synchronous_object = synchronous_object  # type: list[DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObject]

    def validate(self):
        if self.synchronous_object:
            for k in self.synchronous_object:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBodySubscriptionObject, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['SynchronousObject'] = []
        if self.synchronous_object is not None:
            for k in self.synchronous_object:
                result['SynchronousObject'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.synchronous_object = []
        if m.get('SynchronousObject') is not None:
            for k in m.get('SynchronousObject'):
                temp_model = DescribeSubscriptionInstanceStatusResponseBodySubscriptionObjectSynchronousObject()
                self.synchronous_object.append(temp_model.from_map(k))
        return self


class DescribeSubscriptionInstanceStatusResponseBody(TeaModel):
    def __init__(self, begin_timestamp=None, consumption_checkpoint=None, consumption_client=None,
                 end_timestamp=None, err_code=None, err_message=None, error_message=None, pay_type=None, request_id=None,
                 source_endpoint=None, status=None, subscribe_topic=None, subscription_data_type=None, subscription_host=None,
                 subscription_instance_id=None, subscription_instance_name=None, subscription_object=None, success=None, task_id=None):
        # The start of the time range for change tracking. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.begin_timestamp = begin_timestamp  # type: str
        # The consumption checkpoint of the change tracking instance. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The downstream client information, in the following format: \<IP address of the downstream client>:\<Random ID generated by DTS>.
        self.consumption_client = consumption_client  # type: str
        # The end of the time range for change tracking. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.end_timestamp = end_timestamp  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The error message returned if change tracking failed.
        self.error_message = error_message  # type: str
        # The billing method of the change tracking instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeSubscriptionInstanceStatusResponseBodySourceEndpoint
        # The status of the change tracking task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Starting**: The task is being started.
        # *   **Normal**: The task is running as expected.
        # *   **Abnormal**: The task is not running as expected.
        self.status = status  # type: str
        # The topic of the change tracking instance.
        # 
        # >  This parameter is returned only if your change tracking instance is of the new version and you have called the [CreateConsumerGroup](~~122863~~) operation to create a consumer group.
        self.subscribe_topic = subscribe_topic  # type: str
        # The types of operations that are tracked by the task.
        self.subscription_data_type = subscription_data_type  # type: DescribeSubscriptionInstanceStatusResponseBodySubscriptionDataType
        # The endpoint of the change tracking instance.
        self.subscription_host = subscription_host  # type: DescribeSubscriptionInstanceStatusResponseBodySubscriptionHost
        # The ID of the change tracking instance.
        self.subscription_instance_id = subscription_instance_id  # type: str
        # The name of the change tracking instance.
        self.subscription_instance_name = subscription_instance_name  # type: str
        # The objects for change tracking.
        self.subscription_object = subscription_object  # type: DescribeSubscriptionInstanceStatusResponseBodySubscriptionObject
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The ID of the change tracking task.
        self.task_id = task_id  # type: str

    def validate(self):
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()
        if self.subscription_object:
            self.subscription_object.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceID'] = self.subscription_instance_id
        if self.subscription_instance_name is not None:
            result['SubscriptionInstanceName'] = self.subscription_instance_name
        if self.subscription_object is not None:
            result['SubscriptionObject'] = self.subscription_object.to_map()
        if self.success is not None:
            result['Success'] = self.success
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeSubscriptionInstanceStatusResponseBodySourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeSubscriptionInstanceStatusResponseBodySubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeSubscriptionInstanceStatusResponseBodySubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('SubscriptionInstanceID') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceID')
        if m.get('SubscriptionInstanceName') is not None:
            self.subscription_instance_name = m.get('SubscriptionInstanceName')
        if m.get('SubscriptionObject') is not None:
            temp_model = DescribeSubscriptionInstanceStatusResponseBodySubscriptionObject()
            self.subscription_object = temp_model.from_map(m['SubscriptionObject'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class DescribeSubscriptionInstanceStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSubscriptionInstanceStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstanceStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSubscriptionInstanceStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSubscriptionInstancesRequestTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The tag key.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Key specifies the key of the first tag and Tag.2.Key specifies the key of the second tag. You can specify 1 to 20 tag keys at a time.
        # *   This parameter cannot be an empty string.
        self.key = key  # type: str
        # The tag value.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Value specifies the value of the first tag and Tag.2.Value specifies the value of the second tag. You can specify 1 to 20 tag values at a time.
        # *   This parameter can be an empty string.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesRequestTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class DescribeSubscriptionInstancesRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, page_num=None, page_size=None,
                 region_id=None, subscription_instance_name=None, tag=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value must be an integer that is greater than **0** and does not exceed the maximum value of the Integer data type. Default value: **1**.
        self.page_num = page_num  # type: int
        # The number of entries to return on each page. Valid values: **30**, **50**, and **100**. Default value: **30**.
        self.page_size = page_size  # type: int
        # The ID of the region where the change tracking instance resides. For more information, see [List of supported regions](~~49442~~).
        self.region_id = region_id  # type: str
        # The name of the change tracking instance.
        # 
        # >  If you specify this parameter, DTS returns all the change tracking instances that match the specified name.
        self.subscription_instance_name = subscription_instance_name  # type: str
        self.tag = tag  # type: list[DescribeSubscriptionInstancesRequestTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_num is not None:
            result['PageNum'] = self.page_num
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_name is not None:
            result['SubscriptionInstanceName'] = self.subscription_instance_name
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNum') is not None:
            self.page_num = m.get('PageNum')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceName') is not None:
            self.subscription_instance_name = m.get('SubscriptionInstanceName')
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = DescribeSubscriptionInstancesRequestTag()
                self.tag.append(temp_model.from_map(k))
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSourceEndpoint(TeaModel):
    def __init__(self, instance_id=None, instance_type=None):
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        # 
        # >  This parameter is returned only for change tracking instances of the new version.
        self.instance_type = instance_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.instance_id is not None:
            result['InstanceID'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('InstanceID') is not None:
            self.instance_id = m.get('InstanceID')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionDataType(TeaModel):
    def __init__(self, ddl=None, dml=None):
        # Indicates whether data definition language (DDL) operations are tracked. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.ddl = ddl  # type: bool
        # Indicates whether data manipulation language (DML) operations are tracked. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.dml = dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionDataType, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ddl is not None:
            result['DDL'] = self.ddl
        if self.dml is not None:
            result['DML'] = self.dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DDL') is not None:
            self.ddl = m.get('DDL')
        if m.get('DML') is not None:
            self.dml = m.get('DML')
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionHost(TeaModel):
    def __init__(self, private_host=None, public_host=None, vpchost=None):
        # The private endpoint of the change tracking instance. The format is `<Address>:<Port number>`.
        self.private_host = private_host  # type: str
        # The public endpoint of the change tracking instance. The format is `<Address>:<Port number>`.
        self.public_host = public_host  # type: str
        # The virtual private cloud (VPC) endpoint of the change tracking instance. The format is `<Address>:<Port number>`.
        self.vpchost = vpchost  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionHost, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.private_host is not None:
            result['PrivateHost'] = self.private_host
        if self.public_host is not None:
            result['PublicHost'] = self.public_host
        if self.vpchost is not None:
            result['VPCHost'] = self.vpchost
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PrivateHost') is not None:
            self.private_host = m.get('PrivateHost')
        if m.get('PublicHost') is not None:
            self.public_host = m.get('PublicHost')
        if m.get('VPCHost') is not None:
            self.vpchost = m.get('VPCHost')
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObjectTableList(TeaModel):
    def __init__(self, table=None):
        self.table = table  # type: list[str]

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObjectTableList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table is not None:
            result['Table'] = self.table
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Table') is not None:
            self.table = m.get('Table')
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObject(TeaModel):
    def __init__(self, database_name=None, table_list=None, whole_database=None):
        # The name of the database to which the object belongs.
        self.database_name = database_name  # type: str
        # The table name.
        self.table_list = table_list  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObjectTableList
        # Indicates whether the data of an entire database is tracked. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.whole_database = whole_database  # type: str

    def validate(self):
        if self.table_list:
            self.table_list.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObject, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.database_name is not None:
            result['DatabaseName'] = self.database_name
        if self.table_list is not None:
            result['TableList'] = self.table_list.to_map()
        if self.whole_database is not None:
            result['WholeDatabase'] = self.whole_database
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DatabaseName') is not None:
            self.database_name = m.get('DatabaseName')
        if m.get('TableList') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObjectTableList()
            self.table_list = temp_model.from_map(m['TableList'])
        if m.get('WholeDatabase') is not None:
            self.whole_database = m.get('WholeDatabase')
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObject(TeaModel):
    def __init__(self, synchronous_object=None):
        self.synchronous_object = synchronous_object  # type: list[DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObject]

    def validate(self):
        if self.synchronous_object:
            for k in self.synchronous_object:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObject, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['SynchronousObject'] = []
        if self.synchronous_object is not None:
            for k in self.synchronous_object:
                result['SynchronousObject'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.synchronous_object = []
        if m.get('SynchronousObject') is not None:
            for k in m.get('SynchronousObject'):
                temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObjectSynchronousObject()
                self.synchronous_object.append(temp_model.from_map(k))
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTagsTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The tag key.
        self.key = key  # type: str
        # The tag value that corresponds to the tag key.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTagsTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTags(TeaModel):
    def __init__(self, tag=None):
        self.tag = tag  # type: list[DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTagsTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTags, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTagsTag()
                self.tag.append(temp_model.from_map(k))
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstance(TeaModel):
    def __init__(self, begin_timestamp=None, consumption_checkpoint=None, consumption_client=None,
                 end_timestamp=None, error_message=None, instance_create_time=None, job_create_time=None, pay_type=None,
                 source_endpoint=None, status=None, subscribe_topic=None, subscription_data_type=None, subscription_host=None,
                 subscription_instance_id=None, subscription_instance_name=None, subscription_object=None, tags=None):
        # The start of the time range for change tracking. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.begin_timestamp = begin_timestamp  # type: str
        # The consumption checkpoint of the change tracking instance. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.consumption_checkpoint = consumption_checkpoint  # type: str
        # The downstream client information, in the following format: \<IP address of the downstream client>:\<Random ID generated by DTS>.
        self.consumption_client = consumption_client  # type: str
        # The end of the time range for change tracking. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.end_timestamp = end_timestamp  # type: str
        # The error message returned if change tracking failed.
        self.error_message = error_message  # type: str
        # The time when the change tracking instance was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format. The time must be in UTC.
        self.instance_create_time = instance_create_time  # type: str
        # The time when the change tracking task was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.job_create_time = job_create_time  # type: str
        # The billing method of the change tracking instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSourceEndpoint
        # The status of the change tracking task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Starting**: The task is being started.
        # *   **Normal**: The task is running as expected.
        # *   **Abnormal**: The task is not running as expected.
        self.status = status  # type: str
        # The topic of the change tracking instance.
        # 
        # >  This parameter is returned only if your change tracking instances are of the new version and you have called the [CreateConsumerGroup](~~122863~~) operation to create a consumer group.
        self.subscribe_topic = subscribe_topic  # type: str
        # The types of operations that are tracked by the task.
        self.subscription_data_type = subscription_data_type  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionDataType
        # The endpoint of the change tracking instance.
        self.subscription_host = subscription_host  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionHost
        # The ID of the change tracking instance.
        self.subscription_instance_id = subscription_instance_id  # type: str
        # The name of the change tracking instance.
        self.subscription_instance_name = subscription_instance_name  # type: str
        # The objects for change tracking.
        self.subscription_object = subscription_object  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObject
        # The collection of tags.
        self.tags = tags  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTags

    def validate(self):
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.subscription_data_type:
            self.subscription_data_type.validate()
        if self.subscription_host:
            self.subscription_host.validate()
        if self.subscription_object:
            self.subscription_object.validate()
        if self.tags:
            self.tags.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.begin_timestamp is not None:
            result['BeginTimestamp'] = self.begin_timestamp
        if self.consumption_checkpoint is not None:
            result['ConsumptionCheckpoint'] = self.consumption_checkpoint
        if self.consumption_client is not None:
            result['ConsumptionClient'] = self.consumption_client
        if self.end_timestamp is not None:
            result['EndTimestamp'] = self.end_timestamp
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.instance_create_time is not None:
            result['InstanceCreateTime'] = self.instance_create_time
        if self.job_create_time is not None:
            result['JobCreateTime'] = self.job_create_time
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.subscribe_topic is not None:
            result['SubscribeTopic'] = self.subscribe_topic
        if self.subscription_data_type is not None:
            result['SubscriptionDataType'] = self.subscription_data_type.to_map()
        if self.subscription_host is not None:
            result['SubscriptionHost'] = self.subscription_host.to_map()
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceID'] = self.subscription_instance_id
        if self.subscription_instance_name is not None:
            result['SubscriptionInstanceName'] = self.subscription_instance_name
        if self.subscription_object is not None:
            result['SubscriptionObject'] = self.subscription_object.to_map()
        if self.tags is not None:
            result['Tags'] = self.tags.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BeginTimestamp') is not None:
            self.begin_timestamp = m.get('BeginTimestamp')
        if m.get('ConsumptionCheckpoint') is not None:
            self.consumption_checkpoint = m.get('ConsumptionCheckpoint')
        if m.get('ConsumptionClient') is not None:
            self.consumption_client = m.get('ConsumptionClient')
        if m.get('EndTimestamp') is not None:
            self.end_timestamp = m.get('EndTimestamp')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('InstanceCreateTime') is not None:
            self.instance_create_time = m.get('InstanceCreateTime')
        if m.get('JobCreateTime') is not None:
            self.job_create_time = m.get('JobCreateTime')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('SubscribeTopic') is not None:
            self.subscribe_topic = m.get('SubscribeTopic')
        if m.get('SubscriptionDataType') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionDataType()
            self.subscription_data_type = temp_model.from_map(m['SubscriptionDataType'])
        if m.get('SubscriptionHost') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionHost()
            self.subscription_host = temp_model.from_map(m['SubscriptionHost'])
        if m.get('SubscriptionInstanceID') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceID')
        if m.get('SubscriptionInstanceName') is not None:
            self.subscription_instance_name = m.get('SubscriptionInstanceName')
        if m.get('SubscriptionObject') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceSubscriptionObject()
            self.subscription_object = temp_model.from_map(m['SubscriptionObject'])
        if m.get('Tags') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstanceTags()
            self.tags = temp_model.from_map(m['Tags'])
        return self


class DescribeSubscriptionInstancesResponseBodySubscriptionInstances(TeaModel):
    def __init__(self, subscription_instance=None):
        self.subscription_instance = subscription_instance  # type: list[DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstance]

    def validate(self):
        if self.subscription_instance:
            for k in self.subscription_instance:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBodySubscriptionInstances, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['SubscriptionInstance'] = []
        if self.subscription_instance is not None:
            for k in self.subscription_instance:
                result['SubscriptionInstance'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.subscription_instance = []
        if m.get('SubscriptionInstance') is not None:
            for k in m.get('SubscriptionInstance'):
                temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstancesSubscriptionInstance()
                self.subscription_instance.append(temp_model.from_map(k))
        return self


class DescribeSubscriptionInstancesResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, page_number=None, page_record_count=None, request_id=None,
                 subscription_instances=None, success=None, total_record_count=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The maximum number of entries that can be displayed on the current page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The list of change tracking instances and the details of each instance.
        self.subscription_instances = subscription_instances  # type: DescribeSubscriptionInstancesResponseBodySubscriptionInstances
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The total number of change tracking instances that belong to your Alibaba Cloud account.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.subscription_instances:
            self.subscription_instances.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.subscription_instances is not None:
            result['SubscriptionInstances'] = self.subscription_instances.to_map()
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SubscriptionInstances') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBodySubscriptionInstances()
            self.subscription_instances = temp_model.from_map(m['SubscriptionInstances'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeSubscriptionInstancesResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSubscriptionInstancesResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionInstancesResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSubscriptionInstancesResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSubscriptionMetaRequest(TeaModel):
    def __init__(self, dts_instance_id=None, region_id=None, sid=None, sub_migration_job_ids=None, topics=None):
        # The ID of the distributed change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the region in which the change tracking instance resides.
        self.region_id = region_id  # type: str
        # The ID of the consumer group.
        self.sid = sid  # type: str
        # The IDs of all subtasks in the distributed change tracking task. Separate multiple subtask IDs with commas (,).
        # 
        # >  You must specify at least one of the SubMigrationJobIds and **Topics** parameters. We recommend that you specify the SubMigrationJobIds parameter.
        self.sub_migration_job_ids = sub_migration_job_ids  # type: dict[str, any]
        # The topics of all subtasks in the distributed change tracking task. Separate multiple topics with commas (,).
        # 
        # >  You must specify at least one of the **SubMigrationJobIds** and Topics parameters. We recommend that you specify the **SubMigrationJobIds** parameter.
        self.topics = topics  # type: dict[str, any]

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionMetaRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.sid is not None:
            result['Sid'] = self.sid
        if self.sub_migration_job_ids is not None:
            result['SubMigrationJobIds'] = self.sub_migration_job_ids
        if self.topics is not None:
            result['Topics'] = self.topics
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Sid') is not None:
            self.sid = m.get('Sid')
        if m.get('SubMigrationJobIds') is not None:
            self.sub_migration_job_ids = m.get('SubMigrationJobIds')
        if m.get('Topics') is not None:
            self.topics = m.get('Topics')
        return self


class DescribeSubscriptionMetaShrinkRequest(TeaModel):
    def __init__(self, dts_instance_id=None, region_id=None, sid=None, sub_migration_job_ids_shrink=None,
                 topics_shrink=None):
        # The ID of the distributed change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the region in which the change tracking instance resides.
        self.region_id = region_id  # type: str
        # The ID of the consumer group.
        self.sid = sid  # type: str
        # The IDs of all subtasks in the distributed change tracking task. Separate multiple subtask IDs with commas (,).
        # 
        # >  You must specify at least one of the SubMigrationJobIds and **Topics** parameters. We recommend that you specify the SubMigrationJobIds parameter.
        self.sub_migration_job_ids_shrink = sub_migration_job_ids_shrink  # type: str
        # The topics of all subtasks in the distributed change tracking task. Separate multiple topics with commas (,).
        # 
        # >  You must specify at least one of the **SubMigrationJobIds** and Topics parameters. We recommend that you specify the **SubMigrationJobIds** parameter.
        self.topics_shrink = topics_shrink  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionMetaShrinkRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.sid is not None:
            result['Sid'] = self.sid
        if self.sub_migration_job_ids_shrink is not None:
            result['SubMigrationJobIds'] = self.sub_migration_job_ids_shrink
        if self.topics_shrink is not None:
            result['Topics'] = self.topics_shrink
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Sid') is not None:
            self.sid = m.get('Sid')
        if m.get('SubMigrationJobIds') is not None:
            self.sub_migration_job_ids_shrink = m.get('SubMigrationJobIds')
        if m.get('Topics') is not None:
            self.topics_shrink = m.get('Topics')
        return self


class DescribeSubscriptionMetaResponseBodySubscriptionMetaList(TeaModel):
    def __init__(self, checkpoint=None, dblist=None, dproxy_url=None, sid=None, topic=None):
        # The consumer offset of the subtask. It is a UNIX timestamp that is generated when the client consumes the first data record. Unit: seconds.
        # 
        # >  You can use a search engine to obtain a UNIX timestamp converter.
        self.checkpoint = checkpoint  # type: long
        # The objects of the subtask. For more information, see [Objects of DTS tasks](~~209545~~).
        self.dblist = dblist  # type: str
        # The endpoint and port number of the change tracking instance.
        self.dproxy_url = dproxy_url  # type: str
        # The consumer group ID of the subtask.
        self.sid = sid  # type: str
        # The topic of the subtask.
        self.topic = topic  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSubscriptionMetaResponseBodySubscriptionMetaList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.dblist is not None:
            result['DBList'] = self.dblist
        if self.dproxy_url is not None:
            result['DProxyUrl'] = self.dproxy_url
        if self.sid is not None:
            result['Sid'] = self.sid
        if self.topic is not None:
            result['Topic'] = self.topic
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('DBList') is not None:
            self.dblist = m.get('DBList')
        if m.get('DProxyUrl') is not None:
            self.dproxy_url = m.get('DProxyUrl')
        if m.get('Sid') is not None:
            self.sid = m.get('Sid')
        if m.get('Topic') is not None:
            self.topic = m.get('Topic')
        return self


class DescribeSubscriptionMetaResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, http_status_code=None, request_id=None,
                 subscription_meta_list=None, success=None):
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The details of the subtasks.
        self.subscription_meta_list = subscription_meta_list  # type: list[DescribeSubscriptionMetaResponseBodySubscriptionMetaList]
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        if self.subscription_meta_list:
            for k in self.subscription_meta_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionMetaResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        result['SubscriptionMetaList'] = []
        if self.subscription_meta_list is not None:
            for k in self.subscription_meta_list:
                result['SubscriptionMetaList'].append(k.to_map() if k else None)
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        self.subscription_meta_list = []
        if m.get('SubscriptionMetaList') is not None:
            for k in m.get('SubscriptionMetaList'):
                temp_model = DescribeSubscriptionMetaResponseBodySubscriptionMetaList()
                self.subscription_meta_list.append(temp_model.from_map(k))
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeSubscriptionMetaResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSubscriptionMetaResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSubscriptionMetaResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSubscriptionMetaResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSynchronizationJobAlertRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None,
                 synchronization_direction=None, synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that it is unique among different requests. The token can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # >  Default value: **Forward**.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the **DescribeSynchronizationJobs** operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobAlertRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class DescribeSynchronizationJobAlertResponseBody(TeaModel):
    def __init__(self, delay_alert_phone=None, delay_alert_status=None, delay_over_seconds=None, err_code=None,
                 err_message=None, error_alert_phone=None, error_alert_status=None, request_id=None, success=None,
                 synchronization_direction=None, synchronization_job_id=None, synchronization_job_name=None):
        # The mobile phone numbers that receive latency-related alerts.
        self.delay_alert_phone = delay_alert_phone  # type: str
        # Indicates whether task latency is monitored. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        self.delay_alert_status = delay_alert_status  # type: str
        # The threshold for triggering latency alerts. Unit: seconds.
        self.delay_over_seconds = delay_over_seconds  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The mobile phone numbers that receive status-related alerts.
        self.error_alert_phone = error_alert_phone  # type: str
        # Indicates whether task status is monitored. Valid values:
        # 
        # *   **enable**: yes
        # *   **disable**: no
        self.error_alert_status = error_alert_status  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # 
        # *   **Reverse**\
        # 
        # > This parameter is returned only when the topology of data synchronization is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance.
        self.synchronization_job_id = synchronization_job_id  # type: str
        # The name of the data synchronization task.
        self.synchronization_job_name = synchronization_job_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobAlertResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay_alert_phone is not None:
            result['DelayAlertPhone'] = self.delay_alert_phone
        if self.delay_alert_status is not None:
            result['DelayAlertStatus'] = self.delay_alert_status
        if self.delay_over_seconds is not None:
            result['DelayOverSeconds'] = self.delay_over_seconds
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_alert_phone is not None:
            result['ErrorAlertPhone'] = self.error_alert_phone
        if self.error_alert_status is not None:
            result['ErrorAlertStatus'] = self.error_alert_status
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        if self.synchronization_job_name is not None:
            result['SynchronizationJobName'] = self.synchronization_job_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DelayAlertPhone') is not None:
            self.delay_alert_phone = m.get('DelayAlertPhone')
        if m.get('DelayAlertStatus') is not None:
            self.delay_alert_status = m.get('DelayAlertStatus')
        if m.get('DelayOverSeconds') is not None:
            self.delay_over_seconds = m.get('DelayOverSeconds')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorAlertPhone') is not None:
            self.error_alert_phone = m.get('ErrorAlertPhone')
        if m.get('ErrorAlertStatus') is not None:
            self.error_alert_status = m.get('ErrorAlertStatus')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        if m.get('SynchronizationJobName') is not None:
            self.synchronization_job_name = m.get('SynchronizationJobName')
        return self


class DescribeSynchronizationJobAlertResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSynchronizationJobAlertResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobAlertResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSynchronizationJobAlertResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSynchronizationJobReplicatorCompareRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None,
                 synchronization_direction=None, synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   This parameter is required only when the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the [DescribeSynchronizationJobs](~~49454~~) operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobReplicatorCompareRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class DescribeSynchronizationJobReplicatorCompareResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None,
                 synchronization_replicator_compare_enable=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # Indicates whether image matching is enabled. Valid values:
        # 
        # *   **true**: Image matching is enabled.
        # *   **false**: Image matching is disabled.
        self.synchronization_replicator_compare_enable = synchronization_replicator_compare_enable  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobReplicatorCompareResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.synchronization_replicator_compare_enable is not None:
            result['SynchronizationReplicatorCompareEnable'] = self.synchronization_replicator_compare_enable
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('SynchronizationReplicatorCompareEnable') is not None:
            self.synchronization_replicator_compare_enable = m.get('SynchronizationReplicatorCompareEnable')
        return self


class DescribeSynchronizationJobReplicatorCompareResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSynchronizationJobReplicatorCompareResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobReplicatorCompareResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSynchronizationJobReplicatorCompareResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSynchronizationJobStatusRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None,
                 synchronization_direction=None, synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that the value is unique among different requests. The **ClientToken** value can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region where the data synchronization instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # >  Default value: **Forward**.
        # 
        # The value **Reverse** takes effect only if the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the [DescribeSynchronizationJobs](~~49454~~) operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class DescribeSynchronizationJobStatusResponseBodyDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if full data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of full data synchronization. Unit: %.
        self.percent = percent  # type: str
        # The number of records that have been synchronized during full data synchronization.
        self.progress = progress  # type: str
        # The status of full data synchronization. Valid values:
        # 
        # *   **NotStarted**: Full data synchronization is not started.
        # *   **Migrating**: Full data synchronization is in progress.
        # *   **Failed**: Full data synchronization failed.
        # *   **Finished**: Full data synchronization is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobStatusResponseBodyDataSynchronizationStatus(TeaModel):
    def __init__(self, checkpoint=None, delay=None, delay_millis=None, error_message=None, percent=None, status=None):
        # The UNIX timestamp generated when the latest data record was synchronized.
        self.checkpoint = checkpoint  # type: str
        # The synchronization latency, in seconds.
        self.delay = delay  # type: str
        # The synchronization latency, in milliseconds.
        self.delay_millis = delay_millis  # type: long
        # The error message returned if incremental data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of incremental data synchronization. Unit: %.
        self.percent = percent  # type: str
        # The status of incremental data synchronization. Valid values:
        # 
        # *   **NotStarted**: Incremental data synchronization is not started.
        # *   **Migrating**: Incremental data synchronization is in progress.
        # *   **Failed**: Incremental data synchronization failed.
        # *   **Finished**: Incremental data synchronization is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.delay_millis is not None:
            result['DelayMillis'] = self.delay_millis
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DelayMillis') is not None:
            self.delay_millis = m.get('DelayMillis')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobStatusResponseBodyDestinationEndpoint(TeaModel):
    def __init__(self, engine_name=None, ip=None, instance_id=None, instance_type=None, port=None, user_name=None):
        # The database type of the destination instance.
        self.engine_name = engine_name  # type: str
        # The endpoint of the destination instance.
        self.ip = ip  # type: str
        # The ID of the destination instance.
        self.instance_id = instance_id  # type: str
        # The type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The database service port of the destination instance.
        self.port = port  # type: str
        # The database account of the destination instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeSynchronizationJobStatusResponseBodyPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        # The data traffic that is synchronized per second. Unit: MB/s.
        self.flow = flow  # type: str
        # The number of times SQL statements are synchronized per second, including BEGIN, COMMIT, DML, and DDL statements. DML statements include INSERT, DELETE, and UPDATE.
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['FLOW'] = self.flow
        if self.rps is not None:
            result['RPS'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('FLOW') is not None:
            self.flow = m.get('FLOW')
        if m.get('RPS') is not None:
            self.rps = m.get('RPS')
        return self


class DescribeSynchronizationJobStatusResponseBodyPrecheckStatusDetail(TeaModel):
    def __init__(self, check_status=None, error_message=None, item_name=None, repair_method=None):
        # The precheck result. Valid values:
        # 
        # *   **Success**: The task passed the precheck.
        # *   **Failed**: The task failed to pass the precheck.
        self.check_status = check_status  # type: str
        # The error message returned if the task failed to pass the precheck.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.error_message = error_message  # type: str
        # The name of the precheck item.
        self.item_name = item_name  # type: str
        # The method to fix the precheck failure.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_status is not None:
            result['CheckStatus'] = self.check_status
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.item_name is not None:
            result['ItemName'] = self.item_name
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckStatus') is not None:
            self.check_status = m.get('CheckStatus')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ItemName') is not None:
            self.item_name = m.get('ItemName')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeSynchronizationJobStatusResponseBodyPrecheckStatus(TeaModel):
    def __init__(self, detail=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: list[DescribeSynchronizationJobStatusResponseBodyPrecheckStatusDetail]
        # The precheck progress. Unit: %.
        self.percent = percent  # type: str
        # The precheck result. Valid values:
        # 
        # *   **Success**: The task passed the precheck.
        # *   **Failed**: The task failed to pass the precheck.
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeSynchronizationJobStatusResponseBodyPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobStatusResponseBodySourceEndpoint(TeaModel):
    def __init__(self, engine_name=None, ip=None, instance_id=None, instance_type=None, port=None, user_name=None):
        # The database type of the source instance.
        self.engine_name = engine_name  # type: str
        # The endpoint of the source instance.
        self.ip = ip  # type: str
        # The ID of the source instance.
        self.instance_id = instance_id  # type: str
        # The type of the source instance.
        self.instance_type = instance_type  # type: str
        # The database service port of the source instance.
        self.port = port  # type: str
        # The database account of the source instance.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodySourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeSynchronizationJobStatusResponseBodyStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if schema synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of schema synchronization. Unit: %.
        self.percent = percent  # type: str
        # The number of tables whose schemas have been synchronized.
        self.progress = progress  # type: str
        # The status of schema synchronization. Valid values:
        # 
        # *   **NotStarted**: Schema synchronization is not started.
        # *   **Migrating**: Schema synchronization is in progress.
        # *   **Failed**: Schema synchronization failed.
        # *   **Finished**: Schema synchronization is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodyStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableExcludes(TeaModel):
    def __init__(self, table_name=None):
        # The name of the excluded table.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableExcludes, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableIncludes(TeaModel):
    def __init__(self, table_name=None):
        # The name of the synchronized table.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableIncludes, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeSynchronizationJobStatusResponseBodySynchronizationObjects(TeaModel):
    def __init__(self, new_schema_name=None, schema_name=None, table_excludes=None, table_includes=None):
        # The database name that is used in the destination instance.
        self.new_schema_name = new_schema_name  # type: str
        # The name of the synchronized database.
        self.schema_name = schema_name  # type: str
        # The source tables that are excluded from the data synchronization task.
        self.table_excludes = table_excludes  # type: list[DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableExcludes]
        # The tables that are synchronized by the task.
        self.table_includes = table_includes  # type: list[DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableIncludes]

    def validate(self):
        if self.table_excludes:
            for k in self.table_excludes:
                if k:
                    k.validate()
        if self.table_includes:
            for k in self.table_includes:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBodySynchronizationObjects, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.new_schema_name is not None:
            result['NewSchemaName'] = self.new_schema_name
        if self.schema_name is not None:
            result['SchemaName'] = self.schema_name
        result['TableExcludes'] = []
        if self.table_excludes is not None:
            for k in self.table_excludes:
                result['TableExcludes'].append(k.to_map() if k else None)
        result['TableIncludes'] = []
        if self.table_includes is not None:
            for k in self.table_includes:
                result['TableIncludes'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('NewSchemaName') is not None:
            self.new_schema_name = m.get('NewSchemaName')
        if m.get('SchemaName') is not None:
            self.schema_name = m.get('SchemaName')
        self.table_excludes = []
        if m.get('TableExcludes') is not None:
            for k in m.get('TableExcludes'):
                temp_model = DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableExcludes()
                self.table_excludes.append(temp_model.from_map(k))
        self.table_includes = []
        if m.get('TableIncludes') is not None:
            for k in m.get('TableIncludes'):
                temp_model = DescribeSynchronizationJobStatusResponseBodySynchronizationObjectsTableIncludes()
                self.table_includes.append(temp_model.from_map(k))
        return self


class DescribeSynchronizationJobStatusResponseBody(TeaModel):
    def __init__(self, checkpoint=None, data_initialization=None, data_initialization_status=None,
                 data_synchronization_status=None, delay=None, delay_millis=None, destination_endpoint=None, err_code=None, err_message=None,
                 error_message=None, expire_time=None, pay_type=None, performance=None, precheck_status=None, request_id=None,
                 source_endpoint=None, status=None, structure_initialization=None, structure_initialization_status=None,
                 success=None, synchronization_direction=None, synchronization_job_class=None,
                 synchronization_job_id=None, synchronization_job_name=None, synchronization_objects=None, task_id=None):
        # The UNIX timestamp generated when the latest data record was synchronized.
        # 
        # >  You can use a search engine to obtain a UNIX timestamp converter.
        self.checkpoint = checkpoint  # type: str
        # Indicates whether full data synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.data_initialization = data_initialization  # type: str
        # The status of full data synchronization.
        self.data_initialization_status = data_initialization_status  # type: DescribeSynchronizationJobStatusResponseBodyDataInitializationStatus
        # The status of incremental data synchronization.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeSynchronizationJobStatusResponseBodyDataSynchronizationStatus
        # The synchronization latency, in seconds.
        self.delay = delay  # type: str
        # The synchronization delay, in milliseconds.
        self.delay_millis = delay_millis  # type: long
        # The connection settings of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeSynchronizationJobStatusResponseBodyDestinationEndpoint
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The error message returned if data synchronization failed.
        self.error_message = error_message  # type: str
        # The time when the data synchronization instance expires. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        # 
        # >  This parameter is returned only if the return value of the **PayType** parameter is **PrePaid**.
        self.expire_time = expire_time  # type: str
        # The billing method of the data synchronization instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.pay_type = pay_type  # type: str
        # The performance of the data synchronization instance.
        self.performance = performance  # type: DescribeSynchronizationJobStatusResponseBodyPerformance
        # The precheck status.
        self.precheck_status = precheck_status  # type: DescribeSynchronizationJobStatusResponseBodyPrecheckStatus
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The connection settings of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeSynchronizationJobStatusResponseBodySourceEndpoint
        # The status of the data synchronization task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Initializing**: The task is performing initial synchronization.
        # *   **InitializeFailed**: Initial synchronization failed.
        # *   **Synchronizing**: The task is synchronizing data.
        # *   **Failed**: The task failed to synchronize data.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is completed.
        self.status = status  # type: str
        # Indicates whether schema synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.structure_initialization = structure_initialization  # type: str
        # The status of schema synchronization.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeSynchronizationJobStatusResponseBodyStructureInitializationStatus
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        self.synchronization_direction = synchronization_direction  # type: str
        # The specification of the data synchronization instance.
        self.synchronization_job_class = synchronization_job_class  # type: str
        # The ID of the data synchronization instance.
        self.synchronization_job_id = synchronization_job_id  # type: str
        # The name of the data synchronization task.
        self.synchronization_job_name = synchronization_job_name  # type: str
        # The objects that are synchronized by the task.
        self.synchronization_objects = synchronization_objects  # type: list[DescribeSynchronizationJobStatusResponseBodySynchronizationObjects]
        self.task_id = task_id  # type: str

    def validate(self):
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.synchronization_objects:
            for k in self.synchronization_objects:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.delay_millis is not None:
            result['DelayMillis'] = self.delay_millis
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.success is not None:
            result['Success'] = self.success
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_class is not None:
            result['SynchronizationJobClass'] = self.synchronization_job_class
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        if self.synchronization_job_name is not None:
            result['SynchronizationJobName'] = self.synchronization_job_name
        result['SynchronizationObjects'] = []
        if self.synchronization_objects is not None:
            for k in self.synchronization_objects:
                result['SynchronizationObjects'].append(k.to_map() if k else None)
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodyDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodyDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DelayMillis') is not None:
            self.delay_millis = m.get('DelayMillis')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodyDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodyPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodyPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodySourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBodyStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobClass') is not None:
            self.synchronization_job_class = m.get('SynchronizationJobClass')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        if m.get('SynchronizationJobName') is not None:
            self.synchronization_job_name = m.get('SynchronizationJobName')
        self.synchronization_objects = []
        if m.get('SynchronizationObjects') is not None:
            for k in m.get('SynchronizationObjects'):
                temp_model = DescribeSynchronizationJobStatusResponseBodySynchronizationObjects()
                self.synchronization_objects.append(temp_model.from_map(k))
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class DescribeSynchronizationJobStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSynchronizationJobStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSynchronizationJobStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSynchronizationJobStatusListRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None,
                 synchronization_job_id_list_json_str=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The IDs of the data synchronization instances. The value is a JSON array. You can call the [DescribeSynchronizationJobs](~~49454~~) operation to query the instance IDs.
        self.synchronization_job_id_list_json_str = synchronization_job_id_list_json_str  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusListRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_job_id_list_json_str is not None:
            result['SynchronizationJobIdListJsonStr'] = self.synchronization_job_id_list_json_str
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationJobIdListJsonStr') is not None:
            self.synchronization_job_id_list_json_str = m.get('SynchronizationJobIdListJsonStr')
        return self


class DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusListSynchronizationDirectionInfoList(TeaModel):
    def __init__(self, checkpoint=None, status=None, synchronization_direction=None):
        # The UNIX timestamp generated when the latest data record was synchronized.
        # 
        # >  You can use a search engine to obtain a UNIX timestamp converter.
        self.checkpoint = checkpoint  # type: str
        # The status of the data synchronization task in this direction. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Initializing**: The task is performing initial synchronization.
        # *   **InitializeFailed**: Initial synchronization failed.
        # *   **Synchronizing**: The task is synchronizing data.
        # *   **Failed**: The task failed to synchronize data.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is completed.
        self.status = status  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusListSynchronizationDirectionInfoList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.checkpoint is not None:
            result['Checkpoint'] = self.checkpoint
        if self.status is not None:
            result['Status'] = self.status
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Checkpoint') is not None:
            self.checkpoint = m.get('Checkpoint')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusList(TeaModel):
    def __init__(self, synchronization_direction_info_list=None, synchronization_job_id=None):
        # The details of data synchronization tasks in each direction.
        self.synchronization_direction_info_list = synchronization_direction_info_list  # type: list[DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusListSynchronizationDirectionInfoList]
        # The ID of the data synchronization instance.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        if self.synchronization_direction_info_list:
            for k in self.synchronization_direction_info_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['SynchronizationDirectionInfoList'] = []
        if self.synchronization_direction_info_list is not None:
            for k in self.synchronization_direction_info_list:
                result['SynchronizationDirectionInfoList'].append(k.to_map() if k else None)
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.synchronization_direction_info_list = []
        if m.get('SynchronizationDirectionInfoList') is not None:
            for k in m.get('SynchronizationDirectionInfoList'):
                temp_model = DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusListSynchronizationDirectionInfoList()
                self.synchronization_direction_info_list.append(temp_model.from_map(k))
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class DescribeSynchronizationJobStatusListResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, page_number=None, page_record_count=None, request_id=None,
                 success=None, synchronization_job_list_status_list=None, total_record_count=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The page number of the returned page.
        self.page_number = page_number  # type: int
        # The number of data synchronization instances displayed on one page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The status of the data synchronization tasks.
        self.synchronization_job_list_status_list = synchronization_job_list_status_list  # type: list[DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusList]
        # The total number of data synchronization instances.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.synchronization_job_list_status_list:
            for k in self.synchronization_job_list_status_list:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusListResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        result['SynchronizationJobListStatusList'] = []
        if self.synchronization_job_list_status_list is not None:
            for k in self.synchronization_job_list_status_list:
                result['SynchronizationJobListStatusList'].append(k.to_map() if k else None)
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        self.synchronization_job_list_status_list = []
        if m.get('SynchronizationJobListStatusList') is not None:
            for k in m.get('SynchronizationJobListStatusList'):
                temp_model = DescribeSynchronizationJobStatusListResponseBodySynchronizationJobListStatusList()
                self.synchronization_job_list_status_list.append(temp_model.from_map(k))
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeSynchronizationJobStatusListResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSynchronizationJobStatusListResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobStatusListResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSynchronizationJobStatusListResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSynchronizationJobsRequestTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The ID of the request.
        self.key = key  # type: str
        # The maximum number of entries that can be displayed on the current page.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsRequestTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class DescribeSynchronizationJobsRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, page_num=None, page_size=None,
                 region_id=None, synchronization_job_name=None, tag=None):
        # The page number of the returned page.
        self.account_id = account_id  # type: str
        # The tag value. You can call the [ListTagResources](~~191187~~) operation to query the tag value.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Value specifies the value of the first tag and Tag.2.Value specifies the value of the second tag. You can specify 1 to 20 tag values at a time.
        # *   This parameter can be an empty string.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.page_num = page_num  # type: int
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that the value is unique among different requests. The **ClientToken** value can contain only ASCII characters and cannot exceed 64 characters in length.
        self.page_size = page_size  # type: int
        # The name of the data synchronization task.
        # 
        # >  Fuzzy matching is supported.
        self.region_id = region_id  # type: str
        # The tag key. You can call the [ListTagResources](~~191187~~) operation to query the tag key.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Key specifies the key of the first tag and Tag.2.Key specifies the key of the second tag. You can specify 1 to 20 tag keys at a time.
        # *   This parameter cannot be an empty string.
        self.synchronization_job_name = synchronization_job_name  # type: str
        self.tag = tag  # type: list[DescribeSynchronizationJobsRequestTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_num is not None:
            result['PageNum'] = self.page_num
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_job_name is not None:
            result['SynchronizationJobName'] = self.synchronization_job_name
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNum') is not None:
            self.page_num = m.get('PageNum')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationJobName') is not None:
            self.synchronization_job_name = m.get('SynchronizationJobName')
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = DescribeSynchronizationJobsRequestTag()
                self.tag.append(temp_model.from_map(k))
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The status of incremental data synchronization.
        # 
        # >  This parameter is no longer available.
        self.error_message = error_message  # type: str
        # The status of incremental data synchronization.
        # 
        # >  This parameter and its sub-parameters are no longer available.
        self.percent = percent  # type: str
        # The synchronization latency.
        # 
        # >  This parameter is no longer available.
        self.progress = progress  # type: str
        # The number of records that have been synchronized during full data synchronization.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataSynchronizationStatus(TeaModel):
    def __init__(self, delay=None, error_message=None, percent=None, status=None):
        # The connection settings of the destination instance.
        self.delay = delay  # type: str
        # The endpoint of the destination instance.
        self.error_message = error_message  # type: str
        # The ID of the destination instance.
        self.percent = percent  # type: str
        # The error message returned if incremental data synchronization failed.
        # 
        # >  This parameter is no longer available.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesDestinationEndpoint(TeaModel):
    def __init__(self, engine_name=None, ip=None, instance_id=None, instance_type=None, port=None, user_name=None):
        # The data traffic that is synchronized per second. Unit: MB/s.
        self.engine_name = engine_name  # type: str
        # The database account of the destination instance.
        self.ip = ip  # type: str
        # The database service port of the destination instance.
        self.instance_id = instance_id  # type: str
        # The database type of the destination instance.
        self.instance_type = instance_type  # type: str
        # The performance of the data synchronization instance.
        self.port = port  # type: str
        # The number of times SQL statements are synchronized per second, including BEGIN, COMMIT, DML, and DDL statements. DML statements include INSERT, DELETE, and UPDATE.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesDestinationEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesPerformance(TeaModel):
    def __init__(self, flow=None, rps=None):
        # The precheck progress. Unit: %.
        self.flow = flow  # type: str
        # The precheck result. Valid values:
        # 
        # *   **Success**: The task passed the precheck.
        # *   **Failed**: The task failed to pass the precheck.
        self.rps = rps  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesPerformance, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.flow is not None:
            result['FLOW'] = self.flow
        if self.rps is not None:
            result['RPS'] = self.rps
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('FLOW') is not None:
            self.flow = m.get('FLOW')
        if m.get('RPS') is not None:
            self.rps = m.get('RPS')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatusDetail(TeaModel):
    def __init__(self, check_status=None, error_message=None, item_name=None, repair_method=None):
        # The method to fix the precheck failure.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.check_status = check_status  # type: str
        # The connection settings of the source instance.
        self.error_message = error_message  # type: str
        # The ID of the source instance.
        self.item_name = item_name  # type: str
        # The endpoint of the source instance.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_status is not None:
            result['CheckStatus'] = self.check_status
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.item_name is not None:
            result['ItemName'] = self.item_name
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckStatus') is not None:
            self.check_status = m.get('CheckStatus')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ItemName') is not None:
            self.item_name = m.get('ItemName')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatus(TeaModel):
    def __init__(self, detail=None, percent=None, status=None):
        # The name of the precheck item.
        self.detail = detail  # type: list[DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatusDetail]
        # The error message returned if the task failed to pass the precheck.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.percent = percent  # type: str
        # The precheck result. Valid values:
        # 
        # *   **Success**: The task passed the precheck.
        # *   **Failed**: The task failed to pass the precheck.
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesSourceEndpoint(TeaModel):
    def __init__(self, engine_name=None, ip=None, instance_id=None, instance_type=None, port=None, user_name=None):
        # The progress of schema synchronization. Unit: %.
        self.engine_name = engine_name  # type: str
        # The database account of the source instance.
        self.ip = ip  # type: str
        # The database service port of the source instance.
        self.instance_id = instance_id  # type: str
        # The database type of the source instance.
        self.instance_type = instance_type  # type: str
        # The status of schema synchronization.
        self.port = port  # type: str
        # The status of schema synchronization. Valid values:
        # 
        # *   **NotStarted**: Schema synchronization is not started.
        # *   **Migrating**: Schema synchronization is in progress.
        # *   **Failed**: Schema synchronization failed.
        # *   **Finished**: Schema synchronization is completed.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.engine_name is not None:
            result['EngineName'] = self.engine_name
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('EngineName') is not None:
            self.engine_name = m.get('EngineName')
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        self.error_message = error_message  # type: str
        self.percent = percent  # type: str
        self.progress = progress  # type: str
        # The number of tables whose schemas have been synchronized.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableExcludes(TeaModel):
    def __init__(self, table_name=None):
        # The status of full data synchronization.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableExcludes, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableIncludes(TeaModel):
    def __init__(self, table_name=None):
        # The progress of full data synchronization. Unit: %.
        self.table_name = table_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableIncludes, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.table_name is not None:
            result['TableName'] = self.table_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('TableName') is not None:
            self.table_name = m.get('TableName')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjects(TeaModel):
    def __init__(self, new_schema_name=None, schema_name=None, table_excludes=None, table_includes=None):
        # The name of the excluded table.
        self.new_schema_name = new_schema_name  # type: str
        # The tables that are synchronized by the task.
        self.schema_name = schema_name  # type: str
        # The name of the synchronized table.
        self.table_excludes = table_excludes  # type: list[DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableExcludes]
        # The status of full data synchronization. Valid values:
        # 
        # *   **NotStarted**: Full data synchronization is not started.
        # *   **Migrating**: Full data synchronization is in progress.
        # *   **Failed**: Full data synchronization failed.
        # *   **Finished**: Full data synchronization is completed.
        self.table_includes = table_includes  # type: list[DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableIncludes]

    def validate(self):
        if self.table_excludes:
            for k in self.table_excludes:
                if k:
                    k.validate()
        if self.table_includes:
            for k in self.table_includes:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjects, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.new_schema_name is not None:
            result['NewSchemaName'] = self.new_schema_name
        if self.schema_name is not None:
            result['SchemaName'] = self.schema_name
        result['TableExcludes'] = []
        if self.table_excludes is not None:
            for k in self.table_excludes:
                result['TableExcludes'].append(k.to_map() if k else None)
        result['TableIncludes'] = []
        if self.table_includes is not None:
            for k in self.table_includes:
                result['TableIncludes'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('NewSchemaName') is not None:
            self.new_schema_name = m.get('NewSchemaName')
        if m.get('SchemaName') is not None:
            self.schema_name = m.get('SchemaName')
        self.table_excludes = []
        if m.get('TableExcludes') is not None:
            for k in m.get('TableExcludes'):
                temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableExcludes()
                self.table_excludes.append(temp_model.from_map(k))
        self.table_includes = []
        if m.get('TableIncludes') is not None:
            for k in m.get('TableIncludes'):
                temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjectsTableIncludes()
                self.table_includes.append(temp_model.from_map(k))
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstancesTags(TeaModel):
    def __init__(self, key=None, value=None):
        # The database name that is used in the destination instance.
        self.key = key  # type: str
        # The name of the synchronized database.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstancesTags, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class DescribeSynchronizationJobsResponseBodySynchronizationInstances(TeaModel):
    def __init__(self, create_time=None, data_initialization=None, data_initialization_status=None,
                 data_synchronization_status=None, delay=None, destination_endpoint=None, error_message=None, expire_time=None,
                 instance_create_time=None, job_create_time=None, pay_type=None, performance=None, precheck_status=None,
                 source_endpoint=None, status=None, structure_initialization=None, structure_initialization_status=None,
                 synchronization_direction=None, synchronization_job_class=None, synchronization_job_id=None, synchronization_job_name=None,
                 synchronization_objects=None, tags=None):
        # The specification of the data synchronization instance.
        self.create_time = create_time  # type: str
        # The synchronization latency, in seconds.
        self.data_initialization = data_initialization  # type: str
        # The error message returned if full data synchronization failed.
        self.data_initialization_status = data_initialization_status  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataInitializationStatus
        # The progress of incremental data synchronization. Unit: %.
        # 
        # >  This parameter is no longer available.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataSynchronizationStatus
        # The time when the data synchronization task was created. The time is displayed in the *yyyy-MM-dd* *HH:mm:ss*.0 format (UTC+8).
        self.delay = delay  # type: str
        # The type of the destination instance.
        self.destination_endpoint = destination_endpoint  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesDestinationEndpoint
        # The billing method of the data synchronization instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.error_message = error_message  # type: str
        # Indicates whether schema synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.expire_time = expire_time  # type: str
        # The time when the data synchronization task was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.instance_create_time = instance_create_time  # type: str
        # The tag value that corresponds to the tag key.
        self.job_create_time = job_create_time  # type: str
        # The time when the instance was created. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        self.pay_type = pay_type  # type: str
        # The precheck status.
        self.performance = performance  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesPerformance
        # The result of each precheck item.
        self.precheck_status = precheck_status  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatus
        # The type of the source instance.
        self.source_endpoint = source_endpoint  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesSourceEndpoint
        # The error message returned if data synchronization failed.
        self.status = status  # type: str
        # The ID of the data synchronization instance.
        self.structure_initialization = structure_initialization  # type: str
        # The error message returned if schema synchronization failed.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeSynchronizationJobsResponseBodySynchronizationInstancesStructureInitializationStatus
        # The tag key.
        self.synchronization_direction = synchronization_direction  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        self.synchronization_job_class = synchronization_job_class  # type: str
        # The collection of tags.
        self.synchronization_job_id = synchronization_job_id  # type: str
        # The time when the data synchronization instance expires. The time is displayed in the *yyyy-MM-dd*T*HH:mm:ss*Z format in UTC.
        # 
        # >  This parameter is returned only if the return value of the **PayType** parameter is **PrePaid**.
        self.synchronization_job_name = synchronization_job_name  # type: str
        # The source tables that are excluded from the data synchronization task.
        self.synchronization_objects = synchronization_objects  # type: list[DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjects]
        # The objects that are synchronized by the task.
        self.tags = tags  # type: list[DescribeSynchronizationJobsResponseBodySynchronizationInstancesTags]

    def validate(self):
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.destination_endpoint:
            self.destination_endpoint.validate()
        if self.performance:
            self.performance.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()
        if self.synchronization_objects:
            for k in self.synchronization_objects:
                if k:
                    k.validate()
        if self.tags:
            for k in self.tags:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBodySynchronizationInstances, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.create_time is not None:
            result['CreateTime'] = self.create_time
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.destination_endpoint is not None:
            result['DestinationEndpoint'] = self.destination_endpoint.to_map()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.expire_time is not None:
            result['ExpireTime'] = self.expire_time
        if self.instance_create_time is not None:
            result['InstanceCreateTime'] = self.instance_create_time
        if self.job_create_time is not None:
            result['JobCreateTime'] = self.job_create_time
        if self.pay_type is not None:
            result['PayType'] = self.pay_type
        if self.performance is not None:
            result['Performance'] = self.performance.to_map()
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_class is not None:
            result['SynchronizationJobClass'] = self.synchronization_job_class
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        if self.synchronization_job_name is not None:
            result['SynchronizationJobName'] = self.synchronization_job_name
        result['SynchronizationObjects'] = []
        if self.synchronization_objects is not None:
            for k in self.synchronization_objects:
                result['SynchronizationObjects'].append(k.to_map() if k else None)
        result['Tags'] = []
        if self.tags is not None:
            for k in self.tags:
                result['Tags'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CreateTime') is not None:
            self.create_time = m.get('CreateTime')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('DestinationEndpoint') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesDestinationEndpoint()
            self.destination_endpoint = temp_model.from_map(m['DestinationEndpoint'])
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ExpireTime') is not None:
            self.expire_time = m.get('ExpireTime')
        if m.get('InstanceCreateTime') is not None:
            self.instance_create_time = m.get('InstanceCreateTime')
        if m.get('JobCreateTime') is not None:
            self.job_create_time = m.get('JobCreateTime')
        if m.get('PayType') is not None:
            self.pay_type = m.get('PayType')
        if m.get('Performance') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesPerformance()
            self.performance = temp_model.from_map(m['Performance'])
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('SourceEndpoint') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobClass') is not None:
            self.synchronization_job_class = m.get('SynchronizationJobClass')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        if m.get('SynchronizationJobName') is not None:
            self.synchronization_job_name = m.get('SynchronizationJobName')
        self.synchronization_objects = []
        if m.get('SynchronizationObjects') is not None:
            for k in m.get('SynchronizationObjects'):
                temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesSynchronizationObjects()
                self.synchronization_objects.append(temp_model.from_map(k))
        self.tags = []
        if m.get('Tags') is not None:
            for k in m.get('Tags'):
                temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstancesTags()
                self.tags.append(temp_model.from_map(k))
        return self


class DescribeSynchronizationJobsResponseBody(TeaModel):
    def __init__(self, page_number=None, page_record_count=None, request_id=None, synchronization_instances=None,
                 total_record_count=None):
        # The total number of data synchronization instances that belong to your Alibaba Cloud account.
        self.page_number = page_number  # type: int
        # Indicates whether full data synchronization is performed. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.page_record_count = page_record_count  # type: int
        # The list of data synchronization instances and the details of each instance.
        self.request_id = request_id  # type: str
        # The name of the data synchronization task.
        self.synchronization_instances = synchronization_instances  # type: list[DescribeSynchronizationJobsResponseBodySynchronizationInstances]
        # The status of the data synchronization task. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Initializing**: The task is performing initial synchronization.
        # *   **InitializeFailed**: Initial synchronization failed.
        # *   **Synchronizing**: The task is synchronizing data.
        # *   **Failed**: The task failed to synchronize data.
        # *   **Suspending**: The task is paused.
        # *   **Modifying**: The objects in the task are being modified.
        # *   **Finished**: The task is completed.
        self.total_record_count = total_record_count  # type: long

    def validate(self):
        if self.synchronization_instances:
            for k in self.synchronization_instances:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        result['SynchronizationInstances'] = []
        if self.synchronization_instances is not None:
            for k in self.synchronization_instances:
                result['SynchronizationInstances'].append(k.to_map() if k else None)
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        self.synchronization_instances = []
        if m.get('SynchronizationInstances') is not None:
            for k in m.get('SynchronizationInstances'):
                temp_model = DescribeSynchronizationJobsResponseBodySynchronizationInstances()
                self.synchronization_instances.append(temp_model.from_map(k))
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class DescribeSynchronizationJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSynchronizationJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSynchronizationJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeSynchronizationObjectModifyStatusRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, owner_id=None, region_id=None, task_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must make sure that the value is unique among different requests. The **ClientToken** value can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region where the data synchronization instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The task ID, which is returned after you call the [ModifySynchronizationObject](~~49451~~) operation to modify the objects to be synchronized.
        self.task_id = task_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class DescribeSynchronizationObjectModifyStatusResponseBodyDataInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if full data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of full data synchronization. Unit: %.
        self.percent = percent  # type: str
        # The number of records that have been synchronized during full data synchronization.
        self.progress = progress  # type: str
        # The status of full data synchronization. Valid values:
        # 
        # *   **NotStarted**: Full data synchronization is not started.
        # *   **Migrating**: Full data synchronization is in progress.
        # *   **Failed**: Full data synchronization failed.
        # *   **Finished**: Full data synchronization is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponseBodyDataInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationObjectModifyStatusResponseBodyDataSynchronizationStatus(TeaModel):
    def __init__(self, delay=None, error_message=None, percent=None, status=None):
        # The synchronization latency, in seconds.
        self.delay = delay  # type: str
        # The error message returned if incremental data synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of incremental data synchronization. Unit: %.
        self.percent = percent  # type: str
        # The status of incremental data synchronization. Valid values:
        # 
        # *   **NotStarted**: Incremental data synchronization is not started.
        # *   **Migrating**: Incremental data synchronization is in progress.
        # *   **Failed**: Incremental data synchronization failed.
        # *   **Finished**: Incremental data synchronization is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponseBodyDataSynchronizationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.delay is not None:
            result['Delay'] = self.delay
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Delay') is not None:
            self.delay = m.get('Delay')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatusDetail(TeaModel):
    def __init__(self, check_status=None, error_message=None, item_name=None, repair_method=None):
        # The precheck result. Valid values:
        # 
        # *   Success: The task passed the precheck.
        # *   Failed: The task failed to pass the precheck.
        self.check_status = check_status  # type: str
        # The error message returned if the task failed to pass the precheck.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is **Failed**.
        self.error_message = error_message  # type: str
        # The name of the precheck item.
        self.item_name = item_name  # type: str
        # The method to fix the precheck failure.
        # 
        # >  This parameter is returned only if the return value of the **CheckStatus** parameter is Failed.
        self.repair_method = repair_method  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatusDetail, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.check_status is not None:
            result['CheckStatus'] = self.check_status
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.item_name is not None:
            result['ItemName'] = self.item_name
        if self.repair_method is not None:
            result['RepairMethod'] = self.repair_method
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CheckStatus') is not None:
            self.check_status = m.get('CheckStatus')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('ItemName') is not None:
            self.item_name = m.get('ItemName')
        if m.get('RepairMethod') is not None:
            self.repair_method = m.get('RepairMethod')
        return self


class DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatus(TeaModel):
    def __init__(self, detail=None, percent=None, status=None):
        # The result of each precheck item.
        self.detail = detail  # type: list[DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatusDetail]
        # The precheck progress. Unit: %.
        self.percent = percent  # type: str
        # The precheck status.
        self.status = status  # type: str

    def validate(self):
        if self.detail:
            for k in self.detail:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['Detail'] = []
        if self.detail is not None:
            for k in self.detail:
                result['Detail'].append(k.to_map() if k else None)
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.detail = []
        if m.get('Detail') is not None:
            for k in m.get('Detail'):
                temp_model = DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatusDetail()
                self.detail.append(temp_model.from_map(k))
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationObjectModifyStatusResponseBodyStructureInitializationStatus(TeaModel):
    def __init__(self, error_message=None, percent=None, progress=None, status=None):
        # The error message returned if schema synchronization failed.
        self.error_message = error_message  # type: str
        # The progress of schema synchronization. Unit: %.
        self.percent = percent  # type: str
        # The number of tables whose schemas have been synchronized.
        self.progress = progress  # type: str
        # The status of schema synchronization. Valid values:
        # 
        # *   **NotStarted**: Schema synchronization is not started.
        # *   **Migrating**: Schema synchronization is in progress.
        # *   **Failed**: Schema synchronization failed.
        # *   **Finished**: Schema synchronization is completed.
        self.status = status  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponseBodyStructureInitializationStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.percent is not None:
            result['Percent'] = self.percent
        if self.progress is not None:
            result['Progress'] = self.progress
        if self.status is not None:
            result['Status'] = self.status
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('Percent') is not None:
            self.percent = m.get('Percent')
        if m.get('Progress') is not None:
            self.progress = m.get('Progress')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        return self


class DescribeSynchronizationObjectModifyStatusResponseBody(TeaModel):
    def __init__(self, data_initialization_status=None, data_synchronization_status=None, err_code=None,
                 err_message=None, error_message=None, precheck_status=None, request_id=None, status=None,
                 structure_initialization_status=None, success=None):
        # The status of full data synchronization.
        self.data_initialization_status = data_initialization_status  # type: DescribeSynchronizationObjectModifyStatusResponseBodyDataInitializationStatus
        # The status of incremental data synchronization.
        # 
        # >  This parameter and its sub-parameters will be removed in the future.
        self.data_synchronization_status = data_synchronization_status  # type: DescribeSynchronizationObjectModifyStatusResponseBodyDataSynchronizationStatus
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The error message returned if the task failed to modify the objects to be synchronized.
        self.error_message = error_message  # type: str
        # The precheck status.
        self.precheck_status = precheck_status  # type: DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatus
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The status of the task that changes the objects to be synchronized. Valid values:
        # 
        # *   **NotStarted**: The task is not started.
        # *   **Prechecking**: The task is being prechecked.
        # *   **PrecheckFailed**: The task failed to pass the precheck.
        # *   **Migrating**: The task is running.
        # *   **Failed**: The task failed.
        # *   **Finished**: The task is completed.
        self.status = status  # type: str
        # The status of schema synchronization.
        self.structure_initialization_status = structure_initialization_status  # type: DescribeSynchronizationObjectModifyStatusResponseBodyStructureInitializationStatus
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        if self.data_initialization_status:
            self.data_initialization_status.validate()
        if self.data_synchronization_status:
            self.data_synchronization_status.validate()
        if self.precheck_status:
            self.precheck_status.validate()
        if self.structure_initialization_status:
            self.structure_initialization_status.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.data_initialization_status is not None:
            result['DataInitializationStatus'] = self.data_initialization_status.to_map()
        if self.data_synchronization_status is not None:
            result['DataSynchronizationStatus'] = self.data_synchronization_status.to_map()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.error_message is not None:
            result['ErrorMessage'] = self.error_message
        if self.precheck_status is not None:
            result['PrecheckStatus'] = self.precheck_status.to_map()
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.status is not None:
            result['Status'] = self.status
        if self.structure_initialization_status is not None:
            result['StructureInitializationStatus'] = self.structure_initialization_status.to_map()
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DataInitializationStatus') is not None:
            temp_model = DescribeSynchronizationObjectModifyStatusResponseBodyDataInitializationStatus()
            self.data_initialization_status = temp_model.from_map(m['DataInitializationStatus'])
        if m.get('DataSynchronizationStatus') is not None:
            temp_model = DescribeSynchronizationObjectModifyStatusResponseBodyDataSynchronizationStatus()
            self.data_synchronization_status = temp_model.from_map(m['DataSynchronizationStatus'])
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('ErrorMessage') is not None:
            self.error_message = m.get('ErrorMessage')
        if m.get('PrecheckStatus') is not None:
            temp_model = DescribeSynchronizationObjectModifyStatusResponseBodyPrecheckStatus()
            self.precheck_status = temp_model.from_map(m['PrecheckStatus'])
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('StructureInitializationStatus') is not None:
            temp_model = DescribeSynchronizationObjectModifyStatusResponseBodyStructureInitializationStatus()
            self.structure_initialization_status = temp_model.from_map(m['StructureInitializationStatus'])
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class DescribeSynchronizationObjectModifyStatusResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeSynchronizationObjectModifyStatusResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeSynchronizationObjectModifyStatusResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeSynchronizationObjectModifyStatusResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeTagKeysRequest(TeaModel):
    def __init__(self, category=None, page_number=None, page_size=None, region_id=None, resource_id=None,
                 resource_type=None):
        # The type of the tag. Valid values:
        # 
        # *   **Custom**: The tag is added by a user.
        # *   **System**: The tag is added by the system.
        # 
        # >  By default, if the parameter is left empty, custom tags and system tags are returned.
        self.category = category  # type: str
        # The number of the page to return. Pages start from page 1. Default value: 1. This parameter is used together with PageSize.
        self.page_number = page_number  # type: int
        # The number of tags to return on each page if the DTS instance has multiple tags. Default value: 20.
        self.page_size = page_size  # type: int
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.resource_id = resource_id  # type: str
        # The resource type. Set the value to **ALIYUN::DTS::INSTANCE**.
        self.resource_type = resource_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeTagKeysRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.category is not None:
            result['Category'] = self.category
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Category') is not None:
            self.category = m.get('Category')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        return self


class DescribeTagKeysResponseBody(TeaModel):
    def __init__(self, category=None, page_number=None, page_size=None, request_id=None, tag_keys=None,
                 total_count=None):
        # The type of the tag.
        self.category = category  # type: str
        # The start page of the returned pages.
        self.page_number = page_number  # type: int
        # The number of tags returned per page.
        self.page_size = page_size  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The key of the tag.
        self.tag_keys = tag_keys  # type: list[str]
        # The total number of returned tag keys.
        self.total_count = total_count  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeTagKeysResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.category is not None:
            result['Category'] = self.category
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.tag_keys is not None:
            result['TagKeys'] = self.tag_keys
        if self.total_count is not None:
            result['TotalCount'] = self.total_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Category') is not None:
            self.category = m.get('Category')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('TagKeys') is not None:
            self.tag_keys = m.get('TagKeys')
        if m.get('TotalCount') is not None:
            self.total_count = m.get('TotalCount')
        return self


class DescribeTagKeysResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeTagKeysResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeTagKeysResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeTagKeysResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class DescribeTagValuesRequest(TeaModel):
    def __init__(self, category=None, key=None, page_number=None, page_size=None, region_id=None, resource_id=None,
                 resource_type=None):
        # The type of the tag key. Valid values:
        # 
        # *   **Custom**: The tag key is created by users.
        # *   **System**: The tag key is created by the system.
        # 
        # >  By default, if the parameter is left empty, both custom tag keys and system tag keys are returned.
        self.category = category  # type: str
        # The tag key.
        # 
        # >  This parameter is required.
        self.key = key  # type: str
        # The page number of the start page to return for a tag key that has multiple values. The valid value ranges from 1 to the maximum value of the INTEGER data type. This parameter is often used with the PageSize parameter. Default value: 1.
        self.page_number = page_number  # type: int
        # The number of tag values to return each time for a tag key that has multiple values. Default value: 20.
        self.page_size = page_size  # type: int
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        # 
        # >  If this parameter is left empty, the values of all tag keys of the current user are returned.
        self.resource_id = resource_id  # type: str
        # The resource type. Set the value to **ALIYUN::DTS::INSTANCE**.
        self.resource_type = resource_type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeTagValuesRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.category is not None:
            result['Category'] = self.category
        if self.key is not None:
            result['Key'] = self.key
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Category') is not None:
            self.category = m.get('Category')
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        return self


class DescribeTagValuesResponseBody(TeaModel):
    def __init__(self, category=None, page_number=None, page_size=None, request_id=None, tag_values=None,
                 total_count=None):
        # The type of the tag key.
        self.category = category  # type: str
        # The start page of the returned pages.
        self.page_number = page_number  # type: int
        # The number of tag values returned on each page.
        self.page_size = page_size  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The tag values that are associated with the tag key.
        self.tag_values = tag_values  # type: list[str]
        # The total number of tag values that are associated with the tag key.
        self.total_count = total_count  # type: int

    def validate(self):
        pass

    def to_map(self):
        _map = super(DescribeTagValuesResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.category is not None:
            result['Category'] = self.category
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.tag_values is not None:
            result['TagValues'] = self.tag_values
        if self.total_count is not None:
            result['TotalCount'] = self.total_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Category') is not None:
            self.category = m.get('Category')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('TagValues') is not None:
            self.tag_values = m.get('TagValues')
        if m.get('TotalCount') is not None:
            self.total_count = m.get('TotalCount')
        return self


class DescribeTagValuesResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: DescribeTagValuesResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(DescribeTagValuesResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = DescribeTagValuesResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class InitDtsRdsInstanceRequest(TeaModel):
    def __init__(self, dts_instance_id=None, endpoint_cen_id=None, endpoint_instance_id=None,
                 endpoint_instance_type=None, endpoint_region=None, region_id=None):
        # The ID of the data synchronization task.
        self.dts_instance_id = dts_instance_id  # type: str
        # If the node is a self-managed MySQL database that is connected over CEN, you must specify the ID of the CEN instance.
        # 
        # > You must specify the **EndpointRegion** and **EndpointInstanceId** parameters or the EndpointCenId parameter based on the type of the node.
        self.endpoint_cen_id = endpoint_cen_id  # type: str
        # If the node is an ApsaraDB RDS for MySQL instance, you must specify the ID of the ApsaraDB RDS for MySQL instance.
        # 
        # > *   You must also specify the **EndpointRegion** parameter.
        # >*   You must specify the EndpointInstanceId parameter or the **EndpointCenId** parameter based on the type of the node.
        self.endpoint_instance_id = endpoint_instance_id  # type: str
        # The type of the node. Valid values:
        # 
        # *   **RDS**: an ApsaraDB RDS for MySQL instance
        # *   **CEN**: a self-managed MySQL database that is connected over CEN
        self.endpoint_instance_type = endpoint_instance_type  # type: str
        # If the node is an ApsaraDB RDS for MySQL instance, you must specify the region in which the ApsaraDB RDS for MySQL instance resides.
        # 
        # > *   You must also specify the **EndpointInstanceId** parameter.
        # >*   You must specify the EndpointRegion parameter or the **EndpointCenId** parameter based on the type of the node.
        self.endpoint_region = endpoint_region  # type: str
        # The ID of the region in which the active geo-redundancy database cluster resides.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(InitDtsRdsInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.endpoint_cen_id is not None:
            result['EndpointCenId'] = self.endpoint_cen_id
        if self.endpoint_instance_id is not None:
            result['EndpointInstanceId'] = self.endpoint_instance_id
        if self.endpoint_instance_type is not None:
            result['EndpointInstanceType'] = self.endpoint_instance_type
        if self.endpoint_region is not None:
            result['EndpointRegion'] = self.endpoint_region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('EndpointCenId') is not None:
            self.endpoint_cen_id = m.get('EndpointCenId')
        if m.get('EndpointInstanceId') is not None:
            self.endpoint_instance_id = m.get('EndpointInstanceId')
        if m.get('EndpointInstanceType') is not None:
            self.endpoint_instance_type = m.get('EndpointInstanceType')
        if m.get('EndpointRegion') is not None:
            self.endpoint_region = m.get('EndpointRegion')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class InitDtsRdsInstanceResponseBody(TeaModel):
    def __init__(self, admin_account=None, admin_password=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The built-in account that is used by DTS to connect to the node.
        self.admin_account = admin_account  # type: str
        # The password of the built-in account.
        self.admin_password = admin_password  # type: str
        # The error code returned if the request fails.
        self.err_code = err_code  # type: str
        # The error message returned if the request fails.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request is successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(InitDtsRdsInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.admin_account is not None:
            result['AdminAccount'] = self.admin_account
        if self.admin_password is not None:
            result['AdminPassword'] = self.admin_password
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AdminAccount') is not None:
            self.admin_account = m.get('AdminAccount')
        if m.get('AdminPassword') is not None:
            self.admin_password = m.get('AdminPassword')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class InitDtsRdsInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: InitDtsRdsInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(InitDtsRdsInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = InitDtsRdsInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ListDedicatedClusterRequest(TeaModel):
    def __init__(self, order_column=None, order_direction=None, owner_id=None, page_number=None, page_size=None,
                 params=None, region_id=None, state=None, type=None):
        # The basis on which the retrieved entries are sorted if multiple DTS dedicated clusters are returned. Valid values:
        # 
        # *   **gmtCreated**: the time when a cluster was created.
        # *   **orderCount**: the number of nodes in a cluster.
        self.order_column = order_column  # type: str
        # The order in which you want to sort the retrieved entries. Valid values:
        # 
        # *   asc: sorts the retrieved entries in ascending order. This is the default value.
        # *   desc: sorts the retrieved entries in descending order.
        self.order_direction = order_direction  # type: str
        self.owner_id = owner_id  # type: str
        # The number of the page to return. The value of this parameter must be an integer that is greater than 0. Default value: **1**.
        self.page_number = page_number  # type: int
        # The number of clusters to return on each page.
        self.page_size = page_size  # type: int
        # The content of the query condition.
        # 
        # >  You must set the **Type parameter** to specify the type of the query condition.
        self.params = params  # type: str
        # The ID of the region.
        self.region_id = region_id  # type: str
        # The status of the cluster. Valid values:
        # 
        # *   **init**: The cluster is being initialized.
        # *   **schedule**: The cluster is pending scheduling.
        # *   **running**: The cluster is running.
        # *   **upgrade**: The cluster is being upgraded.
        # *   **downgrade**: The cluster is being downgraded.
        # *   **locked**: The cluster is locked.
        # *   **releasing**: The cluster is being released.
        # *   **released**: The cluster is released.
        self.state = state  # type: str
        # The type of the query condition. Valid values:
        # 
        # *   **NAME**: the name of the cluster.
        # *   **INSTANCE**: the ID of a cluster instance.
        # *   **DEDICAETEDCLUSTERID**: the ID of a dedicated cluster.
        # 
        # >  You must specify the query condition by using the **Params** parameter.
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ListDedicatedClusterRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.order_column is not None:
            result['OrderColumn'] = self.order_column
        if self.order_direction is not None:
            result['OrderDirection'] = self.order_direction
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_size is not None:
            result['PageSize'] = self.page_size
        if self.params is not None:
            result['Params'] = self.params
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.state is not None:
            result['State'] = self.state
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('OrderColumn') is not None:
            self.order_column = m.get('OrderColumn')
        if m.get('OrderDirection') is not None:
            self.order_direction = m.get('OrderDirection')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageSize') is not None:
            self.page_size = m.get('PageSize')
        if m.get('Params') is not None:
            self.params = m.get('Params')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class ListDedicatedClusterResponseBodyDedicatedClusterStatusListDedicatedClusterStatus(TeaModel):
    def __init__(self, cpu_utilization=None, dedicated_cluster_id=None, dedicated_cluster_name=None,
                 disk_utilization=None, dts_instance_id=None, du=None, du_utilization=None, gmt_created=None, mem_utilization=None,
                 node_count=None, oversold_du=None, region_id=None, state=None, total_cpu_core=None, total_disk_gbsize=None,
                 total_mem_gbsize=None, used_cpu_core=None, used_disk_gbsize=None, used_du=None, used_mem_gbsize=None):
        # The CPU utilization, in percentage.
        self.cpu_utilization = cpu_utilization  # type: long
        # The ID of the cluster.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The name of the cluster.
        self.dedicated_cluster_name = dedicated_cluster_name  # type: str
        # The disk usage.
        self.disk_utilization = disk_utilization  # type: long
        # The ID of the DTS instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The number of DTS units (DUs).
        self.du = du  # type: long
        # The DU usage, in percentage.
        self.du_utilization = du_utilization  # type: long
        # The time when the cluster was created.
        self.gmt_created = gmt_created  # type: long
        # The memory usage.
        self.mem_utilization = mem_utilization  # type: long
        # The number of nodes in the cluster.
        self.node_count = node_count  # type: long
        # The number of over-provisioned DUs.
        self.oversold_du = oversold_du  # type: long
        # The ID of the region in which the DTS instance resides.
        self.region_id = region_id  # type: str
        # The status of the cluster. Valid values:
        # 
        # *   **init**: The cluster is being initialized.
        # *   **schedule**: The cluster is pending scheduling.
        # *   **running**: The cluster is running.
        # *   **upgrade**: The cluster is being upgraded.
        # *   **downgrade**: The cluster is being downgraded.
        # *   **locked**: The cluster is locked.
        # *   **releasing**: The cluster is being released.
        # *   **released**: The cluster is released.
        self.state = state  # type: str
        # The total number of CPU cores.
        self.total_cpu_core = total_cpu_core  # type: long
        # The total disk capacity. Unit: GB.
        self.total_disk_gbsize = total_disk_gbsize  # type: long
        # The total memory capacity. Unit: GB.
        self.total_mem_gbsize = total_mem_gbsize  # type: long
        # The number of used CPU cores.
        self.used_cpu_core = used_cpu_core  # type: long
        # The used disk capacity. Unit: GB.
        self.used_disk_gbsize = used_disk_gbsize  # type: long
        # The number of used DUs.
        self.used_du = used_du  # type: long
        # The used memory capacity. Unit: GB.
        self.used_mem_gbsize = used_mem_gbsize  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(ListDedicatedClusterResponseBodyDedicatedClusterStatusListDedicatedClusterStatus, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.cpu_utilization is not None:
            result['CpuUtilization'] = self.cpu_utilization
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dedicated_cluster_name is not None:
            result['DedicatedClusterName'] = self.dedicated_cluster_name
        if self.disk_utilization is not None:
            result['DiskUtilization'] = self.disk_utilization
        if self.dts_instance_id is not None:
            result['DtsInstanceID'] = self.dts_instance_id
        if self.du is not None:
            result['Du'] = self.du
        if self.du_utilization is not None:
            result['DuUtilization'] = self.du_utilization
        if self.gmt_created is not None:
            result['GmtCreated'] = self.gmt_created
        if self.mem_utilization is not None:
            result['MemUtilization'] = self.mem_utilization
        if self.node_count is not None:
            result['NodeCount'] = self.node_count
        if self.oversold_du is not None:
            result['OversoldDu'] = self.oversold_du
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.state is not None:
            result['State'] = self.state
        if self.total_cpu_core is not None:
            result['TotalCpuCore'] = self.total_cpu_core
        if self.total_disk_gbsize is not None:
            result['TotalDiskGBSize'] = self.total_disk_gbsize
        if self.total_mem_gbsize is not None:
            result['TotalMemGBSize'] = self.total_mem_gbsize
        if self.used_cpu_core is not None:
            result['UsedCpuCore'] = self.used_cpu_core
        if self.used_disk_gbsize is not None:
            result['UsedDiskGBSize'] = self.used_disk_gbsize
        if self.used_du is not None:
            result['UsedDu'] = self.used_du
        if self.used_mem_gbsize is not None:
            result['UsedMemGBSize'] = self.used_mem_gbsize
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('CpuUtilization') is not None:
            self.cpu_utilization = m.get('CpuUtilization')
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DedicatedClusterName') is not None:
            self.dedicated_cluster_name = m.get('DedicatedClusterName')
        if m.get('DiskUtilization') is not None:
            self.disk_utilization = m.get('DiskUtilization')
        if m.get('DtsInstanceID') is not None:
            self.dts_instance_id = m.get('DtsInstanceID')
        if m.get('Du') is not None:
            self.du = m.get('Du')
        if m.get('DuUtilization') is not None:
            self.du_utilization = m.get('DuUtilization')
        if m.get('GmtCreated') is not None:
            self.gmt_created = m.get('GmtCreated')
        if m.get('MemUtilization') is not None:
            self.mem_utilization = m.get('MemUtilization')
        if m.get('NodeCount') is not None:
            self.node_count = m.get('NodeCount')
        if m.get('OversoldDu') is not None:
            self.oversold_du = m.get('OversoldDu')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('TotalCpuCore') is not None:
            self.total_cpu_core = m.get('TotalCpuCore')
        if m.get('TotalDiskGBSize') is not None:
            self.total_disk_gbsize = m.get('TotalDiskGBSize')
        if m.get('TotalMemGBSize') is not None:
            self.total_mem_gbsize = m.get('TotalMemGBSize')
        if m.get('UsedCpuCore') is not None:
            self.used_cpu_core = m.get('UsedCpuCore')
        if m.get('UsedDiskGBSize') is not None:
            self.used_disk_gbsize = m.get('UsedDiskGBSize')
        if m.get('UsedDu') is not None:
            self.used_du = m.get('UsedDu')
        if m.get('UsedMemGBSize') is not None:
            self.used_mem_gbsize = m.get('UsedMemGBSize')
        return self


class ListDedicatedClusterResponseBodyDedicatedClusterStatusList(TeaModel):
    def __init__(self, dedicated_cluster_status=None):
        self.dedicated_cluster_status = dedicated_cluster_status  # type: list[ListDedicatedClusterResponseBodyDedicatedClusterStatusListDedicatedClusterStatus]

    def validate(self):
        if self.dedicated_cluster_status:
            for k in self.dedicated_cluster_status:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(ListDedicatedClusterResponseBodyDedicatedClusterStatusList, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['DedicatedClusterStatus'] = []
        if self.dedicated_cluster_status is not None:
            for k in self.dedicated_cluster_status:
                result['DedicatedClusterStatus'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.dedicated_cluster_status = []
        if m.get('DedicatedClusterStatus') is not None:
            for k in m.get('DedicatedClusterStatus'):
                temp_model = ListDedicatedClusterResponseBodyDedicatedClusterStatusListDedicatedClusterStatus()
                self.dedicated_cluster_status.append(temp_model.from_map(k))
        return self


class ListDedicatedClusterResponseBody(TeaModel):
    def __init__(self, dedicated_cluster_status_list=None, err_code=None, err_message=None, http_status_code=None,
                 page_number=None, page_record_count=None, request_id=None, success=None, total_record_count=None):
        # The statuses of all clusters.
        self.dedicated_cluster_status_list = dedicated_cluster_status_list  # type: ListDedicatedClusterResponseBodyDedicatedClusterStatusList
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The page number of the returned page. The value must be an integer that is greater than 0. Default value: 1.
        self.page_number = page_number  # type: int
        # The number of entries returned per page.
        self.page_record_count = page_record_count  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str
        # The total number of clusters that meet the query condition.
        self.total_record_count = total_record_count  # type: int

    def validate(self):
        if self.dedicated_cluster_status_list:
            self.dedicated_cluster_status_list.validate()

    def to_map(self):
        _map = super(ListDedicatedClusterResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_status_list is not None:
            result['DedicatedClusterStatusList'] = self.dedicated_cluster_status_list.to_map()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.page_number is not None:
            result['PageNumber'] = self.page_number
        if self.page_record_count is not None:
            result['PageRecordCount'] = self.page_record_count
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.total_record_count is not None:
            result['TotalRecordCount'] = self.total_record_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterStatusList') is not None:
            temp_model = ListDedicatedClusterResponseBodyDedicatedClusterStatusList()
            self.dedicated_cluster_status_list = temp_model.from_map(m['DedicatedClusterStatusList'])
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('PageNumber') is not None:
            self.page_number = m.get('PageNumber')
        if m.get('PageRecordCount') is not None:
            self.page_record_count = m.get('PageRecordCount')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TotalRecordCount') is not None:
            self.total_record_count = m.get('TotalRecordCount')
        return self


class ListDedicatedClusterResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ListDedicatedClusterResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ListDedicatedClusterResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ListDedicatedClusterResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ListTagResourcesRequestTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The tag key.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Key specifies the key of the first tag and Tag.2.Key specifies the key of the second tag. You can specify 1 to 20 tag keys at a time.
        # *   You must specify at least one of the **ResourceId.N** and Tag.N.Key parameters. The parameters cannot be empty strings.
        self.key = key  # type: str
        # The tag value.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Value specifies the value of the first tag and Tag.2.Value specifies the value of the second tag. You can specify 1 to 20 tag values at a time.
        # *   This parameter can be an empty string.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ListTagResourcesRequestTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class ListTagResourcesRequest(TeaModel):
    def __init__(self, next_token=None, region_id=None, resource_id=None, resource_type=None, tag=None):
        # The query token.
        # 
        # >  If a query does not return all results, you can specify the returned **NextToken** parameter in the next query to obtain more results.
        self.next_token = next_token  # type: str
        # The ID of the region where the data migration, data synchronization, or change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        self.resource_id = resource_id  # type: list[str]
        # The resource type. Valid value: **ALIYUN::DTS::INSTANCE**.
        self.resource_type = resource_type  # type: str
        self.tag = tag  # type: list[ListTagResourcesRequestTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(ListTagResourcesRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.next_token is not None:
            result['NextToken'] = self.next_token
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('NextToken') is not None:
            self.next_token = m.get('NextToken')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = ListTagResourcesRequestTag()
                self.tag.append(temp_model.from_map(k))
        return self


class ListTagResourcesResponseBodyTagResourcesTagResource(TeaModel):
    def __init__(self, resource_id=None, resource_type=None, tag_key=None, tag_value=None):
        # The ID of the DTS instance.
        self.resource_id = resource_id  # type: str
        # The resource type. Valid value: **ALIYUN::DTS::INSTANCE**.
        self.resource_type = resource_type  # type: str
        # The tag key.
        self.tag_key = tag_key  # type: str
        # The tag value that corresponds to the tag key.
        self.tag_value = tag_value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ListTagResourcesResponseBodyTagResourcesTagResource, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        if self.tag_value is not None:
            result['TagValue'] = self.tag_value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        if m.get('TagValue') is not None:
            self.tag_value = m.get('TagValue')
        return self


class ListTagResourcesResponseBodyTagResources(TeaModel):
    def __init__(self, tag_resource=None):
        self.tag_resource = tag_resource  # type: list[ListTagResourcesResponseBodyTagResourcesTagResource]

    def validate(self):
        if self.tag_resource:
            for k in self.tag_resource:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(ListTagResourcesResponseBodyTagResources, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        result['TagResource'] = []
        if self.tag_resource is not None:
            for k in self.tag_resource:
                result['TagResource'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        self.tag_resource = []
        if m.get('TagResource') is not None:
            for k in m.get('TagResource'):
                temp_model = ListTagResourcesResponseBodyTagResourcesTagResource()
                self.tag_resource.append(temp_model.from_map(k))
        return self


class ListTagResourcesResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, next_token=None, request_id=None, success=None,
                 tag_resources=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The query token.
        # 
        # >  If a query does not return all results, you can specify the returned **NextToken** parameter in the next query to obtain more results.
        self.next_token = next_token  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool
        # The collection of tags.
        self.tag_resources = tag_resources  # type: ListTagResourcesResponseBodyTagResources

    def validate(self):
        if self.tag_resources:
            self.tag_resources.validate()

    def to_map(self):
        _map = super(ListTagResourcesResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.next_token is not None:
            result['NextToken'] = self.next_token
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.tag_resources is not None:
            result['TagResources'] = self.tag_resources.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('NextToken') is not None:
            self.next_token = m.get('NextToken')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TagResources') is not None:
            temp_model = ListTagResourcesResponseBodyTagResources()
            self.tag_resources = temp_model.from_map(m['TagResources'])
        return self


class ListTagResourcesResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ListTagResourcesResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ListTagResourcesResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ListTagResourcesResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyConsumerChannelRequest(TeaModel):
    def __init__(self, consumer_group_id=None, consumer_group_name=None, consumer_group_password=None,
                 consumer_group_user_name=None, dts_instance_id=None, dts_job_id=None, region_id=None):
        # The ID of the consumer group. You can call the [DescribeConsumerChannel](~~264169~~) operation to query the consumer group ID.
        self.consumer_group_id = consumer_group_id  # type: str
        # The name of the consumer group. The name cannot exceed 128 characters in length. We recommend that you use an informative name for easy identification.
        self.consumer_group_name = consumer_group_name  # type: str
        # The new password of the consumer group.
        # 
        # *   A password must contain two or more of the following characters: uppercase letters, lowercase letters, digits, and special characters.
        # *   A password must be 8 to 32 characters in length.
        self.consumer_group_password = consumer_group_password  # type: str
        # The new username of the consumer group.
        # 
        # *   A username can contain one or more of the following character types: uppercase letters, lowercase letters, digits, and underscores (\_).
        # *   A username cannot exceed 16 characters in length.
        self.consumer_group_user_name = consumer_group_user_name  # type: str
        # The ID of the change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId** parameters.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        # 
        # >  You must specify at least one of the **DtsInstanceId** and **DtsJobId** parameters.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the region where the change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyConsumerChannelRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.consumer_group_id is not None:
            result['ConsumerGroupId'] = self.consumer_group_id
        if self.consumer_group_name is not None:
            result['ConsumerGroupName'] = self.consumer_group_name
        if self.consumer_group_password is not None:
            result['ConsumerGroupPassword'] = self.consumer_group_password
        if self.consumer_group_user_name is not None:
            result['ConsumerGroupUserName'] = self.consumer_group_user_name
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConsumerGroupId') is not None:
            self.consumer_group_id = m.get('ConsumerGroupId')
        if m.get('ConsumerGroupName') is not None:
            self.consumer_group_name = m.get('ConsumerGroupName')
        if m.get('ConsumerGroupPassword') is not None:
            self.consumer_group_password = m.get('ConsumerGroupPassword')
        if m.get('ConsumerGroupUserName') is not None:
            self.consumer_group_user_name = m.get('ConsumerGroupUserName')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyConsumerChannelResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, http_status_code=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyConsumerChannelResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyConsumerChannelResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyConsumerChannelResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyConsumerChannelResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyConsumerChannelResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyConsumerGroupPasswordRequest(TeaModel):
    def __init__(self, account_id=None, consumer_group_id=None, consumer_group_name=None,
                 consumer_group_password=None, consumer_group_user_name=None, owner_id=None, region_id=None, subscription_instance_id=None,
                 consumer_group_new_password=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The ID of the consumer group.
        # 
        # You can call the [DescribeConsumerGroup](~~122886~~) operation to query the consumer group ID.
        self.consumer_group_id = consumer_group_id  # type: str
        # The name of the consumer group. You can call the [DescribeConsumerGroup](~~122886~~) operation to query the consumer group name.
        self.consumer_group_name = consumer_group_name  # type: str
        # The current password of the consumer group.
        self.consumer_group_password = consumer_group_password  # type: str
        # The username of the consumer group. You can call the [DescribeConsumerGroup](~~122886~~) operation to query the username.
        self.consumer_group_user_name = consumer_group_user_name  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str
        # The new password of the consumer group.
        # 
        # *   A password must contain two or more of the following characters: uppercase letters, lowercase letters, digits, and special characters.
        # *   A password must be 8 to 32 characters in length.
        self.consumer_group_new_password = consumer_group_new_password  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyConsumerGroupPasswordRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.consumer_group_id is not None:
            result['ConsumerGroupID'] = self.consumer_group_id
        if self.consumer_group_name is not None:
            result['ConsumerGroupName'] = self.consumer_group_name
        if self.consumer_group_password is not None:
            result['ConsumerGroupPassword'] = self.consumer_group_password
        if self.consumer_group_user_name is not None:
            result['ConsumerGroupUserName'] = self.consumer_group_user_name
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        if self.consumer_group_new_password is not None:
            result['consumerGroupNewPassword'] = self.consumer_group_new_password
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ConsumerGroupID') is not None:
            self.consumer_group_id = m.get('ConsumerGroupID')
        if m.get('ConsumerGroupName') is not None:
            self.consumer_group_name = m.get('ConsumerGroupName')
        if m.get('ConsumerGroupPassword') is not None:
            self.consumer_group_password = m.get('ConsumerGroupPassword')
        if m.get('ConsumerGroupUserName') is not None:
            self.consumer_group_user_name = m.get('ConsumerGroupUserName')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        if m.get('consumerGroupNewPassword') is not None:
            self.consumer_group_new_password = m.get('consumerGroupNewPassword')
        return self


class ModifyConsumerGroupPasswordResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyConsumerGroupPasswordResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyConsumerGroupPasswordResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyConsumerGroupPasswordResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyConsumerGroupPasswordResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyConsumerGroupPasswordResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyConsumptionTimestampRequest(TeaModel):
    def __init__(self, account_id=None, consumption_timestamp=None, owner_id=None, region_id=None,
                 subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The consumption checkpoint. The format is *yyyy-MM-dd*T*HH:mm:ss*Z. The time is displayed in UTC.
        self.consumption_timestamp = consumption_timestamp  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the **DescribeSubscriptionInstances** operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyConsumptionTimestampRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.consumption_timestamp is not None:
            result['ConsumptionTimestamp'] = self.consumption_timestamp
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ConsumptionTimestamp') is not None:
            self.consumption_timestamp = m.get('ConsumptionTimestamp')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class ModifyConsumptionTimestampResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyConsumptionTimestampResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyConsumptionTimestampResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyConsumptionTimestampResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyConsumptionTimestampResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyConsumptionTimestampResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDedicatedClusterRequest(TeaModel):
    def __init__(self, dedicated_cluster_id=None, dedicated_cluster_name=None, instance_id=None,
                 oversold_ratio=None, owner_id=None, region_id=None):
        # The ID of the cluster.
        # 
        # >  You must specify one of the **InstanceId** and **DedicatedClusterId** parameters.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The name of the cluster.
        self.dedicated_cluster_name = dedicated_cluster_name  # type: str
        # The ID of the instance.
        # 
        # >  You must specify one of the **InstanceId** and **DedicatedClusterId** parameters.
        self.instance_id = instance_id  # type: str
        # The overcommit ratio. Unit: %.
        self.oversold_ratio = oversold_ratio  # type: int
        self.owner_id = owner_id  # type: str
        # The ID of the region in which the Data Transmission Service (DTS) instance resides.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDedicatedClusterRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dedicated_cluster_name is not None:
            result['DedicatedClusterName'] = self.dedicated_cluster_name
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.oversold_ratio is not None:
            result['OversoldRatio'] = self.oversold_ratio
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DedicatedClusterName') is not None:
            self.dedicated_cluster_name = m.get('DedicatedClusterName')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('OversoldRatio') is not None:
            self.oversold_ratio = m.get('OversoldRatio')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyDedicatedClusterResponseBody(TeaModel):
    def __init__(self, dedicated_cluster_id=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        # The ID of the cluster.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDedicatedClusterResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDedicatedClusterResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDedicatedClusterResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDedicatedClusterResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDedicatedClusterResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDtsJobRequest(TeaModel):
    def __init__(self, client_token=None, data_initialization=None, data_synchronization=None, db_list=None,
                 dts_instance_id=None, etl_operator_column_reference=None, file_oss_url=None, filter_table_name=None,
                 modify_type_enum=None, region_id=None, reserved=None, structure_initialization=None,
                 synchronization_direction=None):
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        # The objects of the data synchronization task after modification. The value is a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        # 
        # >  Before you call the ModifyDtsJob operation, we recommend that you call the [DescribeDtsJobDetail](~~208925~~) to query the current objects of the data synchronization task. Then, you can specify the new objects based on your business requirements. For example, if the current objects are Table A and Table B and you need to add Table C, you must specify Table A, Table B, and Table C for this parameter.
        self.db_list = db_list  # type: dict[str, any]
        # The ID of the data synchronization instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The operator that is related to the extract, transform, and load (ETL) feature and dedicated to T+1 business.
        self.etl_operator_column_reference = etl_operator_column_reference  # type: str
        # The endpoint of the Object Storage Service (OSS) bucket in which the files to be synchronized are stored.
        self.file_oss_url = file_oss_url  # type: str
        # The name of the table to be filtered.
        self.filter_table_name = filter_table_name  # type: str
        # The method that is used to modify the data synchronization task. If you do not specify the parameter, the objects of the data synchronization task are modified by default. If you specify UPDATE_RESERVED for the parameter, the reserved parameters are modified.
        self.modify_type_enum = modify_type_enum  # type: str
        # The ID of the region in which the data synchronization instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The reserved parameters of the data synchronization task. You can add reserved parameters instead of overwriting the existing reserved parameters. The value of the parameter is a MAP JSON string. You can specify this parameter to meet special requirements, such as specifying whether to automatically start the precheck of the data synchronization task. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        self.structure_initialization = structure_initialization  # type: bool
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   This parameter is required only if the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.db_list is not None:
            result['DbList'] = self.db_list
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.etl_operator_column_reference is not None:
            result['EtlOperatorColumnReference'] = self.etl_operator_column_reference
        if self.file_oss_url is not None:
            result['FileOssUrl'] = self.file_oss_url
        if self.filter_table_name is not None:
            result['FilterTableName'] = self.filter_table_name
        if self.modify_type_enum is not None:
            result['ModifyTypeEnum'] = self.modify_type_enum
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('DbList') is not None:
            self.db_list = m.get('DbList')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('EtlOperatorColumnReference') is not None:
            self.etl_operator_column_reference = m.get('EtlOperatorColumnReference')
        if m.get('FileOssUrl') is not None:
            self.file_oss_url = m.get('FileOssUrl')
        if m.get('FilterTableName') is not None:
            self.filter_table_name = m.get('FilterTableName')
        if m.get('ModifyTypeEnum') is not None:
            self.modify_type_enum = m.get('ModifyTypeEnum')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class ModifyDtsJobAdvanceRequest(TeaModel):
    def __init__(self, client_token=None, data_initialization=None, data_synchronization=None, db_list=None,
                 dts_instance_id=None, etl_operator_column_reference=None, file_oss_url_object=None, filter_table_name=None,
                 modify_type_enum=None, region_id=None, reserved=None, structure_initialization=None,
                 synchronization_direction=None):
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        # The objects of the data synchronization task after modification. The value is a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        # 
        # >  Before you call the ModifyDtsJob operation, we recommend that you call the [DescribeDtsJobDetail](~~208925~~) to query the current objects of the data synchronization task. Then, you can specify the new objects based on your business requirements. For example, if the current objects are Table A and Table B and you need to add Table C, you must specify Table A, Table B, and Table C for this parameter.
        self.db_list = db_list  # type: dict[str, any]
        # The ID of the data synchronization instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The operator that is related to the extract, transform, and load (ETL) feature and dedicated to T+1 business.
        self.etl_operator_column_reference = etl_operator_column_reference  # type: str
        # The endpoint of the Object Storage Service (OSS) bucket in which the files to be synchronized are stored.
        self.file_oss_url_object = file_oss_url_object  # type: READABLE
        # The name of the table to be filtered.
        self.filter_table_name = filter_table_name  # type: str
        # The method that is used to modify the data synchronization task. If you do not specify the parameter, the objects of the data synchronization task are modified by default. If you specify UPDATE_RESERVED for the parameter, the reserved parameters are modified.
        self.modify_type_enum = modify_type_enum  # type: str
        # The ID of the region in which the data synchronization instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The reserved parameters of the data synchronization task. You can add reserved parameters instead of overwriting the existing reserved parameters. The value of the parameter is a MAP JSON string. You can specify this parameter to meet special requirements, such as specifying whether to automatically start the precheck of the data synchronization task. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        self.structure_initialization = structure_initialization  # type: bool
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   This parameter is required only if the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobAdvanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.db_list is not None:
            result['DbList'] = self.db_list
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.etl_operator_column_reference is not None:
            result['EtlOperatorColumnReference'] = self.etl_operator_column_reference
        if self.file_oss_url_object is not None:
            result['FileOssUrl'] = self.file_oss_url_object
        if self.filter_table_name is not None:
            result['FilterTableName'] = self.filter_table_name
        if self.modify_type_enum is not None:
            result['ModifyTypeEnum'] = self.modify_type_enum
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('DbList') is not None:
            self.db_list = m.get('DbList')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('EtlOperatorColumnReference') is not None:
            self.etl_operator_column_reference = m.get('EtlOperatorColumnReference')
        if m.get('FileOssUrl') is not None:
            self.file_oss_url_object = m.get('FileOssUrl')
        if m.get('FilterTableName') is not None:
            self.filter_table_name = m.get('FilterTableName')
        if m.get('ModifyTypeEnum') is not None:
            self.modify_type_enum = m.get('ModifyTypeEnum')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class ModifyDtsJobShrinkRequest(TeaModel):
    def __init__(self, client_token=None, data_initialization=None, data_synchronization=None, db_list_shrink=None,
                 dts_instance_id=None, etl_operator_column_reference=None, file_oss_url=None, filter_table_name=None,
                 modify_type_enum=None, region_id=None, reserved=None, structure_initialization=None,
                 synchronization_direction=None):
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        self.data_initialization = data_initialization  # type: bool
        self.data_synchronization = data_synchronization  # type: bool
        # The objects of the data synchronization task after modification. The value is a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        # 
        # >  Before you call the ModifyDtsJob operation, we recommend that you call the [DescribeDtsJobDetail](~~208925~~) to query the current objects of the data synchronization task. Then, you can specify the new objects based on your business requirements. For example, if the current objects are Table A and Table B and you need to add Table C, you must specify Table A, Table B, and Table C for this parameter.
        self.db_list_shrink = db_list_shrink  # type: str
        # The ID of the data synchronization instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The operator that is related to the extract, transform, and load (ETL) feature and dedicated to T+1 business.
        self.etl_operator_column_reference = etl_operator_column_reference  # type: str
        # The endpoint of the Object Storage Service (OSS) bucket in which the files to be synchronized are stored.
        self.file_oss_url = file_oss_url  # type: str
        # The name of the table to be filtered.
        self.filter_table_name = filter_table_name  # type: str
        # The method that is used to modify the data synchronization task. If you do not specify the parameter, the objects of the data synchronization task are modified by default. If you specify UPDATE_RESERVED for the parameter, the reserved parameters are modified.
        self.modify_type_enum = modify_type_enum  # type: str
        # The ID of the region in which the data synchronization instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The reserved parameters of the data synchronization task. You can add reserved parameters instead of overwriting the existing reserved parameters. The value of the parameter is a MAP JSON string. You can specify this parameter to meet special requirements, such as specifying whether to automatically start the precheck of the data synchronization task. For more information, see [MigrationReserved](~~176470~~).
        self.reserved = reserved  # type: str
        self.structure_initialization = structure_initialization  # type: bool
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   This parameter is required only if the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobShrinkRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.data_initialization is not None:
            result['DataInitialization'] = self.data_initialization
        if self.data_synchronization is not None:
            result['DataSynchronization'] = self.data_synchronization
        if self.db_list_shrink is not None:
            result['DbList'] = self.db_list_shrink
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.etl_operator_column_reference is not None:
            result['EtlOperatorColumnReference'] = self.etl_operator_column_reference
        if self.file_oss_url is not None:
            result['FileOssUrl'] = self.file_oss_url
        if self.filter_table_name is not None:
            result['FilterTableName'] = self.filter_table_name
        if self.modify_type_enum is not None:
            result['ModifyTypeEnum'] = self.modify_type_enum
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.reserved is not None:
            result['Reserved'] = self.reserved
        if self.structure_initialization is not None:
            result['StructureInitialization'] = self.structure_initialization
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('DataInitialization') is not None:
            self.data_initialization = m.get('DataInitialization')
        if m.get('DataSynchronization') is not None:
            self.data_synchronization = m.get('DataSynchronization')
        if m.get('DbList') is not None:
            self.db_list_shrink = m.get('DbList')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('EtlOperatorColumnReference') is not None:
            self.etl_operator_column_reference = m.get('EtlOperatorColumnReference')
        if m.get('FileOssUrl') is not None:
            self.file_oss_url = m.get('FileOssUrl')
        if m.get('FilterTableName') is not None:
            self.filter_table_name = m.get('FilterTableName')
        if m.get('ModifyTypeEnum') is not None:
            self.modify_type_enum = m.get('ModifyTypeEnum')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Reserved') is not None:
            self.reserved = m.get('Reserved')
        if m.get('StructureInitialization') is not None:
            self.structure_initialization = m.get('StructureInitialization')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class ModifyDtsJobResponseBody(TeaModel):
    def __init__(self, dts_job_id=None, err_code=None, err_message=None, request_id=None, status=None, success=None):
        # The ID of the DTS task.
        self.dts_job_id = dts_job_id  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        # 
        # >  The data type of this parameter is String. Sample value: **The actual sample value is The request processing has failed due to some unknown error.
        self.err_message = err_message  # type: bool
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The HTTP status code.
        self.status = status  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.status is not None:
            result['Status'] = self.status
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Status') is not None:
            self.status = m.get('Status')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDtsJobConfigRequest(TeaModel):
    def __init__(self, dts_job_id=None, owner_id=None, parameters=None, region_id=None):
        self.dts_job_id = dts_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.parameters = parameters  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobConfigRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.parameters is not None:
            result['Parameters'] = self.parameters
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('Parameters') is not None:
            self.parameters = m.get('Parameters')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyDtsJobConfigResponseBody(TeaModel):
    def __init__(self, request_id=None):
        self.request_id = request_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobConfigResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        return self


class ModifyDtsJobConfigResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDtsJobConfigResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDtsJobConfigResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDtsJobConfigResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDtsJobDedicatedClusterRequest(TeaModel):
    def __init__(self, dedicated_cluster_id=None, dts_job_ids=None, owner_id=None, region_id=None):
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        self.dts_job_ids = dts_job_ids  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobDedicatedClusterRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dts_job_ids is not None:
            result['DtsJobIds'] = self.dts_job_ids
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DtsJobIds') is not None:
            self.dts_job_ids = m.get('DtsJobIds')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyDtsJobDedicatedClusterResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        self.code = code  # type: str
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: long
        self.request_id = request_id  # type: str
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobDedicatedClusterResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDtsJobDedicatedClusterResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDtsJobDedicatedClusterResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDtsJobDedicatedClusterResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDtsJobDedicatedClusterResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDtsJobDuLimitRequest(TeaModel):
    def __init__(self, dts_job_id=None, du_limit=None, owner_id=None, region_id=None):
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The upper limit of DUs for the DTS task.
        # 
        # >  Minimum value: **1**.
        self.du_limit = du_limit  # type: long
        self.owner_id = owner_id  # type: str
        # The ID of the region in which the DTS instance resides.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobDuLimitRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.du_limit is not None:
            result['DuLimit'] = self.du_limit
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DuLimit') is not None:
            self.du_limit = m.get('DuLimit')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyDtsJobDuLimitResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        # The error code returned by the backend service. The number is incremented.
        self.code = code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the %s variable in the **ErrMessage** parameter.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: long
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobDuLimitResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDtsJobDuLimitResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDtsJobDuLimitResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDtsJobDuLimitResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDtsJobDuLimitResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDtsJobNameRequest(TeaModel):
    def __init__(self, dts_job_id=None, dts_job_name=None, region_id=None):
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The new name of the DTS task.
        # 
        # >  We recommend that you specify a descriptive name for easy identification. You do not need to use a unique name.
        self.dts_job_name = dts_job_name  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobNameRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dts_job_name is not None:
            result['DtsJobName'] = self.dts_job_name
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DtsJobName') is not None:
            self.dts_job_name = m.get('DtsJobName')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyDtsJobNameResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        # The error code. This parameter will be removed in the future.
        self.code = code  # type: str
        # The dynamic part in the error message. The value of this parameter is used to replace the **%s** variable in the value of the **ErrMessage** parameter.
        # 
        # >  For example, if the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobNameResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDtsJobNameResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDtsJobNameResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDtsJobNameResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDtsJobNameResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDtsJobPasswordRequest(TeaModel):
    def __init__(self, dts_job_id=None, endpoint=None, password=None, region_id=None, user_name=None):
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # Specifies the database to which the password belongs. Valid values:
        # 
        # *   **src**: source database
        # *   **dest**: destination database
        # 
        # >  This parameter must be specified.
        self.endpoint = endpoint  # type: str
        # The new password of the account.
        # 
        # >  This parameter must be specified and cannot be the same as the current password.
        self.password = password  # type: str
        # The ID of the region where the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The account of the source or destination database.
        # 
        # >  This parameter must be specified.
        self.user_name = user_name  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobPasswordRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.endpoint is not None:
            result['Endpoint'] = self.endpoint
        if self.password is not None:
            result['Password'] = self.password
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.user_name is not None:
            result['UserName'] = self.user_name
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('Endpoint') is not None:
            self.endpoint = m.get('Endpoint')
        if m.get('Password') is not None:
            self.password = m.get('Password')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('UserName') is not None:
            self.user_name = m.get('UserName')
        return self


class ModifyDtsJobPasswordResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        # The error code. This parameter will be removed in the future.
        self.code = code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDtsJobPasswordResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDtsJobPasswordResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDtsJobPasswordResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDtsJobPasswordResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDtsJobPasswordResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifyDynamicConfigRequest(TeaModel):
    def __init__(self, config_list=None, dts_job_id=None, enable_limit=None, job_code=None, region_id=None):
        self.config_list = config_list  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.enable_limit = enable_limit  # type: bool
        self.job_code = job_code  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDynamicConfigRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.config_list is not None:
            result['ConfigList'] = self.config_list
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.enable_limit is not None:
            result['EnableLimit'] = self.enable_limit
        if self.job_code is not None:
            result['JobCode'] = self.job_code
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ConfigList') is not None:
            self.config_list = m.get('ConfigList')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('EnableLimit') is not None:
            self.enable_limit = m.get('EnableLimit')
        if m.get('JobCode') is not None:
            self.job_code = m.get('JobCode')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ModifyDynamicConfigResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        self.code = code  # type: str
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.request_id = request_id  # type: str
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifyDynamicConfigResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifyDynamicConfigResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifyDynamicConfigResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifyDynamicConfigResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifyDynamicConfigResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifySubscriptionRequest(TeaModel):
    def __init__(self, db_list=None, dts_instance_id=None, dts_job_id=None, region_id=None,
                 subscription_data_type_ddl=None, subscription_data_type_dml=None):
        # The objects of the change tracking task. The value is a JSON string. For more information, see [Objects of DTS tasks](~~209545~~).
        # 
        # >  You can call the [DescribeDtsJobDetail](~~208925~~) operation to query the original objects of the task.
        self.db_list = db_list  # type: str
        # The ID of the change tracking instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the region where the change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # Specifies whether to retrieve data definition language (DDL) statements. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.subscription_data_type_ddl = subscription_data_type_ddl  # type: bool
        # Specifies whether to retrieve data manipulation language (DML) statements. Valid values:
        # 
        # *   **true**: yes
        # *   **false**: no
        self.subscription_data_type_dml = subscription_data_type_dml  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifySubscriptionRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.db_list is not None:
            result['DbList'] = self.db_list
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_data_type_ddl is not None:
            result['SubscriptionDataTypeDDL'] = self.subscription_data_type_ddl
        if self.subscription_data_type_dml is not None:
            result['SubscriptionDataTypeDML'] = self.subscription_data_type_dml
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DbList') is not None:
            self.db_list = m.get('DbList')
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionDataTypeDDL') is not None:
            self.subscription_data_type_ddl = m.get('SubscriptionDataTypeDDL')
        if m.get('SubscriptionDataTypeDML') is not None:
            self.subscription_data_type_dml = m.get('SubscriptionDataTypeDML')
        return self


class ModifySubscriptionResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, http_status_code=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifySubscriptionResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifySubscriptionResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifySubscriptionResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifySubscriptionResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifySubscriptionResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifySubscriptionObjectRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, subscription_instance_id=None,
                 subscription_object=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the [DescribeSubscriptionInstances](~~49442~~) operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str
        # The objects from which you want to track data changes. The value is a JSON string and can contain regular expressions. For more information, see [SubscriptionObjects](~~141902~~).
        self.subscription_object = subscription_object  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifySubscriptionObjectRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        if self.subscription_object is not None:
            result['SubscriptionObject'] = self.subscription_object
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        if m.get('SubscriptionObject') is not None:
            self.subscription_object = m.get('SubscriptionObject')
        return self


class ModifySubscriptionObjectResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifySubscriptionObjectResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ModifySubscriptionObjectResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifySubscriptionObjectResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifySubscriptionObjectResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifySubscriptionObjectResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ModifySynchronizationObjectRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, synchronization_direction=None,
                 synchronization_job_id=None, synchronization_objects=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   This parameter is required only when the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the DescribeSynchronizationJobs operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str
        self.synchronization_objects = synchronization_objects  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifySynchronizationObjectRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        if self.synchronization_objects is not None:
            result['SynchronizationObjects'] = self.synchronization_objects
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        if m.get('SynchronizationObjects') is not None:
            self.synchronization_objects = m.get('SynchronizationObjects')
        return self


class ModifySynchronizationObjectResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None, task_id=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The ID of the task that changes the objects. You must specify the task ID when you call the DescribeSynchronizationObjectModifyStatus operation to query the status and progress of the task.
        self.task_id = task_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ModifySynchronizationObjectResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class ModifySynchronizationObjectResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ModifySynchronizationObjectResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ModifySynchronizationObjectResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ModifySynchronizationObjectResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class RenewInstanceRequest(TeaModel):
    def __init__(self, buy_count=None, charge_type=None, dts_job_id=None, period=None, region_id=None):
        # The subscription duration of the DTS instance after renewal. Default value: 1.
        # 
        # *   If the **Period** parameter is set to **Year**, the valid values are **1 to 5**.
        # *   If the **Period** parameter is set to **Month**, the valid values are **1 to 60**.
        self.buy_count = buy_count  # type: str
        # The billing method of the DTS instance. Set the value to **PREPAY**, which indicates the subscription billing method.
        self.charge_type = charge_type  # type: str
        # The ID of the data synchronization or change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The billing cycle of the DTS instance after renewal. Valid values:
        # 
        # *   **Year**: annual subscription.
        # *   **Month**: monthly subscription. This is the default value.
        self.period = period  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(RenewInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.buy_count is not None:
            result['BuyCount'] = self.buy_count
        if self.charge_type is not None:
            result['ChargeType'] = self.charge_type
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.period is not None:
            result['Period'] = self.period
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BuyCount') is not None:
            self.buy_count = m.get('BuyCount')
        if m.get('ChargeType') is not None:
            self.charge_type = m.get('ChargeType')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class RenewInstanceResponseBody(TeaModel):
    def __init__(self, charge_type=None, code=None, dts_job_id=None, dynamic_message=None, end_time=None,
                 err_code=None, err_message=None, http_status_code=None, instance_id=None, request_id=None, success=None):
        # The billing method of the DTS instance. **PREPAY** is returned, which indicates the subscription billing method.
        self.charge_type = charge_type  # type: str
        # The error code.
        # 
        # >  This parameter will be removed in the future.
        self.code = code  # type: str
        # The ID of the data synchronization or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The time when the DTS instance expires after renewal. The time follows the ISO 8601 standard in the *yyyy-MM-dd*T*HH:mm:ssZZZ* format. The time is displayed in UTC.
        # 
        # >  **ZZZ** indicates the offset of the time zone, which is displayed in the format of a plus sign (+) or a minus sign (-) followed by hours and minutes, such as **+00:00**.
        self.end_time = end_time  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the DTS instance.
        self.instance_id = instance_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful. Valid values:
        # 
        # *   **true**: The request was successful.
        # *   **false**: The request failed.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(RenewInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.charge_type is not None:
            result['ChargeType'] = self.charge_type
        if self.code is not None:
            result['Code'] = self.code
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.end_time is not None:
            result['EndTime'] = self.end_time
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ChargeType') is not None:
            self.charge_type = m.get('ChargeType')
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('EndTime') is not None:
            self.end_time = m.get('EndTime')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class RenewInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: RenewInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(RenewInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = RenewInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ResetDtsJobRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, region_id=None, synchronization_direction=None):
        # The ID of the data synchronization or change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data synchronization or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to reset the reverse synchronization task only when the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ResetDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class ResetDtsJobResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace **%s** in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ResetDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ResetDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ResetDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ResetDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ResetDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ResetSynchronizationJobRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, synchronization_direction=None,
                 synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to stop reverse synchronization only when the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the **DescribeSynchronizationJobs** operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ResetSynchronizationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class ResetSynchronizationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ResetSynchronizationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ResetSynchronizationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ResetSynchronizationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ResetSynchronizationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ResetSynchronizationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ReverseTwoWayDirectionRequest(TeaModel):
    def __init__(self, dts_instance_id=None, ignore_error_sub_job=None, region_id=None):
        self.dts_instance_id = dts_instance_id  # type: str
        self.ignore_error_sub_job = ignore_error_sub_job  # type: bool
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ReverseTwoWayDirectionRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.ignore_error_sub_job is not None:
            result['IgnoreErrorSubJob'] = self.ignore_error_sub_job
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('IgnoreErrorSubJob') is not None:
            self.ignore_error_sub_job = m.get('IgnoreErrorSubJob')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ReverseTwoWayDirectionResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 request_id=None, success=None):
        self.code = code  # type: str
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.request_id = request_id  # type: str
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ReverseTwoWayDirectionResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ReverseTwoWayDirectionResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ReverseTwoWayDirectionResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ReverseTwoWayDirectionResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ReverseTwoWayDirectionResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class ShieldPrecheckRequest(TeaModel):
    def __init__(self, dts_instance_id=None, precheck_items=None, region_id=None):
        # The ID of the data migration or data synchronization instance. You can call the **DescribeMigrationJobs** or DescribeSynchronizationJobs operation to query the instance ID.
        self.dts_instance_id = dts_instance_id  # type: str
        # The precheck items that you want to ignore. Separate multiple items with commas (,). Valid values:
        # 
        # *   **CHECK_SAME_OBJ**: schema name conflict
        # 
        # *   **CHECK_SAME_USER**: multiple usernames for one instance
        # 
        # *   **CHECK_SRC**: source database version
        # 
        # *   **CHECK_TOPOLOGY**: topology
        # 
        # > For more information about the topologies supported by DTS, see [Synchronization topologies](~~124115~~).
        # 
        # *   **CHECK_SERVER_ID**: value of server_id in the source database
        self.precheck_items = precheck_items  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(ShieldPrecheckRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.precheck_items is not None:
            result['PrecheckItems'] = self.precheck_items
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('PrecheckItems') is not None:
            self.precheck_items = m.get('PrecheckItems')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class ShieldPrecheckResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(ShieldPrecheckResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class ShieldPrecheckResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: ShieldPrecheckResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(ShieldPrecheckResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = ShieldPrecheckResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SkipPreCheckRequest(TeaModel):
    def __init__(self, dts_job_id=None, job_id=None, region_id=None, skip=None, skip_pre_check_items=None,
                 skip_pre_check_names=None):
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the precheck task. You can call the **DescribePreCheckStatus** operation to query the task ID.
        self.job_id = job_id  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # Specifies whether to skip the precheck item. Valid values:
        # 
        # *   **true**: skips the precheck item.
        # *   **false**: does not skip the precheck item.
        # 
        # >  This parameter is required.
        self.skip = skip  # type: bool
        # The shortened name of the precheck item. Valid values:
        # 
        # *   **CHECK_SAME_OBJ**: object name conflict
        # 
        # *   **CHECK_SAME_USER**: multiple usernames for one instance
        # 
        # *   **CHECK_SRC**: source database version
        # 
        # *   **CHECK_TOPOLOGY**: topology type
        # 
        # > For more information about the topologies supported by DTS, see [Synchronization topologies](~~124115~~).
        # 
        # *   **CHECK_SERVER_ID**: the server ID of the source database
        # 
        # >  Separate multiple shortened names with commas (,).
        self.skip_pre_check_items = skip_pre_check_items  # type: str
        # The name of the precheck item. This parameter corresponds to the **SkipPreCheckItems** parameter. Valid values:
        # 
        # *   **CHECK_SAME_OBJ_DETAIL**: object name conflict
        # 
        # *   **CHECK_SAME_USER_DETAIL**: multiple usernames for one instance
        # 
        # *   **CHECK_SRC_DETAIL**: source database version
        # 
        # *   **CHECK_TOPOLOGY_DETAIL**: topology type
        # 
        # > For more information about the topologies supported by DTS, see [Synchronization topologies](~~124115~~).
        # 
        # *   **CHECK_SERVER_ID_DETAIL**: the server ID of the source database
        # 
        # >  Separate multiple item names with commas (,).
        self.skip_pre_check_names = skip_pre_check_names  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SkipPreCheckRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.job_id is not None:
            result['JobId'] = self.job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.skip is not None:
            result['Skip'] = self.skip
        if self.skip_pre_check_items is not None:
            result['SkipPreCheckItems'] = self.skip_pre_check_items
        if self.skip_pre_check_names is not None:
            result['SkipPreCheckNames'] = self.skip_pre_check_names
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Skip') is not None:
            self.skip = m.get('Skip')
        if m.get('SkipPreCheckItems') is not None:
            self.skip_pre_check_items = m.get('SkipPreCheckItems')
        if m.get('SkipPreCheckNames') is not None:
            self.skip_pre_check_names = m.get('SkipPreCheckNames')
        return self


class SkipPreCheckResponseBody(TeaModel):
    def __init__(self, code=None, dynamic_message=None, err_code=None, err_message=None, http_status_code=None,
                 migration_job_id=None, request_id=None, schedule_job_id=None, skip_items=None, skip_names=None, success=None):
        # The error code. This parameter will be removed in the future.
        self.code = code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the specified **JobId** parameter is invalid, **The Value of Input Parameter %s is not valid** is returned for **ErrMessage** and **JobId** is returned for **DynamicMessage**.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the DTS task on which the precheck is performed.
        self.migration_job_id = migration_job_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # The ID of the precheck task.
        self.schedule_job_id = schedule_job_id  # type: str
        # The shortened name of the precheck item.
        self.skip_items = skip_items  # type: str
        # The name of the precheck item.
        self.skip_names = skip_names  # type: str
        # Indicates whether the call is successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(SkipPreCheckResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.schedule_job_id is not None:
            result['ScheduleJobId'] = self.schedule_job_id
        if self.skip_items is not None:
            result['SkipItems'] = self.skip_items
        if self.skip_names is not None:
            result['SkipNames'] = self.skip_names
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('ScheduleJobId') is not None:
            self.schedule_job_id = m.get('ScheduleJobId')
        if m.get('SkipItems') is not None:
            self.skip_items = m.get('SkipItems')
        if m.get('SkipNames') is not None:
            self.skip_names = m.get('SkipNames')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SkipPreCheckResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SkipPreCheckResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SkipPreCheckResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SkipPreCheckResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StartDtsJobRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, region_id=None, synchronization_direction=None):
        # The ID of the data migration, data synchronization, or change tracking instance.
        # 
        # >  You can call the [DescribeMigrationJobs](~~208139~~), [DescribeSubscriptionInstances](~~49442~~), or [DescribeSynchronizationJobs](~~49454~~) operation to query the instance ID
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        # The region ID of the Data Transmission Service (DTS) instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The synchronization direction. Default value: Forward. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # 
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # >You can set this parameter to **Reverse** to start the reverse synchronization task only if the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class StartDtsJobResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  For example, if the returned value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the returned value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StartDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StartDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StartDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StartDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StartDtsJobsRequest(TeaModel):
    def __init__(self, dts_job_ids=None, region_id=None):
        # The ID of the data migration or data synchronization task.
        # 
        # > 
        # *   For multiple tasks, separate them with commas (**,**).
        # *   You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_ids = dts_job_ids  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartDtsJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_ids is not None:
            result['DtsJobIds'] = self.dts_job_ids
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobIds') is not None:
            self.dts_job_ids = m.get('DtsJobIds')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class StartDtsJobsResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the returned value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the returned value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request is successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartDtsJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StartDtsJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StartDtsJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StartDtsJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StartDtsJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StartMigrationJobRequest(TeaModel):
    def __init__(self, account_id=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query all data migration instances.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartMigrationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class StartMigrationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartMigrationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StartMigrationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StartMigrationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StartMigrationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StartMigrationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StartSubscriptionInstanceRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, subscription_instance_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The ID of the change tracking instance. You can call the DescribeSubscriptionInstances operation to query the instance ID.
        self.subscription_instance_id = subscription_instance_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartSubscriptionInstanceRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.subscription_instance_id is not None:
            result['SubscriptionInstanceId'] = self.subscription_instance_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SubscriptionInstanceId') is not None:
            self.subscription_instance_id = m.get('SubscriptionInstanceId')
        return self


class StartSubscriptionInstanceResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None, task_id=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The task ID. This parameter will be removed in the future.
        self.task_id = task_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartSubscriptionInstanceResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class StartSubscriptionInstanceResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StartSubscriptionInstanceResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StartSubscriptionInstanceResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StartSubscriptionInstanceResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StartSynchronizationJobRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, synchronization_direction=None,
                 synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to start the reverse synchronization task only when the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the **DescribeSynchronizationJobs** operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartSynchronizationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class StartSynchronizationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StartSynchronizationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StartSynchronizationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StartSynchronizationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StartSynchronizationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StartSynchronizationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StopDedicatedClusterRequest(TeaModel):
    def __init__(self, dedicated_cluster_id=None, dedicated_cluster_name=None, instance_id=None, owner_id=None,
                 region_id=None):
        # The ID of the cluster.
        # 
        # >  You must specify one of the **InstanceId** and **DedicatedClusterId** parameters.
        self.dedicated_cluster_id = dedicated_cluster_id  # type: str
        # The name of the cluster.
        self.dedicated_cluster_name = dedicated_cluster_name  # type: str
        # The ID of the instance.
        # 
        # >  You must specify one of the **InstanceId** and **DedicatedClusterId** parameters.
        self.instance_id = instance_id  # type: str
        self.owner_id = owner_id  # type: str
        # The ID of the region in which the instance resides.
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopDedicatedClusterRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dedicated_cluster_id is not None:
            result['DedicatedClusterId'] = self.dedicated_cluster_id
        if self.dedicated_cluster_name is not None:
            result['DedicatedClusterName'] = self.dedicated_cluster_name
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DedicatedClusterId') is not None:
            self.dedicated_cluster_id = m.get('DedicatedClusterId')
        if m.get('DedicatedClusterName') is not None:
            self.dedicated_cluster_name = m.get('DedicatedClusterName')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class StopDedicatedClusterResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, http_status_code=None, request_id=None, success=None):
        # The error code returned if the request failed.
        self.err_code = err_code  # type: str
        # The error message returned if the request failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopDedicatedClusterResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StopDedicatedClusterResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StopDedicatedClusterResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StopDedicatedClusterResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StopDedicatedClusterResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StopDtsJobRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, region_id=None, synchronization_direction=None):
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        self.dts_job_id = dts_job_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to stop the reverse synchronization task only when the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class StopDtsJobResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic error message, which is used to replace **%s** in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StopDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StopDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StopDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StopDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StopDtsJobsRequest(TeaModel):
    def __init__(self, dts_job_ids=None, region_id=None):
        # The ID of the data migration or data synchronization task.
        # 
        # > 
        # *   Separate multiple task IDs by **,** (commas).
        # *   You can call the [DescribeDtsJobs](~~209702~~) operation to query task IDs.
        self.dts_job_ids = dts_job_ids  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopDtsJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_ids is not None:
            result['DtsJobIds'] = self.dts_job_ids
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobIds') is not None:
            self.dts_job_ids = m.get('DtsJobIds')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class StopDtsJobsResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the returned value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the returned value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request is successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopDtsJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StopDtsJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StopDtsJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StopDtsJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StopDtsJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class StopMigrationJobRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query all data migration instances.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopMigrationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class StopMigrationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(StopMigrationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class StopMigrationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: StopMigrationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(StopMigrationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = StopMigrationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SummaryJobDetailRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, job_code=None, region_id=None, struct_type=None,
                 synchronization_direction=None):
        # The ID of the data migration or data synchronization instance.
        # 
        # >  You must specify at least one of the DtsJobId and DtsInstanceId parameters.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data migration or data synchronization task.
        # 
        # >  You must specify at least one of the DtsJobId and DtsInstanceId parameters.
        self.dts_job_id = dts_job_id  # type: str
        # The phase of the data migration task. Valid values:
        # 
        # *   **02**: The task is in the schema migration phase.
        # *   **03**: The task is in the incremental migration phase.
        self.job_code = job_code  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The type of schema definition. Valid values:
        # 
        # *   **before**: schema migration or initial schema synchronization
        # *   **after**: DDL operations performed during incremental data migration or synchronization
        self.struct_type = struct_type  # type: str
        # The synchronization direction of the data synchronization task. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to delete the reverse synchronization task only if the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SummaryJobDetailRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.job_code is not None:
            result['JobCode'] = self.job_code
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.struct_type is not None:
            result['StructType'] = self.struct_type
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('JobCode') is not None:
            self.job_code = m.get('JobCode')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('StructType') is not None:
            self.struct_type = m.get('StructType')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class SummaryJobDetailResponseBodyProgressSummaryDetails(TeaModel):
    def __init__(self, key=None, state=None, total_count=None):
        # The type of migrated or synchronized object. Valid values: **Table**, **Constraint**, **Index**, **View**, **Materialize View**, **Type**, **Synonym**, **Trigger**, **Function**, **Procedure**, **Package**, **Default**, **Rule**, **PlanGuide**, and **Sequence**.
        self.key = key  # type: str
        # The state of the data migration or data synchronization task. Valid values:
        # 
        # *   **0**: The task was complete.
        # *   **1**: The task was waiting to start.
        # *   **2**: The task was being initialized.
        # *   **3**: The task was in progress.
        # *   **4**: An error occurred.
        # *   **5**: The task failed.
        self.state = state  # type: int
        # The total number of migrated or synchronized objects.
        self.total_count = total_count  # type: long

    def validate(self):
        pass

    def to_map(self):
        _map = super(SummaryJobDetailResponseBodyProgressSummaryDetails, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.state is not None:
            result['State'] = self.state
        if self.total_count is not None:
            result['TotalCount'] = self.total_count
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('State') is not None:
            self.state = m.get('State')
        if m.get('TotalCount') is not None:
            self.total_count = m.get('TotalCount')
        return self


class SummaryJobDetailResponseBody(TeaModel):
    def __init__(self, code=None, http_status_code=None, job_id=None, progress_summary_details=None,
                 request_id=None, success=None):
        # The error code.
        self.code = code  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the data migration or data synchronization task.
        self.job_id = job_id  # type: str
        # The returned information about the migrated or synchronized objects in arrays.
        # 
        # >  The arrays are in the following format: \[{"key":"Function","state":5,"totalCount":22},{"key":"Procedure","state":5,"totalCount":26},{"key":"Table","state":0,"totalCount":68},{"key":"View","state":5,"totalCount":100}].
        self.progress_summary_details = progress_summary_details  # type: list[SummaryJobDetailResponseBodyProgressSummaryDetails]
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request was successful. Valid values:
        # 
        # *   **true**: The request was successful.
        # *   **false**: The request failed.
        self.success = success  # type: bool

    def validate(self):
        if self.progress_summary_details:
            for k in self.progress_summary_details:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(SummaryJobDetailResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.code is not None:
            result['Code'] = self.code
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.job_id is not None:
            result['JobId'] = self.job_id
        result['ProgressSummaryDetails'] = []
        if self.progress_summary_details is not None:
            for k in self.progress_summary_details:
                result['ProgressSummaryDetails'].append(k.to_map() if k else None)
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('JobId') is not None:
            self.job_id = m.get('JobId')
        self.progress_summary_details = []
        if m.get('ProgressSummaryDetails') is not None:
            for k in m.get('ProgressSummaryDetails'):
                temp_model = SummaryJobDetailResponseBodyProgressSummaryDetails()
                self.progress_summary_details.append(temp_model.from_map(k))
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SummaryJobDetailResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SummaryJobDetailResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SummaryJobDetailResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SummaryJobDetailResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SuspendDtsJobRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, region_id=None, synchronization_direction=None):
        # The ID of the data migration, data synchronization, or change tracking instance.
        self.dts_instance_id = dts_instance_id  # type: str
        # The ID of the data migration, data synchronization, or change tracking task.
        # 
        # >  You can call the [DescribeDtsJobs](~~209702~~) operation to obtain the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**: Data is synchronized from the source database to the destination database.
        # *   **Reverse**: Data is synchronized from the destination database to the source database.
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to pause the reverse synchronization task only if the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendDtsJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class SuspendDtsJobResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendDtsJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SuspendDtsJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SuspendDtsJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SuspendDtsJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SuspendDtsJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SuspendDtsJobsRequest(TeaModel):
    def __init__(self, dts_job_ids=None, region_id=None):
        # The ID of the data migration or data synchronization task.
        # 
        # > 
        # *   For multiple tasks, separate them with commas (,).
        # *   You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_ids = dts_job_ids  # type: str
        # The ID of the region in which the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendDtsJobsRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_ids is not None:
            result['DtsJobIds'] = self.dts_job_ids
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobIds') is not None:
            self.dts_job_ids = m.get('DtsJobIds')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class SuspendDtsJobsResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the request is successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendDtsJobsResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SuspendDtsJobsResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SuspendDtsJobsResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SuspendDtsJobsResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SuspendDtsJobsResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SuspendMigrationJobRequest(TeaModel):
    def __init__(self, account_id=None, client_token=None, migration_job_id=None, owner_id=None, region_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        # The client token that is used to ensure the idempotence of the request. You can use the client to generate the value, but you must ensure that it is unique among different requests. The **ClientToken** parameter can contain only ASCII characters and cannot exceed 64 characters in length.
        self.client_token = client_token  # type: str
        # The ID of the data migration instance. You can call the **DescribeMigrationJobs** operation to query all data migration instances.
        self.migration_job_id = migration_job_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendMigrationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.client_token is not None:
            result['ClientToken'] = self.client_token
        if self.migration_job_id is not None:
            result['MigrationJobId'] = self.migration_job_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('ClientToken') is not None:
            self.client_token = m.get('ClientToken')
        if m.get('MigrationJobId') is not None:
            self.migration_job_id = m.get('MigrationJobId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class SuspendMigrationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendMigrationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SuspendMigrationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SuspendMigrationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SuspendMigrationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SuspendMigrationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SuspendSynchronizationJobRequest(TeaModel):
    def __init__(self, account_id=None, owner_id=None, region_id=None, synchronization_direction=None,
                 synchronization_job_id=None):
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # > 
        # *   Default value: **Forward**.
        # *   You can set this parameter to **Reverse** to pause reverse synchronization only when the topology is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the **DescribeSynchronizationJobs** operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendSynchronizationJobRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class SuspendSynchronizationJobResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SuspendSynchronizationJobResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SuspendSynchronizationJobResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SuspendSynchronizationJobResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SuspendSynchronizationJobResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SuspendSynchronizationJobResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SwitchPhysicalDtsJobToCloudRequest(TeaModel):
    def __init__(self, dts_instance_id=None, dts_job_id=None, region_id=None, synchronization_direction=None):
        self.dts_instance_id = dts_instance_id  # type: str
        self.dts_job_id = dts_job_id  # type: str
        self.region_id = region_id  # type: str
        self.synchronization_direction = synchronization_direction  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SwitchPhysicalDtsJobToCloudRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_instance_id is not None:
            result['DtsInstanceId'] = self.dts_instance_id
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsInstanceId') is not None:
            self.dts_instance_id = m.get('DtsInstanceId')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        return self


class SwitchPhysicalDtsJobToCloudResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        self.dynamic_code = dynamic_code  # type: str
        self.dynamic_message = dynamic_message  # type: str
        self.err_code = err_code  # type: str
        self.err_message = err_message  # type: str
        self.http_status_code = http_status_code  # type: int
        self.request_id = request_id  # type: str
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(SwitchPhysicalDtsJobToCloudResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class SwitchPhysicalDtsJobToCloudResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SwitchPhysicalDtsJobToCloudResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SwitchPhysicalDtsJobToCloudResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SwitchPhysicalDtsJobToCloudResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class SwitchSynchronizationEndpointRequestEndpoint(TeaModel):
    def __init__(self, ip=None, instance_id=None, instance_type=None, port=None, type=None):
        # The IP address of the database.
        # 
        # >  You must specify the IP address only if the **Endpoint.InstanceType** parameter is set to **Express**.
        self.ip = ip  # type: str
        # The ID of the ECS instance or the virtual private cloud (VPC).
        # 
        # > 
        # *   If the **Endpoint.InstanceType** parameter is set to **ECS**, you must specify the ID of the ECS instance.
        # *   If the **Endpoint.InstanceType** parameter is set to **Express**, you must specify the ID of the VPC.
        self.instance_id = instance_id  # type: str
        # The instance type of the database. Valid values:
        # 
        # *   **LocalInstance**: self-managed database with a public IP address
        # *   **ECS**: self-managed database that is hosted on ECS
        # *   **Express**: self-managed database that is connected over Express Connect
        self.instance_type = instance_type  # type: str
        # The service port number of the database.
        self.port = port  # type: str
        # Specifies whether to update the connection settings of the source instance or the destination instance. Valid values:
        # 
        # *   **Source**\
        # *   **Destination**\
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SwitchSynchronizationEndpointRequestEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.ip is not None:
            result['IP'] = self.ip
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.instance_type is not None:
            result['InstanceType'] = self.instance_type
        if self.port is not None:
            result['Port'] = self.port
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('IP') is not None:
            self.ip = m.get('IP')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('InstanceType') is not None:
            self.instance_type = m.get('InstanceType')
        if m.get('Port') is not None:
            self.port = m.get('Port')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class SwitchSynchronizationEndpointRequestSourceEndpoint(TeaModel):
    def __init__(self, owner_id=None, role=None):
        # The ID of the Alibaba Cloud account to which the source instance belongs. You must specify this parameter only if the source instance and the destination instance belong to different Alibaba Cloud accounts.
        self.owner_id = owner_id  # type: str
        # The authorized Resource Access Management (RAM) role of the source instance. You must specify the RAM role only if the source instance and the destination instance belong to different Alibaba Cloud accounts. You can use the RAM role to allow the Alibaba Cloud account that owns the destination instance to access the source instance.
        # 
        # >  For information about the permissions and authorization methods of the RAM role, see [Configure RAM authorization for cross-account data migration and synchronization](~~48468~~).
        self.role = role  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SwitchSynchronizationEndpointRequestSourceEndpoint, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.owner_id is not None:
            result['OwnerID'] = self.owner_id
        if self.role is not None:
            result['Role'] = self.role
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('OwnerID') is not None:
            self.owner_id = m.get('OwnerID')
        if m.get('Role') is not None:
            self.role = m.get('Role')
        return self


class SwitchSynchronizationEndpointRequest(TeaModel):
    def __init__(self, endpoint=None, source_endpoint=None, account_id=None, owner_id=None, region_id=None,
                 synchronization_direction=None, synchronization_job_id=None):
        self.endpoint = endpoint  # type: SwitchSynchronizationEndpointRequestEndpoint
        self.source_endpoint = source_endpoint  # type: SwitchSynchronizationEndpointRequestSourceEndpoint
        # The ID of the Alibaba Cloud account. You do not need to specify this parameter because this parameter will be removed in the future.
        self.account_id = account_id  # type: str
        self.owner_id = owner_id  # type: str
        self.region_id = region_id  # type: str
        # The synchronization direction. Valid values:
        # 
        # *   **Forward**\
        # *   **Reverse**\
        # 
        # >  Default value: **Forward**.
        # 
        # The value **Reverse** takes effect only if the topology of the data synchronization instance is two-way synchronization.
        self.synchronization_direction = synchronization_direction  # type: str
        # The ID of the data synchronization instance. You can call the DescribeSynchronizationJobs operation to query the instance ID.
        self.synchronization_job_id = synchronization_job_id  # type: str

    def validate(self):
        if self.endpoint:
            self.endpoint.validate()
        if self.source_endpoint:
            self.source_endpoint.validate()

    def to_map(self):
        _map = super(SwitchSynchronizationEndpointRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.endpoint is not None:
            result['Endpoint'] = self.endpoint.to_map()
        if self.source_endpoint is not None:
            result['SourceEndpoint'] = self.source_endpoint.to_map()
        if self.account_id is not None:
            result['AccountId'] = self.account_id
        if self.owner_id is not None:
            result['OwnerId'] = self.owner_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.synchronization_direction is not None:
            result['SynchronizationDirection'] = self.synchronization_direction
        if self.synchronization_job_id is not None:
            result['SynchronizationJobId'] = self.synchronization_job_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Endpoint') is not None:
            temp_model = SwitchSynchronizationEndpointRequestEndpoint()
            self.endpoint = temp_model.from_map(m['Endpoint'])
        if m.get('SourceEndpoint') is not None:
            temp_model = SwitchSynchronizationEndpointRequestSourceEndpoint()
            self.source_endpoint = temp_model.from_map(m['SourceEndpoint'])
        if m.get('AccountId') is not None:
            self.account_id = m.get('AccountId')
        if m.get('OwnerId') is not None:
            self.owner_id = m.get('OwnerId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('SynchronizationDirection') is not None:
            self.synchronization_direction = m.get('SynchronizationDirection')
        if m.get('SynchronizationJobId') is not None:
            self.synchronization_job_id = m.get('SynchronizationJobId')
        return self


class SwitchSynchronizationEndpointResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None, task_id=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: str
        # The task ID. You must specify the task ID when you call the [DescribeEndpointSwitchStatus](~~135598~~) operation to query the execution status of the task.
        self.task_id = task_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(SwitchSynchronizationEndpointResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        if self.task_id is not None:
            result['TaskId'] = self.task_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        if m.get('TaskId') is not None:
            self.task_id = m.get('TaskId')
        return self


class SwitchSynchronizationEndpointResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: SwitchSynchronizationEndpointResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(SwitchSynchronizationEndpointResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = SwitchSynchronizationEndpointResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class TagResourcesRequestTag(TeaModel):
    def __init__(self, key=None, value=None):
        # The tag key.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Key specifies the key of the first tag and Tag.2.Key specifies the key of the second tag.
        # *   This parameter cannot be an empty string.
        self.key = key  # type: str
        # The tag value.
        # 
        # > 
        # *   N specifies the serial number of the tag. For example, Tag.1.Value specifies the value of the first tag and Tag.2.Value specifies the value of the second tag.
        # *   This parameter can be an empty string.
        self.value = value  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(TagResourcesRequestTag, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.key is not None:
            result['Key'] = self.key
        if self.value is not None:
            result['Value'] = self.value
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('Key') is not None:
            self.key = m.get('Key')
        if m.get('Value') is not None:
            self.value = m.get('Value')
        return self


class TagResourcesRequest(TeaModel):
    def __init__(self, region_id=None, resource_id=None, resource_type=None, tag=None):
        # The ID of the region where the data migration, data synchronization, or change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        self.resource_id = resource_id  # type: list[str]
        # The resource type. Valid value: **ALIYUN::DTS::INSTANCE**.
        self.resource_type = resource_type  # type: str
        self.tag = tag  # type: list[TagResourcesRequestTag]

    def validate(self):
        if self.tag:
            for k in self.tag:
                if k:
                    k.validate()

    def to_map(self):
        _map = super(TagResourcesRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        result['Tag'] = []
        if self.tag is not None:
            for k in self.tag:
                result['Tag'].append(k.to_map() if k else None)
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        self.tag = []
        if m.get('Tag') is not None:
            for k in m.get('Tag'):
                temp_model = TagResourcesRequestTag()
                self.tag.append(temp_model.from_map(k))
        return self


class TagResourcesResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(TagResourcesResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class TagResourcesResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: TagResourcesResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(TagResourcesResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = TagResourcesResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class TransferInstanceClassRequest(TeaModel):
    def __init__(self, dts_job_id=None, instance_class=None, order_type=None, region_id=None):
        # The ID of the data migration or data synchronization task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The new instance class of the DTS instance. You can call the [DescribeDtsJobDetail](~~208925~~) operation to query the original instance class of the DTS instance.
        # 
        # *   DTS supports the following instance classes for a data migration instance: **xxlarge**, **xlarge**, **large**, **medium**, and **small**.
        # *   DTS supports the following instance classes for a data synchronization instance: **large**, **medium**, **small**, and **micro**.
        # 
        # >  For more information about the test performance of each instance class, see [Specifications of data migration instances](~~26606~~) and [Specifications of data synchronization instances](~~26605~~).
        self.instance_class = instance_class  # type: str
        # Specifies whether to upgrade or downgrade the DTS instance. Valid values:
        # 
        # *   **UPGRADE**\
        # *   **DOWNGRADE**\
        self.order_type = order_type  # type: str
        # The ID of the region where the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(TransferInstanceClassRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.instance_class is not None:
            result['InstanceClass'] = self.instance_class
        if self.order_type is not None:
            result['OrderType'] = self.order_type
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('InstanceClass') is not None:
            self.instance_class = m.get('InstanceClass')
        if m.get('OrderType') is not None:
            self.order_type = m.get('OrderType')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class TransferInstanceClassResponseBody(TeaModel):
    def __init__(self, charge_type=None, code=None, dts_job_id=None, dynamic_message=None, end_time=None,
                 err_code=None, err_message=None, http_status_code=None, instance_id=None, request_id=None, success=None):
        # The billing method of the DTS instance. Valid values:
        # 
        # *   **POSTPAY**: pay-as-you-go
        # *   **PREPAY**: subscription
        self.charge_type = charge_type  # type: str
        # The error code.
        self.code = code  # type: str
        # The ID of the data migration or data synchronization task.
        self.dts_job_id = dts_job_id  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The expiration time of the DTS instance.
        # 
        # >  This parameter is returned only if the ChargeType parameter is set to **PREPAY**.
        self.end_time = end_time  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of DTS instance.
        self.instance_id = instance_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful. Valid values:
        # 
        # *   **true**: The call was successful.
        # *   **false**:The call failed.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(TransferInstanceClassResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.charge_type is not None:
            result['ChargeType'] = self.charge_type
        if self.code is not None:
            result['Code'] = self.code
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.end_time is not None:
            result['EndTime'] = self.end_time
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ChargeType') is not None:
            self.charge_type = m.get('ChargeType')
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('EndTime') is not None:
            self.end_time = m.get('EndTime')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class TransferInstanceClassResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: TransferInstanceClassResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(TransferInstanceClassResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = TransferInstanceClassResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class TransferPayTypeRequest(TeaModel):
    def __init__(self, buy_count=None, charge_type=None, dts_job_id=None, period=None, region_id=None):
        # The subscription length.
        # 
        # *   If the **Period** parameter is set to **Year**, the value range is **1** to **5**.
        # *   If the **Period** parameter is set to **Month**, the value range is **1** to **60**.
        # 
        # >  You must specify this parameter only if you set the **ChargeType** parameter to **PrePaid**.
        self.buy_count = buy_count  # type: str
        # The billing method that you want to use. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        # 
        # > 
        # *   The billing method of subscription instances cannot be changed to pay-as-you-go. To prevent resource waste, determine whether you need to change the billing method of your resources.
        # *   If you do not need to change the billing method, specify the current billing method.
        self.charge_type = charge_type  # type: str
        # The ID of the data synchronization or change tracking task. You can call the [DescribeDtsJobs](~~209702~~) operation to query the task ID.
        self.dts_job_id = dts_job_id  # type: str
        # The billing cycle of the subscription instance. Valid values:
        # 
        # *   **Year**\
        # *   **Month** (default value)
        # 
        # >  You must specify this parameter only if you set the **ChargeType** parameter to **PrePaid**.
        self.period = period  # type: str
        # The ID of the region where the DTS instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(TransferPayTypeRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.buy_count is not None:
            result['BuyCount'] = self.buy_count
        if self.charge_type is not None:
            result['ChargeType'] = self.charge_type
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.period is not None:
            result['Period'] = self.period
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('BuyCount') is not None:
            self.buy_count = m.get('BuyCount')
        if m.get('ChargeType') is not None:
            self.charge_type = m.get('ChargeType')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('Period') is not None:
            self.period = m.get('Period')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class TransferPayTypeResponseBody(TeaModel):
    def __init__(self, charge_type=None, code=None, dts_job_id=None, dynamic_message=None, end_time=None,
                 err_code=None, err_message=None, http_status_code=None, instance_id=None, request_id=None, success=None):
        # The billing method of the DTS instance. Valid values:
        # 
        # *   **PrePaid**: subscription
        # *   **PostPaid**: pay-as-you-go
        self.charge_type = charge_type  # type: str
        # The error code. This parameter will be removed in the future.
        self.code = code  # type: str
        # The ID of the DTS task.
        self.dts_job_id = dts_job_id  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and the return value of the **DynamicMessage** parameter is **DtsJobId**, the specified **DtsJobId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The expiration time of the subscription instance. The value is a UNIX timestamp.
        # 
        # > 
        # *   If the DTS instance is a pay-as-you-go instance, the value of this parameter is empty.
        # *   You can use a search engine to obtain a UNIX timestamp converter.
        self.end_time = end_time  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the DTS instance.
        self.instance_id = instance_id  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful. Valid values:
        # 
        # *   **true**: The call was successful.
        # *   **false**: The call failed.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(TransferPayTypeResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.charge_type is not None:
            result['ChargeType'] = self.charge_type
        if self.code is not None:
            result['Code'] = self.code
        if self.dts_job_id is not None:
            result['DtsJobId'] = self.dts_job_id
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.end_time is not None:
            result['EndTime'] = self.end_time
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ChargeType') is not None:
            self.charge_type = m.get('ChargeType')
        if m.get('Code') is not None:
            self.code = m.get('Code')
        if m.get('DtsJobId') is not None:
            self.dts_job_id = m.get('DtsJobId')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('EndTime') is not None:
            self.end_time = m.get('EndTime')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class TransferPayTypeResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: TransferPayTypeResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(TransferPayTypeResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = TransferPayTypeResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class UntagResourcesRequest(TeaModel):
    def __init__(self, all=None, region_id=None, resource_id=None, resource_type=None, tag_key=None):
        # Specifies whether to unbind all tags from the specified instances. Valid values:
        # 
        # *   **true**: unbinds all tags from the specified instances.
        # *   **false**: To unbind only specific tags, you must specify the **TagKey.N** parameter.
        # 
        # > 
        # *   You must specify at least one of the All and **TagKey.N** parameters.
        # *   If you specify both the All parameter and the **TagKey.N** parameter, the All parameter does not take effect.
        self.all = all  # type: bool
        # The ID of the region where the data migration, data synchronization, or change tracking instance resides. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str
        self.resource_id = resource_id  # type: list[str]
        # The resource type. Valid value: **ALIYUN::DTS::INSTANCE**.
        self.resource_type = resource_type  # type: str
        self.tag_key = tag_key  # type: list[str]

    def validate(self):
        pass

    def to_map(self):
        _map = super(UntagResourcesRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.all is not None:
            result['All'] = self.all
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.resource_id is not None:
            result['ResourceId'] = self.resource_id
        if self.resource_type is not None:
            result['ResourceType'] = self.resource_type
        if self.tag_key is not None:
            result['TagKey'] = self.tag_key
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('All') is not None:
            self.all = m.get('All')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('ResourceId') is not None:
            self.resource_id = m.get('ResourceId')
        if m.get('ResourceType') is not None:
            self.resource_type = m.get('ResourceType')
        if m.get('TagKey') is not None:
            self.tag_key = m.get('TagKey')
        return self


class UntagResourcesResponseBody(TeaModel):
    def __init__(self, err_code=None, err_message=None, request_id=None, success=None):
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(UntagResourcesResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class UntagResourcesResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: UntagResourcesResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(UntagResourcesResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = UntagResourcesResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class UpgradeTwoWayRequest(TeaModel):
    def __init__(self, instance_class=None, instance_id=None, region_id=None):
        # The instance class of the two-way synchronization task. Valid values: **large**, **medium**, **micro**, and **small**.
        # 
        # >  For more information, see [Specifications of data synchronization instances](~~26605~~).
        self.instance_class = instance_class  # type: str
        # The ID of the data synchronization instance. You can call the [DescribeDtsJobs](~~209702~~) operation to query the instance ID.
        self.instance_id = instance_id  # type: str
        # The region ID of the DTS instance. For more information, see [List of supported regions](~~141033~~).
        self.region_id = region_id  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(UpgradeTwoWayRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.instance_class is not None:
            result['InstanceClass'] = self.instance_class
        if self.instance_id is not None:
            result['InstanceId'] = self.instance_id
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('InstanceClass') is not None:
            self.instance_class = m.get('InstanceClass')
        if m.get('InstanceId') is not None:
            self.instance_id = m.get('InstanceId')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        return self


class UpgradeTwoWayResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, request_id=None, success=None):
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic part in the error message. This parameter is used to replace the **%s** variable in the **ErrMessage** parameter.
        # 
        # >  If the return value of the **ErrMessage** parameter is **The Value of Input Parameter %s is not valid** and that of the **DynamicMessage** parameter is **InstanceId**, the specified **InstanceId** parameter is invalid.
        self.dynamic_message = dynamic_message  # type: str
        # The error code returned if the call failed.
        self.err_code = err_code  # type: str
        # The error message returned if the call failed.
        self.err_message = err_message  # type: str
        # The HTTP status code.
        self.http_status_code = http_status_code  # type: int
        # The ID of the request.
        self.request_id = request_id  # type: str
        # Indicates whether the call was successful. Valid values:
        # 
        # *   **true**: The call was successful.
        # *   **false**: The call failed.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(UpgradeTwoWayResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class UpgradeTwoWayResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: UpgradeTwoWayResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(UpgradeTwoWayResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = UpgradeTwoWayResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


class WhiteIpListRequest(TeaModel):
    def __init__(self, destination_region=None, region=None, region_id=None, type=None):
        # The HTTP status code.
        self.destination_region = destination_region  # type: str
        # The ID of the region where the destination instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # > 
        # *   If the destination instance is a self-managed database with a public IP address or a third-party cloud database, you can set the parameter to **cn-hangzhou** or the ID of the closest region.
        # *   If the DTS task is a data migration or data synchronization task, you must specify this parameter.
        self.region = region  # type: str
        self.region_id = region_id  # type: str
        # The ID of the region where the source instance resides. For more information, see [List of supported regions](~~141033~~).
        # 
        # >  If the source instance is a self-managed database with a public IP address or a third-party cloud database, you can set the parameter to **cn-hangzhou** or the ID of the closest region.
        self.type = type  # type: str

    def validate(self):
        pass

    def to_map(self):
        _map = super(WhiteIpListRequest, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.destination_region is not None:
            result['DestinationRegion'] = self.destination_region
        if self.region is not None:
            result['Region'] = self.region
        if self.region_id is not None:
            result['RegionId'] = self.region_id
        if self.type is not None:
            result['Type'] = self.type
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DestinationRegion') is not None:
            self.destination_region = m.get('DestinationRegion')
        if m.get('Region') is not None:
            self.region = m.get('Region')
        if m.get('RegionId') is not None:
            self.region_id = m.get('RegionId')
        if m.get('Type') is not None:
            self.type = m.get('Type')
        return self


class WhiteIpListResponseBody(TeaModel):
    def __init__(self, dynamic_code=None, dynamic_message=None, err_code=None, err_message=None,
                 http_status_code=None, ip_list=None, request_id=None, success=None):
        self.dynamic_code = dynamic_code  # type: str
        # The dynamic error code. This parameter will be removed in the future.
        self.dynamic_message = dynamic_message  # type: str
        # Indicates whether the call was successful. Valid values:
        # 
        # *   **true**: The call was successful.
        # *   **false**: The call failed.
        self.err_code = err_code  # type: str
        # The CIDR blocks of DTS servers. Multiple CIDR blocks are separated by commas (,).
        self.err_message = err_message  # type: str
        # The ID of the request.
        self.http_status_code = http_status_code  # type: int
        # The dynamic part in the error message. This parameter is used to replace **%s** in the **ErrMessage** parameter.
        self.ip_list = ip_list  # type: str
        # The error code returned if the call failed.
        self.request_id = request_id  # type: str
        # The error message returned if the call failed.
        self.success = success  # type: bool

    def validate(self):
        pass

    def to_map(self):
        _map = super(WhiteIpListResponseBody, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.dynamic_code is not None:
            result['DynamicCode'] = self.dynamic_code
        if self.dynamic_message is not None:
            result['DynamicMessage'] = self.dynamic_message
        if self.err_code is not None:
            result['ErrCode'] = self.err_code
        if self.err_message is not None:
            result['ErrMessage'] = self.err_message
        if self.http_status_code is not None:
            result['HttpStatusCode'] = self.http_status_code
        if self.ip_list is not None:
            result['IpList'] = self.ip_list
        if self.request_id is not None:
            result['RequestId'] = self.request_id
        if self.success is not None:
            result['Success'] = self.success
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('DynamicCode') is not None:
            self.dynamic_code = m.get('DynamicCode')
        if m.get('DynamicMessage') is not None:
            self.dynamic_message = m.get('DynamicMessage')
        if m.get('ErrCode') is not None:
            self.err_code = m.get('ErrCode')
        if m.get('ErrMessage') is not None:
            self.err_message = m.get('ErrMessage')
        if m.get('HttpStatusCode') is not None:
            self.http_status_code = m.get('HttpStatusCode')
        if m.get('IpList') is not None:
            self.ip_list = m.get('IpList')
        if m.get('RequestId') is not None:
            self.request_id = m.get('RequestId')
        if m.get('Success') is not None:
            self.success = m.get('Success')
        return self


class WhiteIpListResponse(TeaModel):
    def __init__(self, headers=None, status_code=None, body=None):
        self.headers = headers  # type: dict[str, str]
        self.status_code = status_code  # type: int
        self.body = body  # type: WhiteIpListResponseBody

    def validate(self):
        self.validate_required(self.headers, 'headers')
        self.validate_required(self.status_code, 'status_code')
        self.validate_required(self.body, 'body')
        if self.body:
            self.body.validate()

    def to_map(self):
        _map = super(WhiteIpListResponse, self).to_map()
        if _map is not None:
            return _map

        result = dict()
        if self.headers is not None:
            result['headers'] = self.headers
        if self.status_code is not None:
            result['statusCode'] = self.status_code
        if self.body is not None:
            result['body'] = self.body.to_map()
        return result

    def from_map(self, m=None):
        m = m or dict()
        if m.get('headers') is not None:
            self.headers = m.get('headers')
        if m.get('statusCode') is not None:
            self.status_code = m.get('statusCode')
        if m.get('body') is not None:
            temp_model = WhiteIpListResponseBody()
            self.body = temp_model.from_map(m['body'])
        return self


