Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Application/Common/Services/ISavedWorkItemService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Application.Common.Services
public interface ISavedWorkItemService
{
Task CreateSavedWorkItemStatus(WorkItemStatus workItemStatus, string userId, string revitVersion, string objectKey, string fileName);
Task<List<SavedWorkItem>> GetSavedWorkItems(string userId);
List<SavedWorkItem> GetSavedWorkItems(string userId);
Task UpdateSavedWorkItemStatus(WorkItemStatus workItemStatus);
}
}
7 changes: 4 additions & 3 deletions src/Application/Common/Services/SavedWorkItemService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Azure.Data.Tables;
using Domain.Entities;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -62,17 +63,17 @@ public async Task UpdateSavedWorkItemStatus(WorkItemStatus workItemStatus)
}
}

public async Task<List<SavedWorkItem>> GetSavedWorkItems(string userId)
public List<SavedWorkItem> GetSavedWorkItems(string userId)
{
TableClient tableClient = _tableServiceClient.GetTableClient(_partitionKey);
tableClient.CreateIfNotExists();

AsyncPageable<SavedWorkItem> queryResults = tableClient.QueryAsync<SavedWorkItem>(ent =>
Pageable<SavedWorkItem> queryResults = tableClient.Query<SavedWorkItem>(ent =>
ent.UserId == userId && ent.Created >= DateTime.Now.AddDays(-30));

List<SavedWorkItem> savedWorkItems = new List<SavedWorkItem>();

await foreach (SavedWorkItem savedWorkItem in queryResults)
foreach (SavedWorkItem savedWorkItem in queryResults)
{
savedWorkItems.Add(savedWorkItem);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ public async Task<Signeds3downloadResponse> Handle(GetDownloadUrlQuery request,
Signeds3downloadResponse signedUrl = await _ossClient.SignedS3DownloadAsync(
twoLeggedToken.AccessToken, bucketKey, objectKey,
responseContentDisposition: $"attachment; filename=\"{outputFileName}\"",
minutesExpiration: 60);
minutesExpiration: 60,
throwOnError:false);

if (signedUrl == null)
{
signedUrl = new Signeds3downloadResponse();
}

return signedUrl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public async Task<WorkItemStatus> Handle(CreateWorkItemCommand request, Cancella
// 1. input file
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
{
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", inputBucketKey, objectKey + ".rvt"),
//Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", inputBucketKey, ),
Url = $"urn:adsk.objects:os.object:{inputBucketKey}/{objectKey}.rvt",
Verb = Verb.Get,
Headers = new Dictionary<string, string>()
{
Expand All @@ -75,14 +76,21 @@ public async Task<WorkItemStatus> Handle(CreateWorkItemCommand request, Cancella
// 3. output file
XrefTreeArgument outputFileArgument = new XrefTreeArgument()
{
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", outputBucketKey, objectKey + ".ifc"),
Url = $"urn:adsk.objects:os.object:{outputBucketKey}/{objectKey}.ifc",
Verb = Verb.Put,
Headers = new Dictionary<string, string>()
{
{"Authorization", "Bearer " + twoLeggedToken.AccessToken }
}
};

// 3. onComplete callback
XrefTreeArgument onCompleteArgument = new XrefTreeArgument()
{
Url = $"{_forgeConfiguration.CallbackUrl}/callback/oncomplete",
Verb = Verb.Post
};

// prepare & submit workitem
WorkItem workItemSpec = new WorkItem()
{
Expand All @@ -91,7 +99,8 @@ public async Task<WorkItemStatus> Handle(CreateWorkItemCommand request, Cancella
{
{ "inputFile", inputFileArgument },
{ "inputJson", inputJsonArgument },
{ "outputFile", outputFileArgument }
{ "outputFile", outputFileArgument },
{ "onComplete", onCompleteArgument }
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Autodesk.Forge.DesignAutomation.Model;
using Domain.Entities;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application.WorkItems.Commands.UpdateWorkItemStatus
{
public class UpdateWorkItemStatusCommand : IRequest
{
internal readonly WorkItemStatus Status;

public UpdateWorkItemStatusCommand(WorkItemStatus status)
{
Status = status;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Application.Common.Services;
using Application.Files.Queries.GetUploadUrl;
using Application.WorkItems.Queries.GetWorkItemStatus;
using Autodesk.Authentication;
using Autodesk.Forge.DesignAutomation;
using Autodesk.Forge.DesignAutomation.Model;
using Autodesk.Oss;
using MediatR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Application.WorkItems.Commands.UpdateWorkItemStatus
{

public class UpdateWorkItemStatusCommandHandler : IRequestHandler<UpdateWorkItemStatusCommand>
{
private readonly ISavedWorkItemService _savedWorkItemService;

public UpdateWorkItemStatusCommandHandler(ISavedWorkItemService savedWorkItemService)
{
_savedWorkItemService = savedWorkItemService;
}
public async Task Handle(UpdateWorkItemStatusCommand request, CancellationToken cancellationToken)
{
await _savedWorkItemService.UpdateSavedWorkItemStatus(request.Status);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Autodesk.Forge.DesignAutomation.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Application.WorkItems.Commands.UpdateWorkItemStatus
{

public class WorkItemStatusDTO
{
/// <summary>
/// The current status of the workitem.
/// </summary>
/// <value>The current status of the workitem.</value>
public string? Status { get; set; }

/// <summary>
/// The current status of the workitem.
/// </summary>
/// <value>The current status of the workitem.</value>
public string? Progress { get; set; }

/// <summary>
/// The detailed report about the workitem, report url is valid for 1 hours from first receiving it.
/// </summary>
/// <value>The detailed report about the workitem, report url is valid for 1 hours from first receiving it.</value>
public string? ReportUrl { get; set; }

/// <summary>
/// The debug information for the workitem, the url is valid for 1 hours from first receiving it.
/// </summary>
/// <value>The debug information for the workitem, the url is valid for 1 hours from first receiving it.</value>
public Uri? DebugInfoUrl { get; private set; }

/// <summary>
/// Basic statistics about workitem processing.
/// </summary>
/// <value>Basic statistics about workitem processing.</value>
public Statistics? Stats { get; set; }

public string? Id { get; set; }

public static T ToEnum<T>(string str)
{
var enumType = typeof(T);
foreach (var name in Enum.GetNames(enumType))
{
var enumMemberAttribute = ((EnumMemberAttribute[])enumType.GetField(name).GetCustomAttributes(typeof(EnumMemberAttribute), true)).Single();
if (enumMemberAttribute.Value == str) return (T)Enum.Parse(enumType, name);
}
//throw exception or whatever handling you want or
return default(T);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public GetWorkItemsQueryHandler(IAppDbContext context, ISavedWorkItemService sav

public async Task<List<SavedWorkItem>> Handle(GetWorkItemsQuery request, CancellationToken cancellationToken)
{
List<SavedWorkItem> savedWorkItems = await _savedWorkItemService.GetSavedWorkItems(request.UserId);
List<SavedWorkItem> savedWorkItems = _savedWorkItemService.GetSavedWorkItems(request.UserId);

return savedWorkItems;
return await Task.FromResult<List<SavedWorkItem>>(savedWorkItems);
}
}
}
2 changes: 1 addition & 1 deletion src/Domain/Entities/ForgeConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class ForgeConfiguration
public string InputBucketKey { get; set; }
public string OutputBucketKey { get; set; }
public ApplicationDetail ApplicationDetail { get; set; }

public string CallbackUrl { get; set; }
}

public class ApplicationDetail
Expand Down
44 changes: 42 additions & 2 deletions src/WebApp/ConfigureServices.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,46 @@
namespace WebApp
using Infrastructure;
using Microsoft.AspNetCore.Identity;
using Microsoft.OpenApi.Models;

namespace WebApp
{
public class ConfigureServices
public static class ConfigureServices
{
public static IServiceCollection AddIdentityServices(this IServiceCollection services)
{

services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});

c.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header,

},
new List<string>()
}
});
});

return services;
}
}
}
47 changes: 47 additions & 0 deletions src/WebApp/Controllers/CallbackController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Application.Files.Commands.CompleteUpload;
using Application.Files.Commands.CreateBucket;
using Application.Files.Queries.GetDownloadUrlQuery;
using Application.Files.Queries.GetFiles;
using Application.Files.Queries.GetUploadUrl;
using Application.WorkItems.Commands.CreateWorkItem;
using Application.WorkItems.Commands.UpdateWorkItemStatus;
using Application.WorkItems.Queries.GetWorkItem;
using Application.WorkItems.Queries.GetWorkItemStatus;
using Autodesk.Forge.DesignAutomation.Model;
using Autodesk.Oss.Model;
using Domain.Entities;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web;
using WebApp.Models;
using Status = Autodesk.Forge.DesignAutomation.Model.Status;


namespace WebApp.Controllers
{
/// <summary>
/// Manage files
/// </summary>
[ApiController]
[Route("[controller]")]
public class CallbackController : BaseController
{
/// <summary>
/// The onComplete callback controler
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("oncomplete")]
public async Task OnComplete(WorkItemStatusDTO workItemStatusBody)
{
WorkItemStatus workItemStatus = new WorkItemStatus();

workItemStatus.Status = WorkItemStatusDTO.ToEnum<Status>(workItemStatusBody.Status);
workItemStatus.Stats = workItemStatusBody.Stats;
workItemStatus.ReportUrl = workItemStatusBody.ReportUrl;
workItemStatus.Progress = workItemStatusBody.Progress;
workItemStatus.Id = workItemStatusBody.Id;

await Mediator.Send(new UpdateWorkItemStatusCommand(workItemStatus));
}
}
}
4 changes: 2 additions & 2 deletions src/WebApp/Controllers/FilesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public async Task<CompleteUploadResponse> CompleteUpload(UploadCompletion upload
/// <returns></returns>
[HttpGet]
[Route("download")]
public async Task<Signeds3downloadResponse> GetDownloadUrls(string objectKey, string fileName)
public async Task<Signeds3downloadResponse?> GetDownloadUrls(string objectKey, string fileName)
{
Signeds3downloadResponse vm = await Mediator.Send(new GetDownloadUrlQuery(objectKey, fileName));
Signeds3downloadResponse? vm = await Mediator.Send(new GetDownloadUrlQuery(objectKey, fileName));
return vm;
}

Expand Down
1 change: 1 addition & 0 deletions src/WebApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static async Task Main(string[] args)

builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Services.AddIdentityServices();

string userAssignedClientId = builder.Configuration["ManagedIdentityClientId"];

Expand Down
1 change: 1 addition & 0 deletions src/WebApp/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"ClientSecret": "<forge-client-secret>",
"InputBucketKey": "revit-convert-bucket",
"OutputBucketKey": "ifc-convert-bucket",
"CallbackUrl": "https://mouse-joint-mutt.ngrok-free.app",
"ApplicationDetail": {
"Nickname": "RevitToIfc_dev",
"AppBundleName": "RvtToIfc",
Expand Down
2 changes: 1 addition & 1 deletion src/WebClient/Components/Convert/WorkItemsList.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<MudDataGrid T="SavedWorkItemDTO" Items="@SavedWorkItems">
<Columns>
<PropertyColumn Property="x => x.Created" Title="Created"/>
<PropertyColumn Property="x => x.Created" Title="Created" InitialDirection="SortDirection.Descending"/>
<PropertyColumn Property="x => x.FileName" Title="FileName"/>
<PropertyColumn Property="x => x.Status" Title="Status"/>
<TemplateColumn CellClass="d-flex justify-end">
Expand Down
2 changes: 1 addition & 1 deletion src/WebClient/Components/Convert/WorkItemsList.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public async Task DownloadUrl(SavedWorkItemDTO savedWorkItem)

Signeds3downloadResponse signedDownload = await _dataService.GetDownloadUrl(savedWorkItem.ObjectKey, savedWorkItem.FileName);

savedWorkItem.DownloadUrl = signedDownload.Url;
savedWorkItem.DownloadUrl = signedDownload?.Url;
}
}
}
2 changes: 1 addition & 1 deletion src/WebClient/Models/RevitFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public async Task UploadFile(IDataService dataService, IUploadService uploadServ
return;
case Models.Status.Success:
Signeds3downloadResponse signedDownload = await dataService.GetDownloadUrl(objectKey, Name);
DownloadUrl = signedDownload.Url;
DownloadUrl = signedDownload?.Url;
Status = FileStatus.Converted;
return;
default:
Expand Down
Loading