Skip to content

Commit 2ca2c51

Browse files
authored
Merge pull request #51 from simonmoreau/callbacks
Callbacks
2 parents 70098c0 + 88ed3f6 commit 2ca2c51

17 files changed

Lines changed: 234 additions & 18 deletions

File tree

src/Application/Common/Services/ISavedWorkItemService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Application.Common.Services
66
public interface ISavedWorkItemService
77
{
88
Task CreateSavedWorkItemStatus(WorkItemStatus workItemStatus, string userId, string revitVersion, string objectKey, string fileName);
9-
Task<List<SavedWorkItem>> GetSavedWorkItems(string userId);
9+
List<SavedWorkItem> GetSavedWorkItems(string userId);
1010
Task UpdateSavedWorkItemStatus(WorkItemStatus workItemStatus);
1111
}
1212
}

src/Application/Common/Services/SavedWorkItemService.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Azure.Data.Tables;
44
using Domain.Entities;
55
using System;
6+
using System.Collections.Concurrent;
67
using System.Collections.Generic;
78
using System.Linq;
89
using System.Text;
@@ -62,17 +63,17 @@ public async Task UpdateSavedWorkItemStatus(WorkItemStatus workItemStatus)
6263
}
6364
}
6465

65-
public async Task<List<SavedWorkItem>> GetSavedWorkItems(string userId)
66+
public List<SavedWorkItem> GetSavedWorkItems(string userId)
6667
{
6768
TableClient tableClient = _tableServiceClient.GetTableClient(_partitionKey);
6869
tableClient.CreateIfNotExists();
6970

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

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

75-
await foreach (SavedWorkItem savedWorkItem in queryResults)
76+
foreach (SavedWorkItem savedWorkItem in queryResults)
7677
{
7778
savedWorkItems.Add(savedWorkItem);
7879
}

src/Application/Files/Queries/GetDownloadUrlQuery/GetDownloadUrlQueryHandler.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,13 @@ public async Task<Signeds3downloadResponse> Handle(GetDownloadUrlQuery request,
3939
Signeds3downloadResponse signedUrl = await _ossClient.SignedS3DownloadAsync(
4040
twoLeggedToken.AccessToken, bucketKey, objectKey,
4141
responseContentDisposition: $"attachment; filename=\"{outputFileName}\"",
42-
minutesExpiration: 60);
42+
minutesExpiration: 60,
43+
throwOnError:false);
4344

45+
if (signedUrl == null)
46+
{
47+
signedUrl = new Signeds3downloadResponse();
48+
}
4449

4550
return signedUrl;
4651
}

src/Application/WorkItems/Commands/CreateWorkItem/CreateWorkItemCommandHandler.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public async Task<WorkItemStatus> Handle(CreateWorkItemCommand request, Cancella
5757
// 1. input file
5858
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
5959
{
60-
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", inputBucketKey, objectKey + ".rvt"),
60+
//Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", inputBucketKey, ),
61+
Url = $"urn:adsk.objects:os.object:{inputBucketKey}/{objectKey}.rvt",
6162
Verb = Verb.Get,
6263
Headers = new Dictionary<string, string>()
6364
{
@@ -75,14 +76,21 @@ public async Task<WorkItemStatus> Handle(CreateWorkItemCommand request, Cancella
7576
// 3. output file
7677
XrefTreeArgument outputFileArgument = new XrefTreeArgument()
7778
{
78-
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", outputBucketKey, objectKey + ".ifc"),
79+
Url = $"urn:adsk.objects:os.object:{outputBucketKey}/{objectKey}.ifc",
7980
Verb = Verb.Put,
8081
Headers = new Dictionary<string, string>()
8182
{
8283
{"Authorization", "Bearer " + twoLeggedToken.AccessToken }
8384
}
8485
};
8586

87+
// 3. onComplete callback
88+
XrefTreeArgument onCompleteArgument = new XrefTreeArgument()
89+
{
90+
Url = $"{_forgeConfiguration.CallbackUrl}/callback/oncomplete",
91+
Verb = Verb.Post
92+
};
93+
8694
// prepare & submit workitem
8795
WorkItem workItemSpec = new WorkItem()
8896
{
@@ -91,7 +99,8 @@ public async Task<WorkItemStatus> Handle(CreateWorkItemCommand request, Cancella
9199
{
92100
{ "inputFile", inputFileArgument },
93101
{ "inputJson", inputJsonArgument },
94-
{ "outputFile", outputFileArgument }
102+
{ "outputFile", outputFileArgument },
103+
{ "onComplete", onCompleteArgument }
95104
}
96105
};
97106

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Autodesk.Forge.DesignAutomation.Model;
2+
using Domain.Entities;
3+
using MediatR;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
namespace Application.WorkItems.Commands.UpdateWorkItemStatus
11+
{
12+
public class UpdateWorkItemStatusCommand : IRequest
13+
{
14+
internal readonly WorkItemStatus Status;
15+
16+
public UpdateWorkItemStatusCommand(WorkItemStatus status)
17+
{
18+
Status = status;
19+
}
20+
}
21+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Application.Common.Services;
2+
using Application.Files.Queries.GetUploadUrl;
3+
using Application.WorkItems.Queries.GetWorkItemStatus;
4+
using Autodesk.Authentication;
5+
using Autodesk.Forge.DesignAutomation;
6+
using Autodesk.Forge.DesignAutomation.Model;
7+
using Autodesk.Oss;
8+
using MediatR;
9+
using Microsoft.Extensions.Logging;
10+
using Microsoft.Extensions.Options;
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using System.Text;
15+
using System.Threading.Tasks;
16+
17+
namespace Application.WorkItems.Commands.UpdateWorkItemStatus
18+
{
19+
20+
public class UpdateWorkItemStatusCommandHandler : IRequestHandler<UpdateWorkItemStatusCommand>
21+
{
22+
private readonly ISavedWorkItemService _savedWorkItemService;
23+
24+
public UpdateWorkItemStatusCommandHandler(ISavedWorkItemService savedWorkItemService)
25+
{
26+
_savedWorkItemService = savedWorkItemService;
27+
}
28+
public async Task Handle(UpdateWorkItemStatusCommand request, CancellationToken cancellationToken)
29+
{
30+
await _savedWorkItemService.UpdateSavedWorkItemStatus(request.Status);
31+
}
32+
}
33+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using Autodesk.Forge.DesignAutomation.Model;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Runtime.Serialization;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Application.WorkItems.Commands.UpdateWorkItemStatus
10+
{
11+
12+
public class WorkItemStatusDTO
13+
{
14+
/// <summary>
15+
/// The current status of the workitem.
16+
/// </summary>
17+
/// <value>The current status of the workitem.</value>
18+
public string? Status { get; set; }
19+
20+
/// <summary>
21+
/// The current status of the workitem.
22+
/// </summary>
23+
/// <value>The current status of the workitem.</value>
24+
public string? Progress { get; set; }
25+
26+
/// <summary>
27+
/// The detailed report about the workitem, report url is valid for 1 hours from first receiving it.
28+
/// </summary>
29+
/// <value>The detailed report about the workitem, report url is valid for 1 hours from first receiving it.</value>
30+
public string? ReportUrl { get; set; }
31+
32+
/// <summary>
33+
/// The debug information for the workitem, the url is valid for 1 hours from first receiving it.
34+
/// </summary>
35+
/// <value>The debug information for the workitem, the url is valid for 1 hours from first receiving it.</value>
36+
public Uri? DebugInfoUrl { get; private set; }
37+
38+
/// <summary>
39+
/// Basic statistics about workitem processing.
40+
/// </summary>
41+
/// <value>Basic statistics about workitem processing.</value>
42+
public Statistics? Stats { get; set; }
43+
44+
public string? Id { get; set; }
45+
46+
public static T ToEnum<T>(string str)
47+
{
48+
var enumType = typeof(T);
49+
foreach (var name in Enum.GetNames(enumType))
50+
{
51+
var enumMemberAttribute = ((EnumMemberAttribute[])enumType.GetField(name).GetCustomAttributes(typeof(EnumMemberAttribute), true)).Single();
52+
if (enumMemberAttribute.Value == str) return (T)Enum.Parse(enumType, name);
53+
}
54+
//throw exception or whatever handling you want or
55+
return default(T);
56+
}
57+
}
58+
}

src/Application/WorkItems/Queries/GetWorkItem/GetWorkItemsQueryHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ public GetWorkItemsQueryHandler(IAppDbContext context, ISavedWorkItemService sav
2020

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

25-
return savedWorkItems;
25+
return await Task.FromResult<List<SavedWorkItem>>(savedWorkItems);
2626
}
2727
}
2828
}

src/Domain/Entities/ForgeConfiguration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class ForgeConfiguration
77
public string InputBucketKey { get; set; }
88
public string OutputBucketKey { get; set; }
99
public ApplicationDetail ApplicationDetail { get; set; }
10-
10+
public string CallbackUrl { get; set; }
1111
}
1212

1313
public class ApplicationDetail

src/WebApp/ConfigureServices.cs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,46 @@
1-
namespace WebApp
1+
using Infrastructure;
2+
using Microsoft.AspNetCore.Identity;
3+
using Microsoft.OpenApi.Models;
4+
5+
namespace WebApp
26
{
3-
public class ConfigureServices
7+
public static class ConfigureServices
48
{
9+
public static IServiceCollection AddIdentityServices(this IServiceCollection services)
10+
{
11+
12+
services.AddSwaggerGen(c =>
13+
{
14+
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
15+
{
16+
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
17+
Name = "Authorization",
18+
In = ParameterLocation.Header,
19+
Type = SecuritySchemeType.ApiKey,
20+
Scheme = "Bearer"
21+
});
22+
23+
c.AddSecurityRequirement(new OpenApiSecurityRequirement()
24+
{
25+
{
26+
new OpenApiSecurityScheme
27+
{
28+
Reference = new OpenApiReference
29+
{
30+
Type = ReferenceType.SecurityScheme,
31+
Id = "Bearer"
32+
},
33+
Scheme = "oauth2",
34+
Name = "Bearer",
35+
In = ParameterLocation.Header,
36+
37+
},
38+
new List<string>()
39+
}
40+
});
41+
});
42+
43+
return services;
44+
}
545
}
646
}

0 commit comments

Comments
 (0)