示例#1
0
        public async void Should_UploadContinue_Success_200_Pdf()
        {
            var request        = TestFactory.CreateHttpRequestWithDataStream("Data/Sample 1.pdf");
            var uploadDir      = _app.Repository.GetBlobDirectory(BlobNames.UploadDirectory + "/test");
            var uploadTmpTable = _app.Repository.GetTable(TableNames.CommUpload);

            var tmpUploadEntity = new TableEntityAdapter <UploadSession>(
                new UploadSession {
                SessionId = "test"
            }, "test", new IdGenerator().UploadSessionId());

            // call Azure Function
            var response = (ObjectResult)await UploadFunctions.Continue(request,
                                                                        "test",
                                                                        $"{DateTime.Now:u} Sample 1.pdf",
                                                                        uploadDir,
                                                                        tmpUploadEntity,
                                                                        uploadTmpTable,
                                                                        _logger);

            var upload = response.Value.IsOrMap <UploadSession>();

            Assert.Equal(StatusCodes.Status200OK, response.StatusCode);
            Assert.Null(upload.ManifestFile);
            Assert.Contains("test", upload.SessionId);
            Assert.Contains("Sample 1.pdf", upload.LastUploadedFile);

            _output.WriteLine(upload.ToJson(Formatting.Indented));
        }
示例#2
0
        public async void Should_UploadContinue_Fail_400_With_No_Filename()
        {
            var request        = TestFactory.CreateHttpRequestWithDataStream($"Data/Sample 1.pdf");
            var uploadDir      = _app.Repository.GetBlobDirectory(BlobNames.UploadDirectory + "/test");
            var uploadTmpTable = _app.Repository.GetTable(TableNames.CommUpload);

            var tmpUploadEntity = new TableEntityAdapter <UploadSession>(
                new UploadSession {
                SessionId = "test"
            }, "test", new IdGenerator().UploadSessionId());

            // call Azure Function
            var response = (ObjectResult)await UploadFunctions.Continue(request,
                                                                        "test",
                                                                        null,
                                                                        uploadDir,
                                                                        tmpUploadEntity,
                                                                        uploadTmpTable,
                                                                        _logger);

            var upload = response.Value.IsOrMap <UploadSession>();

            Assert.Equal(StatusCodes.Status400BadRequest, response.StatusCode);
            Assert.Null(upload.ManifestFile);
            Assert.Null(upload.LastUploadedFile);
            Assert.Equal("A filename is required. (Parameter 'filename')", upload.Errors);

            _output.WriteLine(upload.ToJson(Formatting.Indented));
        }
示例#3
0
        public static async Task <IActionResult> Continue(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = ServiceNames.UploadContinue + "/{session}/{filename}")]
            HttpRequest req,
            string session,
            string filename,
            [Blob(BlobNames.UploadDirectory + "/{session}")] CloudBlobDirectory uploadDir,
            [Table(TableNames.CommUpload, CommUploadPartitionKeys.Temp, "{session}")] TableEntityAdapter <UploadSession> upload,
            [Table(TableNames.CommUpload)] CloudTable uploadTable,
            ILogger log)
        {
            try
            {
                if (filename.IsNullOrEmpty())
                {
                    throw new ArgumentException("A filename is required.", nameof(filename));
                }

                var uploadTo = await req.Body.UploadTo(uploadDir, filename);

                upload.OriginalEntity.ManifestFile     = new[] { upload.OriginalEntity.ManifestFile, filename }.IsIfManifest();
                upload.OriginalEntity.LastUploadedFile = filename;

                var result = await upload.UpdateIn(uploadTable);

                return(new OkObjectResult(upload.OriginalEntity));
            }
            catch (Exception ex)
            {
                log.LogError(ex.StackTrace);
                return(new BadRequestObjectResult(new UploadSession {
                    Errors = ex.Message
                }));
            }
        }
示例#4
0
        public static async Task DeliveryPostage(
            [QueueTrigger(QueueNames.CommSendPostage)] MessageDispatch sendMessage,
            [Table(TableNames.CommSchedule, CommSchedulePartitionKeys.InProgress, "{RowKey}")] TableEntityAdapter <MessageSchedule> schedule,
            [Table(TableNames.CommMessage, CommMessagePartitionKeys.Created, "{MessageReference}")] TableEntityAdapter <Message> message,
            [Table(TableNames.CommSchedule)] CloudTable scheduleTable,
            [Inject] App app,
            [Inject] IScheduleIdGenerator idGenerator,
            ILogger log)
        {
            if (schedule == null)
            {
                return;
            }

            var postage = message.GetMessageOf <Postage>();

            // handle unexpected non existing message
            if (postage == null)
            {
                await schedule.MoveTo(scheduleTable, s => CommSchedulePartitionKeys.Skipped).ConfigureAwait(false);

                return;
            }

            await schedule.MarkScheduleSent(scheduleTable, app, idGenerator);
        }
示例#5
0
        public async void Should_UploadEnd_Fail_400_With_No_Data()
        {
            var request        = TestFactory.CreateHttpRequest("none", "nil");
            var uploadDir      = _app.Repository.GetBlobDirectory(BlobNames.UploadDirectory + "/test");
            var uploadTmpTable = _app.Repository.GetTable(TableNames.CommUpload);
            var queue          = _app.Repository.GetQueue(QueueNames.CommProcess);

            var tmpUploadEntity = new TableEntityAdapter <UploadSession>(
                new UploadSession {
                SessionId = "test"
            }, "test", new IdGenerator().UploadSessionId());

            // call Azure Function
            var response = (ObjectResult)await UploadFunctions.End(request,
                                                                   "test",
                                                                   $"{DateTime.Now:u} Sample 2.pdf",
                                                                   uploadDir,
                                                                   tmpUploadEntity,
                                                                   uploadTmpTable,
                                                                   queue,
                                                                   _app.App,
                                                                   _logger);

            var upload = response.Value.IsOrMap <UploadSession>();

            Assert.Equal(StatusCodes.Status400BadRequest, response.StatusCode);
            Assert.Null(upload.ManifestFile);
            Assert.Null(upload.LastUploadedFile);
            Assert.Null(upload.UploadEnd);

            _output.WriteLine(upload.ToJson(Formatting.Indented));
        }
示例#6
0
        public static async Task <TableEntityAdapter <T> > MoveTo <T>(this TableEntityAdapter <T> record
                                                                      , CloudTable cloudTable, Func <T, string> partitionKey, Func <T, string> rowKey = null,
                                                                      Func <T, T> updateOriginalEntity = null)
        {
            // update the OriginalEntity.Property value has cause some funny error without cloning the object
            // System.Private.CoreLib: Exception while executing function: TransferEnd.
            // Microsoft.Azure.WebJobs.Host: Error while handling parameter upload after function returned:.
            // Microsoft.WindowsAzure.Storage: Not Found.
            // var oe = record.OriginalEntity;
            var oe = record.OriginalEntity.JClone <T>();

            var moveEntity = new TableEntityAdapter <T>(
                updateOriginalEntity == null ? oe : updateOriginalEntity(oe)
                , partitionKey(oe)
                , rowKey == null ? record.RowKey : rowKey(oe)
                );

            var operations = new[]
            {
                record.CreateOperationDelete(),
                moveEntity.CreateOperationInsert(),
            }
            .Where(op => op != null)
            .Select(cloudTable.ExecuteAsync)
            .ToArray();

            await Task.WhenAll(operations);

            return(moveEntity);
        }
示例#7
0
        public async Task ProcessWebhookEvents(
            [QueueTrigger(WebhookQueueNames.ProcessWebhookEvents)] Tuple <string, string> keys,
            [Table(nameof(WebhookContainerName.WebhookPayloads), nameof(PartitionKeyValue.New), "{Item2}")] TableEntityAdapter <PayloadContent> context,
            [CosmosDB(nameof(DatabaseName.Sufong2001), nameof(WebhookContainerName.WebhookPayloads), ConnectionStringSetting = DatabaseConfig.CosmosDbConnectionString)] IAsyncCollector <InvoiceEntity> invoicesOut,
            [Table(nameof(WebhookContainerName.WebhookPayloads))] CloudTable payloadTable,
            ILogger log)
        {
            if (context == null)
            {
                return;
            }

            var getInvoices = context.OriginalEntity.Payload.To <Payload>().Events
                              .Where(e => e.EventCategory == "INVOICE")
                              .GroupBy(e => e.TenantId)
                              .Select(GetInvoicesAsync);

            // Get Invoice details from Xero
            var result = await Task.WhenAll(getInvoices);

            var invoices = result.SelectMany(i => i);

            var operations = invoices.Select(i => invoicesOut.AddAsync(i));

            await Task.WhenAll(operations);

            await context.MoveTo(payloadTable, p => nameof(PartitionKeyValue.Processed));
        }
        public IHttpActionResult SetAvatar(ODataActionParameters parameters)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            var userId = Request.Headers.Authorization.Parameter.Split(':')[0];

            string avatarUrl = (string)parameters["avatarUrl"];

            TableOperation retrieveOperation = TableOperation.Retrieve <TableEntityAdapter <User> >("User", userId);
            TableResult    retrievedResult   = UserTable.Execute(retrieveOperation);

            TableEntityAdapter <User> userEntity = (TableEntityAdapter <User>)retrievedResult.Result;

            if (userEntity != null)
            {
                userEntity.OriginalEntity.AvatarUrl = avatarUrl;
                TableOperation updateOperation = TableOperation.Replace(userEntity);
                UserTable.Execute(updateOperation);
                return(Ok());
            }
            else
            {
                return(BadRequest("User does not exist."));
            }
        }
        public IHttpActionResult Delete(string formId)
        {
            // Create a retrieve operation that expects a customer entity.
            TableOperation retrieveOperation = TableOperation.Retrieve <TableEntityAdapter <Form> >("test", formId);

            // Execute the operation.
            TableResult retrievedResult = FormTable.Execute(retrieveOperation);

            // Assign the result to a Form.
            TableEntityAdapter <Form> formAdapter = (TableEntityAdapter <Form>)retrievedResult.Result;

            // Create the Delete TableOperation.
            if (formAdapter != null)
            {
                TableOperation deleteOperation = TableOperation.Delete(formAdapter);

                // Execute the operation.
                FormTable.Execute(deleteOperation);

                return(StatusCode(HttpStatusCode.NoContent));
            }
            else
            {
                return(NotFound());
            }
        }
示例#10
0
        /// <summary>
        /// Gets the size of the adapter in bytes. Calculates based from
        /// https://blogs.msdn.microsoft.com/avkashchauhan/2011/11/30/how-the-size-of-an-entity-is-caclulated-in-windows-azure-table-storage/
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="adapter"></param>
        /// <returns></returns>
        public static int GetAdapterSize <T>(this TableEntityAdapter <T> adapter)
        {
            var messageSize = 4; // Message Overhead

            messageSize += !string.IsNullOrEmpty(adapter.PartitionKey) ? adapter.PartitionKey.Length * 2 : 0;
            messageSize += !string.IsNullOrEmpty(adapter.RowKey) ? adapter.RowKey.Length + 2 : 0;

            var properties = adapter.WriteEntity(new OperationContext());

            foreach (var kp in properties)
            {
                var propertySize = 8; // Property Overhead

                propertySize += kp.Key.Length * 2;

                switch (kp.Value.PropertyType)
                {
                case EdmType.String:
                    propertySize += !string.IsNullOrEmpty(kp.Value.StringValue) ? kp.Value.StringValue.Length * 2 + 4 : 0;
                    break;

                case EdmType.Binary:
                    propertySize += kp.Value.BinaryValue?.Length + 4 ?? 0;
                    break;

                case EdmType.Boolean:
                    propertySize += kp.Value.BooleanValue.HasValue ? 1 : 0;
                    break;

                case EdmType.DateTime:
                    propertySize += kp.Value.DateTime.HasValue ? 8 : 0;
                    break;

                case EdmType.Double:
                    propertySize += kp.Value.DoubleValue.HasValue ? 8 : 0;
                    break;

                case EdmType.Guid:
                    propertySize += kp.Value.GuidValue.HasValue ? 16 : 0;
                    break;

                case EdmType.Int32:
                    propertySize += kp.Value.Int32Value.HasValue ? 4 : 0;
                    break;

                case EdmType.Int64:
                    propertySize += kp.Value.Int64Value.HasValue ? 8 : 0;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                messageSize += propertySize;
            }

            return(messageSize);
        }
示例#11
0
        public async Task StoreCode(Code item)
        {
            var table = await GetCloudTable(_appSecretSettings.TableStorageConnectionString, _appSettings.TableStorageContainerName);

            TableEntityAdapter <Code> entity = new TableEntityAdapter <Code>(item, item.EventName, item.PromoCode);

            TableOperation insertOperation = TableOperation.InsertOrReplace(entity);

            await table.ExecuteAsync(insertOperation);
        }
        public static async Task <TableResult> InsertAsync <T>(this CloudTableClient tableClient, string tableName, T item, string partitionKey, string rowKey)
        {
            var table = tableClient.GetTableReference(tableName);
            await table.CreateIfNotExistsAsync();

            var tableEntity    = new TableEntityAdapter <T>(item, partitionKey, rowKey);
            var tableOperation = TableOperation.Insert(tableEntity);

            return(await table.ExecuteAsync(tableOperation));
        }
        public async Task StoreDevice(Device device)
        {
            //get cloudtable
            var table = await GetCloudTable(_appSettings.TableStorageConnectionString, _appSettings.StoreDeviceContainerName);

            TableEntityAdapter <Device> entity = new TableEntityAdapter <Device>(device, _appSettings.StoreDevicePartitionKey, device.Id.ToString());

            TableOperation insertOperation = TableOperation.Insert(entity);

            await table.ExecuteAsync(insertOperation);
        }
示例#14
0
        public async Task <bool> InsertUserMapping(UserMapping userMapping, string partitionKey)
        {
            var table = await GetCloudTable(_appSettings.StorageConnectionString, _appSettings.MappingTableContainerName);

            TableEntityAdapter <UserMapping> entity = new TableEntityAdapter <UserMapping>(userMapping, partitionKey, Guid.NewGuid().ToString());

            TableOperation insertOperation = TableOperation.InsertOrReplace(entity);

            TableResult result = await table.ExecuteAsync(insertOperation);

            return(true);
        }
示例#15
0
        private async Task AddDefinitionToTableAsync(Guid instanceId, WordInformation word)
        {
            word.Serialize();
            var tableEntity = new TableEntityAdapter <WordInformation>()
            {
                PartitionKey   = $"{instanceId}_{word.WordName}",
                RowKey         = Guid.NewGuid().ToString(),
                OriginalEntity = word,
            };

            await definitionsTable.ExecuteAsync(TableOperation.Insert(tableEntity));
        }
示例#16
0
        public async Task <Message> StoreMessage(Message message)
        {
            if (message.Contents == null)
            {
                _logger.LogError($"Message contents cannot be null.");
                return(null);
            }
            if (message.Contents.Length > MessageEntity.MaxMessageSize)
            {
                _logger.LogError($"Message contents are too large. It was {message.Contents.Length}, but the max size is {MessageEntity.MaxMessageSize}");
                return(null);
            }
            var groupTable = _tableClient.GetTableReference(message.GroupId.ToTableString());

            if (!await groupTable.ExistsAsync())
            {
                _logger.LogError($"Could not find any group with ID {message.GroupId}.");
                return(null);
            }

            // Make sure the user belongs to the group
            TableOperation getUserOp     = TableOperation.Retrieve <TableEntityAdapter <UserEntity> >(PartitionNames.User, message.SenderId.ToIdString());
            TableResult    getUserResult = await groupTable.ExecuteAsync(getUserOp);

            if (!(getUserResult.Result is TableEntityAdapter <UserEntity> user))
            {
                _logger.LogError($"User ID {message.SenderId} does not belong to group ID {message.GroupId}.");
                return(null);
            }

            Guid messageId = Guid.NewGuid();

            message.Timestamp  = DateTime.UtcNow;
            message.SenderName = user.OriginalEntity.Name;
            var messageEntity = new TableEntityAdapter <MessageEntity>(new MessageEntity
            {
                SenderId      = message.SenderId,
                Contents      = message.Contents,
                SentTimestamp = message.Timestamp,
                SenderName    = message.SenderName,
            }, PartitionNames.Message, messageId.ToIdString());
            TableOperation insertOp     = TableOperation.Insert(messageEntity);
            TableResult    insertResult = await groupTable.ExecuteAsync(insertOp);

            if (insertResult.HttpStatusCode != StatusCodes.Status204NoContent)
            {
                _logger.LogError($"Failed to add message from sender {message.SenderId} to group {message.GroupId}. Status code: {insertResult.HttpStatusCode}");
                return(null);
            }

            return(message);
        }
示例#17
0
        public async Task <ServiceResult> AddUserToGroup(User user, Guid groupId)
        {
            var groupTable = _tableClient.GetTableReference(groupId.ToTableString());

            if (!await groupTable.ExistsAsync())
            {
                _logger.LogError($"Could not find any group with ID {groupId}.");
                return(ServiceResult.NotFound);
            }

            TableOperation getExistingUser = TableOperation.Retrieve <TableEntityAdapter <UserEntity> >(PartitionNames.User, user.Id.ToIdString());
            TableResult    existsResult    = await groupTable.ExecuteAsync(getExistingUser);

            if (existsResult.Result is TableEntityAdapter <UserEntity> )
            {
                // User already exists. We're done!
                return(ServiceResult.Success);
            }

            // Verify group isn't currently full.
            int groupCount = await GetGroupCount(groupId);

            if (groupCount >= MaxGroupSize)
            {
                _logger.LogInformation($"Unable to add user {user.Name}-{user.Id} to group ID {groupId}. Group already has {groupCount} users.");
                return(ServiceResult.InvalidArguments);
            }

            var userEntity = new TableEntityAdapter <UserEntity>(
                new UserEntity
            {
                Name     = user.Name,
                LastSeen = DateTime.UtcNow
            }, PartitionNames.User, user.Id.ToIdString());
            TableOperation addUser   = TableOperation.Insert(userEntity);
            TableResult    addResult = await groupTable.ExecuteAsync(addUser);

            if (addResult.HttpStatusCode != StatusCodes.Status204NoContent)
            {
                _logger.LogError($"Unable to add user {user.Name}-{user.Id} to group {groupId}. Result code: {addResult.HttpStatusCode}");
                return(ServiceResult.ServerError);
            }

            // User added. Do bookkeeping
            GroupMetadata metadata = await GetGroupMetadata(groupId);

            await AddOrUpdateToGroupsList(metadata, groupId, groupCount + 1);
            await AddToUserGroups(user.Id, groupId, DateTime.UtcNow);

            return(ServiceResult.Success);
        }
示例#18
0
        public async Task <IHttpActionResult> SignIn(ODataActionParameters parameters)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest());
            }

            string code = (string)parameters["code"];

            HttpResponseMessage response = await client.GetAsync($"https://api.weixin.qq.com/sns/jscode2session?appid={ConfigurationManager.AppSettings["wxAppId"]}&secret={ConfigurationManager.AppSettings["wxAppSecret"]}&js_code={code}&grant_type=authorization_code");

            if (response.IsSuccessStatusCode)
            {
                var stream = await response.Content.ReadAsStreamAsync();

                var serializer = new DataContractJsonSerializer(typeof(SignInResult));
                var result     = (SignInResult)serializer.ReadObject(stream);
                if (result.Success)
                {
                    TableOperation            retrieveOperation = TableOperation.Retrieve <TableEntityAdapter <User> >("User", result.OpenId);
                    TableResult               retrievedResult   = UserTable.Execute(retrieveOperation);
                    TableEntityAdapter <User> userEntity        = (TableEntityAdapter <User>)retrievedResult.Result;

                    if (userEntity != null)
                    {
                        userEntity.OriginalEntity.SignInHash = result.SessionKey.GetHashCode();
                        TableOperation updateOperation = TableOperation.Replace(userEntity);
                        UserTable.Execute(updateOperation);
                    }
                    else
                    {
                        User user = new User
                        {
                            Id         = result.OpenId,
                            SignInHash = result.SessionKey.GetHashCode()
                        };
                        userEntity = new TableEntityAdapter <User>(user, "User", user.Id);
                        TableOperation insertOperation = TableOperation.Insert(userEntity);
                        UserTable.Execute(insertOperation);
                    }

                    return(Json(userEntity.OriginalEntity));
                }
                else
                {
                    return(BadRequest(result.ErrorMsg));
                }
            }
            return(BadRequest());
        }
示例#19
0
        private async Task AddWordToReferenceTableAsync(Guid instanceId, string wordName, IEnumerable <WordInformation> wordInfo)
        {
            var wordRef = new WordReference(wordName, wordInfo);

            wordRef.Serialize();
            var tableEntity = new TableEntityAdapter <WordReference>()
            {
                PartitionKey   = instanceId.ToString(),
                RowKey         = wordName,
                OriginalEntity = wordRef,
            };

            await this.wordReferencesTable.ExecuteAsync(TableOperation.Insert(tableEntity));
        }
        public async Task StoreLink(Link item)
        {
            var table = await GetCloudTable(_appSecretSettings.TableStorageConnectionString, _appSecretSettings.TableStorageContainerName);

            // Create the batch operation.
            TableBatchOperation batchOperation = new TableBatchOperation();

            // Create a TableEntityAdapter based on the item
            TableEntityAdapter <Link> entity = new TableEntityAdapter <Link>(item, _appSecretSettings.TableStoragePartitionKey, GetRowKey(item.Label));

            batchOperation.InsertOrReplace(entity);

            // Execute the batch operation.
            await table.ExecuteBatchAsync(batchOperation);
        }
        public async Task <Device> ReplaceDevice(Device device)
        {
            // Get cloudtable
            var table = await GetCloudTable(_appSettings.TableStorageConnectionString, _appSettings.StoreDeviceContainerName);

            // Create the entity based on passed in device
            TableEntityAdapter <Device> entity = new TableEntityAdapter <Device>(device, _appSettings.StoreDevicePartitionKey, device.Id.ToString());

            // Create the InsertOrReplace operation
            TableOperation updateOperation = TableOperation.InsertOrMerge(entity);

            // Execute the operation.
            await table.ExecuteAsync(updateOperation);

            return(device);
        }
示例#22
0
        public async Task <IEnumerable <WordInformation> > GetAndSaveWordInformation(Guid instanceId, string word)
        {
            var wordInfo = await oedClient.GetInformation(word);

            foreach (var info in wordInfo)
            {
                var tableEntity = new TableEntityAdapter <WordInformation>()
                {
                    PartitionKey   = instanceId.ToString(),
                    RowKey         = word,
                    OriginalEntity = info,
                };

                await mainTable.ExecuteAsync(TableOperation.Insert(tableEntity));
            }

            return(wordInfo);
        }
示例#23
0
        /// <summary>
        /// Stuff the result in table storage
        /// </summary>
        /// <param name="receipt"></param>
        /// <returns></returns>
        private async Task SaveReceiptResult(Receipt receipt)
        {
            if (receipt != null)
            {
                receipt.Url = null; // remove as this has the SAS token which will expire
                var entity = new TableEntityAdapter <Receipt>(receipt, receipt.RequestReceived.ToString("yyyyMMdd"), receipt.Id);
                var insert = Microsoft.Azure.Cosmos.Table.TableOperation.InsertOrMerge(entity);

                try
                {
                    _logger.LogInformation($"Saving receipt to table storage: Id: {receipt.Id} Total: {receipt.Total}");
                    var res = await _receiptTable.ExecuteAsync(insert);
                }
                catch (Exception exp)
                {
                    _logger.LogError($"Error saving to table storage: {exp.Message}");
                }
            }
        }
示例#24
0
        public async Task StoreCodes(List <Code> items)
        {
            var table = await GetCloudTable(_appSecretSettings.TableStorageConnectionString, _appSettings.TableStorageContainerName);

            // Need to split list into block of 100 as 100 is the maximum amount of item permitted in a batch operation https://docs.microsoft.com/en-us/azure/cosmos-db/table-storage-how-to-use-dotnet#insert-a-batch-of-entities
            var listOfListOfItems = items.ChunkBy(100);

            foreach (var listOfItems in listOfListOfItems)
            {
                // Create the batch operation.
                TableBatchOperation batchOperation = new TableBatchOperation();

                // Add each item to the batch
                foreach (var item in listOfItems)
                {
                    var rowKey = item.PromoCode;
                    TableEntityAdapter <Code> entity = new TableEntityAdapter <Code>(item, item.EventName, item.PromoCode);
                    batchOperation.InsertOrReplace(entity);
                }

                // Execute the batch operation.
                await table.ExecuteBatchAsync(batchOperation);
            }
        }
示例#25
0
 private static T GetMessageOf <T>(this TableEntityAdapter <Message> message) where T : IMessage
 {
     if (message == null)
     {
         return(default);
示例#26
0
        public async void Should_Upload_Completed_With_Manifest_Last()
        {
            var request        = TestFactory.CreateHttpRequestWithDataStream($"Data/Sample 2.pdf");
            var uploadDir      = _app.Repository.GetBlobDirectory(BlobNames.UploadDirectory);
            var uploadTmpTable = _app.Repository.GetTable(TableNames.CommUpload);
            var queue          = _app.Repository.GetQueue(QueueNames.CommProcess);

            // call step1 upload start
            var response = (ObjectResult)await UploadFunctions.Start(request,
                                                                     $"{DateTime.Now:u} Sample 2.pdf",
                                                                     uploadDir,
                                                                     uploadTmpTable,
                                                                     new IdGenerator(),
                                                                     _app.App,
                                                                     _logger);

            var upload = response.Value.IsOrMap <UploadSession>();

            Assert.Equal(StatusCodes.Status200OK, response.StatusCode);
            Assert.Null(upload.ManifestFile);
            Assert.NotNull(upload.UploadStart);
            Assert.Null(upload.UploadEnd);
            Assert.Contains("Sample 2.pdf", upload.LastUploadedFile);

            _output.WriteLine(upload.ToJson(Formatting.Indented));

            // call step2 upload continue
            var sessionId            = upload.SessionId;
            var sessionBlobDirectory = _app.Repository.GetBlobDirectory(BlobNames.UploadDirectory + $"/{sessionId}");

            var tmpEntity = new TableEntityAdapter <UploadSession>(upload, CommUploadPartitionKeys.Temp, sessionId);

            request = TestFactory.CreateHttpRequestWithDataStream("Data/Sample 1.pdf");

            response = (ObjectResult)await UploadFunctions.Continue(request,
                                                                    sessionId,
                                                                    $"{DateTime.Now:u} Sample 1.pdf",
                                                                    sessionBlobDirectory,
                                                                    tmpEntity,
                                                                    uploadTmpTable,
                                                                    _logger);

            upload = response.Value.IsOrMap <UploadSession>();

            Assert.Equal(StatusCodes.Status200OK, response.StatusCode);
            Assert.Null(upload.ManifestFile);
            Assert.NotNull(upload.UploadStart);
            Assert.Null(upload.UploadEnd);
            Assert.Contains("Sample 1.pdf", upload.LastUploadedFile);

            _output.WriteLine(upload.ToJson(Formatting.Indented));

            // call step3 upload end
            tmpEntity = new TableEntityAdapter <UploadSession>(upload, CommUploadPartitionKeys.Temp, sessionId);
            request   = TestFactory.CreateHttpRequestWithDataStream($"Data/{CommunicationManifest.FileName}");

            response = (ObjectResult)await UploadFunctions.End(request,
                                                               sessionId,
                                                               CommunicationManifest.FileName,
                                                               sessionBlobDirectory,
                                                               tmpEntity,
                                                               uploadTmpTable,
                                                               queue,
                                                               _app.App,
                                                               _logger);

            upload = response.Value.IsOrMap <UploadSession>();

            Assert.Equal(StatusCodes.Status200OK, response.StatusCode);
            Assert.NotNull(upload.ManifestFile);
            Assert.NotNull(upload.UploadStart);
            Assert.NotNull(upload.UploadEnd);
            Assert.Contains(CommunicationManifest.FileName, upload.LastUploadedFile);

            _output.WriteLine(upload.ToJson(Formatting.Indented));
        }
示例#27
0
        public static async Task <IActionResult> End(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = ServiceNames.UploadEnd + "/{session}/{filename?}")]
            HttpRequest req,
            string session,
            string filename,
            [Blob(BlobNames.UploadDirectory + "/{session}")] CloudBlobDirectory uploadDir,
            [Table(TableNames.CommUpload, CommUploadPartitionKeys.Temp, "{session}")] TableEntityAdapter <UploadSession> upload,
            [Table(TableNames.CommUpload)] CloudTable uploadTable,
            [Queue(QueueNames.CommProcess)] CloudQueue processQueue,
            [Inject] App app,
            ILogger log)
        {
            try
            {
                if (session.IsNullOrEmpty())
                {
                    throw new ArgumentException("The Session Id is required.", nameof(session));
                }

                // save the file
                var uploadTo = await req.Body.UploadTo(uploadDir, filename);

                #region unexpected behaviour notes

                /*
                 * update the OriginalEntity.Property value has cause some funny error without cloning the object
                 * System.Private.CoreLib: Exception while executing function: TransferEnd.
                 * Microsoft.Azure.WebJobs.Host: Error while handling parameter upload after function returned:.
                 * Microsoft.WindowsAzure.Storage: Not Found.
                 *
                 * upload.OriginalEntity.UploadEnd = app.DateTimeNow;
                 */

                #endregion unexpected behaviour notes

                UploadSession UpdateOriginalEntity(UploadSession uploadSession)
                {
                    uploadSession.UploadEnd        = app.DateTimeNow;
                    uploadSession.ManifestFile     = new[] { upload.OriginalEntity.ManifestFile, filename }.IsIfManifest();
                    uploadSession.LastUploadedFile = new[] { filename, uploadSession.LastUploadedFile }.FirstIsNotEmpty();
                    return(uploadSession);
                }

                // close the upload session
                upload = await upload.MoveTo(uploadTable
                                             , uploadSession => CommUploadPartitionKeys.Completed
                                             , updateOriginalEntity : UpdateOriginalEntity
                                             );

                // raise the UploadCompleted event
                await new UploadCompleted {
                    SessionId = session
                }.AddMessageToAsync(processQueue);

                return(new OkObjectResult(upload.OriginalEntity));
            }
            catch (Exception ex)
            {
                log.LogError(ex.StackTrace);
                return(new BadRequestObjectResult(new UploadSession {
                    Errors = ex.Message
                }));
            }
        }