/// <summary>
        /// Update a sync member
        /// </summary>
        /// <param name="model">AzureSqlSyncMemberModel object</param>
        /// <param name="databaseType">The type of member database</param>
        /// <param name="password">The password of member database</param>
        /// <returns>Updated AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncMemberModel UpdateSyncMember(AzureSqlSyncMemberModel model)
        {
            SyncMemberCreateOrUpdateProperties properties = new SyncMemberCreateOrUpdateProperties()
            {
                DatabaseType = (DatabaseTypeEnum)(model.MemberDatabaseType != null ? Enum.Parse(typeof(DatabaseTypeEnum), model.MemberDatabaseType, true) : null),
                DatabaseName = model.MemberDatabaseName,
                ServerName   = model.MemberServerName,
                UserName     = model.MemberDatabaseUserName,
                Password     = model.MemberDatabasePassword == null ? null : AzureSqlServerAdapter.Decrypt(model.MemberDatabasePassword)
            };
            var resp = Communicator.UpdateSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, new SyncMemberCreateOrUpdateParameters()
            {
                SyncGroupName  = model.SyncGroupName,
                SyncMemberName = model.SyncMemberName,
                Properties     = properties
            });

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            resp = Communicator.GetSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, new SyncMemberGeneralParameters()
            {
                SyncGroupName  = model.SyncGroupName,
                SyncMemberName = model.SyncMemberName,
            });
            return(CreateSyncMemberModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, resp));
        }
        /// <summary>
        /// Creates a new import request
        /// </summary>
        /// <param name="importRequest">Import request parameters</param>
        /// <returns>Operation response including the OperationStatusLink to get the operation status</returns>
        public AzureSqlDatabaseImportExportBaseModel ImportNewDatabase(AzureSqlDatabaseImportModel importRequest)
        {
            Management.Sql.Models.ImportNewDatabaseDefinition parameters = new Management.Sql.Models.ImportNewDatabaseDefinition()
            {
                AdministratorLogin         = importRequest.AdministratorLogin,
                AdministratorLoginPassword = AzureSqlServerAdapter.Decrypt(importRequest.AdministratorLoginPassword),
                StorageKey           = importRequest.StorageKey,
                StorageKeyType       = importRequest.StorageKeyType.ToString(),
                StorageUri           = importRequest.StorageUri.ToString(),
                MaxSizeBytes         = importRequest.DatabaseMaxSizeBytes.ToString(),
                Edition              = importRequest.Edition != Database.Model.DatabaseEdition.None ? importRequest.Edition.ToString() : string.Empty,
                ServiceObjectiveName = importRequest.ServiceObjectiveName,
                DatabaseName         = importRequest.DatabaseName,
                NetworkIsolation     = new Management.Sql.Models.NetworkIsolationSettings()
                {
                    SqlServerResourceId      = importRequest.NetworkIsolationSettings.SqlServerResourceId,
                    StorageAccountResourceId = importRequest.NetworkIsolationSettings.StorageAccountResourceId
                }
            };

            if (importRequest.AuthenticationType != AuthenticationType.None)
            {
                parameters.AuthenticationType = importRequest.AuthenticationType.ToString().ToLowerInvariant();
            }

            Uri azureAsyncOperation = null;
            ImportExportOperationResult response;

            response = Communicator.BeginImportNewDatabase(importRequest.ResourceGroupName, importRequest.ServerName, parameters, out azureAsyncOperation);

            return(CreateImportExportResponse(response, importRequest, azureAsyncOperation));
        }
        /// <summary>
        /// Creates a new export request
        /// </summary>
        /// <param name="exportRequest">Export request parameters</param>
        /// <returns>Operation response including the OperationStatusLink to get the operation status</returns>
        public AzureSqlDatabaseImportExportBaseModel Export(AzureSqlDatabaseImportExportBaseModel exportRequest)
        {
            ExportDatabaseDefinition parameters = new ExportDatabaseDefinition()
            {
                AdministratorLogin         = exportRequest.AdministratorLogin,
                AdministratorLoginPassword = AzureSqlServerAdapter.Decrypt(exportRequest.AdministratorLoginPassword),
                StorageKey     = exportRequest.StorageKey,
                StorageKeyType = exportRequest.StorageKeyType.ToString(),
                StorageUri     = exportRequest.StorageUri.ToString()
            };

            if (exportRequest.AuthenticationType != AuthenticationType.None)
            {
                parameters.AuthenticationType = exportRequest.AuthenticationType.ToString().ToLowerInvariant();
            }

            Uri azureAsyncOperation = null;
            ImportExportOperationResult response;

            response = Communicator.BeginExport(
                exportRequest.ResourceGroupName,
                exportRequest.ServerName,
                exportRequest.DatabaseName,
                parameters,
                out azureAsyncOperation);

            return(CreateImportExportResponse(response, exportRequest, azureAsyncOperation));
        }
        /// <summary>
        /// Update a sync group
        /// </summary>
        /// <param name="model">AzureSqlSyncGroupModel object</param>
        /// <returns>Updated AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncGroupModel UpdateSyncGroup(AzureSqlSyncGroupModel model)
        {
            var updateResp = Communicator.UpdateSyncGroup(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, new Management.Sql.Models.SyncGroup()
            {
                Interval            = model.IntervalInSeconds,
                HubDatabaseUserName = model.HubDatabaseUserName,
                HubDatabasePassword = model.HubDatabasePassword == null ? null: AzureSqlServerAdapter.Decrypt(model.HubDatabasePassword),
                Schema = model.Schema == null ? null : model.Schema.ToSyncGroupSchema(),
                UsePrivateLinkConnection = model.UsePrivateLinkConnection,
            });

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            var resp = Communicator.GetSyncGroup(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName);

            return(CreateSyncGroupModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, resp));
        }
        /// <summary>
        /// Update a sync group
        /// </summary>
        /// <param name="model">AzureSqlSyncGroupModel object</param>
        /// <returns>Updated AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncGroupModel UpdateSyncGroup(AzureSqlSyncGroupModel model)
        {
            var resp = Communicator.UpdateSyncGroup(model.ResourceGroupName, model.ServerName, model.DatabaseName, new SyncGroupCreateOrUpdateParameters()
            {
                SyncGroupName = model.SyncGroupName,
                Properties    = new SyncGroupCreateOrUpdateProperties
                {
                    Interval            = model.IntervalInSeconds,
                    HubDatabaseUserName = model.HubDatabaseUserName,
                    HubDatabasePassword = model.HubDatabasePassword == null ? null: AzureSqlServerAdapter.Decrypt(model.HubDatabasePassword),
                    Schema = model.Schema == null ? null : model.Schema.ToSyncGroupSchema(),
                },
            });

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            resp = Communicator.GetSyncGroup(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName);
            return(CreateSyncGroupModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, resp));
        }
        /// <summary>
        /// Create a sync group
        /// </summary>
        /// <param name="model">AzureSqlSyncGroupModel object</param>
        /// <returns>Created AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncGroupModel CreateSyncGroup(AzureSqlSyncGroupModel model, string syncDatabaseId)
        {
            var resp = Communicator.CreateSyncGroup(model.ResourceGroupName, model.ServerName, model.DatabaseName, syncDatabaseId, new SyncGroupCreateOrUpdateParameters()
            {
                SyncGroupName = model.SyncGroupName,
                Properties    = new SyncGroupCreateOrUpdateProperties
                {
                    ConflictResolutionPolicy = (ConflictResolutionPolicyType)(model.ConflictResolutionPolicy != null ? Enum.Parse(typeof(ConflictResolutionPolicyType), model.ConflictResolutionPolicy, true) : null),
                    Interval            = model.IntervalInSeconds,
                    HubDatabaseUserName = model.HubDatabaseUserName,
                    HubDatabasePassword = model.HubDatabasePassword == null ? null : AzureSqlServerAdapter.Decrypt(model.HubDatabasePassword),
                    Schema = model.Schema == null ? null : model.Schema.ToSyncGroupSchema(),
                },
            });

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            resp = Communicator.GetSyncGroup(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName);
            return(CreateSyncGroupModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, resp));
        }
        /// <summary>
        /// Creates a new export request
        /// </summary>
        /// <param name="exportRequest">Export request parameters</param>
        /// <returns>Operation response including the OperationStatusLink to get the operation status</returns>
        public AzureSqlDatabaseImportExportBaseModel Export(AzureSqlDatabaseImportExportBaseModel exportRequest)
        {
            ExportRequestParameters parameters = new ExportRequestParameters()
            {
                AdministratorLogin         = exportRequest.AdministratorLogin,
                AdministratorLoginPassword = AzureSqlServerAdapter.Decrypt(exportRequest.AdministratorLoginPassword),
                StorageKey     = exportRequest.StorageKey,
                StorageKeyType = exportRequest.StorageKeyType.ToString(),
                StorageUri     = exportRequest.StorageUri
            };

            if (exportRequest.AuthenticationType != AuthenticationType.None)
            {
                parameters.AuthenticationType = exportRequest.AuthenticationType.ToString().ToLowerInvariant();
            }

            ImportExportResponse response = Communicator.Export(exportRequest.ResourceGroupName, exportRequest.ServerName,
                                                                exportRequest.DatabaseName, parameters, Util.GenerateTracingId());

            return(CreateImportExportResponse(response, exportRequest));
        }
        /// <summary>
        /// Creates a new export request
        /// </summary>
        /// <param name="exportRequest">Export request parameters</param>
        /// <returns>Operation response including the OperationStatusLink to get the operation status</returns>
        public AzureSqlDatabaseImportExportBaseModel Export(AzureSqlDatabaseImportExportBaseModel exportRequest)
        {
            ExportDatabaseDefinition parameters = new ExportDatabaseDefinition()
            {
                AdministratorLogin         = exportRequest.AdministratorLogin,
                AdministratorLoginPassword = AzureSqlServerAdapter.Decrypt(exportRequest.AdministratorLoginPassword),
                StorageKey       = exportRequest.StorageKey,
                StorageKeyType   = exportRequest.StorageKeyType.ToString(),
                StorageUri       = exportRequest.StorageUri.ToString(),
                NetworkIsolation = null
            };

            if (!string.IsNullOrEmpty(exportRequest.NetworkIsolationSettings.SqlServerResourceId) ||
                !string.IsNullOrEmpty(exportRequest.NetworkIsolationSettings.StorageAccountResourceId))
            {
                parameters.NetworkIsolation = new Management.Sql.Models.NetworkIsolationSettings()
                {
                    SqlServerResourceId      = exportRequest.NetworkIsolationSettings.SqlServerResourceId,
                    StorageAccountResourceId = exportRequest.NetworkIsolationSettings.StorageAccountResourceId
                };
            }

            if (exportRequest.AuthenticationType != AuthenticationType.None)
            {
                parameters.AuthenticationType = exportRequest.AuthenticationType.ToString().ToLowerInvariant();
            }

            Uri azureAsyncOperation = null;
            ImportExportOperationResult response;

            response = Communicator.BeginExport(
                exportRequest.ResourceGroupName,
                exportRequest.ServerName,
                exportRequest.DatabaseName,
                parameters,
                out azureAsyncOperation);

            return(CreateImportExportResponse(response, exportRequest, azureAsyncOperation));
        }
        /// <summary>
        /// Creates a new import request
        /// </summary>
        /// <param name="importRequest">Import request parameters</param>
        /// <returns>Operation response including the OperationStatusLink to get the operation status</returns>
        public AzureSqlDatabaseImportExportBaseModel Import(AzureSqlDatabaseImportModel importRequest)
        {
            ImportRequestParameters parameters = new ImportRequestParameters()
            {
                AdministratorLogin         = importRequest.AdministratorLogin,
                AdministratorLoginPassword = AzureSqlServerAdapter.Decrypt(importRequest.AdministratorLoginPassword),
                StorageKey           = importRequest.StorageKey,
                StorageKeyType       = importRequest.StorageKeyType.ToString(),
                StorageUri           = importRequest.StorageUri,
                DatabaseMaxSize      = importRequest.DatabaseMaxSizeBytes,
                Edition              = importRequest.Edition != Database.Model.DatabaseEdition.None ? importRequest.Edition.ToString() : string.Empty,
                ServiceObjectiveName = importRequest.ServiceObjectiveName,
                DatabaseName         = importRequest.DatabaseName
            };

            if (importRequest.AuthenticationType != AuthenticationType.None)
            {
                parameters.AuthenticationType = importRequest.AuthenticationType.ToString().ToLowerInvariant();
            }

            ImportExportResponse response = Communicator.Import(importRequest.ResourceGroupName, importRequest.ServerName, parameters, Util.GenerateTracingId());

            return(CreateImportExportResponse(response, importRequest));
        }
        /// <summary>
        /// Create a sync member
        /// </summary>
        /// <param name="model">AzureSqlSyncMemberModel object</param>
        /// <param name="databaseType">The type of member database</param>
        /// <param name="password">The password of member database</param>
        /// <returns>Created AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncMemberModel CreateSyncMember(AzureSqlSyncMemberModel model, string syncAgentId)
        {
            SyncMemberCreateOrUpdateProperties properties = new SyncMemberCreateOrUpdateProperties()
            {
                SyncDirection = (SyncDirectionEnum?)(model.SyncDirection != null ? Enum.Parse(typeof(SyncDirectionEnum), model.SyncDirection, true) : null),
                DatabaseType  = (DatabaseTypeEnum)(model.MemberDatabaseType != null ? Enum.Parse(typeof(DatabaseTypeEnum), model.MemberDatabaseType, true) : null)
            };

            if (properties.DatabaseType == DatabaseTypeEnum.AzureSqlDatabase)
            {
                properties.DatabaseName = model.MemberDatabaseName;
                properties.ServerName   = model.MemberServerName;
                properties.UserName     = model.MemberDatabaseUserName;
                properties.Password     = model.MemberDatabasePassword == null ? null : AzureSqlServerAdapter.Decrypt(model.MemberDatabasePassword);
            }
            else
            {
                properties.SqlServerDatabaseId = model.SqlServerDatabaseId;
                properties.SyncAgentId         = model.SyncAgentId;
            }
            var resp = Communicator.CreateSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, syncAgentId, new SyncMemberCreateOrUpdateParameters()
            {
                SyncGroupName  = model.SyncGroupName,
                SyncMemberName = model.SyncMemberName,
                Properties     = properties,
            });

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            resp = Communicator.GetSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, new SyncMemberGeneralParameters()
            {
                SyncGroupName  = model.SyncGroupName,
                SyncMemberName = model.SyncMemberName,
            });
            return(CreateSyncMemberModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, resp));
        }
        /// <summary>
        /// Update a sync member
        /// </summary>
        /// <param name="model">AzureSqlSyncMemberModel object</param>
        /// <param name="databaseType">The type of member database</param>
        /// <param name="password">The password of member database</param>
        /// <returns>Updated AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncMemberModel UpdateSyncMember(AzureSqlSyncMemberModel model)
        {
            Management.Sql.Models.SyncMember properties = new Management.Sql.Models.SyncMember()
            {
                DatabaseType                      = model.MemberDatabaseType,
                DatabaseName                      = model.MemberDatabaseName,
                ServerName                        = model.MemberServerName,
                UserName                          = model.MemberDatabaseUserName,
                Password                          = model.MemberDatabasePassword == null ? null : AzureSqlServerAdapter.Decrypt(model.MemberDatabasePassword),
                UsePrivateLinkConnection          = model.UsePrivateLinkConnection,
                SyncMemberAzureDatabaseResourceId = model.SyncMemberAzureDatabaseResourceId
            };
            var updateResp = Communicator.UpdateSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, model.SyncMemberName, properties);

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            var resp = Communicator.GetSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, new SyncMemberGeneralParameters()
            {
                SyncGroupName  = model.SyncGroupName,
                SyncMemberName = model.SyncMemberName,
            });

            return(CreateSyncMemberModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, resp));
        }
        /// <summary>
        /// Create a sync member
        /// </summary>
        /// <param name="model">AzureSqlSyncMemberModel object</param>
        /// <param name="databaseType">The type of member database</param>
        /// <param name="password">The password of member database</param>
        /// <returns>Created AzureSqlSyncGroupModel object</returns>
        internal AzureSqlSyncMemberModel CreateSyncMember(AzureSqlSyncMemberModel model, string syncAgentId)
        {
            Management.Sql.Models.SyncMember properties = new Management.Sql.Models.SyncMember()
            {
                SyncDirection = model.SyncDirection,
                DatabaseType  = model.MemberDatabaseType,
            };

            if (properties.DatabaseType == DatabaseTypeEnum.AzureSqlDatabase.ToString())
            {
                properties.DatabaseName                      = model.MemberDatabaseName;
                properties.ServerName                        = model.MemberServerName;
                properties.UserName                          = model.MemberDatabaseUserName;
                properties.Password                          = model.MemberDatabasePassword == null ? null : AzureSqlServerAdapter.Decrypt(model.MemberDatabasePassword);
                properties.UsePrivateLinkConnection          = model.UsePrivateLinkConnection;
                properties.SyncMemberAzureDatabaseResourceId = model.SyncMemberAzureDatabaseResourceId;
            }
            else
            {
                properties.SqlServerDatabaseId = model.SqlServerDatabaseId == null ? null : (Guid?)Guid.Parse(model.SqlServerDatabaseId);
                properties.SyncAgentId         = model.SyncAgentId;
            }
            var createResp = Communicator.CreateSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, model.SyncMemberName, syncAgentId, properties);

            // Workaround for Rest API return response value incorrect issue. Remove this line after backend fix is deployed
            var resp = Communicator.GetSyncMember(model.ResourceGroupName, model.ServerName, model.DatabaseName, new SyncMemberGeneralParameters()
            {
                SyncGroupName  = model.SyncGroupName,
                SyncMemberName = model.SyncMemberName,
            });

            return(CreateSyncMemberModelFromResponse(model.ResourceGroupName, model.ServerName, model.DatabaseName, model.SyncGroupName, resp));
        }