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/add methods to root of numbers #81

Merged
merged 8 commits into from
Aug 20, 2024
2 changes: 1 addition & 1 deletion examples/Console/ListActiveNumbers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public async Task Example()
Environment.GetEnvironmentVariable("SINCH_KEY_ID")!,
Environment.GetEnvironmentVariable("SINCH_KEY_SECRET")!
);
ListActiveNumbersResponse response = await sinch.Numbers.Active.List(new ListActiveNumbersRequest
ListActiveNumbersResponse response = await sinch.Numbers.List(new ListActiveNumbersRequest
{
RegionCode = "US",
Type = Types.Mobile
Expand Down
2 changes: 1 addition & 1 deletion examples/Console/RentAndConfigureNumbers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class RentAndConfigureNumbers
public static async Task Example()
{
var sinchClient = new SinchClient("PROJECT_ID", "KEY_ID", "KEY_SECRET");
var response = await sinchClient.Numbers.Available.Rent("+4811111111", new RentActiveNumberRequest()
var response = await sinchClient.Numbers.Rent("+4811111111", new RentActiveNumberRequest()
{
SmsConfiguration = new SmsConfiguration
{
Expand Down
7 changes: 6 additions & 1 deletion src/Sinch/Core/Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Http(ISinchAuth auth, HttpClient httpClient, ILoggerAdapter<IHttp>? logge
public Task<TResponse> Send<TResponse>(Uri uri, HttpMethod httpMethod,
CancellationToken cancellationToken = default, Dictionary<string, IEnumerable<string>>? headers = null)
{
return Send<object, TResponse>(uri, httpMethod, null, cancellationToken, headers);
return Send<object, TResponse>(uri, httpMethod, null!, cancellationToken, headers);
}

public async Task<TResponse> Send<TRequest, TResponse>(Uri uri, HttpMethod httpMethod, TRequest request,
Expand Down Expand Up @@ -205,6 +205,11 @@ private static void AddOrOverrideHeaders(HttpRequestMessage msg,
bytes = await msg.Content.ReadAsByteArrayAsync(cancellationToken);
}

if (msg.RequestUri is null)
{
throw new NullReferenceException("HttpRequestMessage request uri is null");
}

token = appSignAuth.GetSignedAuth(
bytes,
msg.Method.ToString().ToUpperInvariant(), msg.RequestUri.PathAndQuery,
Expand Down
19 changes: 16 additions & 3 deletions src/Sinch/Numbers/Active.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public interface ISinchNumbersActive
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.List)} instead.")]
Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request,
CancellationToken cancellationToken = default);

Expand All @@ -37,7 +39,7 @@ Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request,
/// scheduled provisioning status. You can also update the type of number, currency type and amount. Note: You cannot
/// add both objects if you only need to update one object. For example, if you only need to reconfigure
/// smsConfiguration for SMS messaging,
/// do not add the voiceConfiguration object or it will result in an error.
/// do not add the voiceConfiguration object, or it will result in an error.
/// </summary>
/// <param name="phoneNumber">
/// Output only. The phone number in
Expand All @@ -46,6 +48,8 @@ Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request,
/// <param name="request">A request object</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.Update)} instead.")]
Task<ActiveNumber> Update(string phoneNumber,
UpdateActiveNumberRequest request, CancellationToken cancellationToken = default);

Expand All @@ -55,6 +59,8 @@ Task<ActiveNumber> Update(string phoneNumber,
/// <param name="phoneNumber">Number to get info about</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.Get)} instead.")]
Task<ActiveNumber> Get(string phoneNumber,
CancellationToken cancellationToken = default);

Expand All @@ -68,9 +74,13 @@ Task<ActiveNumber> Get(string phoneNumber,
/// </param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.Release)} instead.")]
Task<ActiveNumber> Release(
string phoneNumber, CancellationToken cancellationToken = default);

[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.ListAuto)} instead.")]
IAsyncEnumerable<ActiveNumber> ListAuto(ListActiveNumbersRequest request,
CancellationToken cancellationToken = default);
}
Expand All @@ -91,7 +101,9 @@ public ActiveNumbers(string projectId, Uri baseAddress,
_http = http;
}

public Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request, CancellationToken cancellationToken = default)

public Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about why the formatting changed as there is no configuration change in this PR. Is it linked to the IDE? I just want to make sure this is intentional and won't be reverted by an auto-formatting in another PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto formatted by IDE agnostic dotnet format

CancellationToken cancellationToken = default)
{
_logger?.LogDebug("Fetching active numbers {request}", request);
var uri = new Uri(_baseAddress, $"v1/projects/{_projectId}/activeNumbers?{request.GetQueryString()}");
Expand Down Expand Up @@ -122,7 +134,8 @@ public Task<ActiveNumber> Update(string phoneNumber, UpdateActiveNumberRequest r
_logger?.LogDebug("Updating a {number}", phoneNumber);
var uri = new Uri(_baseAddress, $"v1/projects/{_projectId}/activeNumbers/{phoneNumber}");

return _http.Send<UpdateActiveNumberRequest, ActiveNumber>(uri, HttpMethod.Patch, request, cancellationToken);
return _http.Send<UpdateActiveNumberRequest, ActiveNumber>(uri, HttpMethod.Patch, request,
cancellationToken);
}

/// <inheritdoc />
Expand Down
14 changes: 10 additions & 4 deletions src/Sinch/Numbers/Available.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,28 @@ public interface ISinchNumbersAvailable
{
/// <summary>
/// Search for and activate an available Sinch virtual number all in one API call.
/// Currently the rentAny operation works only for US 10DLC numbers
/// Currently, the rentAny operation works only for US 10DLC numbers
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete($"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.RentAny)} instead.")]
Task<ActiveNumber> RentAny(RentAnyNumberRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Activate a virtual number to use with SMS products, Voice products, or both. <br /><br />
/// You'll use SmsConfiguration to setup your number for SMS and VoiceConfiguration for Voice.
/// To setup for both, add both objects. <br /><br />
/// You'll use SmsConfiguration to set up your number for SMS and VoiceConfiguration for Voice.
/// To set up for both, add both objects. <br /><br />
/// Note: You cannot add both objects if you only need to configure one object.
/// For example, if you only need to configure smsConfiguration for SMS messaging,
/// do not add the voiceConfiguration object or it will result in an error.
/// do not add the voiceConfiguration object, or it will result in an error.
/// </summary>
/// <param name="phoneNumber">Output only. The phone number in E.164 format with leading +.</param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete($"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.Rent)} instead.")]
Task<ActiveNumber> Rent(string phoneNumber,
RentActiveNumberRequest request, CancellationToken cancellationToken = default);

Expand All @@ -49,6 +51,8 @@ Task<ActiveNumber> Rent(string phoneNumber,
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.SearchForAvailableNumbers)} instead.")]
Task<ListAvailableNumbersResponse> List(
ListAvailableNumbersRequest request, CancellationToken cancellationToken = default);

Expand All @@ -62,6 +66,8 @@ Task<ListAvailableNumbersResponse> List(
/// </param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete(
$"This method is obsolete, use {nameof(ISinchNumbers)}.{nameof(Numbers.CheckAvailability)} instead.")]
Task<AvailableNumber> CheckAvailability(string phoneNumber,
CancellationToken cancellationToken = default);
}
Expand Down
114 changes: 113 additions & 1 deletion src/Sinch/Numbers/Numbers.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Sinch.Core;
using Sinch.Logger;
using Sinch.Numbers.Active;
using Sinch.Numbers.Active.List;
using Sinch.Numbers.Active.Update;
using Sinch.Numbers.Available;
using Sinch.Numbers.Available.List;
using Sinch.Numbers.Available.Rent;
using Sinch.Numbers.Available.RentAny;

namespace Sinch.Numbers
{
Expand All @@ -11,20 +21,58 @@ namespace Sinch.Numbers
public interface ISinchNumbers
{
/// <summary>
/// You can use the Available Regions API to list all of the regions that have numbers assigned to a project.
/// You can use the Available Regions API to list all the regions that have numbers assigned to a project.
/// </summary>
public ISinchNumbersRegions Regions { get; }

/// <summary>
/// You can use the Available Number API to search for available numbers or activate an available number.
/// </summary>
[Obsolete($"This property is obsolete, use methods of this ({nameof(ISinchNumbers)}) interface instead.")]
public ISinchNumbersAvailable Available { get; }

/// <summary>
/// You can use the Active Number API to manage numbers you own. Assign numbers to projects,
/// release numbers from projects, or list all numbers assigned to a project.
/// </summary>
[Obsolete($"This property is obsolete, use methods of this ({nameof(ISinchNumbers)}) interface instead.")]
public ISinchNumbersActive Active { get; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may also mark this as obsolete before changing the visibility in the next major


/// <inheritdoc cref="ISinchNumbersAvailable.RentAny" />
Task<ActiveNumber> RentAny(RentAnyNumberRequest request,
CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersAvailable.Rent" />
Task<ActiveNumber> Rent(string phoneNumber,
RentActiveNumberRequest request, CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersAvailable.List" />
Task<ListAvailableNumbersResponse> SearchForAvailableNumbers(
ListAvailableNumbersRequest request, CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersAvailable.CheckAvailability" />
Task<AvailableNumber> CheckAvailability(string phoneNumber,
CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersActive.Release" />
Task<ActiveNumber> Release(
string phoneNumber, CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersActive.Get" />
Task<ActiveNumber> Get(string phoneNumber,
CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersActive.Update" />
Task<ActiveNumber> Update(string phoneNumber,
UpdateActiveNumberRequest request, CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersActive.List" />
Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request,
CancellationToken cancellationToken = default);

/// <inheritdoc cref="ISinchNumbersActive.ListAuto" />
IAsyncEnumerable<ActiveNumber> ListAuto(ListActiveNumbersRequest request,
CancellationToken cancellationToken = default);
}

public sealed class Numbers : ISinchNumbers
Expand All @@ -45,5 +93,69 @@ internal Numbers(string projectId, Uri baseAddress,
public ISinchNumbersActive Active { get; }

public ISinchNumbersAvailable Available { get; }

// disabling obsolete usage as in next major version, active and available interfaces will remain,
// but visibility changed to internal, and public interface will be available only through this methods
#pragma warning disable CS0618 // Type or member is obsolete
/// <inheritdoc />
public Task<ActiveNumber> RentAny(RentAnyNumberRequest request, CancellationToken cancellationToken = default)
{
return Available.RentAny(request, cancellationToken);
}

/// <inheritdoc />
public Task<ActiveNumber> Rent(string phoneNumber, RentActiveNumberRequest request,
CancellationToken cancellationToken = default)
{
return Available.Rent(phoneNumber, request, cancellationToken);
}

/// <inheritdoc />
public Task<ListAvailableNumbersResponse> SearchForAvailableNumbers(ListAvailableNumbersRequest request,
CancellationToken cancellationToken = default)
{
return Available.List(request, cancellationToken);
}

/// <inheritdoc />
public Task<AvailableNumber> CheckAvailability(string phoneNumber,
CancellationToken cancellationToken = default)
{
return Available.CheckAvailability(phoneNumber, cancellationToken);
}

/// <inheritdoc />
public Task<ActiveNumber> Release(string phoneNumber, CancellationToken cancellationToken = default)
{
return Active.Release(phoneNumber, cancellationToken);
}

/// <inheritdoc />
public Task<ActiveNumber> Get(string phoneNumber, CancellationToken cancellationToken = default)
{
return Active.Get(phoneNumber, cancellationToken);
}

/// <inheritdoc />
public Task<ActiveNumber> Update(string phoneNumber, UpdateActiveNumberRequest request,
CancellationToken cancellationToken = default)
{
return Active.Update(phoneNumber, request, cancellationToken);
}

/// <inheritdoc />
public Task<ListActiveNumbersResponse> List(ListActiveNumbersRequest request,
CancellationToken cancellationToken = default)
{
return Active.List(request, cancellationToken);
}

/// <inheritdoc />
public IAsyncEnumerable<ActiveNumber> ListAuto(ListActiveNumbersRequest request,
CancellationToken cancellationToken = default)
{
return Active.ListAuto(request, cancellationToken);
}
#pragma warning restore CS0618 // Type or member is obsolete
}
}
1 change: 0 additions & 1 deletion src/Sinch/SMS/Inbounds/BinaryInbound.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Text.Json.Serialization;

namespace Sinch.SMS.Inbounds
{
Expand Down
12 changes: 6 additions & 6 deletions tests/Sinch.Tests/Numbers/ActiveNumberTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public async Task Get()
.WithHeaders("Authorization", $"Bearer {Token}")
.Respond(HttpStatusCode.OK, JsonContent.Create(TestData.ActiveNumber));

var response = await Numbers.Active.Get("+12025550134");
var response = await Numbers.Get("+12025550134");

response.Should().NotBeNull();
response.PhoneNumber.Should().Be("+12025550134");
Expand All @@ -47,7 +47,7 @@ public async Task List()
totalSize = 5
}));

var response = await Numbers.Active.List(new ListActiveNumbersRequest
var response = await Numbers.List(new ListActiveNumbersRequest
{
RegionCode = "US",
Type = Types.Mobile,
Expand Down Expand Up @@ -96,7 +96,7 @@ public async Task ListWithFullParams()
Capability = new List<Product> { Product.Sms, Product.Voice },
NumberPattern = new NumberPattern { Pattern = "2020", SearchPattern = SearchPattern.Contain }
};
var response = await Numbers.Active.List(request);
var response = await Numbers.List(request);

response.Should().NotBeNull();
response.ActiveNumbers.Should().HaveCount(1);
Expand All @@ -113,7 +113,7 @@ public async Task Release()
.WithHeaders("Authorization", $"Bearer {Token}")
.Respond(HttpStatusCode.OK, JsonContent.Create(TestData.ActiveNumber));

var response = await Numbers.Active.Release("+12025550134");
var response = await Numbers.Release("+12025550134");

response.Should().NotBeNull();
response.PhoneNumber.Should().Be("+12025550134");
Expand All @@ -130,7 +130,7 @@ public async Task Update()
.Respond(HttpStatusCode.OK, JsonContent.Create(TestData.ActiveNumber));


var response = await Numbers.Active.Update("+12025550134", new Sinch.Numbers.Active.Update.UpdateActiveNumberRequest
var response = await Numbers.Update("+12025550134", new Sinch.Numbers.Active.Update.UpdateActiveNumberRequest
{
DisplayName = "Name",
SmsConfiguration = new SmsConfiguration
Expand Down Expand Up @@ -184,7 +184,7 @@ public async Task ListAuto()
}));


var res = Numbers.Active.ListAuto(new ListActiveNumbersRequest
var res = Numbers.ListAuto(new ListActiveNumbersRequest
{
RegionCode = "US",
Type = Types.Mobile,
Expand Down
Loading
Loading