Example #1
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [StorageAccount("StorageConnectionString")] CloudStorageAccount storageAccount,
            TraceWriter log
            )
        {
            var    client       = storageAccount.CreateCloudTableClient();
            string partitionKey = await Authenticator.Authenticate(client, req);

            if (string.IsNullOrEmpty(partitionKey))
            {
                return(new UnauthorizedResult());
            }

            string json = await req.ReadAsStringAsync();

            var items = JsonConvert.DeserializeObject <List <ItemJson> >(json);

            if (items == null)
            {
                return(new BadRequestObjectResult("Could not correctly parse the request parameters"));
            }
            else if (items.Count > 100)
            {
                return(new BadRequestObjectResult("Too many items to store, maximum 100 per call"));
            }
            else if (items.Count <= 0)
            {
                return(new BadRequestObjectResult("No items to store"));
            }

            var partition = await PartionUtility.GetUploadPartitionV2(log, client, partitionKey);

            log.Info($"Received a request from {partitionKey} to upload {items.Count} items to {partition.RowKey}");

            var itemTable = client.GetTableReference(ItemV2.TableName);
            await itemTable.CreateIfNotExistsAsync();

            var itemMapping = await Insert(partitionKey, partition.RowKey, itemTable, items);

            log.Info($"Inserted {items.Count} items over {itemMapping.Count} batches");

            bool shouldClosePartition = items.Count >= 90;

            if (shouldClosePartition)
            {
                log.Info($"Closing partition {partition.PartitionKey}, due to received count at {items.Count}");
                partition.IsActive = false;
                await client.GetTableReference(PartitionV2.TableName).ExecuteAsync(TableOperation.Replace(partition));
            }

            var result = new UploadResultDto {
                Partition = itemMapping.First().Partition,
                IsClosed  = shouldClosePartition,
                Items     = itemMapping
            };

            return(new OkObjectResult(result));
        }
Example #2
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [StorageAccount("StorageConnectionString")] CloudStorageAccount storageAccount,
            TraceWriter log
            )
        {
            var    client       = storageAccount.CreateCloudTableClient();
            string partitionKey = await Authenticator.Authenticate(client, req);

            if (string.IsNullOrEmpty(partitionKey))
            {
                return(new UnauthorizedResult());
            }


            string json = await req.ReadAsStringAsync();

            var data = JsonConvert.DeserializeObject <List <ItemToRemove> >(json);

            if (data == null)
            {
                return(new BadRequestObjectResult("Could not correctly parse the request parameters"));
            }
            else if (data?.Count <= 0)
            {
                return(new BadRequestObjectResult("No items to delete"));
            }

            log.Info($"Received a request from {partitionKey} to remove {data.Count} items");
            var itemTable = client.GetTableReference(ItemV1.TableName);

            DeleteByPartition(partitionKey, itemTable, data, log);


            var partition = await PartionUtility.GetUploadPartition(log, client, partitionKey);

            var deletedItemsTable = client.GetTableReference(DeletedItemV1.TableName);

            DeleteInActivePartition(partition.RowKey, deletedItemsTable, data);
            log.Info($"Marked {data.Count} items as deleted in the active partition {partition.RowKey}");

            return(new OkResult());
        }
Example #3
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [StorageAccount("StorageConnectionString")] CloudStorageAccount storageAccount,
            TraceWriter log
            )
        {
            var    client       = storageAccount.CreateCloudTableClient();
            string partitionKey = await Authenticator.Authenticate(client, req);

            if (string.IsNullOrEmpty(partitionKey))
            {
                return(new UnauthorizedResult());
            }

            string json = await req.ReadAsStringAsync();

            var items = JsonConvert.DeserializeObject <List <ItemJsonV3> >(json);

            if (items == null)
            {
                return(new BadRequestObjectResult("Could not correctly parse the request parameters"));
            }
            else if (items.Count > 100)
            {
                return(new BadRequestObjectResult("Too many items to store, maximum 100 per call"));
            }
            else if (items.Count <= 0)
            {
                return(new BadRequestObjectResult("No items to store"));
            }
            else if (items.Select(item => item.RemotePartition).Distinct().Count() > 1)
            {
                return(new BadRequestObjectResult("Cannot store items from multiple partitions in a single call"));
            }

            // Just ensuring that a partition entry exists, so that we can find it again later.
            var partition = await PartionUtility.GetUploadPartitionV3(log, client, partitionKey, items.First().RemotePartition);

            log.Info($"Received a request from {partitionKey} to upload {items.Count} items to {partition.RowKey}");



            var itemTable = client.GetTableReference(ItemV2.TableName);
            await itemTable.CreateIfNotExistsAsync();

            var itemMapping = await Insert(log, partition.RowKey, itemTable, items);

            log.Info($"Inserted {items.Count} items");

            bool shouldClosePartition = items.Count >= 90;

            if (shouldClosePartition)
            {
                log.Info($"Closing partition {partition.PartitionKey}, due to received count at {items.Count}");
                partition.IsActive = false;
                await client.GetTableReference(PartitionV2.TableName).ExecuteAsync(TableOperation.Replace(partition));
            }

            var result = new UploadResultDto {
                Partition = partition.RowKey.Remove(0, partitionKey.Length), // Strip the owner email from the partition
                IsClosed  = shouldClosePartition,
            };

            return(new OkObjectResult(result));
        }
Example #4
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")]
            HttpRequest req,
            [StorageAccount("StorageConnectionString")]
            CloudStorageAccount storageAccount,
            TraceWriter log
            )
        {
            var    client       = storageAccount.CreateCloudTableClient();
            string partitionKey = await Authenticator.Authenticate(client, req);

            if (string.IsNullOrEmpty(partitionKey))
            {
                return(new UnauthorizedResult());
            }

            var partitions = await PartionUtility.GetAllPartitions(log, client, partitionKey);

            log.Info($"Received a request from {partitionKey} to erase the account");

            // Foreach partition: Delete all items
            var itemTable = client.GetTableReference(ItemV2.TableName);

            foreach (var partition in partitions)
            {
                var query   = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partition.RowKey);
                var exQuery = new TableQuery <ItemV2>().Where(query);
                var items   = await QueryHelper.ListAll(itemTable, exQuery);

                log.Info($"Deleting stored items in partition {partition.RowKey} for {partitionKey}");
                BatchDelete(log, itemTable, partition.RowKey, items);
            }

            // Delete the 'removed items' entries
            foreach (var partition in partitions)
            {
                log.Info($"Deleting removed items in partition {partition.RowKey} for {partitionKey}");
                DeleteDeletedItems(log, client, partition.RowKey);
            }

            // Delete the partition entries
            var partitionTable = client.GetTableReference(PartitionV2.TableName);

            foreach (var partition in partitions)
            {
                log.Info($"Deleting partition {partition.RowKey} for {partitionKey}");
                await partitionTable.ExecuteAsync(TableOperation.Delete(partition));
            }

            // Delete auth entry used for logins
            try {
                var table = client.GetTableReference(Authentication.TableName);
                await table.CreateIfNotExistsAsync();

                var query = TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, Authentication.PartitionName),
                    TableOperators.And,
                    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, req.Headers["Simple-Auth"])
                    );

                var exQuery            = new TableQuery <Authentication>().Where(query);
                var authenticationKeys = await QueryHelper.ListAll(table, exQuery);

                BatchDelete(log, table, Authentication.PartitionName, authenticationKeys);
            }
            catch (Exception ex) {
                log.Warning("Error deleting auth entry", ex.StackTrace);
            }

            return(new OkObjectResult(""));
        }