diff --git a/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj b/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj
index f8143caa2f..9ad8e3bff6 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj
+++ b/modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj
@@ -18,6 +18,7 @@
+
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
index 80f42ed3ff..8adf03faa9 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
@@ -1,4 +1,6 @@
-using Volo.Abp.Domain;
+using System;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Domain;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@@ -35,6 +37,11 @@ namespace Volo.Docs
options.Stores[GithubDocumentStore.Type] = typeof(GithubDocumentStore);
options.Stores[FileSystemDocumentStore.Type] = typeof(FileSystemDocumentStore);
});
+
+ context.Services.AddHttpClient(GithubRepositoryManager.HttpClientName, client =>
+ {
+ client.Timeout = TimeSpan.FromMilliseconds(15000);
+ });
}
}
}
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs
index 5baa073b9c..715306ae5c 100644
--- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs
@@ -1,16 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
-using Octokit;
-using Octokit.Internal;
using Volo.Abp.Domain.Services;
using Volo.Docs.Documents;
using Volo.Docs.GitHub.Projects;
using Volo.Docs.Projects;
using Newtonsoft.Json.Linq;
+using Octokit;
using ProductHeaderValue = Octokit.ProductHeaderValue;
using Project = Volo.Docs.Projects.Project;
@@ -22,6 +20,13 @@ namespace Volo.Docs.GitHub.Documents
{
public const string Type = "GitHub";
+ private readonly IGithubRepositoryManager _githubRepositoryManager;
+
+ public GithubDocumentStore(IGithubRepositoryManager githubRepositoryManager)
+ {
+ _githubRepositoryManager = githubRepositoryManager;
+ }
+
public virtual async Task GetDocumentAsync(Project project, string documentName, string version)
{
var token = project.GetGitHubAccessTokenOrNull();
@@ -102,20 +107,7 @@ namespace Volo.Docs.GitHub.Documents
var url = project.GetGitHubUrl();
var ownerName = GetOwnerNameFromUrl(url);
var repositoryName = GetRepositoryNameFromUrl(url);
- var gitHubClient = CreateGitHubClient(project.GetGitHubAccessTokenOrNull());
-
- return await gitHubClient
- .Repository
- .Release
- .GetAll(ownerName, repositoryName);
- }
-
- private static GitHubClient CreateGitHubClient(string token = null)
- {
- //TODO: Why hard-coded "abpframework"? Should be configurable?
- return token.IsNullOrWhiteSpace()
- ? new GitHubClient(new ProductHeaderValue("abpframework"))
- : new GitHubClient(new ProductHeaderValue("abpframework"), new InMemoryCredentialStore(new Credentials(token)));
+ return await _githubRepositoryManager.GetReleasesAsync(ownerName, repositoryName, project.GetGitHubAccessTokenOrNull());
}
protected virtual string GetOwnerNameFromUrl(string url)
@@ -151,19 +143,7 @@ namespace Volo.Docs.GitHub.Documents
{
Logger.LogInformation("Downloading content from Github (DownloadWebContentAsStringAsync): " + rawUrl);
- using (var webClient = new GithubWebClient())
- {
- if (!token.IsNullOrWhiteSpace())
- {
- webClient.Headers.Add("Authorization", "token " + token);
- }
-
- webClient.Headers.Add("User-Agent", userAgent ?? "");
-
- //TODO: SET TIMEOUT?
-
- return await webClient.DownloadStringTaskAsync(new Uri(rawUrl));
- }
+ return await _githubRepositoryManager.GetFileRawStringContentAsync(rawUrl, token, userAgent);
}
catch (Exception ex)
{
@@ -179,16 +159,7 @@ namespace Volo.Docs.GitHub.Documents
{
Logger.LogInformation("Downloading content from Github (DownloadWebContentAsByteArrayAsync): " + rawUrl);
- using (var webClient = new GithubWebClient())
- {
- if (!token.IsNullOrWhiteSpace())
- {
- webClient.Headers.Add("Authorization", "token " + token);
- }
- webClient.Headers.Add("User-Agent", userAgent ?? "");
-
- return await webClient.DownloadDataTaskAsync(new Uri(rawUrl));
- }
+ return await _githubRepositoryManager.GetFileRawByteArrayContentAsync(rawUrl, token, userAgent);
}
catch (Exception ex)
{
@@ -237,21 +208,5 @@ namespace Volo.Docs.GitHub.Documents
.Replace("github.com", "raw.githubusercontent.com")
.ReplaceFirst("/tree/", "/");
}
-
- private class GithubWebClient : WebClient
- {
- protected override WebRequest GetWebRequest(Uri address)
- {
- var webRequest = base.GetWebRequest(address);
- if (webRequest == null)
- {
- return null;
- }
-
- webRequest.Timeout = 15000;
-
- return webRequest;
- }
- }
}
}
\ No newline at end of file
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs
new file mode 100644
index 0000000000..be71fd4772
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+using Octokit;
+using Octokit.Internal;
+using ProductHeaderValue = Octokit.ProductHeaderValue;
+
+namespace Volo.Docs.GitHub.Documents
+{
+ public class GithubRepositoryManager : IGithubRepositoryManager
+ {
+ public const string HttpClientName = "GithubRepositoryManagerHttpClientName";
+
+ private readonly IHttpClientFactory _clientFactory;
+
+ public GithubRepositoryManager(IHttpClientFactory clientFactory)
+ {
+ _clientFactory = clientFactory;
+ }
+
+ public async Task GetFileRawStringContentAsync(string rawUrl, string token, string userAgent)
+ {
+ var httpClient = _clientFactory.CreateClient(HttpClientName);
+ if (!token.IsNullOrWhiteSpace())
+ {
+ httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", token);
+ }
+
+ httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent ?? "");
+
+ return await httpClient.GetStringAsync(new Uri(rawUrl));
+ }
+
+ public async Task GetFileRawByteArrayContentAsync(string rawUrl, string token, string userAgent)
+ {
+ var httpClient = _clientFactory.CreateClient(HttpClientName);
+ if (!token.IsNullOrWhiteSpace())
+ {
+ httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Token", token);
+ }
+
+ httpClient.DefaultRequestHeaders.Add("User-Agent", userAgent ?? "");
+
+ return await httpClient.GetByteArrayAsync(new Uri(rawUrl));
+ }
+
+ public async Task> GetReleasesAsync(string name, string repositoryName, string token)
+ {
+ var client = token.IsNullOrWhiteSpace()
+ ? new GitHubClient(new ProductHeaderValue(name))
+ : new GitHubClient(new ProductHeaderValue(name), new InMemoryCredentialStore(new Credentials(token)));
+
+ return (await client
+ .Repository
+ .Release
+ .GetAll(name, repositoryName)).ToList();
+ }
+ }
+}
diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubRepositoryManager.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubRepositoryManager.cs
new file mode 100644
index 0000000000..519b9829d5
--- /dev/null
+++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubRepositoryManager.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Octokit;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Docs.GitHub.Documents
+{
+ public interface IGithubRepositoryManager : ITransientDependency
+ {
+ Task GetFileRawStringContentAsync(string rawUrl, string token, string userAgent);
+
+ Task GetFileRawByteArrayContentAsync(string rawUrl, string token, string userAgent);
+
+ Task> GetReleasesAsync(string name, string repositoryName, string token);
+
+ }
+}
diff --git a/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/DocsDomainTestBase.cs b/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/DocsDomainTestBase.cs
index 1a34d74ddf..7de6bb3182 100644
--- a/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/DocsDomainTestBase.cs
+++ b/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/DocsDomainTestBase.cs
@@ -1,7 +1,43 @@
-namespace Volo.Docs
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.DependencyInjection;
+using NSubstitute;
+using Octokit;
+using Volo.Docs.GitHub.Documents;
+
+namespace Volo.Docs
{
public abstract class DocsDomainTestBase : DocsTestBase
{
-
+ protected override void AfterAddApplication(IServiceCollection services)
+ {
+ var repositoryManager = Substitute.For();
+ repositoryManager.GetFileRawStringContentAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ .Returns("stringContent");
+ repositoryManager.GetFileRawByteArrayContentAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ .Returns(new byte[] { 0x01, 0x02, 0x03 });
+ repositoryManager.GetReleasesAsync(Arg.Any(), Arg.Any(), Arg.Any())
+ .Returns(new List
+ {
+ new Release("https://api.github.com/repos/abpframework/abp/releases/16293679",
+ "https://github.com/abpframework/abp/releases/tag/0.15.0",
+ "https://api.github.com/repos/abpframework/abp/releases/16293679/assets",
+ "https://uploads.github.com/repos/abpframework/abp/releases/16293679/assets{?name,label}",
+ 16293679,
+ "0.15.0",
+ "master",
+ "0.15.0",
+ "0.15.0 already release",
+ false,
+ false,
+ DateTimeOffset.Parse("2019-03-22T18:43:58Z"),
+ DateTimeOffset.Parse("2019-03-22T19:44:25Z"),
+ null,
+ "https://api.github.com/repos/abpframework/abp/tarball/0.15.0",
+ "https://api.github.com/repos/abpframework/abp/zipball/0.15.0",
+ null)
+ });
+ services.AddSingleton(repositoryManager);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/GithubDocumentStore_Tests.cs b/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/GithubDocumentStore_Tests.cs
new file mode 100644
index 0000000000..ac04ec0e46
--- /dev/null
+++ b/modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/GithubDocumentStore_Tests.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using NSubstitute;
+using Octokit;
+using Shouldly;
+using Volo.Docs.Documents;
+using Volo.Docs.GitHub.Documents;
+using Volo.Docs.Projects;
+using Xunit;
+
+namespace Volo.Docs
+{
+ public class GithubDocumentStore_Tests : DocsDomainTestBase
+ {
+ private readonly IDocumentStoreFactory _documentStoreFactory;
+ private readonly IProjectRepository _projectRepository;
+ private readonly DocsTestData _testData;
+
+ public GithubDocumentStore_Tests()
+ {
+ _documentStoreFactory = GetRequiredService();
+ _projectRepository = GetRequiredService();
+ _testData = GetRequiredService();
+ }
+
+ [Fact]
+ public async Task GetDocumentAsync()
+ {
+ var store = _documentStoreFactory.Create(GithubDocumentStore.Type);
+ var project = await _projectRepository.FindAsync(_testData.PorjectId);
+ project.ShouldNotBeNull();
+ var document = await store.GetDocumentAsync(project, "index2", "0.123.0");
+ document.ShouldNotBeNull();
+
+ document.Title.ShouldBe("index2");
+ document.FileName.ShouldBe("index2");
+ document.Version.ShouldBe("0.123.0");
+ document.Content.ShouldBe("stringContent");
+ }
+
+ [Fact]
+ public async Task GetVersionsAsync()
+ {
+ var store = _documentStoreFactory.Create(GithubDocumentStore.Type);
+ var project = await _projectRepository.FindAsync(_testData.PorjectId);
+ project.ShouldNotBeNull();
+
+ var document = await store.GetVersionsAsync(project);
+ document.ShouldNotBeNull();
+
+ document.Count.ShouldBe(1);
+ document.ShouldContain(x => x.Name == "0.15.0" && x.DisplayName == "0.15.0");
+ }
+
+ [Fact]
+ public async Task GetResource()
+ {
+ var store = _documentStoreFactory.Create(GithubDocumentStore.Type);
+ var project = await _projectRepository.FindAsync(_testData.PorjectId);
+ project.ShouldNotBeNull();
+
+ var documentResource = await store.GetResource(project, "index.md", "0.123.0");
+ documentResource.ShouldNotBeNull();
+
+ documentResource.Content.ShouldBe(new byte[]
+ {
+ 0x01, 0x02, 0x03
+ });
+ }
+ }
+}