|
|
@@ -0,0 +1,230 @@
|
|
|
+package com.dderp.business.service.flycat;
|
|
|
+
|
|
|
+import com.dderp.common.api.NoSqlKeysService;
|
|
|
+import com.dderp.common.api.PlatformService;
|
|
|
+import com.dderp.common.api.flycat.PlatformAccessTokenService;
|
|
|
+import com.dderp.common.base.BaseService;
|
|
|
+import com.dderp.common.datas.ERPModule;
|
|
|
+import com.dderp.common.datas.RedisKeys;
|
|
|
+import com.dderp.common.datas.flycat.PlatformType;
|
|
|
+import com.dderp.common.entity.base.*;
|
|
|
+import com.dderp.common.entity.platform.PlatformInfo;
|
|
|
+import com.dderp.common.tool.ERPUtils;
|
|
|
+import com.dySweetFishPlugin.redis.RedisService;
|
|
|
+import com.dySweetFishPlugin.tool.lang.ThreadFactoryWithNamePrefix;
|
|
|
+import com.sweetfish.convert.json.JsonConvert;
|
|
|
+import com.sweetfish.service.Local;
|
|
|
+import com.sweetfish.service.RetResult;
|
|
|
+import com.sweetfish.util.AnyValue;
|
|
|
+import com.sweetfish.util.AutoLoad;
|
|
|
+import com.sweetfish.util.ResourceType;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.rex.DB;
|
|
|
+import org.rex.RMap;
|
|
|
+import org.rex.db.exception.DBException;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.time.Instant;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.*;
|
|
|
+
|
|
|
+@AutoLoad(false)
|
|
|
+@Local
|
|
|
+@ResourceType(PlatformAccessTokenService.class)
|
|
|
+public class PlatformAccessTokenServiceImpl extends BaseService implements PlatformAccessTokenService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private RedisService redisService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private PlatformService platformService;
|
|
|
+ private final ConcurrentHashMap<String, ThreadPoolExecutor> threadPoolMap = new ConcurrentHashMap<>();
|
|
|
+ private final ConcurrentHashMap<String, String> sysDataBaseItem = new ConcurrentHashMap<>();
|
|
|
+ private String runEnvironment;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private JsonConvert jsonConvert;
|
|
|
+
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private NoSqlKeysService keysService;
|
|
|
+
|
|
|
+// @Resource(name = "property.DYLK.appId")
|
|
|
+// private String dyAppId;
|
|
|
+//
|
|
|
+// @Resource(name = "property.DYLK.appSecret")
|
|
|
+// private String dyAppSecret;
|
|
|
+//
|
|
|
+// @Resource(name = "property.DYLK.reqUrl")
|
|
|
+// private String dyReqUrl;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void start(AnyValue config) {
|
|
|
+ boolean master = false;
|
|
|
+ AnyValue masterValue = config.getAnyValue("master");
|
|
|
+ if (masterValue != null) {
|
|
|
+ master = masterValue.getBoolValue("value");
|
|
|
+ }
|
|
|
+
|
|
|
+ AnyValue environmentValue = config.getAnyValue("environment");
|
|
|
+ if (environmentValue != null) {
|
|
|
+ runEnvironment = environmentValue.getValue("value");
|
|
|
+ } else {
|
|
|
+ runEnvironment = "dev";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (master) {
|
|
|
+ if (StringUtils.equalsIgnoreCase(runEnvironment, "dev")) {
|
|
|
+ //开发环境,什么也不做
|
|
|
+
|
|
|
+ } else {
|
|
|
+ List<DataBaseMultiItemEx> dataList = null;
|
|
|
+ try {
|
|
|
+ dataList = DB.getList("select * from sys_DataBaseMultiItem where voidFlag = 0 order by id", DataBaseMultiItemEx.class);
|
|
|
+ } catch (DBException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ dataList.forEach((x) -> sysDataBaseItem.put(x.getDataBaseAlias(), x.getShardingKey()));
|
|
|
+
|
|
|
+ sysDataBaseItem.forEach((dataSourceId, supplierCode) -> {
|
|
|
+ List<PlatformInfo> platformInfoList = platformService.getRedisPlatformList(PlatformType.order.getValue(), Long.parseLong(supplierCode));
|
|
|
+ platformInfoList.forEach(platformInfo -> {
|
|
|
+ if (platformInfo.getNeedAccessToken() == 1) {
|
|
|
+ ScheduledThreadPoolExecutor dyAccessTokenThread = new ScheduledThreadPoolExecutor(1,
|
|
|
+ new ThreadFactoryWithNamePrefix("[" + platformInfo.getPlatformName() + "Access_Token线程池]"));
|
|
|
+
|
|
|
+ long tokenInitialDelay = 30;
|
|
|
+
|
|
|
+ long tokenRefreshSeconds = platformInfo.getRefreshTokenSeconds();
|
|
|
+ if (tokenRefreshSeconds <= 0) tokenRefreshSeconds = 5400;
|
|
|
+
|
|
|
+ //判断上次刷新token的时间,
|
|
|
+ if (redisService.exists(keysService.getRedisKey(RedisKeys.KEY_PLATFORM_LASTTOKENDATE, Long.parseLong(supplierCode), true) +
|
|
|
+ platformInfo.getPlatformCode())) {
|
|
|
+ long lastTime = Long.parseLong(redisService.get(keysService.getRedisKey(RedisKeys.KEY_PLATFORM_LASTTOKENDATE,
|
|
|
+ Long.parseLong(supplierCode), true) + platformInfo.getPlatformCode()));
|
|
|
+ int diffSeconds = (int) ((System.currentTimeMillis() - lastTime) / 1000);
|
|
|
+
|
|
|
+ if (diffSeconds <= tokenRefreshSeconds) {
|
|
|
+ tokenInitialDelay = tokenRefreshSeconds - diffSeconds;
|
|
|
+ if (tokenInitialDelay < 30) {
|
|
|
+ tokenInitialDelay = 30;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ dyAccessTokenThread.scheduleWithFixedDelay(() -> {
|
|
|
+ scanRefreshToken(platformInfo.getPlatformCode(), dataSourceId, supplierCode);
|
|
|
+ //写入当前时间
|
|
|
+ redisService.set(keysService.getRedisKey(RedisKeys.KEY_PLATFORM_LASTTOKENDATE, Long.parseLong(supplierCode), true) + platformInfo.getPlatformCode(),
|
|
|
+ String.valueOf(Date.from(Instant.now()).getTime()));
|
|
|
+ }, tokenInitialDelay, tokenRefreshSeconds, TimeUnit.SECONDS);
|
|
|
+
|
|
|
+ threadPoolMap.put(platformInfo.getPlatformCode(), dyAccessTokenThread);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void destroy(AnyValue config) {
|
|
|
+ threadPoolMap.forEach((platformCode, threadPoolExecutor) -> {
|
|
|
+ if (threadPoolExecutor != null) {
|
|
|
+ threadPoolExecutor.shutdownNow();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void scanRefreshToken(String platFormCode, String dataSourceId, String supplierCode) {
|
|
|
+ RMap tokenMap = null;
|
|
|
+ String accessToken = null;
|
|
|
+ //抖音有可能获取不到token,这里循环获取,直到有值?
|
|
|
+ do {
|
|
|
+ tokenMap = this.requestAccessToken(platFormCode, dataSourceId, supplierCode);
|
|
|
+ accessToken = tokenMap.getString("accessToken");
|
|
|
+ } while ((accessToken == null) || (StringUtils.isEmpty(accessToken)));
|
|
|
+
|
|
|
+ redisService.hset(keysService.getRedisKey(RedisKeys.KEY_PLATFORM_ACCESSTOKEN, Long.parseLong(supplierCode)),
|
|
|
+ platFormCode, tokenMap);
|
|
|
+ logger.info("[" + platFormCode + "]服务刷新token:" + accessToken);
|
|
|
+ }
|
|
|
+
|
|
|
+ //map中将会返回 appId/appSecret/accessToken
|
|
|
+ private RMap requestAccessToken(String platFormCode, String dataSourceId, String supplierCode) {
|
|
|
+ RetResult<ScriptMapResult> retResult = this.handleScript("Token_RefreshAccessToken_" + platFormCode, ERPModule.PLATFORM_TOKEN,
|
|
|
+ dataSourceId, Long.parseLong(supplierCode),
|
|
|
+ () -> {
|
|
|
+ return ProcessStringItem.newBuilder().itemValue(platFormCode)
|
|
|
+ .currentUser(ERPUtils.getSysTokenUser())
|
|
|
+ .dataSourceId(dataSourceId)
|
|
|
+ .supplierCode(Long.parseLong(supplierCode))
|
|
|
+ .build();
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!retResult.isSuccess()) return null;
|
|
|
+ return retResult.getResult().getResultMap();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getAccessToken(String platformCode, String dataSourceId, String supplierCode) {
|
|
|
+ PlatformInfo platformInfo = platformService.getPlatformInfoByCode(platformCode, false, Long.parseLong(supplierCode));
|
|
|
+ if (platformInfo == null) return null;
|
|
|
+ if (platformInfo.getNeedAccessToken() != 1) return null;
|
|
|
+
|
|
|
+ String tokenMap = redisService.hget(keysService.getRedisKey(RedisKeys.KEY_PLATFORM_ACCESSTOKEN, Long.parseLong(supplierCode)), platformCode);
|
|
|
+ if (StringUtils.isBlank(tokenMap)) {
|
|
|
+ //token不存在,直接刷新一下
|
|
|
+ this.scanRefreshToken(platformCode, dataSourceId, supplierCode);
|
|
|
+ tokenMap = redisService.hget(keysService.getRedisKey(RedisKeys.KEY_PLATFORM_ACCESSTOKEN, Long.parseLong(supplierCode)), platformCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ RMap map = jsonConvert.convertFrom(RMap.class, tokenMap);
|
|
|
+
|
|
|
+ return map.getString("accessToken");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String postInvoker(String platformCode, String subUrl, String body, String dataSourceId, String supplierCode) {
|
|
|
+ RetResult<ScriptStringResult> retResult = this.handleScript("Invoke_PostInvoker_" + platformCode, ERPModule.PLATFORM_TOKEN,
|
|
|
+ dataSourceId, Long.parseLong(supplierCode),
|
|
|
+ () -> {
|
|
|
+ RMap reqMap = new RMap();
|
|
|
+ reqMap.set("subUrl", subUrl);
|
|
|
+ reqMap.set("body", body);
|
|
|
+ return ProcessMapItem.newBuilder()
|
|
|
+ .itemData(reqMap)
|
|
|
+ .currentUser(ERPUtils.getSysTokenUser())
|
|
|
+ .dataSourceId(dataSourceId)
|
|
|
+ .supplierCode(Long.parseLong(supplierCode))
|
|
|
+ .build();
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!retResult.isSuccess()) return null;
|
|
|
+ return retResult.getResult().getResultStr();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getInvoker(String platformCode, String subUrl, String body, String dataSourceId, String supplierCode) {
|
|
|
+ RetResult<ScriptStringResult> retResult = this.handleScript("Invoke_GetInvoker_" + platformCode, ERPModule.PLATFORM_TOKEN,
|
|
|
+ dataSourceId, Long.parseLong(supplierCode),
|
|
|
+ () -> {
|
|
|
+ RMap reqMap = new RMap();
|
|
|
+ reqMap.set("subUrl", subUrl);
|
|
|
+ reqMap.set("body", body);
|
|
|
+ return ProcessMapItem.newBuilder()
|
|
|
+ .itemData(reqMap)
|
|
|
+ .currentUser(ERPUtils.getSysTokenUser())
|
|
|
+ .dataSourceId(dataSourceId)
|
|
|
+ .supplierCode(Long.parseLong(supplierCode))
|
|
|
+ .build();
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!retResult.isSuccess()) return null;
|
|
|
+ return retResult.getResult().getResultStr();
|
|
|
+ }
|
|
|
+}
|