Implement credit parse result polling and sentinel handling
This commit is contained in:
@@ -18,6 +18,12 @@ import java.util.Map;
|
||||
@Component
|
||||
public class CreditParseClient {
|
||||
|
||||
private static final int PLATFORM_SUCCESS_CODE = 10000;
|
||||
private static final int INITIATE_SUCCESS_STATUS = 1;
|
||||
private static final int INITIATE_SUCCESS_REASON_CODE = 200;
|
||||
private static final int RESULT_QUERY_MAX_ATTEMPTS = 5;
|
||||
private static final long RESULT_QUERY_INTERVAL_MILLIS = 2000L;
|
||||
|
||||
@Resource
|
||||
private HttpUtil httpUtil;
|
||||
|
||||
@@ -27,7 +33,10 @@ public class CreditParseClient {
|
||||
@Value("${credit-parse.api.url}")
|
||||
private String creditParseUrl;
|
||||
|
||||
@Value("${credit-parse.api.org-code:902000}")
|
||||
@Value("${credit-parse.api.result-url}")
|
||||
private String creditParseResultUrl;
|
||||
|
||||
@Value("${credit-parse.api.org-code:999000}")
|
||||
private String orgCode;
|
||||
|
||||
@Value("${credit-parse.api.run-type:1}")
|
||||
@@ -43,19 +52,13 @@ public class CreditParseClient {
|
||||
public CreditParseInvokeResponse parse(String model, String remotePath) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
String actualModel = StringUtils.isBlank(model) ? defaultModel : model;
|
||||
String serialNum = buildSerialNum();
|
||||
try {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("serialNum", buildSerialNum());
|
||||
params.put("orgCode", orgCode);
|
||||
params.put("runType", runType);
|
||||
params.put("remotePath", remotePath);
|
||||
params.put("model", actualModel);
|
||||
Map<String, Object> initiateParams = buildInitiateParams(serialNum, actualModel, remotePath);
|
||||
CreditParseInvokeResponse initiateResponse = request(creditParseUrl, initiateParams, "发起接口");
|
||||
requireSuccessfulInitiateResponse(initiateResponse, "征信解析发起接口");
|
||||
|
||||
log.info("【征信解析】调用请求: url={}, params={}", creditParseUrl, toJson(params));
|
||||
String responseJson = httpUtil.postUrlEncodedFormForString(creditParseUrl, params, null);
|
||||
log.info("【征信解析】调用返回JSON: {}", responseJson);
|
||||
|
||||
CreditParseInvokeResponse response = objectMapper.readValue(responseJson, CreditParseInvokeResponse.class);
|
||||
CreditParseInvokeResponse response = queryResult(serialNum);
|
||||
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
log.info("【征信解析】调用完成: success={}, code={}, businessStatusCode={}, cost={}ms",
|
||||
@@ -65,17 +68,136 @@ public class CreditParseClient {
|
||||
? response.getData().getMappingOutputFields().getStatusCode() : null,
|
||||
elapsed);
|
||||
return response;
|
||||
} catch (LsfxApiException e) {
|
||||
log.error("【征信解析】调用失败: serialNum={}, model={}, remotePath={}, error={}",
|
||||
serialNum, actualModel, remotePath, e.getMessage(), e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("【征信解析】调用失败: model={}, remotePath={}, error={}",
|
||||
actualModel, remotePath, e.getMessage(), e);
|
||||
log.error("【征信解析】调用失败: serialNum={}, model={}, remotePath={}, error={}",
|
||||
serialNum, actualModel, remotePath, e.getMessage(), e);
|
||||
throw new LsfxApiException("征信解析调用失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> buildInitiateParams(String serialNum, String model, String remotePath) {
|
||||
Map<String, Object> params = buildBaseParams(serialNum);
|
||||
params.put("remotePath", remotePath);
|
||||
params.put("model", model);
|
||||
return params;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildBaseParams(String serialNum) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("serialNum", serialNum);
|
||||
params.put("orgCode", orgCode);
|
||||
params.put("runType", runType);
|
||||
return params;
|
||||
}
|
||||
|
||||
private CreditParseInvokeResponse queryResult(String serialNum) {
|
||||
Map<String, Object> params = buildBaseParams(serialNum);
|
||||
for (int attempt = 1; attempt <= RESULT_QUERY_MAX_ATTEMPTS; attempt++) {
|
||||
CreditParseInvokeResponse response = request(creditParseResultUrl, params,
|
||||
"结果接口第" + attempt + "次查询");
|
||||
requireSuccessfulServiceResponse(response, "征信解析结果接口");
|
||||
if (response.getData() == null || response.getData().getMappingOutputFields() == null) {
|
||||
waitForNextResult(serialNum, attempt);
|
||||
continue;
|
||||
}
|
||||
if (response.getData().getMappingOutputFields().getPayload() != null) {
|
||||
return response;
|
||||
}
|
||||
waitForNextResult(serialNum, attempt);
|
||||
}
|
||||
throw new LsfxApiException("征信解析结果未返回");
|
||||
}
|
||||
|
||||
private void waitForNextResult(String serialNum, int attempt) {
|
||||
if (attempt >= RESULT_QUERY_MAX_ATTEMPTS) {
|
||||
return;
|
||||
}
|
||||
log.info("【征信解析】结果未返回: serialNum={}, attempt={}/{}, {}ms后重试",
|
||||
serialNum, attempt, RESULT_QUERY_MAX_ATTEMPTS, RESULT_QUERY_INTERVAL_MILLIS);
|
||||
try {
|
||||
sleepBeforeNextResultQuery(RESULT_QUERY_INTERVAL_MILLIS);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new LsfxApiException("征信解析结果查询被中断", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void sleepBeforeNextResultQuery(long intervalMillis) throws InterruptedException {
|
||||
Thread.sleep(intervalMillis);
|
||||
}
|
||||
|
||||
private CreditParseInvokeResponse request(String url, Map<String, Object> params, String stage) {
|
||||
try {
|
||||
log.info("【征信解析】{}请求: url={}, params={}", stage, url, toJson(params));
|
||||
String responseJson = httpUtil.postUrlEncodedFormForString(url, params, null);
|
||||
log.info("【征信解析】{}返回JSON: {}", stage, responseJson);
|
||||
return objectMapper.readValue(responseJson, CreditParseInvokeResponse.class);
|
||||
} catch (LsfxApiException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new LsfxApiException("征信解析" + stage + "调用失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void requireSuccessfulInitiateResponse(CreditParseInvokeResponse response, String stage) {
|
||||
requireSuccessfulServiceResponse(response, stage);
|
||||
}
|
||||
|
||||
private void requireSuccessfulServiceResponse(CreditParseInvokeResponse response, String stage) {
|
||||
requireSuccessfulPlatformResponse(response, stage);
|
||||
if (response.getData() == null) {
|
||||
throw new LsfxApiException(stage + "返回结果为空");
|
||||
}
|
||||
if (!Integer.valueOf(INITIATE_SUCCESS_STATUS).equals(response.getData().getStatus())) {
|
||||
throw new LsfxApiException(serviceErrorMessage(response, stage + "状态异常: " + response.getData().getStatus()));
|
||||
}
|
||||
if (!Integer.valueOf(INITIATE_SUCCESS_REASON_CODE).equals(response.getData().getReasonCode())) {
|
||||
throw new LsfxApiException(serviceErrorMessage(response, stage + "原因码异常: " + response.getData().getReasonCode()));
|
||||
}
|
||||
}
|
||||
|
||||
private void requireSuccessfulPlatformResponse(CreditParseInvokeResponse response, String stage) {
|
||||
if (response == null) {
|
||||
throw new LsfxApiException(stage + "返回结果为空");
|
||||
}
|
||||
if (!Boolean.TRUE.equals(response.getSuccess())) {
|
||||
throw new LsfxApiException(stage + "平台调用失败");
|
||||
}
|
||||
if (!Integer.valueOf(PLATFORM_SUCCESS_CODE).equals(response.getCode())) {
|
||||
throw new LsfxApiException(stage + "平台状态码异常: " + response.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildSerialNum() {
|
||||
return "CCDI_CREDIT_" + System.currentTimeMillis() + "_" + IdUtils.fastSimpleUUID();
|
||||
}
|
||||
|
||||
private String stringValue(Object value, String defaultValue) {
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
String text = value.toString().trim();
|
||||
return text.isEmpty() ? defaultValue : text;
|
||||
}
|
||||
|
||||
private String serviceErrorMessage(CreditParseInvokeResponse response, String defaultValue) {
|
||||
if (response == null || response.getData() == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
String reasonMessage = stringValue(response.getData().getReasonMessage(), null);
|
||||
if (reasonMessage != null) {
|
||||
return reasonMessage;
|
||||
}
|
||||
if (response.getData().getMappingOutputFields() != null) {
|
||||
return stringValue(response.getData().getMappingOutputFields().getMessage(), defaultValue);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private String toJson(Object value) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(value);
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package com.ruoyi.lsfx.domain.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class CreditParseInvokeData {
|
||||
|
||||
private CreditParseResponse mappingOutputFields;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Integer reasonCode;
|
||||
|
||||
private String reasonMessage;
|
||||
}
|
||||
|
||||
@@ -14,16 +14,20 @@ import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -46,7 +50,7 @@ class CreditParseControllerTest {
|
||||
void shouldUseDefaultModelWhenMissing() {
|
||||
CreditParseInvokeResponse response = new CreditParseInvokeResponse();
|
||||
response.setSuccess(true);
|
||||
response.setCode(1000);
|
||||
response.setCode(10000);
|
||||
|
||||
String remotePath = "http://127.0.0.1:62318/profile/credit-html/a.html";
|
||||
when(client.parse(eq("LXCUSTALL"), eq(remotePath))).thenReturn(response);
|
||||
@@ -69,13 +73,14 @@ class CreditParseControllerTest {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
void creditParseClient_shouldParseSuccessResponseWithStringPayload() throws Exception {
|
||||
void creditParseClient_shouldInitiateAndQueryResultWithSameSerialNum() throws Exception {
|
||||
HttpUtil httpUtil = mock(HttpUtil.class);
|
||||
CreditParseClient parseClient = new CreditParseClient();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ReflectionTestUtils.setField(parseClient, "httpUtil", httpUtil);
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseUrl", "http://tz/api/service/interface/invokeService/xfeature");
|
||||
ReflectionTestUtils.setField(parseClient, "orgCode", "902000");
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseResultUrl", "http://tz/api/service/interface/invokeService/xfeatureResult");
|
||||
ReflectionTestUtils.setField(parseClient, "orgCode", "999000");
|
||||
ReflectionTestUtils.setField(parseClient, "runType", "1");
|
||||
ReflectionTestUtils.setField(parseClient, "defaultModel", "LXCUSTALL");
|
||||
ReflectionTestUtils.setField(parseClient, "objectMapper", objectMapper);
|
||||
@@ -86,8 +91,12 @@ class CreditParseControllerTest {
|
||||
eq("http://tz/api/service/interface/invokeService/xfeature"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn("{\"success\":true,\"code\":10000,\"data\":{\"mappingOutputFields\":{\"message\":\"\",\"status_code\":\"0\",\"payload\":"
|
||||
+ objectMapper.writeValueAsString(payload) + "}}}");
|
||||
)).thenReturn(initiateSuccessResponse());
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn(resultSuccessResponse(objectMapper, payload, "ERR_SHOULD_IGNORE"));
|
||||
|
||||
String remotePath = "http://127.0.0.1:62318/profile/credit-html/a.html";
|
||||
CreditParseInvokeResponse actual = parseClient.parse(remotePath);
|
||||
@@ -96,19 +105,188 @@ class CreditParseControllerTest {
|
||||
assertEquals(10000, actual.getCode());
|
||||
assertEquals("330101199001010011", actual.getData().getMappingOutputFields()
|
||||
.getPayload().getLxHeader().get("query_cert_no"));
|
||||
ArgumentCaptor<Map<String, Object>> paramsCaptor = ArgumentCaptor.forClass((Class) Map.class);
|
||||
ArgumentCaptor<Map<String, Object>> initiateParamsCaptor = ArgumentCaptor.forClass((Class) Map.class);
|
||||
verify(httpUtil).postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeature"),
|
||||
paramsCaptor.capture(),
|
||||
initiateParamsCaptor.capture(),
|
||||
isNull()
|
||||
);
|
||||
ArgumentCaptor<Map<String, Object>> resultParamsCaptor = ArgumentCaptor.forClass((Class) Map.class);
|
||||
verify(httpUtil).postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
resultParamsCaptor.capture(),
|
||||
isNull()
|
||||
);
|
||||
|
||||
Map<String, Object> params = paramsCaptor.getValue();
|
||||
assertNotNull(params.get("serialNum"));
|
||||
assertTrue(params.get("serialNum").toString().startsWith("CCDI_CREDIT_"));
|
||||
assertEquals("902000", params.get("orgCode"));
|
||||
assertEquals("1", params.get("runType"));
|
||||
assertEquals(remotePath, params.get("remotePath"));
|
||||
assertEquals("LXCUSTALL", params.get("model"));
|
||||
Map<String, Object> initiateParams = initiateParamsCaptor.getValue();
|
||||
Map<String, Object> resultParams = resultParamsCaptor.getValue();
|
||||
assertNotNull(initiateParams.get("serialNum"));
|
||||
assertTrue(initiateParams.get("serialNum").toString().startsWith("CCDI_CREDIT_"));
|
||||
assertEquals(initiateParams.get("serialNum"), resultParams.get("serialNum"));
|
||||
assertEquals("999000", initiateParams.get("orgCode"));
|
||||
assertEquals("999000", resultParams.get("orgCode"));
|
||||
assertEquals("1", initiateParams.get("runType"));
|
||||
assertEquals("1", resultParams.get("runType"));
|
||||
assertEquals(remotePath, initiateParams.get("remotePath"));
|
||||
assertEquals("LXCUSTALL", initiateParams.get("model"));
|
||||
assertEquals(false, resultParams.containsKey("remotePath"));
|
||||
assertEquals(false, resultParams.containsKey("model"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
void creditParseClient_shouldRetryEmptyPayloadFiveTimesWithTwoSecondInterval() throws Exception {
|
||||
HttpUtil httpUtil = mock(HttpUtil.class);
|
||||
TestableCreditParseClient parseClient = new TestableCreditParseClient();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ReflectionTestUtils.setField(parseClient, "httpUtil", httpUtil);
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseUrl", "http://tz/api/service/interface/invokeService/xfeature");
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseResultUrl", "http://tz/api/service/interface/invokeService/xfeatureResult");
|
||||
ReflectionTestUtils.setField(parseClient, "orgCode", "999000");
|
||||
ReflectionTestUtils.setField(parseClient, "runType", "1");
|
||||
ReflectionTestUtils.setField(parseClient, "defaultModel", "LXCUSTALL");
|
||||
ReflectionTestUtils.setField(parseClient, "objectMapper", objectMapper);
|
||||
|
||||
String emptyPayloadResponse = "{\"success\":true,\"code\":10000,\"data\":{\"status\":1,\"reasonCode\":200,\"mappingOutputFields\":{\"message\":\"\",\"status_code\":\"ERR_SHOULD_IGNORE\"}}}";
|
||||
String payload = "{\"lx_header\":{\"query_cert_no\":\"330101199001010011\",\"query_cust_name\":\"张三\",\"report_time\":\"2026-03-24\"}}";
|
||||
String resultResponse = resultSuccessResponse(objectMapper, payload, "ERR_SHOULD_IGNORE");
|
||||
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeature"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn(initiateSuccessResponse());
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn(emptyPayloadResponse, emptyPayloadResponse, emptyPayloadResponse, emptyPayloadResponse, resultResponse);
|
||||
|
||||
CreditParseInvokeResponse actual = parseClient.parse("http://127.0.0.1:62318/profile/credit-html/a.html");
|
||||
|
||||
assertEquals("330101199001010011", actual.getData().getMappingOutputFields()
|
||||
.getPayload().getLxHeader().get("query_cert_no"));
|
||||
verify(httpUtil, times(5)).postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
);
|
||||
assertEquals(List.of(2000L, 2000L, 2000L, 2000L), parseClient.getSleepIntervals());
|
||||
}
|
||||
|
||||
@Test
|
||||
void creditParseClient_shouldRejectInvalidOuterCode() throws Exception {
|
||||
HttpUtil httpUtil = mock(HttpUtil.class);
|
||||
TestableCreditParseClient parseClient = new TestableCreditParseClient();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ReflectionTestUtils.setField(parseClient, "httpUtil", httpUtil);
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseUrl", "http://tz/api/service/interface/invokeService/xfeature");
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseResultUrl", "http://tz/api/service/interface/invokeService/xfeatureResult");
|
||||
ReflectionTestUtils.setField(parseClient, "orgCode", "999000");
|
||||
ReflectionTestUtils.setField(parseClient, "runType", "1");
|
||||
ReflectionTestUtils.setField(parseClient, "defaultModel", "LXCUSTALL");
|
||||
ReflectionTestUtils.setField(parseClient, "objectMapper", objectMapper);
|
||||
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeature"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn(initiateSuccessResponse());
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn("{\"success\":true,\"code\":99999,\"data\":{\"mappingOutputFields\":{\"message\":\"\",\"status_code\":\"0\"}}}");
|
||||
|
||||
LsfxApiException exception = assertThrows(LsfxApiException.class,
|
||||
() -> parseClient.parse("http://127.0.0.1:62318/profile/credit-html/a.html"));
|
||||
|
||||
assertTrue(exception.getMessage().contains("平台状态码异常"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void creditParseClient_shouldRejectFailedResultStatus() throws Exception {
|
||||
HttpUtil httpUtil = mock(HttpUtil.class);
|
||||
TestableCreditParseClient parseClient = new TestableCreditParseClient();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ReflectionTestUtils.setField(parseClient, "httpUtil", httpUtil);
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseUrl", "http://tz/api/service/interface/invokeService/xfeature");
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseResultUrl", "http://tz/api/service/interface/invokeService/xfeatureResult");
|
||||
ReflectionTestUtils.setField(parseClient, "orgCode", "999000");
|
||||
ReflectionTestUtils.setField(parseClient, "runType", "1");
|
||||
ReflectionTestUtils.setField(parseClient, "defaultModel", "LXCUSTALL");
|
||||
ReflectionTestUtils.setField(parseClient, "objectMapper", objectMapper);
|
||||
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeature"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn(initiateSuccessResponse());
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn("{\"success\":true,\"code\":10000,\"data\":{\"reasonMessage\":\"解析失败\",\"reasonCode\":500,\"status\":0,\"mappingOutputFields\":{\"message\":\"结果异常\"}}}");
|
||||
|
||||
LsfxApiException exception = assertThrows(LsfxApiException.class,
|
||||
() -> parseClient.parse("http://127.0.0.1:62318/profile/credit-html/a.html"));
|
||||
|
||||
assertTrue(exception.getMessage().contains("解析失败"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void creditParseClient_shouldRejectFailedInitiateStatus() throws Exception {
|
||||
HttpUtil httpUtil = mock(HttpUtil.class);
|
||||
TestableCreditParseClient parseClient = new TestableCreditParseClient();
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
ReflectionTestUtils.setField(parseClient, "httpUtil", httpUtil);
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseUrl", "http://tz/api/service/interface/invokeService/xfeature");
|
||||
ReflectionTestUtils.setField(parseClient, "creditParseResultUrl", "http://tz/api/service/interface/invokeService/xfeatureResult");
|
||||
ReflectionTestUtils.setField(parseClient, "orgCode", "999000");
|
||||
ReflectionTestUtils.setField(parseClient, "runType", "1");
|
||||
ReflectionTestUtils.setField(parseClient, "defaultModel", "LXCUSTALL");
|
||||
ReflectionTestUtils.setField(parseClient, "objectMapper", objectMapper);
|
||||
|
||||
when(httpUtil.postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeature"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
)).thenReturn("{\"success\":true,\"code\":10000,\"data\":{\"mappingOutputFields\":{\"message\":\"文件写入失败\"},\"reasonMessage\":\"文件写入失败\",\"reasonCode\":500,\"status\":0}}");
|
||||
|
||||
LsfxApiException exception = assertThrows(LsfxApiException.class,
|
||||
() -> parseClient.parse("http://127.0.0.1:62318/profile/credit-html/a.html"));
|
||||
|
||||
assertTrue(exception.getMessage().contains("文件写入失败"));
|
||||
verify(httpUtil, times(0)).postUrlEncodedFormForString(
|
||||
eq("http://tz/api/service/interface/invokeService/xfeatureResult"),
|
||||
org.mockito.ArgumentMatchers.<Map<String, Object>>any(),
|
||||
isNull()
|
||||
);
|
||||
}
|
||||
|
||||
private static String initiateSuccessResponse() {
|
||||
return "{\"success\":true,\"code\":10000,\"data\":{\"traceId\":\"TRACE-001\","
|
||||
+ "\"mappingOutputFields\":{\"message\":\"文件写入成功,流水号为: CCDI_CREDIT_TEST\"},"
|
||||
+ "\"reasonMessage\":\"Running successfully\",\"procCode\":\"999000\","
|
||||
+ "\"reasonCode\":200,\"status\":1}}";
|
||||
}
|
||||
|
||||
private static String resultSuccessResponse(ObjectMapper objectMapper, String payload, String statusCode) throws Exception {
|
||||
return "{\"success\":true,\"code\":10000,\"data\":{\"status\":1,\"reasonCode\":200,"
|
||||
+ "\"mappingOutputFields\":{\"message\":\"\",\"status_code\":\"" + statusCode + "\",\"payload\":"
|
||||
+ objectMapper.writeValueAsString(payload) + "}}}";
|
||||
}
|
||||
|
||||
private static class TestableCreditParseClient extends CreditParseClient {
|
||||
private final List<Long> sleepIntervals = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
protected void sleepBeforeNextResultQuery(long intervalMillis) {
|
||||
sleepIntervals.add(intervalMillis);
|
||||
}
|
||||
|
||||
private List<Long> getSleepIntervals() {
|
||||
return sleepIntervals;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user