// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------
namespace Microsoft.Graph
{
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
///
/// Monitor for async operations to the Graph service on the client.
///
/// The object type to return.
public class AsyncMonitor : IAsyncMonitor
{
private AsyncOperationStatus asyncOperationStatus;
private IBaseClient client;
internal string monitorUrl;
///
/// Construct an Async Monitor.
///
/// The client to monitor.
/// The URL to monitor.
public AsyncMonitor(IBaseClient client, string monitorUrl)
{
this.client = client;
this.monitorUrl = monitorUrl;
}
///
/// Poll to check for completion of an async call to the Graph service.
///
/// The progress status.
/// The cancellation token.
/// The operation task.
public async Task PollForOperationCompletionAsync(IProgress progress, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, this.monitorUrl))
{
using (var responseMessage = await this.client.HttpProvider.SendAsync(httpRequestMessage).ConfigureAwait(false))
{
// 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)
{
using (var responseStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
return this.client.HttpProvider.Serializer.DeserializeObject(responseStream);
}
}
using (var responseStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
this.asyncOperationStatus = this.client.HttpProvider.Serializer.DeserializeObject(responseStream);
if (this.asyncOperationStatus == null)
{
throw new ServiceException(
new Error
{
Code = ErrorConstants.Codes.GeneralException,
Message = "Error retrieving monitor status."
});
}
if (string.Equals(this.asyncOperationStatus.Status, "cancelled", StringComparison.OrdinalIgnoreCase))
{
return default(T);
}
if (string.Equals(this.asyncOperationStatus.Status, "failed", StringComparison.OrdinalIgnoreCase)
|| string.Equals(this.asyncOperationStatus.Status, "deleteFailed", StringComparison.OrdinalIgnoreCase))
{
object message = null;
if (this.asyncOperationStatus.AdditionalData != null)
{
this.asyncOperationStatus.AdditionalData.TryGetValue("message", out message);
}
throw new ServiceException(
new Error
{
Code = ErrorConstants.Codes.GeneralException,
Message = message as string
});
}
if (progress != null)
{
progress.Report(this.asyncOperationStatus);
}
}
}
}
await Task.Delay(CoreConstants.PollingIntervalInMs, cancellationToken).ConfigureAwait(false);
}
return default(T);
}
}
}