Skip to content

Commit

Permalink
增加SharedCache.StackExchangeRedis模块
Browse files Browse the repository at this point in the history
  • Loading branch information
gdlcf88 committed Jul 20, 2020
1 parent f32ff21 commit ca1a740
Show file tree
Hide file tree
Showing 23 changed files with 348 additions and 61 deletions.
7 changes: 7 additions & 0 deletions EasyAbp.Abp.WeChat.sln
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{77BCE4
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.Abp.WeChat.MiniProgram.Tests", "tests\EasyAbp.Abp.WeChat.MiniProgram.Tests\EasyAbp.Abp.WeChat.MiniProgram.Tests.csproj", "{278AF624-63F3-455F-B97C-97AC92637E73}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis", "src\Common\EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis\EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.csproj", "{0E6D006A-1A2E-48A5-B68E-E76DF2AEB643}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -84,6 +86,10 @@ Global
{278AF624-63F3-455F-B97C-97AC92637E73}.Debug|Any CPU.Build.0 = Debug|Any CPU
{278AF624-63F3-455F-B97C-97AC92637E73}.Release|Any CPU.ActiveCfg = Release|Any CPU
{278AF624-63F3-455F-B97C-97AC92637E73}.Release|Any CPU.Build.0 = Release|Any CPU
{0E6D006A-1A2E-48A5-B68E-E76DF2AEB643}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E6D006A-1A2E-48A5-B68E-E76DF2AEB643}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E6D006A-1A2E-48A5-B68E-E76DF2AEB643}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E6D006A-1A2E-48A5-B68E-E76DF2AEB643}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{69F0A12F-2151-4F65-B2EB-476E91BEE43A} = {03A4A696-FC94-4F91-B7CE-9C508C1F9EBA}
Expand All @@ -101,5 +107,6 @@ Global
{77BCE44A-CC08-40A1-B6DD-437B5AC431A6} = {90122FA0-637C-46F5-9509-47A581A1CB00}
{B12E7D16-FE59-4F96-9F62-173D471279EE} = {77BCE44A-CC08-40A1-B6DD-437B5AC431A6}
{278AF624-63F3-455F-B97C-97AC92637E73} = {03A4A696-FC94-4F91-B7CE-9C508C1F9EBA}
{0E6D006A-1A2E-48A5-B68E-E76DF2AEB643} = {77BCE44A-CC08-40A1-B6DD-437B5AC431A6}
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion common.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.3.1</Version>
<Version>1.4.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Localization;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Localization;
using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;

namespace EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis
{
[DependsOn(
typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpWeChatCommonModule))]
public class AbpWeChatCommonSharedCacheStackExchangeRedisModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWeChatCommonSharedCacheStackExchangeRedisModule>();
});

Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<SharedCacheStackExchangeRedisResource>("en")
.AddVirtualJson("/Localization/StackExchangeRedis");
});

Configure<AbpExceptionLocalizationOptions>(options =>
{
options.MapCodeNamespace("EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis", typeof(SharedCacheStackExchangeRedisResource));
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\..\..\common.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis</RootNamespace>
<Description>ABP vNext微信模块,基于StackExchangeRedis提供多服务间共享access_token等缓存数据的功能扩展。</Description>
<LangVersion>8</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="3.0.4" />
<ProjectReference Include="..\EasyAbp.Abp.WeChat.Common\EasyAbp.Abp.WeChat.Common.csproj" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Localization\StackExchangeRedis\*.json" />
<Content Remove="Localization\StackExchangeRedis\*.json" />
</ItemGroup>

<ItemGroup>
<Folder Include="Infrastructure" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken;
using EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Settings;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Settings;

namespace EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Infrastructure.AccessToken
{
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)]
public class SharedStackExchangeRedisAccessTokenProvider : IAccessTokenProvider
{
public const string CachePrefix = "CurrentAccessToken:";
public const string SettingName = SharedCacheStackExchangeRedisSettings.RedisConfiguration;

private readonly ISettingProvider _settingProvider;
private readonly IHttpClientFactory _httpClientFactory;

public SharedStackExchangeRedisAccessTokenProvider(
ISettingProvider settingProvider,
IHttpClientFactory httpClientFactory)
{
_settingProvider = settingProvider;
_httpClientFactory = httpClientFactory;
}

public async Task<string> GetAccessTokenAsync(string appId, string appSecret)
{
var redisCache = new AbpRedisCache(new RedisCacheOptions
{
Configuration = await _settingProvider.GetOrNullAsync(SettingName)
});

var key = $"{CachePrefix}{appId}";

var accessToken = await redisCache.GetStringAsync(key);

if (accessToken != null)
{
return accessToken;
}

var client = _httpClientFactory.CreateClient();

var requestUrl = $"https://api.weixin.qq.com/cgi-bin/token?grant_type={GrantTypes.ClientCredential}&appid={appId}&secret={appSecret}";

var resultStr = await (await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUrl)))
.Content.ReadAsStringAsync();

var resultJson = JObject.Parse(resultStr);

var accessTokenObj = resultJson.SelectToken("$.access_token");

if (accessTokenObj == null)
{
throw new NullReferenceException($"无法获取到 AccessToken,微信 API 返回的内容为:{resultStr}");
}

accessToken = accessTokenObj.Value<string>();

await redisCache.SetStringAsync(key, accessToken, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});

return accessToken;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Volo.Abp.Localization;

namespace EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Localization
{
[LocalizationResourceName("EasyAbpAbpWeChatCommonSharedCacheStackExchangeRedis")]
public class SharedCacheStackExchangeRedisResource
{

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "ar",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "cs",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "pl-PL",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "pt-BR",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "ru",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "sl",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "tr",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "vi",
"texts": {
"SharedCacheRedisConfiguration": "SharedCacheRedisConfiguration",
"SharedCacheRedisConfigurationDescription": "SharedCacheRedisConfigurationDescription"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
"SharedCacheRedisConfiguration": "共享缓存RedisConfiguration",
"SharedCacheRedisConfigurationDescription": "共享Redis缓存的连接配置,用于在多个服务之间分享access_token等动态数据"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"culture": "zh-Hant",
"texts": {
"SharedCacheRedisConfiguration": "共享缓存RedisConfiguration",
"SharedCacheRedisConfigurationDescription": "共享Redis缓存的连接配置,用于在多个服务之间分享access_token等动态数据"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Settings;

namespace EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Settings
{
public class SharedCacheStackExchangeRedisSettingDefinitionProvider : SettingDefinitionProvider
{
public override void Define(ISettingDefinitionContext context)
{
//Define your own settings here. Example:
//context.Add(new SettingDefinition(DenturePlusSettings.MySetting1));

context.Add(new SettingDefinition(
SharedCacheStackExchangeRedisSettings.RedisConfiguration,
null,
L("SharedCacheRedisConfiguration"),
L("SharedCacheRedisConfigurationDescription")));
}

private static LocalizableString L(string name)
{
return LocalizableString.Create<SharedCacheStackExchangeRedisResource>(name);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace EasyAbp.Abp.WeChat.Common.SharedCache.StackExchangeRedis.Settings
{
public static class SharedCacheStackExchangeRedisSettings
{
private const string Prefix = "EasyAbp.Abp.WeChat.Common.SharedCache";

//Add your own setting names here. Example:
//public const string MySetting1 = Prefix + ".MySetting1";

public const string RedisConfiguration = Prefix + ".RedisConfiguration";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json.Linq;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken
{
public class DefaultAccessTokenProvider : IAccessTokenProvider, ISingletonDependency
{
private readonly IDistributedCache<string> _distributedCache;
private readonly IHttpClientFactory _httpClientFactory;

public DefaultAccessTokenProvider(IDistributedCache<string> distributedCache,
IHttpClientFactory httpClientFactory)
{
_distributedCache = distributedCache;
_httpClientFactory = httpClientFactory;
}

public virtual async Task<string> GetAccessTokenAsync(string appId, string appSecret)
{
return await _distributedCache.GetOrAddAsync($"CurrentAccessToken:{appId}",
async () =>
{
var client = _httpClientFactory.CreateClient();

var requestUrl = $"https://api.weixin.qq.com/cgi-bin/token?grant_type={GrantTypes.ClientCredential}&appid={appId}&secret={appSecret}";

var resultStr = await (await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, requestUrl)))
.Content.ReadAsStringAsync();

var resultJson = JObject.Parse(resultStr);

var accessTokenObj = resultJson.SelectToken("$.access_token");

if (accessTokenObj == null)
{
throw new NullReferenceException($"无法获取到 AccessToken,微信 API 返回的内容为:{resultStr}");
}

return accessTokenObj.Value<string>();
},
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(115)
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Threading.Tasks;

namespace EasyAbp.Abp.WeChat.Common.Infrastructure.AccessToken
{
public interface IAccessTokenProvider
{
Task<string> GetAccessTokenAsync(string appId, string appSecret);
}
}
Loading

0 comments on commit ca1a740

Please sign in to comment.