<?php
/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * GENERATED CODE WARNING
 * Generated by gapic-generator-php from the file
 * https://github.com/googleapis/googleapis/blob/master/google/cloud/sql/v1beta4/cloud_sql.proto
 * Updates to the above are reflected here through a refresh process.
 *
 * @experimental
 */

namespace Google\Cloud\Sql\V1beta4\Gapic;

use Google\ApiCore\ApiException;
use Google\ApiCore\CredentialsWrapper;
use Google\ApiCore\GapicClientTrait;
use Google\ApiCore\RequestParamsHeaderDescriptor;
use Google\ApiCore\RetrySettings;
use Google\ApiCore\Transport\TransportInterface;
use Google\ApiCore\ValidationException;
use Google\Auth\FetchAuthTokenInterface;
use Google\Cloud\Sql\V1beta4\DatabaseInstance;
use Google\Cloud\Sql\V1beta4\InstancesCloneRequest;
use Google\Cloud\Sql\V1beta4\InstancesDemoteMasterRequest;
use Google\Cloud\Sql\V1beta4\InstancesExportRequest;
use Google\Cloud\Sql\V1beta4\InstancesFailoverRequest;
use Google\Cloud\Sql\V1beta4\InstancesImportRequest;
use Google\Cloud\Sql\V1beta4\InstancesListResponse;
use Google\Cloud\Sql\V1beta4\InstancesListServerCasResponse;
use Google\Cloud\Sql\V1beta4\InstancesRestoreBackupRequest;
use Google\Cloud\Sql\V1beta4\InstancesRotateServerCaRequest;
use Google\Cloud\Sql\V1beta4\InstancesTruncateLogRequest;
use Google\Cloud\Sql\V1beta4\MySqlSyncConfig;
use Google\Cloud\Sql\V1beta4\Operation;
use Google\Cloud\Sql\V1beta4\SqlInstancesAddServerCaRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesCloneRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesCreateEphemeralCertRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesDeleteRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesDemoteMasterRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesExportRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesFailoverRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesGetRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesImportRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesInsertRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesListRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesListServerCasRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesPatchRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesPromoteReplicaRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesRescheduleMaintenanceRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesRescheduleMaintenanceRequestBody;
use Google\Cloud\Sql\V1beta4\SqlInstancesResetSslConfigRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesRestartRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesRestoreBackupRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesRotateServerCaRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesStartExternalSyncRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesStartReplicaRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesStopReplicaRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesTruncateLogRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesUpdateRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesVerifyExternalSyncSettingsRequest;
use Google\Cloud\Sql\V1beta4\SqlInstancesVerifyExternalSyncSettingsResponse;
use Google\Cloud\Sql\V1beta4\SslCert;
use Google\Cloud\Sql\V1beta4\SslCertsCreateEphemeralRequest;

/**
 * Service Description:
 *
 * This class provides the ability to make remote calls to the backing service through method
 * calls that map to API methods. Sample code to get started:
 *
 * ```
 * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
 * try {
 *     $response = $sqlInstancesServiceClient->addServerCa();
 * } finally {
 *     $sqlInstancesServiceClient->close();
 * }
 * ```
 *
 * @experimental
 */
class SqlInstancesServiceGapicClient
{
    use GapicClientTrait;

    /** The name of the service. */
    const SERVICE_NAME = 'google.cloud.sql.v1beta4.SqlInstancesService';

    /** The default address of the service. */
    const SERVICE_ADDRESS = 'sqladmin.googleapis.com';

    /** The default port of the service. */
    const DEFAULT_SERVICE_PORT = 443;

    /** The name of the code generator, to be included in the agent header. */
    const CODEGEN_NAME = 'gapic';

    /** The default scopes required by the service. */
    public static $serviceScopes = [
        'https://www.googleapis.com/auth/cloud-platform',
        'https://www.googleapis.com/auth/sqlservice.admin',
    ];

    private static function getClientDefaults()
    {
        return [
            'serviceName' => self::SERVICE_NAME,
            'apiEndpoint' =>
                self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT,
            'clientConfig' =>
                __DIR__ .
                '/../resources/sql_instances_service_client_config.json',
            'descriptorsConfigPath' =>
                __DIR__ .
                '/../resources/sql_instances_service_descriptor_config.php',
            'gcpApiConfigPath' =>
                __DIR__ .
                '/../resources/sql_instances_service_grpc_config.json',
            'credentialsConfig' => [
                'defaultScopes' => self::$serviceScopes,
            ],
            'transportConfig' => [
                'rest' => [
                    'restClientConfigPath' =>
                        __DIR__ .
                        '/../resources/sql_instances_service_rest_client_config.php',
                ],
            ],
        ];
    }

    /**
     * Constructor.
     *
     * @param array $options {
     *     Optional. Options for configuring the service API wrapper.
     *
     *     @type string $apiEndpoint
     *           The address of the API remote host. May optionally include the port, formatted
     *           as "<uri>:<port>". Default 'sqladmin.googleapis.com:443'.
     *     @type string|array|FetchAuthTokenInterface|CredentialsWrapper $credentials
     *           The credentials to be used by the client to authorize API calls. This option
     *           accepts either a path to a credentials file, or a decoded credentials file as a
     *           PHP array.
     *           *Advanced usage*: In addition, this option can also accept a pre-constructed
     *           {@see \Google\Auth\FetchAuthTokenInterface} object or
     *           {@see \Google\ApiCore\CredentialsWrapper} object. Note that when one of these
     *           objects are provided, any settings in $credentialsConfig will be ignored.
     *     @type array $credentialsConfig
     *           Options used to configure credentials, including auth token caching, for the
     *           client. For a full list of supporting configuration options, see
     *           {@see \Google\ApiCore\CredentialsWrapper::build()} .
     *     @type bool $disableRetries
     *           Determines whether or not retries defined by the client configuration should be
     *           disabled. Defaults to `false`.
     *     @type string|array $clientConfig
     *           Client method configuration, including retry settings. This option can be either
     *           a path to a JSON file, or a PHP array containing the decoded JSON data. By
     *           default this settings points to the default client config file, which is
     *           provided in the resources folder.
     *     @type string|TransportInterface $transport
     *           The transport used for executing network requests. May be either the string
     *           `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system.
     *           *Advanced usage*: Additionally, it is possible to pass in an already
     *           instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note
     *           that when this object is provided, any settings in $transportConfig, and any
     *           $apiEndpoint setting, will be ignored.
     *     @type array $transportConfig
     *           Configuration options that will be used to construct the transport. Options for
     *           each supported transport type should be passed in a key for that transport. For
     *           example:
     *           $transportConfig = [
     *               'grpc' => [...],
     *               'rest' => [...],
     *           ];
     *           See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and
     *           {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the
     *           supported options.
     *     @type callable $clientCertSource
     *           A callable which returns the client cert as a string. This can be used to
     *           provide a certificate and private key to the transport layer for mTLS.
     * }
     *
     * @throws ValidationException
     *
     * @experimental
     */
    public function __construct(array $options = [])
    {
        $clientOptions = $this->buildClientOptions($options);
        $this->setClientOptions($clientOptions);
    }

    /**
     * Add a new trusted Certificate Authority (CA) version for the specified
     * instance. Required to prepare for a certificate rotation. If a CA version
     * was previously added but never used in a certificate rotation, this
     * operation replaces that version. There cannot be more than one CA version
     * waiting to be rotated in.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->addServerCa();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function addServerCa(array $optionalArgs = [])
    {
        $request = new SqlInstancesAddServerCaRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'AddServerCa',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Creates a Cloud SQL instance as a clone of the source instance. Using this
     * operation might cause your instance to restart.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->clone();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           The ID of the Cloud SQL instance to be cloned (source). This does not
     *           include the project ID.
     *     @type string $project
     *           Project ID of the source as well as the clone Cloud SQL instance.
     *     @type InstancesCloneRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function clone(array $optionalArgs = [])
    {
        $request = new SqlInstancesCloneRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Clone',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Generates a short-lived X509 certificate containing the provided public key
     * and signed by a private key specific to the target instance. Users may use
     * the certificate to authenticate as themselves when connecting to the
     * database.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->createEphemeral();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the Cloud SQL project.
     *     @type SslCertsCreateEphemeralRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\SslCert
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function createEphemeral(array $optionalArgs = [])
    {
        $request = new SqlInstancesCreateEphemeralCertRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'CreateEphemeral',
            SslCert::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Deletes a Cloud SQL instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->delete();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance to be deleted.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function delete(array $optionalArgs = [])
    {
        $request = new SqlInstancesDeleteRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Delete',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Demotes the stand-alone instance to be a Cloud SQL read replica for an
     * external database server.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->demoteMaster();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance name.
     *     @type string $project
     *           ID of the project that contains the instance.
     *     @type InstancesDemoteMasterRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function demoteMaster(array $optionalArgs = [])
    {
        $request = new SqlInstancesDemoteMasterRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'DemoteMaster',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Exports data from a Cloud SQL instance to a Cloud Storage bucket as a SQL
     * dump or CSV file.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->export();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance to be exported.
     *     @type InstancesExportRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function export(array $optionalArgs = [])
    {
        $request = new SqlInstancesExportRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Export',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Initiates a manual failover of a high availability (HA) primary instance
     * to a standby instance, which becomes the primary instance. Users are
     * then rerouted to the new primary. For more information, see the
     * [Overview of high
     * availability](https://cloud.google.com/sql/docs/mysql/high-availability)
     * page in the Cloud SQL documentation.
     * If using Legacy HA (MySQL only), this causes the instance to failover to
     * its failover replica instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->failover();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           ID of the project that contains the read replica.
     *     @type InstancesFailoverRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function failover(array $optionalArgs = [])
    {
        $request = new SqlInstancesFailoverRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Failover',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Retrieves a resource containing information about a Cloud SQL instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->get();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Database instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\DatabaseInstance
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function get(array $optionalArgs = [])
    {
        $request = new SqlInstancesGetRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Get',
            DatabaseInstance::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Imports data into a Cloud SQL instance from a SQL dump  or CSV file in
     * Cloud Storage.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->import();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type InstancesImportRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function import(array $optionalArgs = [])
    {
        $request = new SqlInstancesImportRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Import',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Creates a new Cloud SQL instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->insert();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $project
     *           Project ID of the project to which the newly created Cloud SQL instances
     *           should belong.
     *     @type DatabaseInstance $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function insert(array $optionalArgs = [])
    {
        $request = new SqlInstancesInsertRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Insert',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Lists instances under a given project.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->list();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $filter
     *           A filter expression that filters resources listed in the response.
     *           The expression is in the form of field:value. For example,
     *           'instanceType:CLOUD_SQL_INSTANCE'. Fields can be nested as needed as per
     *           their JSON representation, such as 'settings.userLabels.auto_start:true'.
     *
     *           Multiple filter queries are space-separated. For example.
     *           'state:RUNNABLE instanceType:CLOUD_SQL_INSTANCE'. By default, each
     *           expression is an AND expression. However, you can include AND and OR
     *           expressions explicitly.
     *     @type int $maxResults
     *           The maximum number of results to return per response.
     *     @type string $pageToken
     *           A previously-returned page token representing part of the larger set of
     *           results to view.
     *     @type string $project
     *           Project ID of the project for which to list Cloud SQL instances.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\InstancesListResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function list(array $optionalArgs = [])
    {
        $request = new SqlInstancesListRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['filter'])) {
            $request->setFilter($optionalArgs['filter']);
        }

        if (isset($optionalArgs['maxResults'])) {
            $request->setMaxResults($optionalArgs['maxResults']);
        }

        if (isset($optionalArgs['pageToken'])) {
            $request->setPageToken($optionalArgs['pageToken']);
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'List',
            InstancesListResponse::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Lists all of the trusted Certificate Authorities (CAs) for the specified
     * instance. There can be up to three CAs listed: the CA that was used to sign
     * the certificate that is currently in use, a CA that has been added but not
     * yet used to sign a certificate, and a CA used to sign a certificate that
     * has previously rotated out.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->listServerCas();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\InstancesListServerCasResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function listServerCas(array $optionalArgs = [])
    {
        $request = new SqlInstancesListServerCasRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'ListServerCas',
            InstancesListServerCasResponse::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Updates settings of a Cloud SQL instance.
     * This method supports patch semantics.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->patch();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type DatabaseInstance $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function patch(array $optionalArgs = [])
    {
        $request = new SqlInstancesPatchRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Patch',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Promotes the read replica instance to be a stand-alone Cloud SQL instance.
     * Using this operation might cause your instance to restart.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->promoteReplica();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL read replica instance name.
     *     @type string $project
     *           ID of the project that contains the read replica.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function promoteReplica(array $optionalArgs = [])
    {
        $request = new SqlInstancesPromoteReplicaRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'PromoteReplica',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Reschedules the maintenance on the given instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->rescheduleMaintenance();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           ID of the project that contains the instance.
     *     @type SqlInstancesRescheduleMaintenanceRequestBody $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function rescheduleMaintenance(array $optionalArgs = [])
    {
        $request = new SqlInstancesRescheduleMaintenanceRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'RescheduleMaintenance',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Deletes all client certificates and generates a new server SSL certificate
     * for the instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->resetSslConfig();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function resetSslConfig(array $optionalArgs = [])
    {
        $request = new SqlInstancesResetSslConfigRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'ResetSslConfig',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Restarts a Cloud SQL instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->restart();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance to be restarted.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function restart(array $optionalArgs = [])
    {
        $request = new SqlInstancesRestartRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Restart',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Restores a backup of a Cloud SQL instance. Using this operation might cause
     * your instance to restart.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->restoreBackup();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type InstancesRestoreBackupRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function restoreBackup(array $optionalArgs = [])
    {
        $request = new SqlInstancesRestoreBackupRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'RestoreBackup',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Rotates the server certificate to one signed by the Certificate Authority
     * (CA) version previously added with the addServerCA method.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->rotateServerCa();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type InstancesRotateServerCaRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function rotateServerCa(array $optionalArgs = [])
    {
        $request = new SqlInstancesRotateServerCaRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'RotateServerCa',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Start External primary instance migration.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->startExternalSync();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           ID of the project that contains the instance.
     *     @type int $syncMode
     *           External sync mode.
     *           For allowed values, use constants defined on {@see \Google\Cloud\Sql\V1beta4\SqlInstancesVerifyExternalSyncSettingsRequest\ExternalSyncMode}
     *     @type bool $skipVerification
     *           Whether to skip the verification step (VESS).
     *     @type MySqlSyncConfig $mysqlSyncConfig
     *           MySQL-specific settings for start external sync.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function startExternalSync(array $optionalArgs = [])
    {
        $request = new SqlInstancesStartExternalSyncRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['syncMode'])) {
            $request->setSyncMode($optionalArgs['syncMode']);
        }

        if (isset($optionalArgs['skipVerification'])) {
            $request->setSkipVerification($optionalArgs['skipVerification']);
        }

        if (isset($optionalArgs['mysqlSyncConfig'])) {
            $request->setMysqlSyncConfig($optionalArgs['mysqlSyncConfig']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'StartExternalSync',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Starts the replication in the read replica instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->startReplica();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL read replica instance name.
     *     @type string $project
     *           ID of the project that contains the read replica.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function startReplica(array $optionalArgs = [])
    {
        $request = new SqlInstancesStartReplicaRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'StartReplica',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Stops the replication in the read replica instance.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->stopReplica();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL read replica instance name.
     *     @type string $project
     *           ID of the project that contains the read replica.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function stopReplica(array $optionalArgs = [])
    {
        $request = new SqlInstancesStopReplicaRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'StopReplica',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Truncate MySQL general and slow query log tables
     * MySQL only.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->truncateLog();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the Cloud SQL project.
     *     @type InstancesTruncateLogRequest $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function truncateLog(array $optionalArgs = [])
    {
        $request = new SqlInstancesTruncateLogRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'TruncateLog',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Updates settings of a Cloud SQL instance. Using this operation might cause
     * your instance to restart.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->update();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type DatabaseInstance $body
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\Operation
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function update(array $optionalArgs = [])
    {
        $request = new SqlInstancesUpdateRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['body'])) {
            $request->setBody($optionalArgs['body']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'Update',
            Operation::class,
            $optionalArgs,
            $request
        )->wait();
    }

    /**
     * Verify External primary instance external sync settings.
     *
     * Sample code:
     * ```
     * $sqlInstancesServiceClient = new SqlInstancesServiceClient();
     * try {
     *     $response = $sqlInstancesServiceClient->verifyExternalSyncSettings();
     * } finally {
     *     $sqlInstancesServiceClient->close();
     * }
     * ```
     *
     * @param array $optionalArgs {
     *     Optional.
     *
     *     @type string $instance
     *           Cloud SQL instance ID. This does not include the project ID.
     *     @type string $project
     *           Project ID of the project that contains the instance.
     *     @type bool $verifyConnectionOnly
     *           Flag to enable verifying connection only
     *     @type int $syncMode
     *           External sync mode
     *           For allowed values, use constants defined on {@see \Google\Cloud\Sql\V1beta4\SqlInstancesVerifyExternalSyncSettingsRequest\ExternalSyncMode}
     *     @type bool $verifyReplicationOnly
     *           Optional. Flag to verify settings required by replication setup only
     *     @type MySqlSyncConfig $mysqlSyncConfig
     *           Optional. MySQL-specific settings for start external sync.
     *     @type RetrySettings|array $retrySettings
     *           Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
     *           associative array of retry settings parameters. See the documentation on
     *           {@see RetrySettings} for example usage.
     * }
     *
     * @return \Google\Cloud\Sql\V1beta4\SqlInstancesVerifyExternalSyncSettingsResponse
     *
     * @throws ApiException if the remote call fails
     *
     * @experimental
     */
    public function verifyExternalSyncSettings(array $optionalArgs = [])
    {
        $request = new SqlInstancesVerifyExternalSyncSettingsRequest();
        $requestParamHeaders = [];
        if (isset($optionalArgs['instance'])) {
            $request->setInstance($optionalArgs['instance']);
            $requestParamHeaders['instance'] = $optionalArgs['instance'];
        }

        if (isset($optionalArgs['project'])) {
            $request->setProject($optionalArgs['project']);
            $requestParamHeaders['project'] = $optionalArgs['project'];
        }

        if (isset($optionalArgs['verifyConnectionOnly'])) {
            $request->setVerifyConnectionOnly(
                $optionalArgs['verifyConnectionOnly']
            );
        }

        if (isset($optionalArgs['syncMode'])) {
            $request->setSyncMode($optionalArgs['syncMode']);
        }

        if (isset($optionalArgs['verifyReplicationOnly'])) {
            $request->setVerifyReplicationOnly(
                $optionalArgs['verifyReplicationOnly']
            );
        }

        if (isset($optionalArgs['mysqlSyncConfig'])) {
            $request->setMysqlSyncConfig($optionalArgs['mysqlSyncConfig']);
        }

        $requestParams = new RequestParamsHeaderDescriptor(
            $requestParamHeaders
        );
        $optionalArgs['headers'] = isset($optionalArgs['headers'])
            ? array_merge($requestParams->getHeader(), $optionalArgs['headers'])
            : $requestParams->getHeader();
        return $this->startCall(
            'VerifyExternalSyncSettings',
            SqlInstancesVerifyExternalSyncSettingsResponse::class,
            $optionalArgs,
            $request
        )->wait();
    }
}
