🎨 #2138 【企业微信】优化Redisson实现类,可单独配置provider的redis key,并使keyPrefix可设置

This commit is contained in:
momosv 2021-05-30 23:08:55 +08:00 committed by GitHub
parent 317c98b6da
commit 2c108c4628
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 14 deletions

View File

@ -26,7 +26,8 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
private final WxRedisOps wxRedisOps;
//redis里面key的统一前缀
private final String keyPrefix = "";
//private final String keyPrefix = "";//4.0.9.B 有final为不可设置,去掉final改为可设置
private String keyPrefix = "";
private final String suiteAccessTokenKey = ":suiteAccessTokenKey:";
@ -298,23 +299,23 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
@Override
public boolean isProviderTokenExpired() {
//remain time to live in seconds, or key not exist
return wxRedisOps.getExpire(keyWithPrefix(providerTokenKey)) == 0L || wxRedisOps.getExpire(keyWithPrefix(providerTokenKey)) == -2;
return wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == 0L || wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == -2;
}
@Override
public void updateProviderToken(String providerToken, int expiredInSeconds) {
wxRedisOps.setValue(keyWithPrefix(providerTokenKey), providerToken, expiredInSeconds, TimeUnit.SECONDS);
wxRedisOps.setValue(providerKeyWithPrefix(providerTokenKey), providerToken, expiredInSeconds, TimeUnit.SECONDS);
}
@Override
public String getProviderToken() {
return wxRedisOps.getValue(keyWithPrefix(providerTokenKey));
return wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
}
@Override
public WxCpProviderToken getProviderTokenEntity() {
String providerToken = wxRedisOps.getValue(keyWithPrefix(providerTokenKey));
Long expire = wxRedisOps.getExpire(keyWithPrefix(providerTokenKey));
String providerToken = wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
Long expire = wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey));
if (StringUtils.isBlank(providerToken) || expire == null || expire == 0 || expire == -2) {
return new WxCpProviderToken();
@ -328,7 +329,7 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
@Override
public void expireProviderToken() {
wxRedisOps.expire(keyWithPrefix(providerTokenKey), 0, TimeUnit.SECONDS);
wxRedisOps.expire(providerKeyWithPrefix(providerTokenKey), 0, TimeUnit.SECONDS);
}
/**
@ -361,7 +362,7 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
@Override
public Lock getProviderAccessTokenLock() {
return getLockByKey(String.join(":", this.corpId, LOCKER_PROVIDER_ACCESS_TOKEN));
return getProviderLockByKey(String.join(":", this.corpId, LOCKER_PROVIDER_ACCESS_TOKEN));
}
@Override
@ -390,6 +391,15 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
return this.wxRedisOps.getLock(String.join(":", keyWithPrefix(LOCK_KEY + this.suiteId), key));
}
/**
* 单独处理provider,且不应和suite 有关系
* @param key
* @return
*/
private Lock getProviderLockByKey(String key) {
return this.wxRedisOps.getLock(String.join(":", providerKeyWithPrefix(LOCK_KEY), key));
}
@Override
public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
return this.apacheHttpClientBuilder;
@ -406,7 +416,22 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
return WxCpGsonBuilder.create().toJson(this);
}
/**
* 一个provider 会有多个suite,需要唯一标识作为前缀
* @param key
* @return
*/
private String keyWithPrefix(String key) {
return keyPrefix + key;
return keyPrefix +":"+suiteId+":" + key;
}
/**
* provider 应该独享一个key,且不和任何suite关联
* 一个provider 会有多个suite,不同的suite 都应该指向同一个provider 的数据
* @param key
* @return
*/
private String providerKeyWithPrefix(String key) {
return keyPrefix +":"+corpId+":" + key;
}
}

View File

@ -305,7 +305,11 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
@Override
public String post(String url, String postData) throws WxErrorException {
return execute(SimplePostRequestExecutor.create(this), url, postData);
return execute(SimplePostRequestExecutor.create(this), url, postData,false);
}
public String post(String url, String postData,boolean withoutSuiteAccessToken) throws WxErrorException {
return execute(SimplePostRequestExecutor.create(this), url, postData,withoutSuiteAccessToken);
}
/**
@ -313,10 +317,13 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
*/
@Override
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
return execute(executor, uri, data,false);
}
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data,boolean withoutSuiteAccessToken) throws WxErrorException {
int retryTimes = 0;
do {
try {
return this.executeInternal(executor, uri, data);
return this.executeInternal(executor, uri, data,withoutSuiteAccessToken);
} catch (WxErrorException e) {
if (retryTimes + 1 > this.maxRetryTimes) {
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
@ -347,14 +354,22 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
}
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
return executeInternal( executor, uri,data,false);
}
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data,boolean withoutSuiteAccessToken) throws WxErrorException {
E dataForLog = DataUtils.handleDataWithSecret(data);
if (uri.contains("suite_access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有suite_access_token: " + uri);
}
String uriWithAccessToken;
if(!withoutSuiteAccessToken){
String suiteAccessToken = getSuiteAccessToken(false);
uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "suite_access_token=" + suiteAccessToken;
}else{
uriWithAccessToken = uri;
}
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "suite_access_token=" + suiteAccessToken;
try {
T result = executor.execute(uriWithAccessToken, data, WxType.CP);
@ -452,9 +467,10 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("corpid", configStorage.getCorpId());
jsonObject.addProperty("provider_secret", configStorage.getProviderSecret());
//providerAccessToken 的获取不需要suiteAccessToken ,一不必要二可以提高效率
WxCpProviderToken wxCpProviderToken =
WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(GET_PROVIDER_TOKEN)
, jsonObject.toString()));
, jsonObject.toString(),true));
String providerAccessToken = wxCpProviderToken.getProviderAccessToken();
Integer expiresIn = wxCpProviderToken.getExpiresIn();