@@ -13,8 +13,9 @@ dependencies { | |||
implementation "${groupname}:common-core:1.0.0-SNAPSHOT" | |||
implementation "${groupname}:entity-core:1.0.0-SNAPSHOT" | |||
implementation "${groupname}:comm-core:1.0.0-SNAPSHOT" | |||
implementation "${groupname}:sample-protocol:1.0.0-SNAPSHOT" | |||
implementation "${groupname}:inss-protocol:1.0.0-SNAPSHOT" | |||
implementation "${groupname}:smp-protocol:1.0.0-SNAPSHOT" | |||
implementation "org.springframework.boot:spring-boot-starter-data-redis" | |||
implementation "com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery" | |||
implementation "com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config" | |||
implementation "org.springframework.cloud:spring-cloud-starter-openfeign" |
@@ -0,0 +1,49 @@ | |||
package cn.com.taiji.inss.config; | |||
import com.fasterxml.jackson.annotation.JsonAutoDetect; | |||
import com.fasterxml.jackson.annotation.PropertyAccessor; | |||
import com.fasterxml.jackson.databind.ObjectMapper; | |||
import com.fasterxml.jackson.databind.SerializationFeature; | |||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; | |||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.data.redis.connection.RedisConnectionFactory; | |||
import org.springframework.data.redis.core.RedisTemplate; | |||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; | |||
import org.springframework.data.redis.serializer.StringRedisSerializer; | |||
@Configuration | |||
public class RedisConfig { | |||
@Autowired | |||
private RedisConnectionFactory factory; | |||
@Bean | |||
public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() { | |||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); | |||
ObjectMapper objectMapper = new ObjectMapper(); | |||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); | |||
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); | |||
// 解决redis 序列化时不支持 LocalDateTime 的问题 | |||
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); | |||
//格式化时间格式 | |||
JavaTimeModule javaTimeModule = new JavaTimeModule(); | |||
objectMapper.registerModule(javaTimeModule); | |||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper); | |||
return jackson2JsonRedisSerializer; | |||
} | |||
@Bean | |||
public RedisTemplate<String, Object> redisTemplate() { | |||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); | |||
redisTemplate.setKeySerializer(new StringRedisSerializer()); | |||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer()); | |||
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); | |||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer()); | |||
redisTemplate.setConnectionFactory(factory); | |||
return redisTemplate; | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
package cn.com.taiji.inss.config; | |||
import lombok.Data; | |||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||
import org.springframework.stereotype.Component; | |||
@Data | |||
@ConfigurationProperties("vfj") | |||
@Component | |||
public class VfjConfigProperties { | |||
private String url; | |||
private String terminalId; | |||
private String netNodeId; | |||
private String serverPublicKey; | |||
private String clientPublicKey; | |||
private String clientPrivateKey; | |||
} |
@@ -2,46 +2,38 @@ package cn.com.taiji.inss.manager; | |||
import javax.annotation.PostConstruct; | |||
import cn.com.taiji.core.model.comm.protocol.SignJsonRequest; | |||
import cn.com.taiji.core.model.comm.protocol.SignServiceType; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceSystem; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceType; | |||
import cn.com.taiji.inss.manager.handler.VfjServiceHandler; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import com.zgglyun.common.model.AbstractCommRequest; | |||
import com.zgglyun.common.model.AbstractHttpRequestInfo; | |||
import cn.com.taiji.core.manager.comm.AbstractCommHandleManager; | |||
import cn.com.taiji.core.model.comm.protocol.sample.SampleServiceSystem; | |||
import cn.com.taiji.core.model.comm.protocol.sample.SampleServiceType; | |||
import cn.com.taiji.inss.manager.handler.SampleServiceHandler; | |||
/** | |||
* | |||
* @author Peream <br> | |||
* Create Time:2019年7月28日 下午3:35:29<br> | |||
* @since 1.0 | |||
* Create Time:2019年7月28日 下午3:35:29<br> | |||
* @version 1.0 | |||
* @since 1.0 | |||
*/ | |||
@Service | |||
public class MyCommHandleManager extends AbstractCommHandleManager { | |||
@Autowired | |||
private SampleServiceHandler sampleServiceHandler; | |||
private VfjServiceHandler vfjServiceHandler; | |||
public MyCommHandleManager() { | |||
super(SampleServiceSystem.SAMPLE); | |||
super(InssServiceSystem.INSS); | |||
} | |||
@PostConstruct | |||
public void init() { | |||
registerJsonService(sampleServiceHandler); | |||
registerJsonService(vfjServiceHandler); | |||
} | |||
@Override | |||
protected SignServiceType getServiceType(String ifCode) { | |||
return SampleServiceType.fromIfCode(ifCode); | |||
return InssServiceType.fromIfCode(ifCode); | |||
} | |||
} |
@@ -0,0 +1,225 @@ | |||
package cn.com.taiji.inss.manager.cache; | |||
import cn.com.taiji.common.entity.BaseEntity; | |||
import cn.com.taiji.common.manager.AbstractManager; | |||
import cn.com.taiji.common.model.dao.Pagination; | |||
import cn.com.taiji.common.pub.StringTools; | |||
import cn.com.taiji.common.pub.json.JsonTools; | |||
import org.apache.commons.collections4.map.HashedMap; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.data.redis.core.Cursor; | |||
import org.springframework.data.redis.core.HashOperations; | |||
import org.springframework.data.redis.core.RedisTemplate; | |||
import org.springframework.data.redis.core.ScanOptions.ScanOptionsBuilder; | |||
import org.springframework.stereotype.Service; | |||
import java.io.IOException; | |||
import java.util.*; | |||
import java.util.Map.Entry; | |||
import java.util.concurrent.TimeUnit; | |||
import java.util.function.Supplier; | |||
/** | |||
* hash操作的方法以hash开头,如:hashGet<br> | |||
* | |||
* @author lijun <br> | |||
* Create Time:2018年12月9日 下午1:43:54<br> | |||
* mail:756915505@qq.com | |||
* @since 1.0 | |||
* @version 1.0 | |||
*/ | |||
@Service | |||
public class RedisWrapManager extends AbstractManager { | |||
@Autowired(required = false) | |||
private RedisTemplate<String, String> redisTemplate; | |||
public Set<String> key(String pattern) { | |||
if ("*".equals(pattern)) { | |||
throw new RuntimeException("禁止全扫描key"); | |||
} | |||
return redisTemplate.keys(pattern); | |||
} | |||
public Boolean expire(String key, final long timeout, final TimeUnit unit) { | |||
return redisTemplate.expire(key, timeout, unit); | |||
} | |||
public Boolean hasKey(String key) { | |||
return redisTemplate.hasKey(key); | |||
} | |||
public String get(String key) { | |||
return redisTemplate.opsForValue().get(key); | |||
} | |||
public String getAndSet(String key, String value) { | |||
return redisTemplate.opsForValue().getAndSet(key, value); | |||
} | |||
public void set(String key, String value, long timeout, TimeUnit unit) { | |||
redisTemplate.opsForValue().set(key, value, timeout, unit); | |||
} | |||
/** | |||
* 往redis中存入数据 默认为不过期 | |||
* | |||
* @param key key | |||
* @param value value | |||
*/ | |||
public void setDefault(String key, String value) { | |||
redisTemplate.opsForValue().set(key, value); | |||
} | |||
public boolean setIfAbsent(String key, String value, long timeout, TimeUnit unit) { | |||
return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit); | |||
} | |||
public long increment(String key, long delta) { | |||
return redisTemplate.opsForValue().increment(key, delta); | |||
} | |||
public Boolean delete(String key) { | |||
return redisTemplate.delete(key); | |||
} | |||
public long listRightPush(String key, String value) { | |||
return redisTemplate.opsForList().rightPush(key, value); | |||
} | |||
/** | |||
* 返回存储在 key 的列表里指定范围内的元素。 start 和 end 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推。 | |||
* 偏移量也可以是负数,表示偏移量是从list尾部开始计数。 例如, -1 表示列表的最后一个元素,-2 是倒数第二个,以此类推 | |||
*/ | |||
public List<String> listRange(String key, long start, long end) { | |||
return redisTemplate.opsForList().range(key, start, end); | |||
} | |||
public Long listSize(String key) { | |||
return redisTemplate.opsForList().size(key); | |||
} | |||
public Boolean hashHasKey(String key, Object hashKey) { | |||
return opsForHash().hasKey(key, hashKey); | |||
} | |||
public Object hashGet(String key, Object hashKey) { | |||
return opsForHash().get(key, hashKey); | |||
} | |||
public void hashPut(String key, Object hashKey, Object value) { | |||
opsForHash().put(key, hashKey, value); | |||
} | |||
public Boolean hashPutIfAbsent(String key, Object hashKey, Object value) { | |||
return opsForHash().putIfAbsent(key, hashKey, value); | |||
} | |||
public void hashPutAll(String key, Map<? extends Object, ? extends Object> m) { | |||
opsForHash().putAll(key, m); | |||
} | |||
public Long hashIncrement(String key, Object hashKey, long delta) { | |||
return opsForHash().increment(key, hashKey, delta); | |||
} | |||
public Long hashDelete(String key, Object... hashKeys) { | |||
return opsForHash().delete(key, hashKeys); | |||
} | |||
public Map<Object, Object> hashScan(String key, String pattern) { | |||
ScanOptionsBuilder b = new ScanOptionsBuilder(); | |||
Cursor<Entry<Object, Object>> s = opsForHash().scan(key, b.match(pattern).build()); | |||
Map<Object, Object> map = new HashMap<>(); | |||
s.forEachRemaining(e -> map.put(e.getKey(), e.getValue())); | |||
return map; | |||
} | |||
public String findStr(String key, int timeout, Supplier<String> valueSupplier) { | |||
String str = get(key); | |||
if (!StringTools.hasText(str)) { | |||
str = valueSupplier.get(); | |||
set(key, str, timeout); | |||
} | |||
return str; | |||
} | |||
public <T extends BaseEntity> T findObj(Class<T> clazz, String key, int timeout, Supplier<T> valueSupplier) { | |||
String jsonStr = (String)get(key); | |||
try { | |||
if (!StringTools.hasText(jsonStr)) { | |||
T obj = valueSupplier.get(); | |||
jsonStr = JsonTools.toJsonStr(obj); | |||
set(key, jsonStr, timeout); | |||
} | |||
return JsonTools.json2Object(jsonStr, clazz); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
public <T extends BaseEntity> T findObj(Class<T> clazz, String key) { | |||
String jsonStr = redisTemplate.opsForValue().get(key); | |||
try { | |||
return JsonTools.json2Object(jsonStr, clazz); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
public <T> Map<String, T> findMap(Class<T> clazz, String key, int timeout, Supplier<Map<String, T>> valueSupplier) { | |||
String jsonStr = get(key); | |||
try { | |||
if (!StringTools.hasText(jsonStr)) { | |||
Map<String, T> map = valueSupplier.get(); | |||
jsonStr = JsonTools.toJsonStr(map); | |||
set(key, jsonStr, timeout); | |||
} | |||
return JsonTools.json2Map(jsonStr, String.class, clazz); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
return new HashedMap<>(); | |||
} | |||
} | |||
public <T> List<T> findList(Class<T> clazz, String key, int timeout, Supplier<Collection<T>> valueSupplier) { | |||
String jsonStr = get(key); | |||
try { | |||
if (!StringTools.hasText(jsonStr)) { | |||
Collection<T> c = valueSupplier.get(); | |||
jsonStr = JsonTools.toJsonStr(c); | |||
set(key, jsonStr, timeout); | |||
} | |||
return JsonTools.json2List(jsonStr, clazz); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
return new ArrayList<>(); | |||
} | |||
} | |||
public <T extends BaseEntity> Pagination findPagn(Class<T> clazz, String key, int timeout, | |||
Supplier<Pagination> valueSupplier) { | |||
String jsonStr = get(key); | |||
try { | |||
if (!StringTools.hasText(jsonStr)) { | |||
Pagination c = valueSupplier.get(); | |||
jsonStr = JsonTools.toJsonStr(c); | |||
set(key, jsonStr, timeout); | |||
} | |||
return JsonTools.json2Pagn(jsonStr, clazz); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
return new Pagination().setResult(new ArrayList<>()); | |||
} | |||
} | |||
private <HK, HV> HashOperations<String, HK, HV> opsForHash() { | |||
return redisTemplate.opsForHash(); | |||
} | |||
private void set(String key, String value, int timeout) { | |||
redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS); | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
package cn.com.taiji.inss.manager.handler; | |||
import cn.com.taiji.core.manager.comm.AbstractCommServiceHandler; | |||
import cn.com.taiji.core.model.comm.protocol.SignServiceCommand; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceType; | |||
public abstract class AbstractInssServiceHandler<C extends SignServiceCommand> | |||
extends AbstractCommServiceHandler<InssServiceType> { | |||
protected AbstractInssServiceHandler(InssServiceType serviceType) { | |||
super(serviceType); | |||
} | |||
} |
@@ -1,15 +0,0 @@ | |||
package cn.com.taiji.inss.manager.handler; | |||
import cn.com.taiji.core.manager.comm.AbstractCommServiceHandler; | |||
import cn.com.taiji.core.model.comm.protocol.SignServiceCommand; | |||
import cn.com.taiji.core.model.comm.protocol.sample.SampleServiceType; | |||
public abstract class AbstractSampleServiceHandler<C extends SignServiceCommand> | |||
extends AbstractCommServiceHandler<SampleServiceType> { | |||
protected AbstractSampleServiceHandler(SampleServiceType serviceType) { | |||
super(serviceType); | |||
} | |||
} |
@@ -1,61 +0,0 @@ | |||
package cn.com.taiji.inss.manager.handler; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import com.zgglyun.common.model.AbstractHttpRequestInfo; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.com.taiji.common.model.file.FileProtocolSystemError; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeRequest; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeResponse; | |||
import cn.com.taiji.core.model.comm.protocol.SignJsonRequest; | |||
import cn.com.taiji.core.model.comm.protocol.sample.DemoServiceCmd; | |||
import cn.com.taiji.core.model.comm.protocol.sample.SampleServiceType; | |||
import cn.com.taiji.core.model.comm.protocol.sample.TypeSampleRequest; | |||
import cn.com.taiji.core.model.comm.protocol.sample.TypeSampleResponse; | |||
import cn.com.taiji.core.model.comm.protocol.sample.valid.demo.CommonResponse; | |||
import cn.com.taiji.core.model.comm.protocol.valid.GlyServiceError; | |||
/** | |||
* | |||
* @author Peream <br> | |||
* Create Time:2019年7月28日 下午4:45:09<br> | |||
* @since 1.0 | |||
* @version 1.0 | |||
*/ | |||
@Service | |||
public class SampleServiceHandler extends AbstractSampleServiceHandler<DemoServiceCmd> { | |||
@Autowired | |||
public SampleServiceHandler() { | |||
super(SampleServiceType.SAMPLE); | |||
} | |||
@Override | |||
protected <T extends AbstractSignTypeRequest<?>> AbstractSignTypeResponse handleInternal(T request, | |||
SignJsonRequest jsonReq, AbstractHttpRequestInfo reqInfo) throws ServiceHandleException { | |||
DemoServiceCmd cmd = DemoServiceCmd.fromIfCode(jsonReq.getIfCode()); | |||
switch (cmd) { | |||
case TYPESAMMPLE: | |||
return typeSample((TypeSampleRequest)request, jsonReq, reqInfo); | |||
case ETCTRANS: | |||
return new CommonResponse(); | |||
default: | |||
throw FileProtocolSystemError.NOT_SUPPORT.toHandleException(jsonReq.getIfCode()); | |||
} | |||
} | |||
private TypeSampleResponse typeSample(TypeSampleRequest req, SignJsonRequest jsonReq, | |||
AbstractHttpRequestInfo reqInfo) throws ServiceHandleException { | |||
logger.info("jsonReq:{}", jsonReq); | |||
// 注意,业务逻辑应该写在manager,handler类似controller | |||
if (req.isValid()) { | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("valid为true会抛出异常"); | |||
} | |||
TypeSampleResponse res = new TypeSampleResponse(); | |||
res.setMsg(req.getCardId() + " success!"); | |||
return res; | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
package cn.com.taiji.inss.manager.handler; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.com.taiji.common.model.file.FileProtocolSystemError; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeRequest; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeResponse; | |||
import cn.com.taiji.core.model.comm.protocol.SignJsonRequest; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceCmd; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceType; | |||
import cn.com.taiji.core.model.comm.protocol.inss.VfjBatchApplyRequest; | |||
import cn.com.taiji.inss.manager.vfj.VfjBatchApplyManager; | |||
import com.zgglyun.common.model.AbstractHttpRequestInfo; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
@Service | |||
public class VfjServiceHandler extends AbstractInssServiceHandler<InssServiceCmd> { | |||
public VfjServiceHandler() { | |||
super(InssServiceType.VFJ); | |||
} | |||
@Autowired | |||
private VfjBatchApplyManager vfjBatchApplyManager; | |||
@Override | |||
protected <T extends AbstractSignTypeRequest<?>> AbstractSignTypeResponse handleInternal(T request, SignJsonRequest jsonReq, AbstractHttpRequestInfo reqInfo) throws ServiceHandleException { | |||
InssServiceCmd cmd = InssServiceCmd.fromIfCode(jsonReq.getIfCode()); | |||
switch (cmd) { | |||
case BATCHAPPLY: | |||
return vfjBatchApplyManager.serviceHandle(cmd, (VfjBatchApplyRequest) request); | |||
default: | |||
throw FileProtocolSystemError.NOT_SUPPORT.toHandleException(jsonReq.getIfCode()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,79 @@ | |||
package cn.com.taiji.inss.manager.model; | |||
import cn.com.taiji.common.manager.ManagerException; | |||
import cn.com.taiji.common.model.BaseModel; | |||
import cn.com.taiji.core.model.comm.protocol.SM3Utils; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceCmd; | |||
import cn.com.taiji.inss.config.VfjConfigProperties; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
import lombok.experimental.Accessors; | |||
import java.nio.charset.StandardCharsets; | |||
import java.time.LocalDateTime; | |||
import java.time.format.DateTimeFormatter; | |||
@Getter | |||
@Setter | |||
@Accessors(chain = true) | |||
public class VfjCommonRequest extends BaseModel { | |||
@JsonProperty(value = "TransCode") | |||
private String transCode; | |||
@JsonProperty(value = "TermTrace") | |||
private String termTrace; | |||
@JsonProperty(value = "TermTime") | |||
private String termTime; | |||
@JsonProperty(value = "NetNodeId") | |||
private String netNodeId; | |||
@JsonProperty(value = "TerminalId") | |||
private String terminalId; | |||
@JsonProperty(value = "Sign") | |||
private String sign; | |||
@JsonProperty(value = "BuzzData") | |||
private String buzzData; | |||
public VfjCommonRequest(VfjConfigProperties vfjConfig, InssServiceCmd cmd, String sessionId, String buzzData, String termTrace) { | |||
this.transCode = cmd.getTransCode(); | |||
this.termTrace = termTrace; | |||
this.termTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); | |||
this.netNodeId = vfjConfig.getNetNodeId(); | |||
this.terminalId = vfjConfig.getTerminalId(); | |||
this.buzzData = buzzData; | |||
this.sign = this.createSign(sessionId); | |||
} | |||
private String createSign(String sessionId) { | |||
String sign = this.transCode + "," + this.netNodeId + "," + this.terminalId + "," + | |||
this.termTrace + "," + this.termTime + "," + this.buzzData + "," + | |||
"0000" + "," + sessionId; | |||
return sm3(sign.getBytes(StandardCharsets.UTF_8)); | |||
} | |||
/** | |||
* 计算sha256消息摘要,结果为小写 | |||
*/ | |||
private String sm3(byte[] src) { | |||
String hex = byte2Hex(SM3Utils.hash(src)); | |||
return hex.toLowerCase(); | |||
} | |||
/** | |||
* 将字节数组转为16进制HEX | |||
*/ | |||
private String byte2Hex(byte[] bytes) { | |||
StringBuilder stringBuffer = new StringBuilder(); | |||
String temp = null; | |||
for (byte aByte : bytes) { | |||
temp = Integer.toHexString(aByte & 0xFF); | |||
if (temp.length() == 1) { | |||
// 补0 | |||
stringBuffer.append("0"); | |||
} | |||
stringBuffer.append(temp); | |||
} | |||
return stringBuffer.toString(); | |||
} | |||
} |
@@ -0,0 +1,18 @@ | |||
package cn.com.taiji.inss.manager.model; | |||
import cn.com.taiji.common.model.BaseModel; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
@Getter | |||
@Setter | |||
public class VfjCommonResponse extends BaseModel { | |||
@JsonProperty(value = "Code") | |||
private String code; | |||
@JsonProperty(value = "Msg") | |||
private String msg; | |||
@JsonProperty(value = "BuzzData") | |||
private String buzzData; | |||
} |
@@ -0,0 +1,95 @@ | |||
package cn.com.taiji.inss.manager.vfj; | |||
import cn.com.taiji.common.manager.AbstractManager; | |||
import cn.com.taiji.common.manager.ManagerException; | |||
import cn.com.taiji.common.manager.net.http.HttpClientHelper; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.com.taiji.common.model.BaseModel; | |||
import cn.com.taiji.common.pub.EncodeTool; | |||
import cn.com.taiji.common.pub.json.JsonTools; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeResponse; | |||
import cn.com.taiji.core.model.comm.protocol.SignServiceCommand; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceCmd; | |||
import cn.com.taiji.core.model.comm.protocol.inss.VfjBatchApplyRequest; | |||
import cn.com.taiji.core.model.comm.protocol.inss.VfjStartUpRequest; | |||
import cn.com.taiji.core.model.comm.protocol.inss.VfjStartUpResponse; | |||
import cn.com.taiji.core.model.comm.protocol.valid.GlyServiceError; | |||
import cn.com.taiji.inss.config.VfjConfigProperties; | |||
import cn.com.taiji.inss.manager.cache.RedisWrapManager; | |||
import cn.com.taiji.inss.manager.model.VfjCommonRequest; | |||
import cn.com.taiji.inss.manager.model.VfjCommonResponse; | |||
import cn.hutool.crypto.asymmetric.KeyType; | |||
import cn.hutool.crypto.asymmetric.SM2; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
import java.io.IOException; | |||
import java.util.concurrent.TimeUnit; | |||
@Service | |||
public abstract class AbstractHandleManager extends AbstractManager { | |||
private static final String VFJ_SESSION_ID_KEY = "vfj_session_id"; | |||
private static final String VFJ_TERM_TRACE = "vfj_term_trace"; | |||
@Autowired | |||
protected RedisWrapManager redisWrapManager; | |||
@Autowired | |||
private VfjConfigProperties vfjConfig; | |||
private final SM2 sm2 = new SM2(vfjConfig.getClientPrivateKey(), vfjConfig.getServerPublicKey()); | |||
public String getSessionId(InssServiceCmd cmd) throws ServiceHandleException { | |||
if (cmd == InssServiceCmd.REGISTRY) | |||
return "0000000000000000"; | |||
if (cmd == InssServiceCmd.STARTUP) | |||
return "0000000000000000"; | |||
String sessionId = redisWrapManager.get(VFJ_SESSION_ID_KEY); | |||
if (!hasText(sessionId)) { | |||
VfjStartUpResponse response = this.excute(InssServiceCmd.STARTUP, new VfjStartUpRequest(), VfjStartUpResponse.class); | |||
if (!hasText(response.getEnvelop())) | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:VFJ会话ID加密信封返回为空"); | |||
byte[] sessionIdBytes = sm2.decrypt(EncodeTool.decodeBase64(response.getEnvelop()), KeyType.PrivateKey); | |||
sessionId = new String(sessionIdBytes); | |||
redisWrapManager.set(VFJ_SESSION_ID_KEY, sessionId, 86400, TimeUnit.SECONDS); | |||
} | |||
return sessionId; | |||
} | |||
protected final String excute(InssServiceCmd cmd, BaseModel req) throws ServiceHandleException { | |||
try { | |||
VfjCommonRequest vfjRequest = new VfjCommonRequest(vfjConfig, cmd, this.getSessionId(cmd), req.toJson(), this.getTermTrace()); | |||
VfjCommonResponse vfjResponse = HttpClientHelper.jsonPost(VfjCommonResponse.class, vfjConfig.getUrl(), vfjRequest.toJson()); | |||
if (vfjResponse.getCode().equals("E9997")) { | |||
return this.excute(cmd, req); | |||
} else if (vfjResponse.getCode().equals("0000")) { | |||
if (!hasText(vfjResponse.getBuzzData())) | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:无返回信息!"); | |||
return vfjResponse.getBuzzData(); | |||
} else { | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:" + vfjResponse.getMsg()); | |||
} | |||
} catch (IOException e) { | |||
logger.info("{}", e); | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:网络异常!"); | |||
} | |||
} | |||
protected final <E extends AbstractSignTypeResponse> E excute(InssServiceCmd cmd, BaseModel req, Class<E> resClass) throws ServiceHandleException { | |||
String responseStr = this.excute(cmd, req); | |||
try { | |||
return JsonTools.json2Object(responseStr, resClass); | |||
} catch (IOException e) { | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:VFJ接口返回值格式错误!"); | |||
} | |||
} | |||
private String getTermTrace() { | |||
// long termTrace = redisWrapManager.increment(VFJ_TERM_TRACE,1); | |||
// return termTrace; | |||
return ""; | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
package cn.com.taiji.inss.manager.vfj; | |||
import cn.com.taiji.common.manager.ManagerException; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.com.taiji.common.pub.json.JsonTools; | |||
import cn.com.taiji.core.model.comm.protocol.inss.InssServiceCmd; | |||
import cn.com.taiji.core.model.comm.protocol.inss.VfjBatchApplyRequest; | |||
import cn.com.taiji.core.model.comm.protocol.inss.VfjStartUpResponse; | |||
import org.springframework.stereotype.Service; | |||
import java.io.IOException; | |||
@Service | |||
public class VfjBatchApplyManager extends AbstractHandleManager{ | |||
public VfjStartUpResponse serviceHandle(InssServiceCmd cmd,VfjBatchApplyRequest request) throws ServiceHandleException { | |||
return excute(cmd,request,VfjStartUpResponse.class); | |||
} | |||
} |
@@ -45,3 +45,18 @@ app: | |||
# 自定义服务地址map,key为服务名、value为服务地址。如果配置了服务地址,接口调用时请求到该地址,如果没配置,默认请求到gateway | |||
serviceAddr: | |||
sample: http://127.0.0.1:8086 | |||
vfj: | |||
# vfj 环境变量配置 | |||
# vfj 请求url地址 | |||
url: https://10.52.0.139:8060/api/scobu/issuework.do | |||
# vfj 终端号 | |||
terminalId: 520000000009 | |||
# vfj 网点号 | |||
netNodeId: 02000000 | |||
# VFJ 服务端公钥 | |||
serverPublicKey: ApjSuPm4MQLWSBp/7TVG80jrd9O1LDJ30lrU2EQr8otw | |||
# VFJ 核心生成的公钥 | |||
clientPublicKey: A9oRr3Aq8czQZWRogGUoHvPcXl6aRJHdfND1CqN0NiKu | |||
# VFJ 核心生成的公钥 | |||
clientPrivateKey: UZv2a6R9gxcWgZSwydA6hI5SU85W4Q1WsbP84Iqe1iE= |