- Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathAsyncMonitor.cs
99 lines (85 loc) · 5.09 KB
/
AsyncMonitor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
namespaceMicrosoft.Graph
{
usingSystem;
usingSystem.Net;
usingSystem.Net.Http;
usingSystem.Threading;
usingSystem.Threading.Tasks;
usingMicrosoft.Kiota.Abstractions;
usingMicrosoft.Kiota.Abstractions.Serialization;
/// <summary>
/// Monitor for async operations to the Graph service on the client.
/// </summary>
/// <typeparam name="T">The object type to return.</typeparam>
publicclassAsyncMonitor<T>:IAsyncMonitor<T>whereT:IParsable,new()
{
privateAsyncOperationStatusasyncOperationStatus;
privateIBaseClientclient;
internalstringmonitorUrl;
privatereadonlyIAsyncParseNodeFactoryparseNodeFactory;
/// <summary>
/// Construct an Async Monitor.
/// </summary>
/// <param name="client">The client to monitor.</param>
/// <param name="monitorUrl">The URL to monitor.</param>
/// <param name="parseNodeFactory"> The <see cref="IParseNodeFactory"/> to use for response handling</param>
publicAsyncMonitor(IBaseClientclient,stringmonitorUrl,IParseNodeFactoryparseNodeFactory=null)
{
this.client=client;
this.monitorUrl=monitorUrl;
this.parseNodeFactory=parseNodeFactoryasIAsyncParseNodeFactory??ParseNodeFactoryRegistry.DefaultInstance;
}
/// <summary>
/// Poll to check for completion of an async call to the Graph service.
/// </summary>
/// <param name="progress">The progress status.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The operation task.</returns>
publicasyncTask<T>PollForOperationCompletionAsync(IProgress<AsyncOperationStatus>progress,CancellationTokencancellationToken)
{
while(!cancellationToken.IsCancellationRequested)
{
varrequestInformation=newRequestInformation(){HttpMethod=Method.GET,UrlTemplate=this.monitorUrl};
varnativeResponseHandler=newNativeResponseHandler();
requestInformation.SetResponseHandler(nativeResponseHandler);
awaitthis.client.RequestAdapter.SendNoContentAsync(requestInformation,cancellationToken:cancellationToken).ConfigureAwait(false);
usingvarresponseMessage=nativeResponseHandler.ValueasHttpResponseMessage;
// The monitor service will return an Accepted status for any monitor operation that hasn't completed.
// If we have a success code that isn't Accepted, the operation is complete. Return the resulting object.
if(responseMessage.StatusCode!=HttpStatusCode.Accepted&&responseMessage.IsSuccessStatusCode)
{
usingvarresponseStream=awaitresponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false);
returnresponseStream.Length>0?(awaitparseNodeFactory.GetRootParseNodeAsync(CoreConstants.MimeTypeNames.Application.Json,responseStream,cancellationToken)).GetObjectValue(_ =>newT()):default;
}
using(varresponseStream=awaitresponseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
this.asyncOperationStatus=responseStream.Length>0?(awaitparseNodeFactory.GetRootParseNodeAsync(CoreConstants.MimeTypeNames.Application.Json,responseStream,cancellationToken).ConfigureAwait(false)).GetObjectValue(_ =>newAsyncOperationStatus()):null;
if(this.asyncOperationStatus==null)
{
thrownewServiceException("Error retrieving monitor status.");
}
if(string.Equals(this.asyncOperationStatus.Status,"cancelled",StringComparison.OrdinalIgnoreCase))
{
returndefault(T);
}
if(string.Equals(this.asyncOperationStatus.Status,"failed",StringComparison.OrdinalIgnoreCase)
||string.Equals(this.asyncOperationStatus.Status,"deleteFailed",StringComparison.OrdinalIgnoreCase))
{
objectmessage=null;
this.asyncOperationStatus.AdditionalData?.TryGetValue("message",outmessage);
thrownewServiceException(message?.ToString()??"delete operation failed");
}
if(progress!=null)
{
progress.Report(this.asyncOperationStatus);
}
}
awaitTask.Delay(CoreConstants.PollingIntervalInMs,cancellationToken).ConfigureAwait(false);
}
returndefault(T);
}
}
}