work on HttpClientFactory in twitter client

This commit is contained in:
Vincent Cloutier 2023-02-10 16:26:24 -05:00
parent da8092cfd5
commit 210b820e90
8 changed files with 26 additions and 13 deletions

View file

@ -6,6 +6,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -5,7 +5,7 @@ using System.Threading.Tasks;
using BirdsiteLive.Common.Settings; using BirdsiteLive.Common.Settings;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net;
using System.Text.Json; using System.Text.Json;
namespace BirdsiteLive.Twitter.Tools namespace BirdsiteLive.Twitter.Tools
@ -21,7 +21,7 @@ namespace BirdsiteLive.Twitter.Tools
private readonly ILogger<TwitterAuthenticationInitializer> _logger; private readonly ILogger<TwitterAuthenticationInitializer> _logger;
private static bool _initialized; private static bool _initialized;
private static System.Timers.Timer aTimer; private static System.Timers.Timer aTimer;
private readonly HttpClient _httpClient = new HttpClient(); private readonly IHttpClientFactory _httpClientFactory;
private List<HttpClient> _twitterClients = new List<HttpClient>(); private List<HttpClient> _twitterClients = new List<HttpClient>();
private List<String> _tokens = new List<string>(); private List<String> _tokens = new List<string>();
static Random rnd = new Random(); static Random rnd = new Random();
@ -30,9 +30,10 @@ namespace BirdsiteLive.Twitter.Tools
} }
#region Ctor #region Ctor
public TwitterAuthenticationInitializer(ILogger<TwitterAuthenticationInitializer> logger) public TwitterAuthenticationInitializer(IHttpClientFactory httpClientFactory, ILogger<TwitterAuthenticationInitializer> logger)
{ {
_logger = logger; _logger = logger;
_httpClientFactory = httpClientFactory;
aTimer = new System.Timers.Timer(); aTimer = new System.Timers.Timer();
aTimer.Interval = 20 * 1000; aTimer.Interval = 20 * 1000;
@ -53,6 +54,7 @@ namespace BirdsiteLive.Twitter.Tools
{ {
(string bearer, string guest) = await GetCred(); (string bearer, string guest) = await GetCred();
// HttpClient client = _httpClientFactory.CreateClient();
HttpClient client = new HttpClient(); HttpClient client = new HttpClient();
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Bearer " + bearer); client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Bearer " + bearer);
client.DefaultRequestHeaders.TryAddWithoutValidation("x-guest-token", guest); client.DefaultRequestHeaders.TryAddWithoutValidation("x-guest-token", guest);
@ -60,19 +62,24 @@ namespace BirdsiteLive.Twitter.Tools
client.DefaultRequestHeaders.TryAddWithoutValidation("x-twitter-active-user", "yes"); client.DefaultRequestHeaders.TryAddWithoutValidation("x-twitter-active-user", "yes");
_twitterClients.Add(client); _twitterClients.Add(client);
_tokens.Add(guest);
if (_twitterClients.Count > 10) if (_twitterClients.Count > 10)
{
_twitterClients.RemoveAt(0); _twitterClients.RemoveAt(0);
_tokens.RemoveAt(0);
}
} }
private async Task<(string, string)> GetCred() private async Task<(string, string)> GetCred()
{ {
string token; string token;
var httpClient = _httpClientFactory.CreateClient();
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.twitter.com/1.1/guest/activate.json")) using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.twitter.com/1.1/guest/activate.json"))
{ {
request.Headers.TryAddWithoutValidation("Authorization", $"Bearer " + BearerToken); request.Headers.TryAddWithoutValidation("Authorization", $"Bearer " + BearerToken);
var httpResponse = await _httpClient.SendAsync(request); var httpResponse = await httpClient.SendAsync(request);
var c = await httpResponse.Content.ReadAsStringAsync(); var c = await httpResponse.Content.ReadAsStringAsync();
httpResponse.EnsureSuccessStatusCode(); httpResponse.EnsureSuccessStatusCode();

View file

@ -31,7 +31,6 @@ namespace BirdsiteLive.Twitter
private readonly ITwitterUserDal _twitterUserDal; private readonly ITwitterUserDal _twitterUserDal;
private readonly ILogger<TwitterTweetsService> _logger; private readonly ILogger<TwitterTweetsService> _logger;
private readonly InstanceSettings _instanceSettings; private readonly InstanceSettings _instanceSettings;
private HttpClient _httpClient = new HttpClient();
#region Ctor #region Ctor
public TwitterTweetsService(ITwitterAuthenticationInitializer twitterAuthenticationInitializer, ITwitterStatisticsHandler statisticsHandler, ICachedTwitterUserService twitterUserService, ITwitterUserDal twitterUserDal, InstanceSettings instanceSettings, ILogger<TwitterTweetsService> logger) public TwitterTweetsService(ITwitterAuthenticationInitializer twitterAuthenticationInitializer, ITwitterStatisticsHandler statisticsHandler, ICachedTwitterUserService twitterUserService, ITwitterUserDal twitterUserDal, InstanceSettings instanceSettings, ILogger<TwitterTweetsService> logger)

View file

@ -23,7 +23,6 @@ namespace BirdsiteLive.Twitter
private readonly ITwitterAuthenticationInitializer _twitterAuthenticationInitializer; private readonly ITwitterAuthenticationInitializer _twitterAuthenticationInitializer;
private readonly ITwitterStatisticsHandler _statisticsHandler; private readonly ITwitterStatisticsHandler _statisticsHandler;
private readonly ILogger<TwitterUserService> _logger; private readonly ILogger<TwitterUserService> _logger;
private HttpClient _httpClient = new HttpClient();
private readonly string endpoint = "https://twitter.com/i/api/graphql/4LB4fkCe3RDLDmOEEYtueg/UserByScreenName?variables=%7B%22screen_name%22%3A%22elonmusk%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D&features=%7B%22responsive_web_twitter_blue_verified_badge_is_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22responsive_web_twitter_blue_new_verification_copy_is_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%7D"; private readonly string endpoint = "https://twitter.com/i/api/graphql/4LB4fkCe3RDLDmOEEYtueg/UserByScreenName?variables=%7B%22screen_name%22%3A%22elonmusk%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D&features=%7B%22responsive_web_twitter_blue_verified_badge_is_enabled%22%3Atrue%2C%22verified_phone_label_enabled%22%3Afalse%2C%22responsive_web_twitter_blue_new_verification_copy_is_enabled%22%3Afalse%2C%22responsive_web_graphql_timeline_navigation_enabled%22%3Atrue%7D";
@ -38,7 +37,6 @@ namespace BirdsiteLive.Twitter
public async Task<TwitterUser> GetUserAsync(string username) public async Task<TwitterUser> GetUserAsync(string username)
{ {
await _twitterAuthenticationInitializer.EnsureAuthenticationIsInitialized();
JsonDocument res; JsonDocument res;
try try

View file

@ -12,7 +12,7 @@
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" /> <PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" /> <PackageReference Include="coverlet.collector" Version="1.2.0" />
<PackageReference Include="moq" Version="4.16.1" /> <PackageReference Include="moq" Version="4.16.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -8,6 +8,7 @@ using BirdsiteLive.Common.Settings;
using Moq; using Moq;
using BirdsiteLive.DAL.Contracts; using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.DAL.Models; using BirdsiteLive.DAL.Models;
using System.Net.Http;
namespace BirdsiteLive.ActivityPub.Tests namespace BirdsiteLive.ActivityPub.Tests
{ {
@ -23,7 +24,8 @@ namespace BirdsiteLive.ActivityPub.Tests
var logger3 = new Mock<ILogger<TwitterTweetsService>>(); var logger3 = new Mock<ILogger<TwitterTweetsService>>();
var stats = new Mock<ITwitterStatisticsHandler>(); var stats = new Mock<ITwitterStatisticsHandler>();
var twitterDal = new Mock<ITwitterUserDal>(); var twitterDal = new Mock<ITwitterUserDal>();
var httpFactory = new Mock<IHttpClientFactory>();
httpFactory.Setup(_ => _.CreateClient(string.Empty)).Returns(new HttpClient());
var settings = new InstanceSettings var settings = new InstanceSettings
{ {
Domain = "domain.name" Domain = "domain.name"
@ -35,7 +37,7 @@ namespace BirdsiteLive.ActivityPub.Tests
)) ))
.ReturnsAsync(new SyncTwitterUser { TwitterUserId = default }); .ReturnsAsync(new SyncTwitterUser { TwitterUserId = default });
ITwitterAuthenticationInitializer auth = new TwitterAuthenticationInitializer(logger1.Object); ITwitterAuthenticationInitializer auth = new TwitterAuthenticationInitializer(httpFactory.Object, logger1.Object);
ITwitterUserService user = new TwitterUserService(auth, stats.Object, logger2.Object); ITwitterUserService user = new TwitterUserService(auth, stats.Object, logger2.Object);
ICachedTwitterUserService user2 = new CachedTwitterUserService(user, settings); ICachedTwitterUserService user2 = new CachedTwitterUserService(user, settings);
_tweetService = new TwitterTweetsService(auth, stats.Object, user2, twitterDal.Object, settings, logger3.Object); _tweetService = new TwitterTweetsService(auth, stats.Object, user2, twitterDal.Object, settings, logger3.Object);

View file

@ -7,6 +7,7 @@ using BirdsiteLive.Statistics.Domain;
using Moq; using Moq;
using BirdsiteLive.DAL.Contracts; using BirdsiteLive.DAL.Contracts;
using BirdsiteLive.Common.Settings; using BirdsiteLive.Common.Settings;
using System.Net.Http;
namespace BirdsiteLive.ActivityPub.Tests namespace BirdsiteLive.ActivityPub.Tests
{ {
@ -22,11 +23,13 @@ namespace BirdsiteLive.ActivityPub.Tests
var logger3 = new Mock<ILogger<TwitterTweetsService>>(); var logger3 = new Mock<ILogger<TwitterTweetsService>>();
var stats = new Mock<ITwitterStatisticsHandler>(); var stats = new Mock<ITwitterStatisticsHandler>();
var twitterDal = new Mock<ITwitterUserDal>(); var twitterDal = new Mock<ITwitterUserDal>();
var httpFactory = new Mock<IHttpClientFactory>();
httpFactory.Setup(_ => _.CreateClient(string.Empty)).Returns(new HttpClient());
var settings = new InstanceSettings var settings = new InstanceSettings
{ {
Domain = "domain.name" Domain = "domain.name"
}; };
ITwitterAuthenticationInitializer auth = new TwitterAuthenticationInitializer(logger1.Object); ITwitterAuthenticationInitializer auth = new TwitterAuthenticationInitializer(httpFactory.Object, logger1.Object);
ITwitterUserService user = new TwitterUserService(auth, stats.Object, logger2.Object); ITwitterUserService user = new TwitterUserService(auth, stats.Object, logger2.Object);
ICachedTwitterUserService user2 = new CachedTwitterUserService(user, settings); ICachedTwitterUserService user2 = new CachedTwitterUserService(user, settings);
_tweetService = new TwitterTweetsService(auth, stats.Object, user2, twitterDal.Object, settings, logger3.Object); _tweetService = new TwitterTweetsService(auth, stats.Object, user2, twitterDal.Object, settings, logger3.Object);

View file

@ -5,6 +5,7 @@ using BirdsiteLive.Twitter;
using BirdsiteLive.Twitter.Tools; using BirdsiteLive.Twitter.Tools;
using BirdsiteLive.Statistics.Domain; using BirdsiteLive.Statistics.Domain;
using Moq; using Moq;
using System.Net.Http;
namespace BirdsiteLive.ActivityPub.Tests namespace BirdsiteLive.ActivityPub.Tests
{ {
@ -19,12 +20,14 @@ namespace BirdsiteLive.ActivityPub.Tests
var logger2 = new Mock<ILogger<TwitterUserService>>(MockBehavior.Strict); var logger2 = new Mock<ILogger<TwitterUserService>>(MockBehavior.Strict);
var logger3 = new Mock<ILogger<TwitterUserService>>(); var logger3 = new Mock<ILogger<TwitterUserService>>();
var stats = new Mock<ITwitterStatisticsHandler>(); var stats = new Mock<ITwitterStatisticsHandler>();
ITwitterAuthenticationInitializer auth = new TwitterAuthenticationInitializer(logger1.Object); var httpFactory = new Mock<IHttpClientFactory>();
httpFactory.Setup(_ => _.CreateClient(string.Empty)).Returns(new HttpClient());
ITwitterAuthenticationInitializer auth = new TwitterAuthenticationInitializer(httpFactory.Object, logger1.Object);
_tweetService = new TwitterUserService(auth, stats.Object, logger3.Object); _tweetService = new TwitterUserService(auth, stats.Object, logger3.Object);
} }
[TestMethod] [TestMethod]
public async Task TimelineKobe() public async Task UserKobe()
{ {
var user = await _tweetService.GetUserAsync("kobebryant"); var user = await _tweetService.GetUserAsync("kobebryant");
Assert.AreEqual(user.Name, "Kobe Bryant"); Assert.AreEqual(user.Name, "Kobe Bryant");