package info.aspirecn.iov.sjjh.supplier10000043.service;
import brave.Tracer;
import com.alibaba.fastjson.JSONArray;
import info.aspirecn.iov.sjjh.channel.inter.platform.ChannelActionInterface;
import info.aspirecn.iov.sjjh.service.sms.action.SmsActionInterface;
import info.aspirecn.iov.sjjh.supplier10000043.constant.SupplierProperties;
import info.aspirecn.iov.sjjh.supplier10000043.util.AesUtil;
import info.aspirecn.iov.sjjh.supplier10000043.util.CommonUtil;
import info.aspirecn.iov.sjjh.supplier10000043.util.NotifyThread;
import okhttp3.*;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import info.aspirecn.iov.sjjh.commons.lang.ChannelTypeHandleResponseObject;
import info.aspirecn.iov.sjjh.commons.lang.Constant;
import info.aspirecn.iov.sjjh.commons.lang.PatternTools;
import info.aspirecn.iov.sjjh.supplier10000043.constant.SjjhConstant;
import info.aspirecn.iov.sjjh.supplier10000043.model.*;
import info.aspirecn.iov.sjjh.supplier10000043.util.DESedeUtil;
import info.aspirecn.rdc.aspirecloud.node.except.utils.ErrorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.axis.AxisFault;
import org.apache.axis.AxisProperties;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.rpc.encoding.XMLType;
import javax.xml.ws.WebServiceException;
import java.io.IOException;
import java.io.StringReader;
import java.net.SocketTimeoutException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* @description:
* @author: xusonglin
* @create: 2020/6/15 16:02
* @version: V1.0
**/
@Service
@Slf4j
public class ChannelServiceImpl implements ChannelService {
@Autowired
private Tracer tracer;
@Value("${supplier.url}")
private String url;
@Autowired
private CommonUtil commonUtil;
@Value("${supplier.twoElementsMethod}")
private String twoElementsMethod;
@Value("${supplier.photoIdentityMethod}")
private String photoIdentityMethod;
@Value("${supplier.decryptKey}")
private String decryptKey;
@Value("${supplier.urlV2}")
private String urlV2;
@Value("${spring.application.name}")
private String applicationName;
@Value("${supplier.decodeApi}")
private String decodeApi;
@Value("${supplier.decodeUrl}")
private String decodeUrl;
@Value("${supplier.decodeAppKey}")
private String decodeAppKey;
@Value("${supplier.decodeAppSecret}")
private String decodeAppSecret;
@Value("${supplier.aesDecryptKey}")
private String aesDecryptKey;
@Value("${supplier.urlV3}")
private String urlV3;
@Value("${supplier.urlV4}")
private String urlV4;
@Autowired
SupplierProperties supplierProperties;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
SmsActionInterface smsActionInterface;
@Autowired
ChannelActionInterface channelActionInterface;
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
@Autowired
private ObjectMapper objectMapper;
@Override
public ChannelTypeHandleResponseObject twoElementsCheck(HttpServletRequest request, String customBody, int outTime, String decodeType) {
ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
ret.setCode(Constant.SUCCESS);
String upstreamCode = "" + Constant.LOG_UPSTREAM_DEFAULT_RESPONSE_CODE;
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
String returnType = request.getHeader(Constant.CUSTOMER_RETURN_TYPE_PARA);
if (StringUtils.isBlank(returnType)) {
returnType = Constant.CUSTOMER_RETURN_ZW;
}
if (outTime <= SjjhConstant.PARA_ZERO) {
outTime = Constant.HTTPCLIENT_CONNECTTIMEOUT;
}
log.info("supplier10000043.twoElementsCheck---customBody={},outTime={}", customBody, outTime);
/* String key="url"+twoElementsMethod;
LocalDateTime now = LocalDateTime.now();
String ymd = dateTimeFormatter.format(now);
String hashKey = "043-"+ymd;
boolean flag = checkVisitCount(hashKey,key,supplierProperties.getUrlSecondUp());
if(!flag){
countOver(ret);
return ret;
}*/
if (!decodeType.equals(SjjhConstant.DECODE_TYPE_COMMON)) {
customBody = decodeParams(ret, returnType, customBody, decodeType);
if (StringUtils.isBlank(customBody)) {
// ret.setCode(Constant.SUCCESS);
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
//reduceVisitCount(hashKey,key);
return ret;
}
}
try {
TwoElementsRequestObject requestObject = objectMapper.readValue(customBody,
TwoElementsRequestObject.class);
log.info("supplier10000043.twoElementsCheck---requestObject={}", requestObject);
// 参数校验
if (!validateRequestParams(ret, returnType, requestObject)) {
ret.setCode(Constant.SUCCESS);
// reduceVisitCount(hashKey,key);
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
return ret;
}
// 直接引用远程的wsdl文件
// 以下都是套路
AxisProperties.setProperty("axis.socketSecureFactory", "org.apache.axis.components.net.SunFakeTrustSocketFactory");
org.apache.axis.client.Service service = new org.apache.axis.client.Service();
org.apache.axis.client.Call call = (org.apache.axis.client.Call) service.createCall();
call.setTargetEndpointAddress(url);
call.setOperationName(twoElementsMethod);// WSDL里面描述的接口名称
call.setTimeout(outTime);
call.addParameter(SjjhConstant.PARAMETER_INLICENSE,
XMLType.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);// 接口的参数
call.addParameter(SjjhConstant.PARAMETER_INCONDITIONS,
XMLType.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 设置返回类型
String paramXml = SjjhConstant.TWO_ELEMENTS_XML_TEMPLATE
.replace("{fsd}", requestObject.getIdCode().substring(0, 6))
.replace("{ywlx}", SjjhConstant.PARAMETER_YWLX)
.replace("{idCode}", requestObject.getIdCode())
.replace("{name}", requestObject.getName());
String result = (String) call.invoke(new Object[]{SjjhConstant.TWO_ELEMENTS_SECRET_KEY, paramXml});
// String result = "-20计费失败,请与管理员联系(errorcode=-20)!
";
log.info("twoElementsCheck上游返回xml:{}", result);
upstreamCode = setTwoElementsCheckResponse(ret, returnType, result);
} catch (SocketTimeoutException ste) {
log.info("supplier10000043.twoElementsCheck接口-SocketTimeoutException:{}", ste);
ErrorUtils.captureException(ste);
ret.setCode(Constant.REQUEST_TIMEOUT);
} catch (AxisFault axisFault) {
log.info("supplier10000043.twoElementsCheck接口-AxisFaultException:{}", axisFault);
ErrorUtils.captureException(axisFault);
ret.setCode(Constant.REQUEST_TIMEOUT);
} catch (Exception ioe) {
log.info("supplier10000043.twoElementsCheck接口-Exception:{}", ioe);
ErrorUtils.captureException(ioe);
ret.setCode(Constant.FAIL);
}
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
return ret;
}
@Override
public ChannelTypeHandleResponseObject twoElementsCheckNew(HttpServletRequest request, String customBody, int outTime, String decodeType) {
ChannelTypeHandleResponseObject ret = new ChannelTypeHandleResponseObject();
ret.setIsCharge(Constant.INTERFACE_QUERY_NO_FEE);
ret.setCode(Constant.SUCCESS);
String upstreamCode = "" + Constant.LOG_UPSTREAM_DEFAULT_RESPONSE_CODE;
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
String returnType = request.getHeader(Constant.CUSTOMER_RETURN_TYPE_PARA);
if (StringUtils.isBlank(returnType)) {
returnType = Constant.CUSTOMER_RETURN_ZW;
}
if (outTime <= SjjhConstant.PARA_ZERO) {
outTime = Constant.HTTPCLIENT_CONNECTTIMEOUT;
}
log.info("supplier10000043.twoElementsCheckNew---customBody={},outTime={}", customBody, outTime);
/* String key="url"+twoElementsMethod;
LocalDateTime now = LocalDateTime.now();
String ymd = dateTimeFormatter.format(now);
String hashKey = "043-"+ymd;
boolean flag = checkVisitCount(hashKey,key,supplierProperties.getUrlSecondUp());
if(!flag){
countOver(ret);
return ret;
}*/
if (!decodeType.equals(SjjhConstant.DECODE_TYPE_COMMON)) {
customBody = decodeParams(ret, returnType, customBody, decodeType);
if (StringUtils.isBlank(customBody)) {
ret.setCode(Constant.SUCCESS);
//reduceVisitCount(hashKey,key);
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
return ret;
}
}
try {
TwoElementsRequestObject requestObject = objectMapper.readValue(customBody,
TwoElementsRequestObject.class);
log.info("supplier10000043.twoElementsCheckNew---requestObject={}", requestObject);
// 参数校验
if (!validateRequestParams(ret, returnType, requestObject)) {
ret.setCode(Constant.SUCCESS);
//reduceVisitCount(hashKey,key);
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
return ret;
}
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(NciicServicesPortType.class);// 设置请求接口
factory.setAddress(url);
NciicServicesPortType nciicServices = (NciicServicesPortType) factory.create(); // 创建客户端对象
// 设置客户端的配置信息,超时等.
Client proxy = ClientProxy.getClient(nciicServices);
HTTPConduit conduit = (HTTPConduit) proxy.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(outTime); // 连接超时时间
policy.setReceiveTimeout(outTime);// 请求超时时间.
conduit.setClient(policy);
String paramXml = SjjhConstant.TWO_ELEMENTS_XML_TEMPLATE
.replace("{fsd}", requestObject.getIdCode().substring(0, 6))
.replace("{ywlx}", SjjhConstant.PARAMETER_YWLX)
.replace("{idCode}", requestObject.getIdCode())
.replace("{name}", requestObject.getName());
String result = nciicServices.nciicCheck(SjjhConstant.TWO_ELEMENTS_SECRET_KEY,paramXml);
// String result = "-20计费失败,请与管理员联系(errorcode=-20)!
";
log.info("twoElementsCheck上游返回xml:{}", result);
upstreamCode = setTwoElementsCheckResponse(ret, returnType, result);
} catch (SocketTimeoutException ste) {
log.info("supplier10000043.twoElementsCheck接口-SocketTimeoutException:{}", ste);
ErrorUtils.captureException(ste);
ret.setCode(Constant.REQUEST_TIMEOUT);
} catch (AxisFault axisFault) {
log.info("supplier10000043.twoElementsCheck接口-AxisFaultException:{}", axisFault);
ErrorUtils.captureException(axisFault);
ret.setCode(Constant.REQUEST_TIMEOUT);
} catch (Exception ioe) {
log.info("supplier10000043.twoElementsCheck接口-Exception:{}", ioe);
ErrorUtils.captureException(ioe);
ret.setCode(Constant.FAIL);
}
request.setAttribute(Constant.LOG_UPSTREAM_RESPONSE_CODE, upstreamCode);
return ret;
}
private String decodeParams(ChannelTypeHandleResponseObject ret, String returnType, String customBody, String decodeType) {
JSONObject requestParamObject = JSONObject.parseObject(customBody);
if (decodeType.equals(SjjhConstant.DECODE_TYPE_WEIZHONG)) {
if (requestParamObject.get("params") == null) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
ret.setResultBody(Constant.INVALID_PARAMETER);
ret.setResultDesc(Constant.INVALID_PARAMETER);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
ret.setResultBody(Constant.INVALID_PARAMETER);
ret.setResultDesc(Constant.INVALID_PARAMETER);
}
return "";
}
customBody = DESedeUtil.decryptMode(requestParamObject.getString("params"), decryptKey);
if (StringUtils.isBlank(customBody)) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.ZW_RETURN_CODE_133);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_9931);
}
ret.setResultBody(Constant.RETURN_MESSAGE_133);
ret.setResultDesc(Constant.RETURN_MESSAGE_133);
return "";
}
requestParamObject = null;
return customBody;
}
if (decodeType.equals(SjjhConstant.DECODE_TYPE_MD5) || decodeType.equals(SjjhConstant.DECODE_TYPE_SHA256)) {
if (requestParamObject.get("idCode") == null || requestParamObject.get("name") == null) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
}
ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
return "";
}
if (StringUtils.isBlank(requestParamObject.getString("idCode"))
|| StringUtils.isBlank(requestParamObject.getString("name"))
|| (decodeType.equals(SjjhConstant.DECODE_TYPE_MD5)
&& (requestParamObject.getString("idCode").length() != 32
|| requestParamObject.getString("name").length() != 32))
|| (decodeType.equals(SjjhConstant.DECODE_TYPE_SHA256)
&& (requestParamObject.getString("idCode").length() != 64
|| requestParamObject.getString("name").length() != 64))) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
}
ret.setResultBody(Constant.INVALID_PARAMETER);
ret.setResultDesc(Constant.INVALID_PARAMETER);
return "";
}
requestParamObject = getDecodeIdCard(requestParamObject, 10000, decodeType);
if (StringUtils.isBlank(requestParamObject.getString("idCode")) || StringUtils.isBlank(requestParamObject.getString("name"))) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.ZW_RETURN_CODE_134);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_9932);
}
ret.setResultBody(Constant.RETURN_MESSAGE_134);
ret.setResultDesc(Constant.RETURN_MESSAGE_134);
return "";
} else {
customBody = JSON.toJSONString(requestParamObject);
requestParamObject = null;
return customBody;
}
}
if (decodeType.equals(SjjhConstant.DECODE_TYPE_AES)) {
if (requestParamObject.get("params") == null) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
ret.setResultBody(Constant.INVALID_PARAMETER);
ret.setResultDesc(Constant.INVALID_PARAMETER);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
ret.setResultBody(Constant.INVALID_PARAMETER);
ret.setResultDesc(Constant.INVALID_PARAMETER);
}
return "";
}
try {
customBody = AesUtil.decryAES(aesDecryptKey, requestParamObject.getString("params"));
if (StringUtils.isBlank(customBody)) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.ZW_RETURN_CODE_133);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_9931);
}
ret.setResultBody(Constant.RETURN_MESSAGE_133);
ret.setResultDesc(Constant.RETURN_MESSAGE_133);
return "";
}
requestParamObject = null;
return customBody;
} catch (Exception e) {
ErrorUtils.captureException(e);
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.ZW_RETURN_CODE_133);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_9931);
}
ret.setResultBody(Constant.RETURN_MESSAGE_133);
ret.setResultDesc(Constant.RETURN_MESSAGE_133);
return "";
}
}
return customBody;
}
private boolean validateRequestParams(ChannelTypeHandleResponseObject ret, String returnType,
TwoElementsRequestObject requestObject) {
if (!validateParamNullValue(requestObject)) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.INVALID_PARAMETER_CODE);
ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
} else {
ret.setResultCode(Constant.JK_RETURN_CODE_INVALID_PARAMETER);
ret.setResultBody(Constant.PARAMETER_NAME_ERROR);
ret.setResultDesc(Constant.PARAMETER_NAME_ERROR);
}
return false;
} else if (StringUtils.isBlank(requestObject.getName()) ||
!PatternTools.checkResult(Constant.PATTERN_SPECIAL_CN_NAME_REGEX, requestObject.getName())) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.NAME_FORMAT_ERROR_CODE);
ret.setResultDesc(Constant.NAME_FORMAT_ERROR);
ret.setResultBody(Constant.NAME_FORMAT_ERROR);
} else {
ret.setResultCode(Constant.JK_NAME_FORMAT_ERROR_CODE);
ret.setResultDesc(Constant.JK_NAME_FORMAT_ERROR);
ret.setResultBody(Constant.JK_NAME_FORMAT_ERROR);
}
return false;
} else if (StringUtils.isBlank(requestObject.getIdCode())
|| !PatternTools.checkResult(Constant.PATTERN_SPECIAL_ID_NUMBER_REGEX, requestObject.getIdCode())) {
if (Constant.CUSTOMER_RETURN_ZW.equals(returnType)) {
ret.setResultCode(Constant.IDCODE_FORMAT_ERROR_CODE);
ret.setResultDesc(Constant.IDCODE_FORMAT_ERROR);
ret.setResultBody(Constant.IDCODE_FORMAT_ERROR);
} else {
ret.setResultCode(Constant.JK_IDCODE_FORMAT_ERROR_CODE);
ret.setResultDesc(Constant.JK_IDCODE_FORMAT_ERROR);
ret.setResultBody(Constant.JK_IDCODE_FORMAT_ERROR);
}
return false;
} else {
return true;
}
}
private boolean validateParamNullValue(Object jsonResolveObject) {
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
Set> set = validator.validate(jsonResolveObject);
for (ConstraintViolation