All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sdn.api.DefaultOpenClient Maven / Gradle / Ivy

package org.sdn.api;

import com.alibaba.fastjson.JSON;
import org.apache.log4j.BasicConfigurator;
import org.sdn.api.constants.ErrorMsgEnum;
import org.sdn.api.constants.OpenApiConstants;
import org.sdn.api.domain.OpenClientDO;
import org.sdn.api.event.MessageEvent;
import org.sdn.api.request.OpenAuthRequest;
import org.sdn.api.request.OpenRequest;
import org.sdn.api.response.OpenAuthResponse;
import org.sdn.api.response.OpenResponse;
import org.sdn.api.utils.Signature;
import org.sdn.api.utils.StringUtils;
import org.sdn.api.utils.http.rest.RestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author gaosong
 * @date 2018/10/15.
 */
public class DefaultOpenClient implements OpenClient {

    private Logger logger = LoggerFactory.getLogger(DefaultOpenClient.class);

    private static ConcurrentHashMap clientConcurrentHashMap = new ConcurrentHashMap<>();

    /**
     * http请求工具
     */
    private RestTemplate restTemplate;
    /**
     * 服务端url
     */
    private String serverUrl;
    /**
     * 客户id
     */
    private String appKey;
    /**
     * 客户密钥
     */
    private String appSecret;
    /**
     * token
     */
    private String authToken;

    private String charset;

    private String authEvent;

    /**
     * 接口请求超时时间,单位毫秒,如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
     * 

默认在6s内接口未返回报超时

*/ private int socketTimeout = 6000; ConcurrentHashMap futureMap = new ConcurrentHashMap<>(); /** * 初始化token,默认启动事件监听器 * * @param serverUrl * @param appKey * @param appSecret * @throws OpenApiException */ public DefaultOpenClient(String serverUrl, String appKey, String appSecret) throws OpenApiException { this(serverUrl, appKey, appSecret, true); } public OpenClientDO getOpenClientDO() { OpenClientDO openClientDO = new OpenClientDO(); openClientDO.setAuthEvent(this.authEvent); openClientDO.setAuthToken(this.authToken); openClientDO.setAppSecret(this.appSecret); return openClientDO; } /** * 初始化 * * @param serverUrl * @param appKey * @param appSecret * @param needSubscribe 是否需要启动事件监听器 * @throws OpenApiException */ public DefaultOpenClient(String serverUrl, String appKey, String appSecret, boolean needSubscribe) throws OpenApiException { this.restTemplate = new RestTemplate(); this.serverUrl = serverUrl; this.appKey = appKey; this.appSecret = appSecret; ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); try { if (needSubscribe) { initTokenAndSub(); } else { initToken(); } String checkKey = serverUrl + ":" + appKey; if (clientConcurrentHashMap.containsKey(checkKey)) { throw new OpenApiException(ErrorMsgEnum.DUPLICATE_ERROR.getErrno(), String.format("serverUrl[%s],app[%s] has been inited.", serverUrl, appKey)); } else { clientConcurrentHashMap.put(checkKey, this); } } catch (OpenApiException e) { if (e.getErrno() == ErrorMsgEnum.DUPLICATE_ERROR.getErrno()) { throw e; } // 非重复注册异常,创建重新初始化job Runnable runnable = new Runnable() { @Override public void run() { try { if (futureMap.get(true)) { logger.info("定时任务,初始化token成功,关闭定时任务 token ={}", authToken); scheduler.shutdown(); } else { boolean isTrue = false; if (needSubscribe) { isTrue = initTokenAndSub(); } else { isTrue = initToken(); } futureMap.put(true, isTrue); } } catch (OpenApiException e) { } } }; // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间 scheduler.scheduleAtFixedRate(runnable, 10, 10, TimeUnit.SECONDS); futureMap.put(true, false); logger.info("初始化token失败,启动定时任务初始化token"); } } /** * 取消初始化client * * @param serverUrl * @param appKey */ @Override public boolean removeClient(String serverUrl, String appKey) { String checkKey = serverUrl + ":" + appKey; boolean remove = false; if (clientConcurrentHashMap.containsKey(checkKey)) { DefaultOpenClient defaultOpenClient = clientConcurrentHashMap.get(checkKey); remove = clientConcurrentHashMap.remove(checkKey, defaultOpenClient); } return remove; } public static DefaultOpenClient getClient(String serverUrl, String appKey) { String checkKey = serverUrl + ":" + appKey; return clientConcurrentHashMap.get(checkKey); } /** * 更新 appSecret 同时更新 authToken * * @param appSecret * @return * @throws OpenApiException */ public boolean updateSecret(String appSecret) throws OpenApiException { boolean result = false; this.appSecret = appSecret; initToken(); return result; } /** * 初始化token并订阅事件 */ public boolean initToken() throws OpenApiException { boolean isTrue = false; try { OpenAuthRequest openAuthRequest = new OpenAuthRequest(); OpenAuthResponse openAuthResponse = defaultExecute(openAuthRequest); if (openAuthResponse.isSuccess()) { if (StringUtils.isEmpty(openAuthResponse.getAccess_token())) { throw new OpenApiException(ErrorMsgEnum.INITCLIENT_ERROR.getErrno(), openAuthResponse.getMsg()); } this.authEvent = openAuthResponse.getAuth_event(); this.socketTimeout = openAuthResponse.getSocketTimeout() == 0 ? this.socketTimeout : openAuthResponse.getSocketTimeout(); this.authToken = openAuthResponse.getAccess_token(); isTrue = true; } } catch (OpenApiException e) { logger.error("initToken() error={}", e.getMessage()); throw e; } catch (Exception e) { logger.error("initToken() error={}", e.getMessage()); throw new OpenApiException(ErrorMsgEnum.INITCLIENT_ERROR.getErrno(), ErrorMsgEnum.INITCLIENT_ERROR.getErrmsg()); } return isTrue; } /** * 初始化token并订阅事件 */ public boolean initTokenAndSub() throws OpenApiException { boolean isTrue = false; try { initToken(); MessageEvent.start(this, this.authToken); isTrue = true; } catch (Exception e) { logger.error("initTokenAndSub() error={}", e.getMessage()); throw new OpenApiException(e); } return isTrue; } @Override public T defaultExecute(OpenRequest request) throws OpenApiException { return doDefaultExecute(request, this.authToken); } @Override public T defaultExecute(OpenRequest request, String authToken) throws OpenApiException { return doDefaultExecute(request, authToken); } /** * 执行 * * @param request * @param * @return * @throws OpenApiException */ private T doDefaultExecute(OpenRequest request, String authToken) throws OpenApiException { Map result = doExecute(request, authToken); T rsp = null; try { Class clazz = request.getResponseClass(); rsp = clazz.newInstance(); } catch (InstantiationException e) { logger.error("doDefaultExecute() InstantiationException error={}", e.getMessage()); throw new OpenApiException(e); } catch (IllegalAccessException e) { logger.error("doDefaultExecute() IllegalAccessException error={}", e.getMessage()); throw new OpenApiException(e); } String body = (String) result.get("rsp"); rsp = JSON.parseObject(body, request.getResponseClass()); rsp.setBody(body); return rsp; } /** * @param request * @param accessToken * @return * @throws OpenApiException */ private Map doExecute(OpenRequest request, String accessToken) throws OpenApiException { if (appKey == null) { throw new OpenApiException(ErrorMsgEnum.MISSING_APPKEY); } if (appSecret == null) { throw new OpenApiException(ErrorMsgEnum.LACK_PARAMS.getErrno(), ErrorMsgEnum.LACK_PARAMS.getErrmsg() + ":appSecret"); } /**请求url*/ String url = getRequestUrl(request); Map result = new HashMap(); String rsp = null; try { if (accessToken == null || accessToken.equals("")) { accessToken = this.authToken; } Map reqMap = getRequestWithSign(request, accessToken); /**设置header*/ Map headers = request.getHeaderMap(); if (headers == null) { headers = new HashMap<>(); } headers.put(OpenApiConstants.METHOD, request.getApiMethodName()); if (!StringUtils.isEmpty(accessToken)) { headers.put(OpenApiConstants.ACCESS_TOKEN, accessToken); } String method = request.getRequestMethod(); if (method.equalsIgnoreCase(OpenApiConstants.REQUEST_METHOD)) { rsp = restTemplate.post(url, JSON.toJSONString(reqMap), headers, socketTimeout, method); } else if (method.equalsIgnoreCase(OpenApiConstants.REQUEST_METHOD_PUT)) { rsp = restTemplate.post(url, JSON.toJSONString(reqMap), headers, socketTimeout, method); } else { rsp = restTemplate.get(url, reqMap, headers, socketTimeout, method); } } catch (Exception e) { logger.error("doExecute() error={}", e.getMessage()); throw new OpenApiException(e); } result.put("rsp", rsp); return result; } /** * 组装接口参数,处理加密、签名逻辑 * * @param request * @param accessToken * @return * @throws OpenApiException */ public Map getRequestWithSign(OpenRequest request, String accessToken) throws OpenApiException { /**过滤请求参数*/ Map reqMap = Signature.paraFilter(request.getMapParams()); if (StringUtils.isEmpty(charset)) { charset = OpenApiConstants.CHARSET_UTF8; } if (request.getApiMethodName().contains("?")) { reqMap = StringUtils.getUrlParams(request.getApiMethodName()); } reqMap.put(OpenApiConstants.METHOD, request.getApiMethodName()); if (request instanceof OpenAuthRequest) { reqMap.put(OpenApiConstants.APP_ID, this.appKey); reqMap.put(OpenApiConstants.CLIENT_SECRET, this.appSecret); } else { reqMap.put(OpenApiConstants.SIGN, Signature.getSign(reqMap, appSecret)); } return reqMap; } /** * 获取POST请求的base url * * @param request * @return * @throws OpenApiException */ public String getRequestUrl(OpenRequest request) throws OpenApiException { StringBuffer urlSb = new StringBuffer(serverUrl); try { if (!serverUrl.endsWith("/")) { urlSb.append("/"); } String method = request.getApiMethodName().replace(".", "/"); int len = method.indexOf("?"); if (len > 0) { urlSb.append(method.substring(0, len)); } else { urlSb.append(method); } } catch (Exception e) { logger.error("getRequestUrl() error={}", e.getMessage()); throw new OpenApiException(e); } return urlSb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy