Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zihzhan/fix #21764

Merged
merged 9 commits into from
Jun 10, 2021
3 changes: 3 additions & 0 deletions .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"contoso",
"deserializes",
"diagnoser",
"dtmf",
"epsg",
"expando",
"finalizer",
Expand All @@ -50,13 +51,15 @@
"overridden",
"parallelization",
"pkcs",
"pstn",
"pwsh",
"referer",
"renormalize",
"retriable",
"structs",
"uints",
"unformattable",
"unhold",
"uninstrumented",
"westus",
"xunit"
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Core.Pipeline;
using Azure.Communication.Pipeline;

namespace Azure.Communication.CallingServer
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ namespace Azure.Communication.CallingServer
/// </summary>
public class CallingServerClient
{
private readonly ClientDiagnostics _clientDiagnostics;
internal readonly ClientDiagnostics _clientDiagnostics;
internal readonly HttpPipeline _pipeline;
internal readonly string _resourceEndpoint;
internal readonly ContentDownloader _contentDownloader;

internal CallConnectionRestClient CallConnectionRestClient { get; }
internal ServerCallRestClient ServerCallRestClient { get; }

Expand Down Expand Up @@ -72,7 +76,10 @@ private CallingServerClient(string endpoint, AzureKeyCredential keyCredential, C

private CallingServerClient(string endpoint, HttpPipeline httpPipeline, CallingServerClientOptions options)
{
_pipeline = httpPipeline;
_resourceEndpoint = endpoint;
_clientDiagnostics = new ClientDiagnostics(options);
_contentDownloader = new(this);
CallConnectionRestClient = new CallConnectionRestClient(_clientDiagnostics, httpPipeline, endpoint, options.ApiVersion);
ServerCallRestClient = new ServerCallRestClient(_clientDiagnostics, httpPipeline, endpoint, options.ApiVersion);
}
Expand All @@ -82,7 +89,10 @@ private CallingServerClient(string endpoint, HttpPipeline httpPipeline, CallingS
/// <summary>Initializes a new instance of <see cref="CallingServerClient"/> for mocking.</summary>
protected CallingServerClient()
{
_pipeline = null;
_resourceEndpoint = null;
_clientDiagnostics = null;
_contentDownloader = new(this);
CallConnectionRestClient = null;
ServerCallRestClient = null;
}
Expand All @@ -106,15 +116,13 @@ public virtual async Task<Response<CallConnection>> CreateCallConnectionAsync(Co
Argument.AssertNotNullOrEmpty(targets, nameof(targets));
Argument.AssertNotNull(options, nameof(options));

var alternateCallerId = options.AlternateCallerId == null ? null : new PhoneNumberIdentifierModel(options.AlternateCallerId.PhoneNumber);

var createCallResponse = await CallConnectionRestClient.CreateCallAsync(
targets: targets.Select(t => CommunicationIdentifierSerializer.Serialize(t)),
source: CommunicationIdentifierSerializer.Serialize(source),
targets: targets.Select(t => CommunicationIdentifierSerializer.Serialize(t)),
callbackUri: options.CallbackUri?.AbsoluteUri,
requestedMediaTypes: options.RequestedMediaTypes,
requestedCallEvents: options.RequestedCallEvents,
alternateCallerId: alternateCallerId,
alternateCallerId: options.AlternateCallerId == null ? null : new PhoneNumberIdentifierModel(options.AlternateCallerId.PhoneNumber),
subject: options.Subject,
cancellationToken: cancellationToken
).ConfigureAwait(false);
Expand Down Expand Up @@ -149,15 +157,13 @@ public virtual Response<CallConnection> CreateCallConnection(CommunicationIdenti
Argument.AssertNotNullOrEmpty(targets, nameof(targets));
Argument.AssertNotNull(options, nameof(options));

var alternateCallerId = options.AlternateCallerId == null ? null : new PhoneNumberIdentifierModel(options.AlternateCallerId.PhoneNumber);

var createCallResponse = CallConnectionRestClient.CreateCall(
targets: targets.Select(t => CommunicationIdentifierSerializer.Serialize(t)),
source: CommunicationIdentifierSerializer.Serialize(source),
targets: targets.Select(t => CommunicationIdentifierSerializer.Serialize(t)),
callbackUri: options.CallbackUri?.AbsoluteUri,
requestedMediaTypes: options.RequestedMediaTypes,
requestedCallEvents: options.RequestedCallEvents,
alternateCallerId: alternateCallerId,
alternateCallerId: options.AlternateCallerId == null ? null : new PhoneNumberIdentifierModel(options.AlternateCallerId.PhoneNumber),
subject: options.Subject,
cancellationToken: cancellationToken
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace Azure.Communication.CallingServer
{
internal class ContentDownloader
{
private readonly ConversationClient _client;
private readonly CallingServerClient _client;

internal ContentDownloader(ConversationClient client)
internal ContentDownloader(CallingServerClient client)
{
_client = client;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Pipeline;

namespace Azure.Communication.CallingServer
{
/// <summary>
/// CallingServerClient _contentDownloader methods extentions class.
/// </summary>
public static class DownloadExtentions
{
/// <summary>
/// The <see cref="DownloadStreamingAsync(CallingServerClient, Uri, HttpRange, CancellationToken)"/>
/// operation downloads the recording's content.
///
/// </summary>
/// <param name="callingServerClient">
/// The Azure Communication Services Calling Server client.
/// </param>
/// <param name="sourceEndpoint">
/// Recording's content's url location.
/// </param>
/// <param name="range">
/// If provided, only download the bytes of the content in the specified range.
/// If not provided, download the entire content.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{Stream}"/> containing the
/// downloaded content.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public static async Task<Response<Stream>> DownloadStreamingAsync(
this CallingServerClient callingServerClient,
Uri sourceEndpoint,
HttpRange range = default,
CancellationToken cancellationToken = default) =>
await callingServerClient._contentDownloader.DownloadStreamingInternal(
sourceEndpoint,
range,
async: true,
cancellationToken)
.ConfigureAwait(false);

/// <summary>
/// The <see cref="DownloadStreaming(CallingServerClient, Uri, HttpRange, CancellationToken)"/>
/// operation downloads the recording's content.
///
/// </summary>
/// <param name="callingServerClient">
/// The Azure Communication Services Calling Server client.
/// </param>
/// <param name="sourceEndpoint">
/// Recording's content's url location.
/// </param>
/// <param name="range">
/// If provided, only download the bytes of the content in the specified range.
/// If not provided, download the entire content.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{Stream}"/> containing the
/// downloaded content.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public static Response<Stream> DownloadStreaming(
this CallingServerClient callingServerClient,
Uri sourceEndpoint,
HttpRange range = default,
CancellationToken cancellationToken = default) =>
callingServerClient._contentDownloader.DownloadStreamingInternal(
sourceEndpoint,
range,
async: false,
cancellationToken)
.EnsureCompleted();

/// <summary>
/// The <see cref="DownloadTo(CallingServerClient, Uri, Stream, ContentTransferOptions, CancellationToken)"/>
/// operation downloads the specified content using parallel requests,
/// and writes the content to <paramref name="destinationStream"/>.
/// </summary>
/// <param name="callingServerClient">
/// The Azure Communication Services Calling Server client.
/// </param>
/// <param name="sourceEndpoint">
/// A <see cref="Uri"/> with the Recording's content's url location.
/// </param>
/// <param name="destinationStream">
/// A <see cref="Stream"/> to write the downloaded content to.
/// </param>
/// <param name="transferOptions">
/// Optional <see cref="ContentTransferOptions"/> to configure
/// parallel transfer behavior.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> describing the operation.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public static Response DownloadTo(this CallingServerClient callingServerClient, Uri sourceEndpoint, Stream destinationStream,
ContentTransferOptions transferOptions = default, CancellationToken cancellationToken = default) =>
callingServerClient._contentDownloader.StagedDownloadAsync(sourceEndpoint, destinationStream, transferOptions, async: false, cancellationToken: cancellationToken).EnsureCompleted();

/// <summary>
/// The <see cref="DownloadToAsync(CallingServerClient, Uri, Stream, ContentTransferOptions, CancellationToken)"/>
/// operation downloads the specified content using parallel requests,
/// and writes the content to <paramref name="destinationStream"/>.
/// </summary>
/// <param name="callingServerClient">
/// The Azure Communication Services Calling Server client.
/// </param>
/// <param name="sourceEndpoint">
/// A <see cref="Uri"/> with the Recording's content's url location.
/// </param>
/// <param name="destinationStream">
/// A <see cref="Stream"/> to write the downloaded content to.
/// </param>
/// <param name="transferOptions">
/// Optional <see cref="ContentTransferOptions"/> to configure
/// parallel transfer behavior.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> describing the operation.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public static async Task<Response> DownloadToAsync(this CallingServerClient callingServerClient, Uri sourceEndpoint, Stream destinationStream, ContentTransferOptions transferOptions = default, CancellationToken cancellationToken = default) =>
await callingServerClient._contentDownloader.StagedDownloadAsync(sourceEndpoint, destinationStream, transferOptions, async: true, cancellationToken: cancellationToken).ConfigureAwait(false);

/// <summary>
/// The <see cref="DownloadTo(CallingServerClient, Uri, string, ContentTransferOptions, CancellationToken)"/>
/// operation downloads the specified content using parallel requests,
/// and writes the content to <paramref name="destinationPath"/>.
/// </summary>
/// <param name="callingServerClient">
/// The Azure Communication Services Calling Server client.
/// </param>
/// <param name="sourceEndpoint">
/// A <see cref="Uri"/> with the Recording's content's url location.
/// </param>
/// <param name="destinationPath">
/// A file path to write the downloaded content to.
/// </param>
/// <param name="transferOptions">
/// Optional <see cref="ContentTransferOptions"/> to configure
/// parallel transfer behavior.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> describing the operation.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public static Response DownloadTo(this CallingServerClient callingServerClient, Uri sourceEndpoint, string destinationPath,
ContentTransferOptions transferOptions = default, CancellationToken cancellationToken = default)
{
using Stream destination = File.Create(destinationPath);
return callingServerClient._contentDownloader.StagedDownloadAsync(sourceEndpoint, destination, transferOptions,
async: false, cancellationToken: cancellationToken).EnsureCompleted();
}

/// <summary>
/// The <see cref="DownloadToAsync(CallingServerClient, Uri, string, ContentTransferOptions, CancellationToken)"/>
/// operation downloads the specified content using parallel requests,
/// and writes the content to <paramref name="destinationPath"/>.
/// </summary>
/// <param name="callingServerClient">
/// The Azure Communication Services Calling Server client.
/// </param>
/// <param name="sourceEndpoint">
/// A <see cref="Uri"/> with the Recording's content's url location.
/// </param>
/// <param name="destinationPath">
/// A file path to write the downloaded content to.
/// </param>
/// <param name="transferOptions">
/// Optional <see cref="ContentTransferOptions"/> to configure
/// parallel transfer behavior.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response"/> describing the operation.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// </remarks>
public static async Task<Response> DownloadToAsync(this CallingServerClient callingServerClient, Uri sourceEndpoint, string destinationPath,
ContentTransferOptions transferOptions = default, CancellationToken cancellationToken = default)
{
using Stream destination = File.Create(destinationPath);
return await callingServerClient._contentDownloader.StagedDownloadAsync(sourceEndpoint, destination, transferOptions,
async: true, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal class PartitionedDownloader
/// <summary>
/// The client used to download the blob.
/// </summary>
private readonly ConversationClient _client;
private readonly CallingServerClient _client;

/// <summary>
/// The maximum number of simultaneous workers.
Expand All @@ -34,7 +34,7 @@ internal class PartitionedDownloader
private readonly long _rangeSize;

internal PartitionedDownloader(
ConversationClient client,
CallingServerClient client,
ContentTransferOptions transferOptions = default)
{
_client = client;
Expand Down
Loading