/// <summary>
 /// Exports a database into blob storage
 /// </summary>
 /// <param name="proxy">Channel used for communication with Azure's service management APIs.</param>
 /// <param name="subscriptionId">The subscription ID in which the server resides</param>
 /// <param name="serverName">The name of the server that contains the database</param>
 /// <param name="input">The input data for the export operation</param>
 /// <returns>An <see cref="XmlElement"/> containing the request ID (GUID).</returns>
 public static XmlElement ExportDatabase(
     this ISqlDatabaseManagement proxy,
     string subscriptionId,
     string serverName,
     ExportInput input)
 {
     return proxy.EndExportDatabase(proxy.BeginExportDatabase(
         subscriptionId,
         serverName,
         input,
         null,
         null));
 }
 /// <summary>
 /// Starts a mock call to Begin Export Database.
 /// </summary>
 /// <param name="subscriptionId">The subscription Id to pass through</param>
 /// <param name="serverName">The server name to pass through</param>
 /// <param name="input">The input object to pass through</param>
 /// <param name="callback">The callback object to pass through</param>
 /// <param name="state">The state object to pass through</param>
 /// <returns>A <see cref="SimpleServiceManagementAsyncResult"/> object</returns>
 public IAsyncResult BeginExportDatabase(
     string subscriptionId,
     string serverName,
     ExportInput input,
     AsyncCallback callback,
     object state)
 {
     SimpleServiceManagementAsyncResult result = new SimpleServiceManagementAsyncResult();
     result.Values["subscriptionId"] = subscriptionId;
     result.Values["serverName"] = serverName;
     result.Values["input"] = input;
     result.Values["callback"] = callback;
     result.Values["state"] = state;
     return result;
 }
        /// <summary>
        /// Performs the call to export database using the server data service context channel.
        /// </summary>
        /// <param name="serverName">The name of the server to connect to.</param>
        /// <param name="input">The <see cref="ExportInput"/> object that contains 
        /// all the connection information</param>
        /// <returns>The result of export request.  Upon success the <see cref="ImportExportRequest"/>
        /// for the request</returns>
        internal ImportExportRequest ExportSqlAzureDatabaseProcess(string serverName, ExportInput input)
        {
            ImportExportRequest result = null;

            try
            {
                XmlElement requestId = RetryCall(subscription =>
                    this.Channel.ExportDatabase(subscription, serverName, input));
                Microsoft.WindowsAzure.ServiceManagement.Operation operation = WaitForSqlDatabaseOperation();

                if (requestId != null)
                {
                    result = new ImportExportRequest();
                    result.RequestGuid = requestId.InnerText;
                }
            }
            catch (Exception ex)
            {
                SqlDatabaseExceptionHandler.WriteErrorDetails(
                    this,
                    this.SqlConnectionContext.ClientRequestId,
                    ex);
            }

            return result;
        }
        /// <summary>
        /// Process the export request
        /// </summary>
        protected override void ProcessRecord()
        {
            this.WriteVerbose("Starting to process the record");
            try
            {
                base.ProcessRecord();

                string accessKey = null;
                string blobUri = null;

                switch(this.ParameterSetName)
                {
                    case ByContainerNameParameterSet:
                        accessKey =
                            System.Convert.ToBase64String(
                                this.StorageContext.StorageAccount.Credentials.ExportKey());

                        blobUri =
                            this.StorageContext.BlobEndPoint +
                            this.StorageContainerName + "/" +
                            this.BlobName;
                        break;

                    case ByContainerObjectParameterSet:
                        accessKey =
                            System.Convert.ToBase64String(
                                this.StorageContainer.CloudBlobContainer.ServiceClient.Credentials.ExportKey());

                        blobUri =
                            this.StorageContainer.Context.BlobEndPoint +
                            this.StorageContainer.Name + "/" +
                            this.BlobName;
                        break;
                }

                string fullyQualifiedServerName =
                    this.SqlConnectionContext.ServerName + DataServiceConstants.AzureSqlDatabaseDnsSuffix;

                // Create Web Request Inputs - Blob Storage Credentials and Server Connection Info
                ExportInput exportInput = new ExportInput
                {
                    BlobCredentials = new BlobStorageAccessKeyCredentials
                    {
                        StorageAccessKey = accessKey,
                        Uri = blobUri
                    },
                    ConnectionInfo = new ConnectionInfo
                    {
                        ServerName = fullyQualifiedServerName,
                        DatabaseName = this.DatabaseName,
                        UserName = this.SqlConnectionContext.SqlCredentials.UserName,
                        Password = this.SqlConnectionContext.SqlCredentials.Password
                    }
                };

                this.WriteVerbose("AccessKey: " + accessKey);
                this.WriteVerbose("blobUri: " + blobUri);
                this.WriteVerbose("ServerName: " + exportInput.ConnectionInfo.ServerName);
                this.WriteVerbose("DatabaseName: " + exportInput.ConnectionInfo.DatabaseName);
                this.WriteVerbose("UserName: "******"Password: " + exportInput.ConnectionInfo.Password);

                ImportExportRequest request =
                    this.ExportSqlAzureDatabaseProcess(this.SqlConnectionContext.ServerName, exportInput);

                if (request != null)
                {
                    request.SqlCredentials = this.SqlConnectionContext.SqlCredentials;
                    request.ServerName = this.SqlConnectionContext.ServerName;
                    this.WriteObject(request);
                }
            }
            catch (Exception ex)
            {
                SqlDatabaseExceptionHandler.WriteErrorDetails(
                    this,
                    this.SqlConnectionContext.ClientRequestId,
                    ex);
            }
        }
        public void ExportAzureSqlDatabaseProcessTest()
        {
            string serverName = "TestServer";
            ExportInput input = new ExportInput()
            {
                BlobCredentials = new BlobStorageAccessKeyCredentials()
                {
                    Uri = "blobUri",
                    StorageAccessKey = "storage access key"
                },
                ConnectionInfo = new ConnectionInfo()
                {
                    DatabaseName = "databaseName",
                    Password = "******",
                    ServerName = "serverName",
                    UserName = "******"
                }
            };

            Guid guid = Guid.NewGuid();

            MockCommandRuntime commandRuntime = new MockCommandRuntime();
            SimpleSqlDatabaseManagement channel = new SimpleSqlDatabaseManagement();
            channel.ExportDatabaseThunk = ar =>
            {
                Assert.AreEqual(serverName, (string)ar.Values["serverName"]);
                Assert.AreEqual(
                    input.BlobCredentials.Uri,
                    ((ExportInput)ar.Values["input"]).BlobCredentials.Uri);
                Assert.AreEqual(
                    input.ConnectionInfo.DatabaseName,
                    ((ExportInput)ar.Values["input"]).ConnectionInfo.DatabaseName);
                Assert.AreEqual(
                    input.ConnectionInfo.Password,
                    ((ExportInput)ar.Values["input"]).ConnectionInfo.Password);
                Assert.AreEqual(
                    input.ConnectionInfo.ServerName,
                    ((ExportInput)ar.Values["input"]).ConnectionInfo.ServerName);
                Assert.AreEqual(
                    input.ConnectionInfo.UserName,
                    ((ExportInput)ar.Values["input"]).ConnectionInfo.UserName);

                XmlElement operationResult =
                    new XmlDocument().CreateElement(
                        "guid",
                        "http://schemas.microsoft.com/2003/10/Serialization/");

                operationResult.InnerText = guid.ToString();
                return operationResult;
            };

            StartAzureSqlDatabaseExport exportAzureSqlDatabase =
                new StartAzureSqlDatabaseExport(channel) { ShareChannel = true };
            exportAzureSqlDatabase.CurrentSubscription = UnitTestHelper.CreateUnitTestSubscription();
            exportAzureSqlDatabase.CommandRuntime = commandRuntime;

            var result = exportAzureSqlDatabase.ExportSqlAzureDatabaseProcess(serverName, input);
            Assert.AreEqual(guid.ToString(), result.RequestGuid);

            Assert.AreEqual(0, commandRuntime.ErrorStream.Count);
        }