예제 #1
0
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "workitem")] HttpRequest req,
            [Table("token", "token", "token", Connection = "StorageConnectionString")] Token token,
            [Table("workItems", Connection = "StorageConnectionString")] IAsyncCollector <WorkItemStatusEntity> workItemsTable,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed CreateWorkItem.");

            try
            {
                Autodesk.Forge.Client.Configuration.Default.AccessToken = token.ForgeToken.access_token;
                // Parse the body of the request
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                WorkItemDescription workItemDescription = JsonConvert.DeserializeObject <WorkItemDescription>(requestBody);

                int existingCredits = await _utilities.GetConversionCredits(workItemDescription.userId);

                if (existingCredits > 0)
                {
                    // Create two signed URLs to upload the file to the activity and download the result
                    ObjectsApi        apiInstance           = new ObjectsApi();
                    string            rvtBucketKey          = Environment.GetEnvironmentVariable("rvtStorageKey"); // string | URL-encoded bucket key
                    string            ifcBucketKey          = Environment.GetEnvironmentVariable("ifcStorageKey"); // string | URL-encoded bucket key
                    string            inputObjectName       = workItemDescription.inputObjectName;                 // string | URL-encoded object name
                    string            outputObjectName      = workItemDescription.outputObjectName;
                    string            onCompleteCallbackUrl = Environment.GetEnvironmentVariable("api_uri") + "/api/onworkitemcomplete";
                    PostBucketsSigned postBucketsSigned     = new PostBucketsSigned(60 * 24 * 30);

                    DynamicJsonResponse dynamicJsonResponseDownload = await apiInstance.CreateSignedResourceAsync(rvtBucketKey, inputObjectName, postBucketsSigned, "read");

                    PostObjectSigned    downloadSigned            = dynamicJsonResponseDownload.ToObject <PostObjectSigned>();
                    DynamicJsonResponse dynamicJsonResponseUpload = await apiInstance.CreateSignedResourceAsync(ifcBucketKey, outputObjectName, postBucketsSigned, "readwrite");

                    PostObjectSigned uploadSigned = dynamicJsonResponseUpload.ToObject <PostObjectSigned>();

                    Autodesk.Forge.DesignAutomation.Model.WorkItem workItem = new Autodesk.Forge.DesignAutomation.Model.WorkItem()
                    {
                        ActivityId = workItemDescription.activityId,
                        Arguments  = new Dictionary <string, IArgument>
                        {
                            { "rvtFile", new XrefTreeArgument()
                              {
                                  Url = downloadSigned.SignedUrl
                              } },
                            { "result", new XrefTreeArgument {
                                  Verb = Verb.Put, Url = uploadSigned.SignedUrl
                              } },
                            { "onComplete", new XrefTreeArgument {
                                  Verb = Verb.Post, Url = onCompleteCallbackUrl
                              } }
                        }
                    };

                    Autodesk.Forge.Core.ApiResponse <WorkItemStatus> workItemResponse = await _workItemApi.CreateWorkItemAsync(workItem);

                    // ApiResponse<Page<string>> page = await _engineApi.GetEnginesAsync();
                    WorkItemStatus workItemStatusCreationResponse = workItemResponse.Content;

                    WorkItemStatusEntity WorkItemStatusObject = Mappings.ToWorkItemStatusEntity(
                        workItemStatusCreationResponse,
                        workItemDescription.userId,
                        workItemDescription.fileSize,
                        workItemDescription.version,
                        workItemDescription.fileName,
                        uploadSigned.SignedUrl,
                        downloadSigned.SignedUrl);

                    await workItemsTable.AddAsync(WorkItemStatusObject);

                    WorkItemStatusResponse workItemStatusResponse = new WorkItemStatusResponse()
                    {
                        WorkItemId             = workItemResponse.Content.Id,
                        OutputUrl              = uploadSigned.SignedUrl,
                        WorkItemCreationStatus = WorkItemCreationStatus.Created
                    };

                    return(new OkObjectResult(workItemStatusResponse));
                }
                else
                {
                    WorkItemStatusResponse workItemStatusResponse = new WorkItemStatusResponse()
                    {
                        WorkItemId             = null,
                        OutputUrl              = null,
                        WorkItemCreationStatus = WorkItemCreationStatus.NotEnoughCredit
                    };

                    return(new OkObjectResult(workItemStatusResponse));
                }
            }
            catch (Exception ex)
            {
                return(new BadRequestObjectResult(ex));
            }
        }
        public async Task Run(
            [QueueTrigger("completedworkitems", Connection = "StorageConnectionString")] WorkItemStatus completedWorkItemStatus,
            // [Table("completedWorkItems", Connection = "StorageConnectionString")] IAsyncCollector<WorkItemStatusEntity> completedWorkItemsTable,
            // [Table("completedWorkItems", Connection = "StorageConnectionString")] CloudTable completedWorkItemsCloudTable,
            [Blob("reports", FileAccess.Write, Connection = "StorageConnectionString")] CloudBlobContainer reportsCloudBlobContainer,
            [Table("workItems", Connection = "StorageConnectionString")] CloudTable workItemsCloudTable,
            [Queue("failedConversions", Connection = "StorageConnectionString")] IAsyncCollector <WorkItemStatusEntity> failedConversionsQueue,
            ILogger log)
        {
            log.LogInformation($"C# Queue trigger function ProcessCompletedWorkItem processed");

            string userId      = null;
            string fileVersion = null;
            string fileName    = null;
            int    fileSize    = 0;
            string fileUrl     = null;
            string inputUrl    = null;

            // Get user id
            TableQuery <WorkItemStatusEntity> createdWorkItemsQuery = new TableQuery <WorkItemStatusEntity>().Where(
                TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
                                                       "workItems"),
                    TableOperators.And,
                    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal,
                                                       completedWorkItemStatus.Id)));

            // Execute the query and loop through the results
            foreach (WorkItemStatusEntity workItemStatusObject in
                     await workItemsCloudTable.ExecuteQuerySegmentedAsync(createdWorkItemsQuery, null))
            {
                userId      = workItemStatusObject.UserId;
                fileSize    = workItemStatusObject.Size;
                fileVersion = workItemStatusObject.Version;
                fileName    = workItemStatusObject.FileName;
                fileUrl     = workItemStatusObject.FileUrl;
                inputUrl    = workItemStatusObject.InputUrl;
            }

            // Add to the completed work item

            if (userId != null)
            {
                WorkItemStatusEntity completedWorkItemStatusObject = Mappings.ToWorkItemStatusEntity(
                    completedWorkItemStatus,
                    userId,
                    fileSize,
                    fileVersion,
                    fileName,
                    fileUrl,
                    inputUrl);

                // Save the report in Azure
                await reportsCloudBlobContainer.CreateIfNotExistsAsync();

                // Create a SAS token that's valid for one hour.
                SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
                sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddDays(30);
                sasConstraints.Permissions            = SharedAccessBlobPermissions.Read;

                Uri            reportUri  = new Uri(completedWorkItemStatusObject.ReportUrl);
                string         reportName = DateTime.Now.ToString() + "_" + Path.GetFileNameWithoutExtension(completedWorkItemStatusObject.FileName) + ".txt";
                CloudBlockBlob target     = reportsCloudBlobContainer.GetBlockBlobReference(reportName);
                await target.StartCopyAsync(reportUri);

                // Get its url
                string reportUrl = target.Uri.AbsoluteUri + target.GetSharedAccessSignature(sasConstraints);
                completedWorkItemStatusObject.ReportUrl = reportUrl;

                TableOperation tableOperation = TableOperation.InsertOrMerge(completedWorkItemStatusObject);
                await workItemsCloudTable.ExecuteAsync(tableOperation);

                if (completedWorkItemStatusObject.Status == "Success")
                {
                    // update the number of credits
                    int newCreditsNumber = await _utilities.UpdateCustomAttributeByUserId(completedWorkItemStatusObject.UserId, -1);

                    log.LogInformation($"The user {completedWorkItemStatusObject.UserId} has now {newCreditsNumber} credits.");
                }
                else
                {
                    await failedConversionsQueue.AddAsync(completedWorkItemStatusObject);
                }
            }
        }