示例#1
0
        /// <summary>
        /// Create a new data entry in the Azure table (insert new, not update existing).
        /// Fails if the data already exists.
        /// </summary>
        /// <param name="data">Data to be inserted into the table.</param>
        /// <returns>Value promise with new Etag for this data entry after completing this storage operation.</returns>
        public async Task <string> CreateTableEntryAsync(T data)
        {
            const string operation = "CreateTableEntry";
            var          startTime = DateTime.UtcNow;

            if (Logger.IsVerbose2)
            {
                Logger.Verbose2("Creating {0} table entry: {1}", TableName, data);
            }

            try
            {
                TableServiceContext svc = tableOperationsClient.GetDataServiceContext();
                svc.AddObject(TableName, data);

                try
                {
                    await Task <DataServiceResponse> .Factory.FromAsync(
                        svc.BeginSaveChangesWithRetries,
                        svc.EndSaveChangesWithRetries,
                        SaveChangesOptions.None,
                        null);

                    return(svc.GetEntityDescriptor(data).ETag);
                }
                catch (Exception exc)
                {
                    Logger.Warn(ErrorCode.AzureTable_05, String.Format("Intermediate error creating entry {0} in the table {1}",
                                                                       (data == null ? "null" : data.ToString()), TableName), exc);
                    throw;
                }
            }
            finally
            {
                CheckAlertSlowAccess(startTime, operation);
            }
        }
        /// <summary>
        /// Stores the value of a Setting.
        /// </summary>
        /// <param name="name">The name of the Setting.</param>
        /// <param name="value">The value of the Setting. Value cannot contain CR and LF characters, which will be removed.</param>
        /// <returns>True if the Setting is stored, false otherwise.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="name"/> is empty.</exception>
        public bool SetSetting(string name, string value)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            if (name.Length == 0)
            {
                throw new ArgumentException("name");
            }

            _settingsDictionary = null;

            // Nulls are converted to empty strings
            if (value == null)
            {
                value = "";
            }

            SettingsEntity settingsEntity = GetSettingsEntity(_wiki, name);

            if (settingsEntity == null)
            {
                settingsEntity = new SettingsEntity()
                {
                    PartitionKey = _wiki,
                    RowKey       = name,
                    Value        = value
                };
                _context.AddObject(SettingsTable, settingsEntity);
            }
            else
            {
                settingsEntity.Value = value;
                _context.UpdateObject(settingsEntity);
            }
            _context.SaveChangesStandard();
            return(true);
        }
        public bool InsertEntityForBatch(string tableName, object obj)
        {
            try
            {
                TableServiceContext tableServiceContext = TableClient.GetDataServiceContext();

                tableServiceContext.AddObject(tableName, obj);

                return(true);
            }
            catch (DataServiceRequestException)
            {
                return(false);
            }
            catch (StorageClientException ex)
            {
                if ((int)ex.StatusCode == 404)
                {
                    return(false);
                }

                throw;
            }
        }
        public void TableSetGetPermissionsSync()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable       table       = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                table.Create();

                TableServiceContext context = tableClient.GetTableServiceContext();
                context.AddObject(table.Name, new BaseEntity("PK", "RK"));
                context.SaveChangesWithRetries();

                TablePermissions expectedPermissions = new TablePermissions();
                TablePermissions testPermissions     = table.GetPermissions();

                AssertPermissionsEqual(expectedPermissions, testPermissions);

                // Add a policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Query,
                    SharedAccessStartTime  = DateTimeOffset.Now - TimeSpan.FromHours(1),
                    SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1)
                });

                table.SetPermissions(expectedPermissions);
                Thread.Sleep(30 * 1000);
                testPermissions = table.GetPermissions();
                AssertPermissionsEqual(expectedPermissions, testPermissions);
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
示例#5
0
        public override void Run()
        {
            var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");

            TableServiceContext tableServiceContext = new TableServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);

            storageAccount.CreateCloudTableClient().CreateTableIfNotExist("ResultsTable");

            //var tableClient = storageAccount.CreateCloudTableClient();
            //tableClient.CreateTableIfNotExist("ResultsTable");

            CloudBlobClient    blobStorage = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer container   = blobStorage.GetContainerReference("datasets");

            CloudQueueClient queueStorage = storageAccount.CreateCloudQueueClient();
            CloudQueue       queue        = queueStorage.GetQueueReference("inputreceiver");

            Trace.TraceInformation("Creating container and queue...");

            // If the Start() method throws an exception, the role recycles.
            // If this sample is run locally and the development storage tool has not been started, this
            // can cause a number of exceptions to be thrown because roles are restarted repeatedly.
            // Lets try to create the queue and the container and check whether the storage services are running
            // at all.
            bool containerAndQueueCreated = false;

            while (!containerAndQueueCreated)
            {
                try
                {
                    container.CreateIfNotExist();

                    var permissions = container.GetPermissions();

                    permissions.PublicAccess = BlobContainerPublicAccessType.Container;

                    container.SetPermissions(permissions);

                    permissions = container.GetPermissions();

                    queue.CreateIfNotExist();

                    containerAndQueueCreated = true;
                }
                catch (StorageClientException e)
                {
                    if (e.ErrorCode == StorageErrorCode.TransportError)
                    {
                        Trace.TraceError(string.Format("Connect failure! The most likely reason is that the local " +
                                                       "Development Storage tool is not running or your storage account configuration is incorrect. " +
                                                       "Message: '{0}'", e.Message));
                        System.Threading.Thread.Sleep(5000);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            Trace.TraceInformation("Listening for queue messages...");

            // Now that the queue and the container have been created in the above initialization process, get messages
            // from the queue and process them individually.
            while (true)
            {
                try
                {
                    CloudQueueMessage msg = queue.GetMessage();
                    if (msg != null)
                    {
                        // Protocol: [path, (y|n - isHeightMap), filename]
                        string[] parts = msg.AsString.Split('\n');

                        // Get the blob directories
                        string         path       = parts[0];
                        CloudBlockBlob content    = container.GetBlockBlobReference(path);
                        CloudBlockBlob resultBlob = container.GetBlockBlobReference("results/" + path);

                        // Read the input file from its blob to a MemoryStream
                        MemoryStream input = new MemoryStream();
                        content.DownloadToStream(input);
                        input.Seek(0, SeekOrigin.Begin);

                        Trace.TraceInformation("Creating Rasterizer...");

                        // Initialize the rasterizer
                        bool       isHeightMap = (parts[1] == "y");
                        bool       runParallel = (parts[3] == "y");
                        Rasterizer r           = new Rasterizer();
                        r.readInput(input, isHeightMap);
                        r.initializeConstraints();

                        Trace.TraceInformation("Will run...");

                        // Run
                        DateTime startTime = DateTime.Now;
                        if (runParallel)
                        {
                            r.stSimplexParallel();
                        }
                        else
                        {
                            r.stSimplex();
                        }
                        TimeSpan duration = DateTime.Now - startTime;

                        Trace.TraceInformation("Finished! Took " + duration.TotalMilliseconds + "ms");

                        // Save results in "/datasets/results/" blob
                        string       result    = r.getConstraintsStr();
                        byte[]       byteArray = Encoding.Default.GetBytes(result);
                        MemoryStream stream    = new MemoryStream(byteArray);
                        resultBlob.Properties.ContentType = "text/plain";
                        resultBlob.UploadFromStream(stream);

                        // Save results metadata in ResultsTable table
                        Uri dsetUri;
                        Uri.TryCreate(content.Uri, path, out dsetUri);
                        tableServiceContext.AddObject("ResultsTable", new ResultsTable()
                        {
                            ResultURL       = resultBlob.Uri,
                            DatasetURL      = dsetUri,
                            DatasetFilename = parts[2],
                            Time            = duration.TotalMilliseconds,
                            IsHeightMap     = isHeightMap,
                            IsParallel      = runParallel
                        });
                        tableServiceContext.SaveChanges();

                        Trace.TraceInformation(string.Format("Done with '{0}'", path));

                        queue.DeleteMessage(msg);
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                }
                catch (Exception e)
                {
                    // Explicitly catch all exceptions of type StorageException here because we should be able to
                    // recover from these exceptions next time the queue message, which caused this exception,
                    // becomes visible again.
                    System.Threading.Thread.Sleep(5000);
                    Trace.TraceError(string.Format("Exception when processing queue item. Message: '{0}'", e.Message));
                }
            }
        }
示例#6
0
        static void DoTables(CloudStorageAccount account)
        {
            Console.WriteLine("=======================TABLE==========================");
            CloudTableClient    tableClient = new CloudTableClient(account.TableEndpoint.AbsoluteUri, account.Credentials);
            TableServiceContext context     = tableClient.GetDataServiceContext();

            Console.WriteLine("Clearning container...");
            tableClient.DeleteTableIfExist("AzureStorageTestTableFrom");
            tableClient.DeleteTableIfExist("AzureStorageTestTableTo");

            Console.WriteLine("Creating container...");
            while (true)
            {
                try
                {
                    tableClient.CreateTable("AzureStorageTestTableFrom");
                    break;
                }
                catch (Exception)
                {
                    Thread.Sleep(1000);
                }
            }
            while (true)
            {
                try
                {
                    tableClient.CreateTable("AzureStorageTestTableTo");
                    break;
                }
                catch (Exception)
                {
                    Thread.Sleep(1000);
                }
            }

            Console.WriteLine("Uploading data...");
            for (int i = 0; i < 30; i++)
            {
                SquareRow row = new SquareRow()
                {
                    Number       = i,
                    Squared      = i * i,
                    PartitionKey = "0",
                    RowKey       = Guid.NewGuid().ToString(),
                };
                context.AddObject("AzureStorageTestTableFrom", row);
            }
            context.SaveChanges();

            Console.WriteLine("Checking data...");
            var query =
                from row in context.CreateQuery <SquareRow>("AzureStorageTestTableFrom")
                where row.Number < 10
                select row;

            foreach (var square in query)
            {
                DoubleRow row = new DoubleRow()
                {
                    Number       = square.Squared,
                    Doubled      = square.Squared * 2,
                    PartitionKey = "0",
                    RowKey       = Guid.NewGuid().ToString(),
                };
                context.AddObject("AzureStorageTestTableTo", row);
            }
            context.SaveChanges();
        }
示例#7
0
 public static void Insert <TEntity>(TableServiceContext serviceContext, EntitySetName <TEntity> entitySetName, TEntity entity) where TEntity : TableServiceEntity
 {
     serviceContext.AddObject(entitySetName.Name, entity);
     serviceContext.SaveChanges();
 }
        public void TableSetGetPermissionsAPM()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable       table       = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                table.Create();

                TableServiceContext context = tableClient.GetTableServiceContext();
                context.AddObject(table.Name, new BaseEntity("PK", "RK"));
                context.SaveChangesWithRetries();

                TablePermissions expectedPermissions = new TablePermissions();
                TablePermissions testPermissions     = table.GetPermissions();

                AssertPermissionsEqual(expectedPermissions, testPermissions);

                // Add a policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Query,
                    SharedAccessStartTime  = DateTimeOffset.Now - TimeSpan.FromHours(1),
                    SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1)
                });

                using (ManualResetEvent evt = new ManualResetEvent(false))
                {
                    IAsyncResult result = null;
                    table.BeginSetPermissions(expectedPermissions, (res) =>
                    {
                        result = res;
                        evt.Set();
                    }, null);

                    evt.WaitOne();

                    table.EndSetPermissions(result);
                }

                Thread.Sleep(30 * 1000);

                using (ManualResetEvent evt = new ManualResetEvent(false))
                {
                    IAsyncResult result = null;
                    table.BeginGetPermissions((res) =>
                    {
                        result = res;
                        evt.Set();
                    }, null);

                    evt.WaitOne();

                    testPermissions = table.EndGetPermissions(result);
                }

                AssertPermissionsEqual(expectedPermissions, testPermissions);
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
示例#9
0
        public void TableGetSetPermissionTest()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable       table       = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                table.Create();

                TableServiceContext context = tableClient.GetTableServiceContext();
                context.AddObject(table.Name, new BaseEntity("PK", "RK"));
                context.SaveChangesWithRetries();

                TablePermissions expectedPermissions;
                TablePermissions testPermissions;

                // Test new table permissions.
                expectedPermissions = new TablePermissions();
                testPermissions     = table.GetPermissions();
                AssertPermissionsEqual(expectedPermissions, testPermissions);

                // Test setting empty permissions.
                table.SetPermissions(expectedPermissions);
                TestHelper.SpinUpTo30SecondsIgnoringFailures(() =>
                {
                    testPermissions = table.GetPermissions();
                    AssertPermissionsEqual(expectedPermissions, testPermissions);
                });

                // Add a policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Query,
                    SharedAccessStartTime  = DateTimeOffset.Now - TimeSpan.FromHours(1),
                    SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(1)
                });

                table.SetPermissions(expectedPermissions);
                TestHelper.SpinUpTo30SecondsIgnoringFailures(() =>
                {
                    testPermissions = table.GetPermissions();
                    AssertPermissionsEqual(expectedPermissions, testPermissions);
                });

                // Add a policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Add,
                    SharedAccessStartTime  = DateTimeOffset.Now + TimeSpan.FromHours(1),
                    SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1)
                });

                table.SetPermissions(expectedPermissions);
                TestHelper.SpinUpTo30SecondsIgnoringFailures(() =>
                {
                    testPermissions = table.GetPermissions();
                    AssertPermissionsEqual(expectedPermissions, testPermissions);
                });

                // Add a null policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions = SharedAccessTablePermissions.None,
                });

                table.SetPermissions(expectedPermissions);
                TestHelper.SpinUpTo30SecondsIgnoringFailures(() =>
                {
                    testPermissions = table.GetPermissions();
                    AssertPermissionsEqual(expectedPermissions, testPermissions);
                });

                // Add a policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Delete,
                    SharedAccessStartTime  = DateTimeOffset.Now + TimeSpan.FromDays(0.5),
                    SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromDays(1)
                });

                table.SetPermissions(expectedPermissions);
                TestHelper.SpinUpTo30SecondsIgnoringFailures(() =>
                {
                    testPermissions = table.GetPermissions();
                    AssertPermissionsEqual(expectedPermissions, testPermissions);
                });

                // Add a policy, check setting and getting.
                expectedPermissions.SharedAccessPolicies.Add(Guid.NewGuid().ToString(), new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Update,
                    SharedAccessStartTime  = DateTimeOffset.Now + TimeSpan.FromHours(6),
                    SharedAccessExpiryTime = DateTimeOffset.Now + TimeSpan.FromHours(6.5)
                });

                table.SetPermissions(expectedPermissions);
                TestHelper.SpinUpTo30SecondsIgnoringFailures(() =>
                {
                    testPermissions = table.GetPermissions();
                    AssertPermissionsEqual(expectedPermissions, testPermissions);
                });
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
示例#10
0
        /// <summary>
        /// Adds a new User.
        /// </summary>
        /// <param name="username">The Username.</param>
        /// <param name="displayName">The display name (can be <c>null</c>).</param>
        /// <param name="password">The Password.</param>
        /// <param name="email">The Email address.</param>
        /// <param name="active">A value indicating whether the account is active.</param>
        /// <param name="dateTime">The Account creation Date/Time.</param>
        /// <returns>The correct <see cref="T:UserInfo"/> object or <c>null</c>.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="username"/>, <paramref name="password"/> or <paramref name="email"/> are <c>null</c>.</exception>
        /// <exception cref="ArgumentException">If <paramref name="username"/>, <paramref name="password"/> or <paramref name="email"/> are empty.</exception>
        public UserInfo AddUser(string username, string displayName, string password, string email, bool active, DateTime dateTime)
        {
            if (username == null)
            {
                throw new ArgumentNullException("username");
            }
            if (username.Length == 0)
            {
                throw new ArgumentException("Username cannot be empty", "username");
            }
            if (password == null)
            {
                throw new ArgumentNullException("password");
            }
            if (password.Length == 0)
            {
                throw new ArgumentException("Password cannot be empty", "password");
            }
            if (email == null)
            {
                throw new ArgumentNullException("email");
            }
            if (email.Length == 0)
            {
                throw new ArgumentException("Email cannot be empty", "email");
            }

            try {
                // If a user with the given username altready exists return null
                if (GetUserEntity(_wiki, username) != null)
                {
                    return(null);
                }

                // If a user with the given email already exists return null
                if (GetUserByEmail(email) != null)
                {
                    return(null);
                }

                UserEntity userEntity = new UserEntity()
                {
                    PartitionKey     = _wiki,
                    RowKey           = username,
                    DisplayName      = displayName,
                    Password         = Hash.Compute(password),
                    Email            = email,
                    Active           = active,
                    CreationDateTime = dateTime
                };
                _context.AddObject(UsersTable, userEntity);
                _context.SaveChangesStandard();

                _users = null;

                return(new UserInfo(username, displayName, email, active, dateTime, this));
            }
            catch (Exception ex) {
                throw ex;
            }
        }
示例#11
0
        private void btnUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                TableStorageClient = new TableStorageHelper(txtStorageAcc.Text);

                TableStorageClient.CreateTable(DeploymentTracking.TABLE_NAME);

                Stopwatch s = new Stopwatch();
                s.Start();
                TableServiceContext context = TableStorageClient.GetTableServiceContext();

                long count = int.Parse(txtNumberEntities.Text);

                for (long i = 0; i < count; i++)
                {
                    if (i > 0 && (i % 100) == 0)
                    {
                        //Finish first batch
                        DataServiceResponse resp = context.SaveChangesWithRetries(SaveChangesOptions.Batch);
                        //start second batch
                        context.AddObject(DeploymentTracking.TABLE_NAME,
                                          new DeploymentTracking()
                        {
                            Created       = DateTime.UtcNow,
                            CreatedBy     = Environment.MachineName,
                            IsSuccessful  = true,
                            Operation     = "Test Operation" + i,
                            ProvId        = 1,
                            RetryNumber   = 1,
                            StatusCode    = "Status Code " + i,
                            StatusMessage = "Test Message" + i,
                            // RowKey = System.Guid.NewGuid().ToString("N")
                            RowKey = (i + 1).ToString()
                        });
                    }
                    else
                    {
                        //continue
                        context.AddObject(DeploymentTracking.TABLE_NAME,
                                          new DeploymentTracking()
                        {
                            Created       = DateTime.UtcNow,
                            CreatedBy     = Environment.MachineName,
                            IsSuccessful  = true,
                            Operation     = "Test Operation" + i,
                            ProvId        = 1,
                            RetryNumber   = 1,
                            StatusCode    = "Status Code " + i,
                            StatusMessage = "Test Message" + i,
                            // RowKey = System.Guid.NewGuid().ToString("N")
                            RowKey = (i + 1).ToString()
                        });
                    }
                }

                DataServiceResponse resp1 = context.SaveChangesWithRetries(SaveChangesOptions.Batch);
                s.Stop();
                MessageBox.Show("Entities Inserted. Time Required i milliseconds. " + s.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
 public void AddProAzureReader(ProAzureReader newItem)
 {
     dContext.AddObject(ENTITY_SET_NAME, newItem);
     dContext.SaveChangesWithRetries(SaveChangesOptions.None);
 }
示例#13
0
 private void LogJob(string jobId)
 {
     try
     {
         JobInfo jobInfo = null;
         using (var conn = new SqlConnection(_connectionString))
         {
             conn.Open();
             try
             {
                 using (var cmd = conn.CreateCommand())
                 {
                     cmd.CommandType = CommandType.StoredProcedure;
                     cmd.CommandText = "GetJobDetail";
                     cmd.Parameters.AddWithValue("jobId", jobId);
                     using (var reader = cmd.ExecuteReader())
                     {
                         if (reader.Read())
                         {
                             jobInfo                  = new JobInfo(reader.GetString(0), reader.GetString(1));
                             jobInfo.JobType          = (JobType)reader.GetInt32(2);
                             jobInfo.Status           = (JobStatus)reader.GetInt32(3);
                             jobInfo.StatusMessage    = reader.IsDBNull(4) ? String.Empty : reader.GetString(4);
                             jobInfo.ScheduledRunTime =
                                 reader.IsDBNull(5) ? (DateTime?)null : reader.GetDateTime(5);
                             jobInfo.StartTime           = reader.IsDBNull(6) ? (DateTime?)null : reader.GetDateTime(6);
                             jobInfo.ProcessorId         = reader.IsDBNull(7) ? String.Empty : reader.GetString(7);
                             jobInfo.ProcessingCompleted =
                                 reader.IsDBNull(8) ? (DateTime?)null : reader.GetDateTime(8);
                             jobInfo.ProcessingException =
                                 reader.IsDBNull(9) ? String.Empty : reader.GetString(9);
                             jobInfo.RetryCount = reader.GetInt32(10);
                         }
                     }
                 }
             }
             catch (Exception ex)
             {
                 Trace.TraceError("Error retrieving job detail for job {0}. Cause: {1}", jobId, ex);
             }
             finally
             {
                 conn.Close();
             }
         }
         if (jobInfo != null)
         {
             var connectionString =
                 RoleEnvironment.GetConfigurationSettingValue(AzureConstants.DiagnosticsConnectionStringName);
             CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
             CloudTableClient    tableClient    = storageAccount.CreateCloudTableClient();
             tableClient.CreateTableIfNotExist("jobs");
             TableServiceContext serviceContext = tableClient.GetDataServiceContext();
             JobLogEntity        jobLogEntity   = new JobLogEntity(jobInfo);
             serviceContext.AddObject("jobs", jobLogEntity);
             serviceContext.SaveChangesWithRetries();
         }
     }
     catch (Exception ex)
     {
         Trace.TraceError("Error logging detail for job {0}. Cause: {1}", jobId, ex);
     }
 }
示例#14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="loginUrl">Login url</param>
        /// <param name="userName">User's login name</param>
        /// <param name="password">User's password</param>
        /// <param name="formParams">Optional string which contains any additional form params</param>
        /// <returns></returns>
        public bool LoginToSite(String userName, String password)
        {
            //////////////////////////////////////////////////////////////////////////////
            //
            // local variables
            // TODO: Review if there is a better solution to hard-coding these
            //
            string           formParams = string.Format("language=en&affiliateName=espn&parentLocation=&registrationFormId=espn");
            string           loginUrl   = "https://r.espn.go.com/members/util/loginUser";
            CookieCollection cookies;
            string           leagueId    = "";
            string           teamId      = "";
            string           season      = "";
            string           userTable   = "ausers00";
            string           teamTable   = "ateams00";
            string           cookieTable = "acookies00";
            bool             newUser     = true;


            /////////////////////////////////////////////////////////////////////////////
            //
            // Lookup / Store user in storage.
            //
            // Encrypt the user password for safe persistence
            // TODO: Store the key somewhere safe. Also, it may be better to store password on the device?
            //
            string passwordHash = Crypto.EncryptStringAES(password, "foobar");

            // Retrieve storage account from connection string
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
                CloudConfigurationManager.GetSetting("StorageConnectionString"));

            //
            // Create the table client
            //
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

            //
            // Create the user/team/cookie tables if they don't exist
            //
            tableClient.CreateTableIfNotExist(userTable);
            tableClient.CreateTableIfNotExist(teamTable);
            tableClient.CreateTableIfNotExist(cookieTable);

            // Get the data service context
            TableServiceContext serviceContext = tableClient.GetDataServiceContext();


            //
            // Look up the user in the storage tables
            //
            UserEntity specificEntity =
                (from e in serviceContext.CreateQuery <UserEntity>(userTable)
                 where e.RowKey == userName
                 select e).FirstOrDefault();


            //
            // Check to see if password is correct
            //
            if (specificEntity != null)
            {
                string userPassword = Crypto.DecryptStringAES(specificEntity.PasswordHash, "foobar");

                if (userPassword == password)
                {
                    newUser = false;
                }
            }


            //
            // If this is a new user add them to the users databse
            //
            if (newUser)
            {
                //
                // Setup formUrl string
                //
                string formUrl = "";

                if (!String.IsNullOrEmpty(formParams))
                {
                    formUrl = formParams + "&";
                }
                formUrl += string.Format("username={0}&password={1}", userName, password);


                //
                // Now setup the POST request
                //
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(loginUrl);
                req.CookieContainer = new CookieContainer();
                req.ContentType     = "application/x-www-form-urlencoded";
                req.Method          = "POST";

                byte[] bytes = Encoding.ASCII.GetBytes(formUrl);
                req.ContentLength = bytes.Length;

                using (Stream os = req.GetRequestStream())
                {
                    os.Write(bytes, 0, bytes.Length);
                }


                //
                // Read the response
                //
                string respString = "";

                using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
                {
                    //
                    // Gather cookie info
                    //
                    cookies = resp.Cookies;


                    //
                    // Read the response stream to determine if login was successful.
                    //
                    using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
                    {
                        Char[] buffer = new Char[256];
                        int    count  = reader.Read(buffer, 0, 256);
                        while (count > 0)
                        {
                            respString += new String(buffer, 0, count);
                            count       = reader.Read(buffer, 0, 256);
                        }
                    } // reader is disposed here
                }

                //writeLog(respString);

                //
                // If response string contains "login":"******" this indicates success
                //
                if (!respString.Contains("{\"login\":\"true\"}"))
                {
                    throw new InvalidOperationException("Failed to login with given credentials");
                }


                //
                // Login success - Now save user to databse
                // TODO: Figure out a better partition key other than "key"
                //
                UserEntity user = new UserEntity("key", userName);
                user.PasswordHash = passwordHash;

                // Add the new team to the teams table
                serviceContext.AddObject(userTable, user);


                //////////////////////////////////////////////////////////////////////////////////
                //
                // Now that we have logged in, extract user info from the page
                //

                string url2 = "http://games.espn.go.com/frontpage/football";

                HttpWebRequest req2 = (HttpWebRequest)WebRequest.Create(url2);
                req2.CookieContainer = new CookieContainer();
                req2.ContentType     = "application/x-www-form-urlencoded";
                req2.Method          = "POST";

                //
                // Add the login cookies
                //
                foreach (Cookie cook in cookies)
                {
                    //writeLog("**name = " + cook.Name + " value = " + cook.Value);
                    CookieEntity newCook = new CookieEntity(userName, cook.Name);
                    newCook.Value  = cook.Value;
                    newCook.Path   = cook.Path;
                    newCook.Domain = cook.Domain;

                    // Add the new cookie to the cookies table
                    serviceContext.AddObject(cookieTable, newCook);

                    req2.CookieContainer.Add(cook);
                }


                //
                // Read the response
                //
                using (HttpWebResponse resp = (HttpWebResponse)req2.GetResponse())
                {
                    //
                    // Do something with the response stream. As an example, we'll
                    // stream the response to the console via a 256 character buffer
                    using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
                    {
                        HtmlDocument doc = new HtmlDocument();
                        doc.Load(reader);

                        //
                        // Build regEx for extracting legue info from link address
                        //
                        string pattern = @"(clubhouse\?leagueId=)(\d+)(&teamId=)(\d+)(&seasonId=)(\d+)";
                        Regex  rgx     = new Regex(pattern, RegexOptions.IgnoreCase);

                        foreach (HtmlNode hNode in doc.DocumentNode.SelectNodes("//a[@href]"))
                        {
                            HtmlAttribute att   = hNode.Attributes["href"];
                            Match         match = rgx.Match(att.Value);

                            //
                            // If our regEx finds a match then we have leagueId, teamId, and seasonId
                            //
                            if (match.Success)
                            {
                                //writeLog("NODE> Name: " + hNode.Name + ", ID: " + hNode.Id + "attr: " + att.Value);

                                GroupCollection groups = match.Groups;

                                leagueId = groups[2].Value;
                                teamId   = groups[4].Value;
                                season   = groups[6].Value;

                                //
                                // Create a new team entity
                                //
                                TeamEntity team = new TeamEntity(leagueId, teamId);

                                team.Season = season;
                                team.UserId = userName;

                                // Add the new team to the teams table
                                serviceContext.AddObject(teamTable, team);
                            }
                        }
                    } // reader is disposed here
                }

                // Submit the operation to the table service
                serviceContext.SaveChangesWithRetries();
            }

            return(true);
        }
        public void TableSASConstructors()
        {
            CloudTableClient tableClient = GenerateCloudTableClient();
            CloudTable       table       = tableClient.GetTableReference("T" + Guid.NewGuid().ToString("N"));

            try
            {
                table.Create();

                TableServiceContext context = tableClient.GetTableServiceContext();
                context.AddObject(table.Name, new BaseEntity("PK", "RK"));
                context.SaveChangesWithRetries();

                // Prepare SAS authentication with full permissions
                string sasToken = table.GetSharedAccessSignature(
                    new SharedAccessTablePolicy
                {
                    Permissions            = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Delete | SharedAccessTablePermissions.Query,
                    SharedAccessExpiryTime = DateTimeOffset.Now.AddMinutes(30)
                },
                    null /* accessPolicyIdentifier */,
                    null /* startPk */,
                    null /* startRk */,
                    null /* endPk */,
                    null /* endRk */);

                CloudStorageAccount sasAccount;
                StorageCredentials  sasCreds;
                CloudTableClient    sasClient;
                CloudTable          sasTable;
                TableServiceContext sasContext;
                Uri baseUri = new Uri(TestBase.TargetTenantConfig.TableServiceEndpoint);
                int count;

                // SAS via connection string parse
                sasAccount = CloudStorageAccount.Parse(string.Format("TableEndpoint={0};SharedAccessSignature={1}", baseUri.AbsoluteUri, sasToken));
                sasClient  = sasAccount.CreateCloudTableClient();
                sasTable   = sasClient.GetTableReference(table.Name);
                sasContext = sasClient.GetTableServiceContext();
                count      = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count();
                Assert.AreEqual(1, count);

                // SAS via account constructor
                sasCreds   = new StorageCredentials(sasToken);
                sasAccount = new CloudStorageAccount(sasCreds, null, null, baseUri);
                sasClient  = sasAccount.CreateCloudTableClient();
                sasTable   = sasClient.GetTableReference(table.Name);
                sasContext = sasClient.GetTableServiceContext();
                count      = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count();
                Assert.AreEqual(1, count);

                // SAS via client constructor URI + Creds
                sasCreds   = new StorageCredentials(sasToken);
                sasClient  = new CloudTableClient(baseUri, sasCreds);
                sasContext = sasClient.GetTableServiceContext();
                count      = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count();
                Assert.AreEqual(1, count);

                // SAS via CloudTable constructor Uri + Client
                sasCreds   = new StorageCredentials(sasToken);
                sasTable   = new CloudTable(table.Uri, tableClient);
                sasClient  = sasTable.ServiceClient;
                sasContext = sasClient.GetTableServiceContext();
                count      = sasContext.CreateQuery <BaseEntity>(sasTable.Name).AsTableServiceQuery(sasContext).Execute().Count();
                Assert.AreEqual(1, count);
            }
            finally
            {
                table.DeleteIfExists();
            }
        }
示例#16
0
        // Write a DataTable to an AzureTable.
        // DataTable's Rows are an unstructured property bag.
        // columnTypes - type of the column, or null if column should be skipped. Length of columnTypes should be the same as number of columns.
        public static void SaveToAzureTable(DataTable table, CloudStorageAccount account, string tableName, Type[] columnTypes, Func <int, Row, PartitionRowKey> funcComputeKeys)
        {
            if (table == null)
            {
                throw new ArgumentNullException("table");
            }
            if (account == null)
            {
                throw new ArgumentNullException("account");
            }
            if (columnTypes == null)
            {
                throw new ArgumentNullException("columnTypes");
            }
            if (tableName == null)
            {
                throw new ArgumentNullException("tableName");
            }
            ValidateAzureTableName(tableName);

            // Azure tables have "special" columns.
            // We can skip these by settings columnType[i] to null, which means don't write that column
            string[] columnNames = table.ColumnNames.ToArray();
            if (columnNames.Length != columnTypes.Length)
            {
                throw new ArgumentException(string.Format("columnTypes should have {0} elements", columnNames.Length), "columnTypes");
            }

            columnTypes = columnTypes.ToArray(); // create a copy for mutation.
            for (int i = 0; i < columnNames.Length; i++)
            {
                if (IsSpecialColumnName(columnNames[i]))
                {
                    columnTypes[i] = null;
                }
            }

            if (funcComputeKeys == null)
            {
                funcComputeKeys = GetPartitionRowKeyFunc(columnNames);
            }

            // Validate columnTypes
            string [] edmTypeNames = Array.ConvertAll(columnTypes,
                                                      columnType => {
                if (columnType == null)
                {
                    return(null);
                }
                string edmTypeName;
                _edmNameMapping.TryGetValue(columnType, out edmTypeName);
                if (edmTypeName == null)
                {
                    // Unsupported type!
                    throw new InvalidOperationException(string.Format("Type '{0}' is not a supported type on azure tables", columnType.FullName));
                }
                return(edmTypeName);
            });


            CloudTableClient tableClient = account.CreateCloudTableClient();

            tableClient.DeleteTableIfExist(tableName);
            tableClient.CreateTableIfNotExist(tableName);


            GenericTableWriter w = new GenericTableWriter
            {
                _edmTypeNames = edmTypeNames,
                _columnNames  = table.ColumnNames.ToArray()
            };

            // Batch rows for performance,
            // but all rows in the batch must have the same partition key
            TableServiceContext ctx = null;
            string lastPartitionKey = null;

            HashSet <PartitionRowKey> dups = new HashSet <PartitionRowKey>();

            int rowCounter = 0;
            int batchSize  = 0;

            foreach (Row row in table.Rows)
            {
                GenericWriterEntity entity = new GenericWriterEntity {
                    _source = row
                };
                // Compute row and partition keys too.
                var partRow = funcComputeKeys(rowCounter, row);
                entity.PartitionKey = partRow.PartitionKey;
                entity.RowKey       = partRow.RowKey;
                rowCounter++;

                // but all rows in the batch must have the same partition key
                if ((ctx != null) && (lastPartitionKey != null) && (lastPartitionKey != entity.PartitionKey))
                {
                    ctx.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
                    ctx = null;
                }

                if (ctx == null)
                {
                    dups.Clear();
                    lastPartitionKey = null;
                    ctx = tableClient.GetDataServiceContext();
                    ctx.WritingEntity += new EventHandler <ReadingWritingEntityEventArgs>(w.ctx_WritingEntity);
                    batchSize          = 0;
                }

                // Add enty to the current batch
                // Upsert means insert+Replace. But still need uniqueness within a batch.
                bool allowUpsert = true;

                // Check for dups within a batch.
                var key = new PartitionRowKey {
                    PartitionKey = entity.PartitionKey, RowKey = entity.RowKey
                };
                bool dupWithinBatch = dups.Contains(key);
                dups.Add(key);


                if (allowUpsert)
                {
                    // Upsert allows overwriting existing keys. But still must be unique within a batch.
                    if (!dupWithinBatch)
                    {
                        ctx.AttachTo(tableName, entity);
                        ctx.UpdateObject(entity);
                    }
                }
                else
                {
                    // AddObject requires uniquess.
                    if (dupWithinBatch)
                    {
                        // Azure REST APIs will give us a horrible cryptic error (400 with no message).
                        // Provide users a useful error instead.
                        throw new InvalidOperationException(string.Format("Table has duplicate keys: {0}", key));
                    }

                    ctx.AddObject(tableName, entity);
                }


                lastPartitionKey = entity.PartitionKey;
                batchSize++;

                if (batchSize % UploadBatchSize == 0)
                {
                    // Beware, if keys collide within a batch, we get a very cryptic error and 400.
                    // If they collide across batches, we get a more useful 409 (conflict).
                    try
                    {
                        ctx.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
                    }
                    catch (DataServiceRequestException de)
                    {
                        var e = de.InnerException as DataServiceClientException;
                        if (e != null)
                        {
                            if (e.StatusCode == 409)
                            {
                                // Conflict. Duplicate keys. We don't get the specific duplicate key.
                                // Server shouldn't do this if we support upsert.
                                // (although an old emulator that doesn't yet support upsert may throw it).
                                throw new InvalidOperationException(string.Format("Table has duplicate keys. {0}", e.Message));
                            }
                        }
                    }
                    ctx = null;
                }
            }

            if (ctx != null)
            {
                ctx.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
            }
        }
示例#17
0
        // Based on: http://blogs.msdn.com/b/cesardelatorre/archive/2011/03/12/typical-issue-one-of-the-request-inputs-is-not-valid-when-working-with-the-wa-development-storage.aspx
        private async Task InitializeTableSchemaFromEntity(CloudTableClient tableClient)
        {
            const string operation = "InitializeTableSchemaFromEntity";
            var          startTime = DateTime.UtcNow;

            TableServiceEntity entity = new T();

            entity.PartitionKey = Guid.NewGuid().ToString();
            entity.RowKey       = Guid.NewGuid().ToString();
            Array.ForEach(
                entity.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
                p =>
            {
                if ((p.Name == "PartitionKey") || (p.Name == "RowKey") || (p.Name == "Timestamp"))
                {
                    return;
                }

                if (p.PropertyType == typeof(string))
                {
                    p.SetValue(entity, Guid.NewGuid().ToString(),
                               null);
                }
                else if (p.PropertyType == typeof(DateTime))
                {
                    p.SetValue(entity, startTime, null);
                }
            });

            try
            {
                TableServiceContext svc = tableClient.GetDataServiceContext();
                svc.AddObject(TableName, entity);

                try
                {
                    await Task <DataServiceResponse> .Factory.FromAsync(
                        svc.BeginSaveChangesWithRetries,
                        svc.EndSaveChangesWithRetries,
                        SaveChangesOptions.None,
                        null);
                }
                catch (Exception exc)
                {
                    CheckAlertWriteError(operation + "-Create", entity, null, exc);
                    throw;
                }

                try
                {
                    svc.DeleteObject(entity);
                    await Task <DataServiceResponse> .Factory.FromAsync(
                        svc.BeginSaveChangesWithRetries,
                        svc.EndSaveChangesWithRetries,
                        SaveChangesOptions.None,
                        null);
                }
                catch (Exception exc)
                {
                    CheckAlertWriteError(operation + "-Delete", entity, null, exc);
                    throw;
                }
            }
            finally
            {
                CheckAlertSlowAccess(startTime, operation);
            }
        }
示例#18
0
        // Write a DataTable to an AzureTable.
        // DataTable's Rows are an unstructured property bag.
        // columnTypes - type of the column, or null if column should be skipped. Length of columnTypes should be the same as number of columns.
        public static void SaveToAzureTable(DataTable table, CloudStorageAccount account, string tableName, Type[] columnTypes, Func <int, Row, ParitionRowKey> funcComputeKeys)
        {
            if (table == null)
            {
                throw new ArgumentNullException("table");
            }
            if (account == null)
            {
                throw new ArgumentNullException("account");
            }
            if (columnTypes == null)
            {
                throw new ArgumentNullException("columnTypes");
            }
            if (tableName == null)
            {
                throw new ArgumentNullException("tableName");
            }
            ValidateAzureTableName(tableName);

            // Azure tables have "special" columns.
            // We can skip these by settings columnType[i] to null, which means don't write that column
            string[] columnNames = table.ColumnNames.ToArray();
            if (columnNames.Length != columnTypes.Length)
            {
                throw new ArgumentException(string.Format("columnTypes should have {0} elements", columnNames.Length), "columnTypes");
            }

            columnTypes = columnTypes.ToArray(); // create a copy for mutation.
            for (int i = 0; i < columnNames.Length; i++)
            {
                if (IsSpecialColumnName(columnNames[i]))
                {
                    columnTypes[i] = null;
                }
            }

            if (funcComputeKeys == null)
            {
                funcComputeKeys = GetPartitionRowKeyFunc(columnNames);
            }

            // Validate columnTypes
            string [] edmTypeNames = Array.ConvertAll(columnTypes,
                                                      columnType => {
                if (columnType == null)
                {
                    return(null);
                }
                string edmTypeName;
                _edmNameMapping.TryGetValue(columnType, out edmTypeName);
                if (edmTypeName == null)
                {
                    // Unsupported type!
                    throw new InvalidOperationException(string.Format("Type '{0}' is not a supported type on azure tables", columnType.FullName));
                }
                return(edmTypeName);
            });


            CloudTableClient tableClient = account.CreateCloudTableClient();

            tableClient.DeleteTableIfExist(tableName);
            tableClient.CreateTableIfNotExist(tableName);


            GenericTableWriter w = new GenericTableWriter
            {
                _edmTypeNames = edmTypeNames,
                _columnNames  = table.ColumnNames.ToArray()
            };

            // Batch rows for performance,
            // but all rows in the batch must have the same partition key
            TableServiceContext ctx = null;
            string lastPartitionKey = null;

            int rowCounter = 0;
            int batchSize  = 0;

            foreach (Row row in table.Rows)
            {
                GenericWriterEntity entity = new GenericWriterEntity {
                    _source = row
                };
                // Compute row and partition keys too.
                var partRow = funcComputeKeys(rowCounter, row);
                entity.PartitionKey = partRow.PartitionKey;
                entity.RowKey       = partRow.RowKey;
                rowCounter++;

                // but all rows in the batch must have the same partition key
                if ((ctx != null) && (lastPartitionKey != null) && (lastPartitionKey != entity.PartitionKey))
                {
                    ctx.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
                    ctx = null;
                }

                if (ctx == null)
                {
                    lastPartitionKey = null;
                    ctx = tableClient.GetDataServiceContext();
                    ctx.WritingEntity += new EventHandler <ReadingWritingEntityEventArgs>(w.ctx_WritingEntity);
                    batchSize          = 0;
                }

                // Add enty to the current batch
                ctx.AddObject(tableName, entity);
                lastPartitionKey = entity.PartitionKey;
                batchSize++;

                if (batchSize % 50 == 0)
                {
                    ctx.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
                    ctx = null;
                }
            }

            if (ctx != null)
            {
                ctx.SaveChangesWithRetries(SaveChangesOptions.Batch | SaveChangesOptions.ReplaceOnUpdate);
            }
        }
示例#19
0
        public override void SetAndReleaseItemExclusive(HttpContext context, string id,
                                                        SessionStateStoreData item, object lockId, bool newItem)
        {
            Debug.Assert(context != null);
            SecUtility.CheckParameter(ref id, true, true, false, Configuration.MaxStringPropertySizeInChars, "id");

            _providerRetry(() =>
            {
                TableServiceContext svc = CreateDataServiceContext();
                SessionRow session;

                if (!newItem)
                {
                    session = GetSession(id, svc);
                    if (session == null || session.Lock != (int)lockId)
                    {
                        Debug.Assert(false);
                        return;
                    }
                }
                else
                {
                    session             = new SessionRow(id, _applicationName);
                    session.Lock        = 1;
                    session.LockDateUtc = DateTime.UtcNow;
                }
                session.Initialized = true;
                Debug.Assert(session.Timeout >= 0);
                session.Timeout    = item.Timeout;
                session.ExpiresUtc = DateTime.UtcNow.AddMinutes(session.Timeout);
                session.Locked     = false;

                // yes, we always create a new blob here
                session.BlobName = GetBlobNamePrefix(id) + Guid.NewGuid().ToString("N");


                // Serialize the session and write the blob
                byte[] items, statics;
                SerializeSession(item, out items, out statics);
                string serializedItems   = Convert.ToBase64String(items);
                string serializedStatics = Convert.ToBase64String(statics);
                MemoryStream output      = new MemoryStream();
                StreamWriter writer      = new StreamWriter(output);

                try
                {
                    writer.WriteLine(serializedItems);
                    writer.WriteLine(serializedStatics);
                    writer.Flush();
                    // for us, it shouldn't matter whether newItem is set to true or false
                    // because we always create the entire blob and cannot append to an
                    // existing one
                    _blobProvider.UploadStream(session.BlobName, output);
                    writer.Close();
                    output.Close();
                }
                catch (Exception e)
                {
                    if (!newItem)
                    {
                        ReleaseItemExclusive(svc, session, lockId);
                    }
                    throw new ProviderException("Error accessing the data store.", e);
                }
                finally
                {
                    if (writer != null)
                    {
                        writer.Close();
                    }
                    if (output != null)
                    {
                        output.Close();
                    }
                }

                if (newItem)
                {
                    svc.AddObject(_tableName, session);
                    svc.SaveChangesWithRetries();
                }
                else
                {
                    // Unlock the session and save changes
                    ReleaseItemExclusive(svc, session, lockId);
                }
            });
        }
 /// <summary>
 /// Insert a new item in a table
 /// </summary>
 /// <param name="tableName">Precisely table's name</param>
 /// <param name="entity">The item which need to be inserted</param>
 public void Insert(string tableName, TElement entity)
 {
     CloudStorageAccount.CreateCloudTableClient().CreateTableIfNotExist(tableName);
     TableServiceContext.AddObject(tableName, entity);
     TableServiceContext.SaveChanges();
 }