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

feat: [breaking] add connection and socket timeouts on voice application #548

Merged
merged 14 commits into from
Mar 13, 2024
Merged
287 changes: 190 additions & 97 deletions Vonage.Test/ApplicationTests.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"capabilities": {
"voice": {
"webhooks": {
"answer_url": {
"http_method": "GET",
"address": "https://example.com/webhooks/answer",
"connection_timeout": 300,
"socket_timeout": 2000
},
"event_url": {
"http_method": "POST",
"address": "https://example.com/webhooks/events",
"connection_timeout": 500,
"socket_timeout": 3000
},
"fallback_answer_url": {
"http_method": "GET",
"address": "https://fallback.example.com/webhooks/answer",
"connection_timeout": 800,
"socket_timeout": 4000
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"capabilities": {
"voice": {
"webhooks": {
"answer_url": {
"http_method": "GET",
"address": "https://example.com/webhooks/answer",
"connection_timeout": 300,
"socket_timeout": 2000
},
"event_url": {
"http_method": "POST",
"address": "https://example.com/webhooks/events",
"connection_timeout": 500,
"socket_timeout": 3000
},
"fallback_answer_url": {
"http_method": "GET",
"address": "https://fallback.example.com/webhooks/answer",
"connection_timeout": 800,
"socket_timeout": 4000
}
}
}
}
}
9 changes: 9 additions & 0 deletions Vonage.Test/Vonage.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,12 @@
<None Update="Data\ApplicationTests\CreateApplicationAsyncWithPrivacySettings-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Data\ApplicationTests\CreateApplicationAsyncWithVoiceTimeouts-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Data\ApplicationTests\CreateApplicationAsyncWithVoiceTimeouts-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\StartVerification\Data\ShouldSerializeSilentAuthWorkflowWithRedirectUrl-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down Expand Up @@ -1092,6 +1098,9 @@
<None Update="Conversations\GetUserConversations\Data\ShouldDeserialize200-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Data\ApplicationTests\CreateApplicationAsyncWithVoiceTimeouts-response.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="VerifyV2\StartVerification\Data\ShouldSerializeSmsWorkflowWithOptionalValues-request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
2 changes: 1 addition & 1 deletion Vonage/Applications/Capabilities/Capability.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public abstract class Capability

[JsonIgnore] protected CapabilityType Type { get; set; }

protected enum CapabilityType
public enum CapabilityType
{
[Description("voice")] Voice,
[Description("rtc")] Rtc,
Expand Down
59 changes: 52 additions & 7 deletions Vonage/Applications/Capabilities/Voice.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Vonage.Common;
using Newtonsoft.Json.Converters;
using Vonage.Serialization;

namespace Vonage.Applications.Capabilities;

public class Voice : Capability
/// <summary>
/// Represents Voice capabilities.
/// </summary>
public class Voice
{
/// <summary>
/// The length of time named conversations will remain active for after creation, in hours. 0 means infinite. Maximum
Expand All @@ -28,9 +35,47 @@ public class Voice : Capability
[JsonProperty("signed_callbacks", Order = 1)]
public bool SignedCallbacks { get; set; }

public Voice(IDictionary<Webhook.Type, Webhook> webhooks)
{
this.Webhooks = webhooks;
this.Type = CapabilityType.Voice;
}
/// <summary>
/// Represents the collection of Webhook URLs with their configuration.
/// </summary>
[JsonProperty("webhooks")]
public IDictionary<VoiceWebhookType, VoiceWebhook> Webhooks { get; set; }

/// <summary>
/// Represents a webhook for Voice API.
/// </summary>
/// <param name="Address">The webhook address.</param>
/// <param name="Method">Must be one of GET or POST.</param>
/// <param name="ConnectionTimeout">If Vonage can't connect to the webhook URL for this specified amount of time, then Vonage makes one additional attempt to connect to the webhook endpoint. This is an integer value specified in milliseconds.</param>
/// <param name="SocketTimeout">If a response from the webhook URL can't be read for this specified amount of time, then Vonage makes one additional attempt to read the webhook endpoint. This is an integer value specified in milliseconds.</param>
public record VoiceWebhook(
[property: JsonProperty("address", Order = 1)]
Uri Address,
[property: JsonProperty("http_method", Order = 0)]
[property: JsonConverter(typeof(HttpMethodConverter))]
HttpMethod Method,
[property: JsonProperty("connection_timeout", Order = 2)]
int ConnectionTimeout = 0,
[property: JsonProperty("socket_timeout", Order = 3)]
int SocketTimeout = 0);
}

/// <summary>
/// Represents various Webhook urls.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum VoiceWebhookType
{
/// <summary>
/// </summary>
[EnumMember(Value = "answer_url")] AnswerUrl = 0,

/// <summary>
/// </summary>
[EnumMember(Value = "event_url")] EventUrl = 1,

/// <summary>
/// </summary>
[EnumMember(Value = "fallback_answer_url")]
FallbackAnswerUrl = 2,
}
35 changes: 11 additions & 24 deletions Vonage/Common/Webhook.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,33 @@
using System.Runtime.Serialization;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Vonage.Common;

public class Webhook
{
[JsonProperty("http_method")]
[JsonProperty("address", Order = 1)] public string Address { get; set; }

[JsonProperty("http_method", Order = 0)]
public string Method { get; set; }

[JsonProperty("address")]
public string Address { get; set; }

[JsonConverter(typeof(StringEnumConverter))]
public enum Type
{
[EnumMember(Value = "answer_url")]
AnswerUrl = 1,
[EnumMember(Value = "event_url")] EventUrl = 2,

[EnumMember(Value = "event_url")]
EventUrl = 2,
[EnumMember(Value = "inbound_url")] InboundUrl = 3,

[EnumMember(Value = "inbound_url")]
InboundUrl = 3,
[EnumMember(Value = "status_url")] StatusUrl = 4,

[EnumMember(Value = "status_url")]
StatusUrl = 4,
[EnumMember(Value = "Unknown")] Unknown = 6,

[EnumMember(Value = "fallback_answer_url")]
FallbackAnswerUrl = 5,
[EnumMember(Value = "room_changed")] RoomChanged = 7,

[EnumMember(Value = "Unknown")]
Unknown = 6,

[EnumMember(Value = "room_changed")]
RoomChanged =7,

[EnumMember(Value = "session_changed")]
SessionChanged=8,
SessionChanged = 8,

[EnumMember(Value = "recording_changed")]
RecordingChanged = 9,
}

}
29 changes: 29 additions & 0 deletions Vonage/Serialization/HttpMethodConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Net.Http;
using Newtonsoft.Json;

namespace Vonage.Serialization;

/// <summary>
/// Converter from HttpMethod to Json.
/// </summary>
public class HttpMethodConverter : JsonConverter
{
/// <inheritdoc />
public override bool CanConvert(Type objectType) => objectType == typeof(HttpMethod);

/// <inheritdoc />
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return new HttpMethod((string) reader.Value);
}

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is null || !this.CanConvert(value.GetType()))
writer.WriteNull();
else
writer.WriteValue(((HttpMethod) value).Method);
}
}
Loading