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

make repeatabilityHeaders internal and generated automatically #33965

Merged
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
37 changes: 1 addition & 36 deletions sdk/communication/Azure.Communication.CallAutomation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,41 +113,6 @@ Your app will receive mid-connection call back events via the callbackEndpoint y
return Ok();
}
```
### Idempotent Requests
An operation is idempotent if it can be performed multiple times and have the same result as a single execution.

The following operations are idempotent:
- `AnswerCall`
- `RedirectCall`
- `RejectCall`
- `CreateCall`
- `HangUp` when terminating the call for everyone, ie. `forEveryone` parameter is set to `true`.
- `TransferCallToParticipant`
- `AddParticipants`
- `RemoveParticipants`
- `StartRecording`

By default, SDK generates a new `RepeatabilityHeaders` object every time the above operation is called. If you would
like to provide your own `RepeatabilityHeaders` for your application (eg. for your own retry mechanism), you can do so by specifying
the `RepeatabilityHeaders` in the operation's `Options` object. If this is not set by user, then the SDK will generate
it. You can also disable this by setting `RepeatabilityHeaders` to NULL in the option.

The parameters for the `RepeatabilityHeaders` class are `repeatabilityRequestId` and `repeatabilityFirstSent`. Two or
more requests are considered the same request **if and only if** both repeatability parameters are the same.
- `repeatabilityRequestId`: an opaque string representing a client-generated unique identifier for the request.
It is a version 4 (random) UUID.
- `repeatabilityFirstSent`: The value should be the date and time at which the request was **first** created.

To set repeatability parameters, see below C# code snippet as an example:
```C#
var createCallOptions = new CreateCallOptions(callSource, new CommunicationIdentifier[] { target }, new Uri("https://exmaple.com/callback")) {
RepeatabilityHeaders = new RepeatabilityHeaders(Guid.NewGuid(), DateTimeOffset.UtcNow);
};
CreateCallResult response1 = await callAutomationClient.CreateCallAsync(createCallOptions).ConfigureAwait(false);
await Task.Delay(5000);
CreateCallResult response2 = await callAutomationClient.CreateCallAsync(createCallOptions).ConfigureAwait(false);
// response1 and response2 will have the same CallConnectionId as they have the same reapeatability parameters which means that the CreateCall operation was only executed once.
```

## Troubleshooting
A `RequestFailedException` is thrown as a service response for any unsuccessful requests. The exception contains information about what response code was returned from the service.
Expand Down Expand Up @@ -188,4 +153,4 @@ This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For m
[build3]: https://learn.microsoft.com/azure/communication-services/quickstarts/voice-video-calling/play-action?pivots=programming-language-csharp
[build4]: https://learn.microsoft.com/azure/communication-services/quickstarts/voice-video-calling/recognize-action?pivots=programming-language-csharp
[recording1]: https://learn.microsoft.com/azure/communication-services/concepts/voice-video-calling/call-recording
[recording2]: https://learn.microsoft.com/azure/communication-services/quickstarts/voice-video-calling/get-started-call-recording?pivots=programming-language-csharp
[recording2]: https://learn.microsoft.com/azure/communication-services/quickstarts/voice-video-calling/get-started-call-recording?pivots=programming-language-csharp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public AddParticipantsOptions(System.Collections.Generic.IEnumerable<Azure.Commu
public int? InvitationTimeoutInSeconds { get { throw null; } set { } }
public string OperationContext { get { throw null; } set { } }
public System.Collections.Generic.IEnumerable<Azure.Communication.CommunicationIdentifier> ParticipantsToAdd { get { throw null; } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
public System.Collections.Generic.IDictionary<string, string> SipHeaders { get { throw null; } set { } }
public Azure.Communication.PhoneNumberIdentifier SourceCallerId { get { throw null; } set { } }
public string SourceDisplayName { get { throw null; } set { } }
Expand Down Expand Up @@ -50,7 +49,6 @@ public AnswerCallOptions(string incomingCallContext, System.Uri callbackUri) { }
public System.Uri CallbackUri { get { throw null; } }
public string IncomingCallContext { get { throw null; } }
public Azure.Communication.CallAutomation.MediaStreamingOptions MediaStreamingOptions { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
}
public partial class AnswerCallResult : Azure.Communication.CallAutomation.ResultWithWaitForEventBase
{
Expand Down Expand Up @@ -417,7 +415,6 @@ public CreateCallOptions(Azure.Communication.CallAutomation.CallSource callSourc
public Azure.Communication.CallAutomation.CallSource CallSource { get { throw null; } }
public Azure.Communication.CallAutomation.MediaStreamingOptions MediaStreamingOptions { get { throw null; } set { } }
public string OperationContext { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
public System.Collections.Generic.IReadOnlyList<Azure.Communication.CommunicationIdentifier> Targets { get { throw null; } }
}
public partial class CreateCallResult : Azure.Communication.CallAutomation.ResultWithWaitForEventBase
Expand Down Expand Up @@ -513,7 +510,6 @@ public partial class HangUpOptions
{
public HangUpOptions(bool forEveryone) { }
public bool ForEveryone { get { throw null; } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct MediaStreamingAudioChannel : System.IEquatable<Azure.Communication.CallAutomation.MediaStreamingAudioChannel>
Expand Down Expand Up @@ -619,7 +615,6 @@ public partial class MuteParticipantsOptions
{
public MuteParticipantsOptions(System.Collections.Generic.IEnumerable<Azure.Communication.CommunicationIdentifier> targetParticipants) { }
public string OperationContext { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
public System.Collections.Generic.IEnumerable<Azure.Communication.CommunicationIdentifier> TargetParticipants { get { throw null; } }
}
public partial class MuteParticipantsResponse
Expand Down Expand Up @@ -855,35 +850,25 @@ public partial class RedirectCallOptions
{
public RedirectCallOptions(string incomingCallContext, Azure.Communication.CommunicationIdentifier target) { }
public string IncomingCallContext { get { throw null; } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
public Azure.Communication.CommunicationIdentifier Target { get { throw null; } }
}
public partial class RejectCallOptions
{
public RejectCallOptions(string incomingCallContext) { }
public Azure.Communication.CallAutomation.CallRejectReason CallRejectReason { get { throw null; } set { } }
public string IncomingCallContext { get { throw null; } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
}
public partial class RemoveParticipantsOptions
{
public RemoveParticipantsOptions(System.Collections.Generic.IEnumerable<Azure.Communication.CommunicationIdentifier> participantsToRemove) { }
public string OperationContext { get { throw null; } set { } }
public System.Collections.Generic.IReadOnlyList<Azure.Communication.CommunicationIdentifier> ParticipantsToRemove { get { throw null; } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
}
public partial class RemoveParticipantsResult
{
internal RemoveParticipantsResult() { }
public string OperationContext { get { throw null; } }
}
public partial class RepeatabilityHeaders
{
public RepeatabilityHeaders() { }
public RepeatabilityHeaders(System.Guid repeatabilityRequestId, System.DateTimeOffset repeatabilityFirstSent) { }
public System.DateTimeOffset RepeatabilityFirstSent { get { throw null; } }
public System.Guid RepeatabilityRequestId { get { throw null; } }
}
public partial class ResultInformation
{
internal ResultInformation() { }
Expand Down Expand Up @@ -923,7 +908,6 @@ public StartRecordingOptions(Azure.Communication.CallAutomation.CallLocator call
public Azure.Communication.CallAutomation.RecordingFormat RecordingFormat { get { throw null; } set { } }
public System.Uri RecordingStateCallbackEndpoint { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RecordingStorageType? RecordingStorageType { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
}
public partial class TextSource : Azure.Communication.CallAutomation.PlaySource
{
Expand Down Expand Up @@ -951,7 +935,6 @@ public partial class TransferToParticipantOptions
{
public TransferToParticipantOptions(Azure.Communication.CommunicationIdentifier targetParticipant) { }
public string OperationContext { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
public Azure.Communication.PhoneNumberIdentifier SourceCallerId { get { throw null; } set { } }
public Azure.Communication.CommunicationIdentifier TargetParticipant { get { throw null; } }
public string UserToUserInformation { get { throw null; } set { } }
Expand All @@ -960,7 +943,6 @@ public partial class UnmuteParticipantsOptions
{
public UnmuteParticipantsOptions(System.Collections.Generic.IEnumerable<Azure.Communication.CommunicationIdentifier> targetParticipant) { }
public string OperationContext { get { throw null; } set { } }
public Azure.Communication.CallAutomation.RepeatabilityHeaders RepeatabilityHeaders { get { throw null; } set { } }
public System.Collections.Generic.IEnumerable<Azure.Communication.CommunicationIdentifier> TargetParticipants { get { throw null; } }
}
public partial class UnmuteParticipantsResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ public virtual async Task<Response<AnswerCallResult>> AnswerCallAsync(AnswerCall
if (options == null) throw new ArgumentNullException(nameof(options));

AnswerCallRequestInternal request = CreateAnswerCallRequest(options);
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

var answerResponse = await AzureCommunicationServicesRestClient.AnswerCallAsync(request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
cancellationToken)
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken)
.ConfigureAwait(false);

var result = new AnswerCallResult(GetCallConnection(answerResponse.Value.CallConnectionId), new CallConnectionProperties(answerResponse.Value));
Expand Down Expand Up @@ -194,11 +194,11 @@ public virtual Response<AnswerCallResult> AnswerCall(AnswerCallOptions options,
if (options == null) throw new ArgumentNullException(nameof(options));

AnswerCallRequestInternal request = CreateAnswerCallRequest(options);
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

var answerResponse = AzureCommunicationServicesRestClient.AnswerCall(request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken);

var result = new AnswerCallResult(GetCallConnection(answerResponse.Value.CallConnectionId), new CallConnectionProperties(answerResponse.Value));
Expand Down Expand Up @@ -267,12 +267,12 @@ public virtual async Task<Response> RedirectCallAsync(RedirectCallOptions option
throw new ArgumentNullException(nameof(options));

RedirectCallRequestInternal request = new RedirectCallRequestInternal(options.IncomingCallContext, CommunicationIdentifierSerializer.Serialize(options.Target));
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

return await AzureCommunicationServicesRestClient.RedirectCallAsync(
request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken
).ConfigureAwait(false);
}
Expand Down Expand Up @@ -313,12 +313,12 @@ public virtual Response RedirectCall(RedirectCallOptions options, CancellationTo
throw new ArgumentNullException(nameof(options));

RedirectCallRequestInternal request = new RedirectCallRequestInternal(options.IncomingCallContext, CommunicationIdentifierSerializer.Serialize(options.Target));
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

return AzureCommunicationServicesRestClient.RedirectCall(
request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken);
}
catch (Exception ex)
Expand Down Expand Up @@ -357,12 +357,12 @@ public virtual async Task<Response> RejectCallAsync(RejectCallOptions options, C

RejectCallRequestInternal request = new RejectCallRequestInternal(options.IncomingCallContext);
request.CallRejectReason = options.CallRejectReason.ToString();
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

return await AzureCommunicationServicesRestClient.RejectCallAsync(
request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken
).ConfigureAwait(false);
}
Expand Down Expand Up @@ -402,12 +402,12 @@ public virtual Response RejectCall(RejectCallOptions options, CancellationToken

RejectCallRequestInternal request = new RejectCallRequestInternal(options.IncomingCallContext);
request.CallRejectReason = options.CallRejectReason.ToString();
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

return AzureCommunicationServicesRestClient.RejectCall(
request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken
);
}
Expand Down Expand Up @@ -438,12 +438,12 @@ public virtual async Task<Response<CreateCallResult>> CreateCallAsync(CreateCall
throw new ArgumentNullException(nameof(options));

CreateCallRequestInternal request = CreateCallRequest(options);
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

var createCallResponse = await AzureCommunicationServicesRestClient.CreateCallAsync(
request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken
).ConfigureAwait(false);

Expand Down Expand Up @@ -482,12 +482,12 @@ public virtual Response<CreateCallResult> CreateCall(CreateCallOptions options,
if (options == null) throw new ArgumentNullException(nameof(options));

CreateCallRequestInternal request = CreateCallRequest(options);
options.RepeatabilityHeaders?.GenerateIfRepeatabilityHeadersNotProvided();
var repeatabilityHeaders = new RepeatabilityHeaders();

var createCallResponse = AzureCommunicationServicesRestClient.CreateCall(
request,
options.RepeatabilityHeaders?.RepeatabilityRequestId,
options.RepeatabilityHeaders?.GetRepeatabilityFirstSentString(),
repeatabilityHeaders.RepeatabilityRequestId,
repeatabilityHeaders.GetRepeatabilityFirstSentString(),
cancellationToken
);

Expand Down
Loading