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

Added call connection Id for recording and live and unit test code. #47646

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -56,16 +55,24 @@ public virtual Response<RecordingStateResult> Start(StartRecordingOptions option
scope.Start();
try
{
StartCallRecordingRequestInternal request = new()
var request = new StartCallRecordingRequestInternal()
{
CallLocator = CallLocatorSerializer.Serialize(options.CallLocator),
RecordingStateCallbackUri = options.RecordingStateCallbackUri?.AbsoluteUri,
RecordingChannelType = options.RecordingChannel,
RecordingContentType = options.RecordingContent,
RecordingFormatType = options.RecordingFormat,
PauseOnStart = options.PauseOnStart,
PauseOnStart = options.PauseOnStart
};

if (options.CallLocator != null)
{
request.CallLocator = CallLocatorSerializer.Serialize(options.CallLocator);
}
else if (options.CallConnectionId != null)
{
request.CallConnectionId = options.CallConnectionId;
}

if (options.AudioChannelParticipantOrdering != null && options.AudioChannelParticipantOrdering.Any())
{
foreach (var c in options.AudioChannelParticipantOrdering)
Expand Down Expand Up @@ -119,16 +126,24 @@ public virtual async Task<Response<RecordingStateResult>> StartAsync(StartRecord
scope.Start();
try
{
StartCallRecordingRequestInternal request = new()
var request = new StartCallRecordingRequestInternal()
{
CallLocator = CallLocatorSerializer.Serialize(options.CallLocator),
RecordingStateCallbackUri = options.RecordingStateCallbackUri?.AbsoluteUri,
RecordingChannelType = options.RecordingChannel,
RecordingContentType = options.RecordingContent,
RecordingFormatType = options.RecordingFormat,
PauseOnStart = options.PauseOnStart,
PauseOnStart = options.PauseOnStart
};

if (options.CallLocator != null)
{
request.CallLocator = CallLocatorSerializer.Serialize(options.CallLocator);
}
else if (options.CallConnectionId != null)
{
request.CallConnectionId = options.CallConnectionId;
}

if (options.AudioChannelParticipantOrdering != null && options.AudioChannelParticipantOrdering.Any())
{
foreach (var c in options.AudioChannelParticipantOrdering)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ private static CallAutomationEventBase Deserialize(string eventData, string type
return ParticipantsUpdated.Deserialize(eventData);
case nameof(RecordingStateChanged):
return RecordingStateChanged.Deserialize(eventData);
case nameof(StartRecordingFailed):
return StartRecordingFailed.Deserialize(eventData);
case nameof(PlayCompleted):
return PlayCompleted.Deserialize(eventData);
case nameof(PlayFailed):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Text.Json;
using Azure.Core;

namespace Azure.Communication.CallAutomation
{
/// <summary>
/// The StartRecordingFailed event.
/// </summary>

[CodeGenModel("StartRecordingFailed", Usage = new string[] { "output" }, Formats = new string[] { "json" })]
public partial class StartRecordingFailed : CallAutomationEventBase
{
/// <summary>
/// Reason code.
/// </summary>
public MediaEventReasonCode ReasonCode { get; internal set; }

/// <summary>
/// Deserialize <see cref="StartRecordingFailed"/> event.
/// </summary>
/// <param name="content">The json content.</param>
/// <returns>The new <see cref="StartRecordingFailed"/> object.</returns>
public static StartRecordingFailed Deserialize(string content)
{
using var document = JsonDocument.Parse(content);
JsonElement element = document.RootElement;

return DeserializeStartRecordingFailed(element);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
Expand All @@ -17,14 +17,28 @@ public class StartRecordingOptions
/// <param name="callLocator"> . </param>
public StartRecordingOptions(CallLocator callLocator)
{
CallLocator = callLocator ?? throw new ArgumentNullException(nameof(callLocator));
CallLocator = callLocator;
}

/// <summary>
/// Parameters for the Start Recording operation.
/// </summary>
/// <param name="callConnectionId"> . </param>
public StartRecordingOptions(string callConnectionId)
{
CallConnectionId = callConnectionId;
}

/// <summary>
/// The callLocator.
/// </summary>
internal CallLocator CallLocator { get; }

/// <summary>
/// The call connection id.
/// </summary>
internal string CallConnectionId { get; }

/// <summary>
/// The callLocator.
/// </summary>
Expand Down Expand Up @@ -72,4 +86,4 @@ public StartRecordingOptions(CallLocator callLocator)
/// </summary>
public IList<ChannelAffinity> ChannelAffinity { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public CallRecordingAutomatedLiveTests(bool isAsync) : base(isAsync)
{
}

[Ignore (reason: "Recording is currently broken with error Removing modality controller as this conversation has ended. Waiting on fix for this")]
//[Ignore (reason: "Recording is currently broken with error Removing modality controller as this conversation has ended. Waiting on fix for this")]
[RecordedTest]
public async Task RecordingOperationsTest()
{
Expand Down Expand Up @@ -213,7 +213,6 @@ public async Task CreateACSCallAndUnmixedAudioTest()
}
}

[Ignore(reason: "Recording is currently broken with error Removing modality controller as this conversation has ended. Waiting on fix for this")]
[RecordedTest]
public async Task CreateACSCallUnmixedAudioAffinityTest()
{
Expand Down Expand Up @@ -312,5 +311,102 @@ public async Task CreateACSCallUnmixedAudioAffinityTest()
await CleanUpCall(client, callConnectionId, uniqueId);
}
}

[Ignore(reason: "Recording is currently broken with error Removing modality controller as this conversation has ended. Waiting on fix for this")]
[RecordedTest]
public async Task StartRecordingWithCallConnectionIdTest()
{
// create caller and receiver
var target = await CreateIdentityUserAsync().ConfigureAwait(false);
var user = await CreateIdentityUserAsync().ConfigureAwait(false);

CallAutomationClient client = CreateInstrumentedCallAutomationClientWithConnectionString(user);
CallAutomationClient targetClient = CreateInstrumentedCallAutomationClientWithConnectionString(target);
bool stopRecording = false;

// setup service bus
var uniqueId = await ServiceBusWithNewCall(user, target);

// create call and assert response
var createCallOptions = new CreateCallOptions(new CallInvite(target), new Uri(TestEnvironment.DispatcherCallback + $"?q={uniqueId}"));
CreateCallResult response = await client.CreateCallAsync(createCallOptions).ConfigureAwait(false);
string callConnectionId = response.CallConnectionProperties.CallConnectionId;
Assert.IsNotEmpty(response.CallConnectionProperties.CallConnectionId);

// wait for incomingcall context
string? incomingCallContext = await WaitForIncomingCallContext(uniqueId, TimeSpan.FromSeconds(20));
Assert.IsNotNull(incomingCallContext);

// answer the call
var answerCallOptions = new AnswerCallOptions(incomingCallContext, new Uri(TestEnvironment.DispatcherCallback));
var answerResponse = await targetClient.AnswerCallAsync(answerCallOptions);
Assert.AreEqual(answerResponse.GetRawResponse().Status, StatusCodes.Status200OK);

// wait for callConnected
var connectedEvent = await WaitForEvent<CallConnected>(callConnectionId, TimeSpan.FromSeconds(20));
Assert.IsNotNull(connectedEvent);
Assert.IsTrue(connectedEvent is CallConnected);
Assert.IsTrue(((CallConnected)connectedEvent!).CallConnectionId == callConnectionId);

// test get properties
Response<CallConnectionProperties> properties = await response.CallConnection.GetCallConnectionPropertiesAsync().ConfigureAwait(false);
Assert.AreEqual(CallConnectionState.Connected, properties.Value.CallConnectionState);

var serverCallId = properties.Value.ServerCallId;

CallRecording callRecording = client.GetCallRecording();
StartRecordingOptions recordingOptions = new StartRecordingOptions(callConnectionId)
{
RecordingStateCallbackUri = new Uri(TestEnvironment.DispatcherCallback)
};
var recordingResponse = await callRecording.StartAsync(recordingOptions).ConfigureAwait(false);
Assert.NotNull(recordingResponse.Value);

var recordingId = recordingResponse.Value.RecordingId;
Assert.NotNull(recordingId);
await WaitForOperationCompletion().ConfigureAwait(false);

recordingResponse = await callRecording.GetStateAsync(recordingId).ConfigureAwait(false);
Assert.NotNull(recordingResponse.Value);
Assert.NotNull(recordingResponse.Value.RecordingState);
Assert.AreEqual(recordingResponse.Value.RecordingState, RecordingState.Active);

await callRecording.PauseAsync(recordingId);
await WaitForOperationCompletion().ConfigureAwait(false);
recordingResponse = await callRecording.GetStateAsync(recordingId).ConfigureAwait(false);
Assert.NotNull(recordingResponse.Value);
Assert.NotNull(recordingResponse.Value.RecordingState);
Assert.AreEqual(recordingResponse.Value.RecordingState, RecordingState.Inactive);

await callRecording.ResumeAsync(recordingId);
await WaitForOperationCompletion().ConfigureAwait(false);
recordingResponse = await callRecording.GetStateAsync(recordingId).ConfigureAwait(false);
Assert.NotNull(recordingResponse.Value);
Assert.NotNull(recordingResponse.Value.RecordingState);
Assert.AreEqual(recordingResponse.Value.RecordingState, RecordingState.Active);

await callRecording.StopAsync(recordingId);
await WaitForOperationCompletion().ConfigureAwait(false);
stopRecording = true;

try
{
recordingResponse = await callRecording.GetStateAsync(recordingId).ConfigureAwait(false);
}
catch (RequestFailedException ex)
{
if (ex.Status == 404 && stopRecording)
{
// recording stopped successfully
return;
}

Assert.Fail($"Unexpected error: {ex}");
}
finally
{
await CleanUpCall(client, callConnectionId, uniqueId);
}
}
}
}
Loading
Loading